From: Michael Tremer Date: Tue, 2 Aug 2022 14:40:09 +0000 (+0000) Subject: jail: Drop capabilities X-Git-Tag: 0.9.28~632 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=980b15af0279d20250b3a47bce96f173105f3913;p=pakfire.git jail: Drop capabilities Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 57efb93ab..16539d121 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -19,13 +19,16 @@ #############################################################################*/ #include +#include #include #include #include #include #include +#include #include #include +#include #include #include @@ -222,6 +225,122 @@ int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* return 0; } +// Capabilities + +static int pakfire_jail_drop_capabilities(struct pakfire_jail* jail) { + 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, + }; + + DEBUG(jail->pakfire, "Dropping capabilities...\n"); + + 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(jail->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(jail->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(jail->pakfire, "cap_set_flag() failed: %m\n"); + goto ERROR; + } + + // Restore capabilities + r = cap_set_proc(caps); + if (r) { + ERROR(jail->pakfire, "Could not restore capabilities: %m\n"); + goto ERROR; + } + +ERROR: + if (caps) + cap_free(caps); + + return r; +} + // UID/GID Mapping static int pakfire_jail_write_uidgid_mapping(struct pakfire_jail* jail, @@ -462,6 +581,11 @@ static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[], int if (r) return r; + // Drop capabilities + r = pakfire_jail_drop_capabilities(jail); + if (r) + return r; + return 0; }