From: Michael Tremer Date: Fri, 20 May 2022 18:43:33 +0000 (+0000) Subject: execute: Drop capabilities X-Git-Tag: 0.9.28~769 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d40cf8d41de1e6ae41facb1e74257733ee9296ac;p=pakfire.git execute: Drop capabilities Signed-off-by: Michael Tremer --- diff --git a/configure.ac b/configure.ac index 2632006f8..20f06cd15 100644 --- a/configure.ac +++ b/configure.ac @@ -162,6 +162,7 @@ AC_CHECK_HEADERS([ \ grp.h \ libgen.h \ libintl.h \ + linux/capability.h \ linux/limits.h \ linux/magic.h \ linux/sched.h \ @@ -176,11 +177,13 @@ AC_CHECK_HEADERS([ \ stdlib.h \ string.h \ syslog.h \ + sys/capability.h \ sys/epoll.h \ sys/file.h \ sys/ioctl.h \ sys/mount.h \ sys/personality.h \ + sys/prctl.h \ sys/random.h \ sys/resource.h \ sys/sendfile.h \ @@ -211,6 +214,7 @@ AC_CHECK_FUNCS([ \ nftw \ openlog \ personality \ + prctl \ remove \ secure_getenv \ sendfile \ diff --git a/src/libpakfire/execute.c b/src/libpakfire/execute.c index 88d21dffa..37262e60d 100644 --- a/src/libpakfire/execute.c +++ b/src/libpakfire/execute.c @@ -21,13 +21,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -323,6 +326,118 @@ int pakfire_execute_capture_stdout_to_array(struct pakfire* pakfire, void* data, return default_logging_callback(pakfire, NULL, priority, line, length); } +static int pakfire_drop_capabilities(struct pakfire* pakfire) { + const int capabilities[] = { + // Deny access to the kernel's audit system + CAP_AUDIT_CONTROL, + CAP_AUDIT_READ, + CAP_AUDIT_WRITE, + + // Deny suspending block devices + CAP_BLOCK_SUSPEND, + + // Deny any stuff with BPF + CAP_BPF, + + // Deny checkpoint restore + CAP_CHECKPOINT_RESTORE, + + // Deny opening files by inode number (open_by_handle_at) + CAP_DAC_READ_SEARCH, + + // Deny setting SUID bits + CAP_FSETID, + + // Deny locking more memory + CAP_IPC_LOCK, + + // Deny modifying any Apparmor/SELinux/SMACK configuration + CAP_MAC_ADMIN, + CAP_MAC_OVERRIDE, + + // Deny creating any special devices + CAP_MKNOD, + + // Deny setting any capabilities + CAP_SETFCAP, + + // Deny reading from syslog + CAP_SYSLOG, + + // Deny any admin actions (mount, sethostname, ...) + CAP_SYS_ADMIN, + + // Deny rebooting the system + CAP_SYS_BOOT, + + // Deny loading kernel modules + CAP_SYS_MODULE, + + // Deny setting nice level + CAP_SYS_NICE, + + // Deny access to /proc/kcore, /dev/mem, /dev/kmem + CAP_SYS_RAWIO, + + // Deny circumventing any resource limits + CAP_SYS_RESOURCE, + + // Deny setting the system time + CAP_SYS_TIME, + + // Deny playing with suspend + CAP_WAKE_ALARM, + + 0, + }; + + size_t num_caps = 0; + int r; + + // Drop any capabilities + for (const int* cap = capabilities; *cap; cap++) { + r = prctl(PR_CAPBSET_DROP, *cap, 0, 0, 0); + if (r) { + ERROR(pakfire, "Could not drop capability %d: %m\n", *cap); + return r; + } + + num_caps++; + } + + // Fetch any capabilities + cap_t caps = cap_get_proc(); + if (!caps) { + ERROR(pakfire, "Could not read capabilities: %m\n"); + return 1; + } + + /* + Set inheritable capabilities + + This ensures that no processes will be able to gain any of the listed + capabilities again. + */ + r = cap_set_flag(caps, CAP_INHERITABLE, num_caps, capabilities, CAP_CLEAR); + if (r) { + ERROR(pakfire, "cap_set_flag() failed: %m\n"); + goto ERROR; + } + + // Restore capabilities + r = cap_set_proc(caps); + if (r) { + ERROR(pakfire, "Could not restore capabilities: %m\n"); + goto ERROR; + } + +ERROR: + if (caps) + cap_free(caps); + + return r; +} + static int find_environ(struct pakfire_execute* env, const char* key) { if (!key) { errno = EINVAL; @@ -437,6 +552,11 @@ static int pakfire_execute_fork(void* data) { if (r) return r; + // Drop capabilities + r = pakfire_drop_capabilities(pakfire); + if (r) + return r; + // exec() command r = execvpe(env->argv[0], (char**)env->argv, env->envp); if (r < 0) {