]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: return ENOSYS by default, EPERM for "known" calls
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 21 Aug 2020 15:23:48 +0000 (17:23 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 24 Aug 2020 18:05:17 +0000 (20:05 +0200)
src/nspawn/nspawn-seccomp.c

index 5b0ba465946a1404ca15ff414a55956d735fd084..2a64cf8258639dc13d01c76638d489cccaba7322 100644 (file)
@@ -21,7 +21,7 @@
 
 #if HAVE_SECCOMP
 
-static int seccomp_add_default_syscall_filter(
+static int add_syscall_filters(
                 scmp_filter_ctx ctx,
                 uint32_t arch,
                 uint64_t cap_list_retain,
@@ -139,6 +139,7 @@ static int seccomp_add_default_syscall_filter(
                  */
         };
 
+        _cleanup_strv_free_ char **added = NULL;
         char **p;
         int r;
 
@@ -151,18 +152,25 @@ static int seccomp_add_default_syscall_filter(
                                                     SCMP_ACT_ALLOW,
                                                     syscall_deny_list,
                                                     false,
-                                                    NULL);
+                                                    &added);
                 if (r < 0)
                         return log_error_errno(r, "Failed to add syscall filter item %s: %m", allow_list[i].name);
         }
 
         STRV_FOREACH(p, syscall_allow_list) {
-                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true, NULL);
+                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true, &added);
                 if (r < 0)
                         log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m",
                                           *p, seccomp_arch_to_string(arch));
         }
 
+        /* The default action is ENOSYS. Respond with EPERM to all other "known" but not allow-listed
+         * syscalls. */
+        r = seccomp_add_syscall_filter_item(ctx, "@known", SCMP_ACT_ERRNO(EPERM), added, true, NULL);
+        if (r < 0)
+                log_warning_errno(r, "Failed to add rule for @known set on %s, ignoring: %m",
+                                  seccomp_arch_to_string(arch));
+
         return 0;
 }
 
@@ -180,11 +188,13 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_allow_list, char **sy
 
                 log_debug("Applying allow list on architecture: %s", seccomp_arch_to_string(arch));
 
-                r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(EPERM));
+                /* We install ENOSYS as the default action, but it will only apply to syscalls which are not
+                 * in the @known set, see above. */
+                r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(ENOSYS));
                 if (r < 0)
                         return log_error_errno(r, "Failed to allocate seccomp object: %m");
 
-                r = seccomp_add_default_syscall_filter(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list);
+                r = add_syscall_filters(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list);
                 if (r < 0)
                         return r;