From 685fe4a4e52acc80dcbe98bee55611d81bf84835 Mon Sep 17 00:00:00 2001 From: Jay Faulkner Date: Fri, 20 Feb 2015 21:59:47 +0000 Subject: [PATCH] nspawn: Map all seccomp filters to capabilities This change makes it so all seccomp filters are mapped to the appropriate capability and are only added if that capability was not requested when running the container. This unbreaks the remaining use cases broken by the addition of seccomp filters without respecting requested capabilities. --- src/nspawn/nspawn.c | 58 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0d8d199de..6d10d72c3 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2560,13 +2560,19 @@ static int setup_ipvlan(pid_t pid) { static int setup_seccomp(void) { #ifdef HAVE_SECCOMP - static const int blacklist[] = { - SCMP_SYS(kexec_load), - SCMP_SYS(open_by_handle_at), + static const int sysrawio_blacklist[] = { SCMP_SYS(iopl), SCMP_SYS(ioperm), + }; + + static const int sysboot_blacklist[] = { + SCMP_SYS(kexec_load), + }; + + static const int sysadmin_blacklist[] = { SCMP_SYS(swapon), SCMP_SYS(swapoff), + SCMP_SYS(open_by_handle_at), }; static const int kmod_blacklist[] = { @@ -2589,13 +2595,45 @@ static int setup_seccomp(void) { goto finish; } - for (i = 0; i < ELEMENTSOF(blacklist); i++) { - r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), blacklist[i], 0); - if (r == -EFAULT) - continue; /* unknown syscall */ - if (r < 0) { - log_error_errno(r, "Failed to block syscall: %m"); - goto finish; + /* If the CAP_SYS_RAWIO capability is not requested, + * then block iopl and ioperm */ + if (!(arg_retain & (1ULL << CAP_SYS_RAWIO))) { + for (i = 0; i < ELEMENTSOF(sysrawio_blacklist); i++) { + r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), sysrawio_blacklist[i], 0); + if (r == -EFAULT) + continue; /* unknown syscall */ + if (r < 0) { + log_error_errno(r, "Failed to block syscall: %m"); + goto finish; + } + } + } + + /* If the CAP_SYS_BOOT capability is not requested then + * we'll block kexec syscall too */ + if (!(arg_retain & (1ULL << CAP_SYS_BOOT))) { + for (i = 0; i < ELEMENTSOF(sysboot_blacklist); i++) { + r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), sysboot_blacklist[i], 0); + if (r == -EFAULT) + continue; /* unknown syscall */ + if (r < 0) { + log_error_errno(r, "Failed to block syscall: %m"); + goto finish; + } + } + } + + /* If the CAP_SYS_ADMIN capability is not requested then + * we'll block use of swap and open_by_handle_at */ + if (!(arg_retain & (1ULL << CAP_SYS_ADMIN))) { + for (i = 0; i < ELEMENTSOF(sysadmin_blacklist); i++) { + r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), sysadmin_blacklist[i], 0); + if (r == -EFAULT) + continue; /* unknown syscall */ + if (r < 0) { + log_error_errno(r, "Failed to block syscall: %m"); + goto finish; + } } }