chiark / gitweb /
nspawn: Allow module loading if CAP_SYS_MODULE is requested
authorJay Faulkner <jay@jvf.cc>
Wed, 4 Feb 2015 01:45:50 +0000 (17:45 -0800)
committerLennart Poettering <lennart@poettering.net>
Wed, 4 Feb 2015 12:34:46 +0000 (13:34 +0100)
nspawn containers currently block module loading in all cases, with
no option to disable it. This allows an admin, specifically setting
capability=CAP_SYS_MODULE or capability=all to load modules.

src/nspawn/nspawn.c

index 1e6e7bf..fb67251 100644 (file)
@@ -2485,15 +2485,18 @@ static int setup_seccomp(void) {
         static const int blacklist[] = {
                 SCMP_SYS(kexec_load),
                 SCMP_SYS(open_by_handle_at),
         static const int blacklist[] = {
                 SCMP_SYS(kexec_load),
                 SCMP_SYS(open_by_handle_at),
-                SCMP_SYS(init_module),
-                SCMP_SYS(finit_module),
-                SCMP_SYS(delete_module),
                 SCMP_SYS(iopl),
                 SCMP_SYS(ioperm),
                 SCMP_SYS(swapon),
                 SCMP_SYS(swapoff),
         };
 
                 SCMP_SYS(iopl),
                 SCMP_SYS(ioperm),
                 SCMP_SYS(swapon),
                 SCMP_SYS(swapoff),
         };
 
+        static const int kmod_blacklist[] = {
+                SCMP_SYS(init_module),
+                SCMP_SYS(finit_module),
+                SCMP_SYS(delete_module),
+        };
+
         scmp_filter_ctx seccomp;
         unsigned i;
         int r;
         scmp_filter_ctx seccomp;
         unsigned i;
         int r;
@@ -2518,6 +2521,20 @@ static int setup_seccomp(void) {
                 }
         }
 
                 }
         }
 
+        /* If the CAP_SYS_MODULE capability is not requested then
+         * we'll block the kmod syscalls too */
+        if (!(arg_retain & (1ULL << CAP_SYS_MODULE))) {
+                for (i = 0; i < ELEMENTSOF(kmod_blacklist); i++) {
+                        r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), kmod_blacklist[i], 0);
+                        if (r == -EFAULT)
+                                continue; /* unknown syscall */
+                        if (r < 0) {
+                                log_error_errno(r, "Failed to block syscall: %m");
+                                goto finish;
+                        }
+                }
+        }
+
         /*
            Audit is broken in containers, much of the userspace audit
            hookup will fail if running inside a container. We don't
         /*
            Audit is broken in containers, much of the userspace audit
            hookup will fail if running inside a container. We don't