b7dd4d
From 42ed3377b5817f2c1f84e1bdca301ea51ecc3299 Mon Sep 17 00:00:00 2001
b7dd4d
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
b7dd4d
Date: Thu, 20 Sep 2018 14:19:41 +0200
b7dd4d
Subject: [PATCH] seccomp: tighten checking of seccomp filter creation
b7dd4d
b7dd4d
In seccomp code, the code is changed to propagate errors which are about
b7dd4d
anything other than unknown/unimplemented syscalls. I *think* such errors
b7dd4d
should not happen in normal usage, but so far we would summarilly ignore all
b7dd4d
errors, so that part is uncertain. If it turns out that other errors occur and
b7dd4d
should be ignored, this should be added later.
b7dd4d
b7dd4d
In nspawn, we would count the number of added filters, but didn't use this for
b7dd4d
anything. Drop that part.
b7dd4d
b7dd4d
The comments suggested that seccomp_add_syscall_filter_item() returned negative
b7dd4d
if the syscall is unknown, but this wasn't true: it returns 0.
b7dd4d
b7dd4d
The error at this point can only be if the syscall was known but couldn't be
b7dd4d
added. If the error comes from our internal whitelist in nspawn, treat this as
b7dd4d
error, because it means that our internal table is wrong. If the error comes
b7dd4d
from user arguments, warn and ignore. (If some syscall is not known at current
b7dd4d
architecture, it is still silently ignored.)
b7dd4d
b7dd4d
(cherry picked from commit 7e86bd73a47f2b8dd3d9a743e69fb0117f450ad8)
b7dd4d
b7dd4d
Related: #2040247
b7dd4d
---
b7dd4d
 src/nspawn/nspawn-seccomp.c | 14 +++++---------
b7dd4d
 src/shared/seccomp-util.c   | 26 ++++++++++++++++----------
b7dd4d
 2 files changed, 21 insertions(+), 19 deletions(-)
b7dd4d
b7dd4d
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
b7dd4d
index fba22644da..17abfcec26 100644
b7dd4d
--- a/src/nspawn/nspawn-seccomp.c
b7dd4d
+++ b/src/nspawn/nspawn-seccomp.c
b7dd4d
@@ -140,7 +140,7 @@ static int seccomp_add_default_syscall_filter(
b7dd4d
                  */
b7dd4d
         };
b7dd4d
 
b7dd4d
-        int r, c = 0;
b7dd4d
+        int r;
b7dd4d
         size_t i;
b7dd4d
         char **p;
b7dd4d
 
b7dd4d
@@ -150,21 +150,17 @@ static int seccomp_add_default_syscall_filter(
b7dd4d
 
b7dd4d
                 r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false);
b7dd4d
                 if (r < 0)
b7dd4d
-                        /* If the system call is not known on this architecture, then that's fine, let's ignore it */
b7dd4d
-                        log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", whitelist[i].name, seccomp_arch_to_string(arch));
b7dd4d
-                else
b7dd4d
-                        c++;
b7dd4d
+                        return log_error_errno(r, "Failed to add syscall filter item %s: %m", whitelist[i].name);
b7dd4d
         }
b7dd4d
 
b7dd4d
         STRV_FOREACH(p, syscall_whitelist) {
b7dd4d
                 r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false);
b7dd4d
                 if (r < 0)
b7dd4d
-                        log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch));
b7dd4d
-                else
b7dd4d
-                        c++;
b7dd4d
+                        log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m",
b7dd4d
+                                          *p, seccomp_arch_to_string(arch));
b7dd4d
         }
b7dd4d
 
b7dd4d
-        return c;
b7dd4d
+        return 0;
b7dd4d
 }
b7dd4d
 
b7dd4d
 int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **syscall_blacklist) {
b7dd4d
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
b7dd4d
index 4d2ba31d47..710a734715 100644
b7dd4d
--- a/src/shared/seccomp-util.c
b7dd4d
+++ b/src/shared/seccomp-util.c
b7dd4d
@@ -907,9 +907,13 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name,
b7dd4d
                 r = seccomp_rule_add_exact(seccomp, action, id, 0);
b7dd4d
                 if (r < 0) {
b7dd4d
                         /* If the system call is not known on this architecture, then that's fine, let's ignore it */
b7dd4d
-                        if (log_missing)
b7dd4d
-                                log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m",
b7dd4d
-                                                name, id);
b7dd4d
+                        bool ignore = r == -EDOM;
b7dd4d
+
b7dd4d
+                        if (!ignore || log_missing)
b7dd4d
+                                log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m",
b7dd4d
+                                                name, id, ignore ? ", ignoring" : "");
b7dd4d
+                        if (!ignore)
b7dd4d
+                                return r;
b7dd4d
                 }
b7dd4d
 
b7dd4d
                 return 0;
b7dd4d
@@ -957,10 +961,8 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
b7dd4d
                         return r;
b7dd4d
 
b7dd4d
                 r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing);
b7dd4d
-                if (r < 0) {
b7dd4d
-                        log_debug_errno(r, "Failed to add filter set, ignoring: %m");
b7dd4d
-                        continue;
b7dd4d
-                }
b7dd4d
+                if (r < 0)
b7dd4d
+                        return log_debug_errno(r, "Failed to add filter set: %m");
b7dd4d
 
b7dd4d
                 r = seccomp_load(seccomp);
b7dd4d
                 if (IN_SET(r, -EPERM, -EACCES))
b7dd4d
@@ -1005,11 +1007,15 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
b7dd4d
                         if (r < 0) {
b7dd4d
                                 /* If the system call is not known on this architecture, then that's fine, let's ignore it */
b7dd4d
                                 _cleanup_free_ char *n = NULL;
b7dd4d
+                                bool ignore;
b7dd4d
 
b7dd4d
                                 n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id);
b7dd4d
-                                if (log_missing)
b7dd4d
-                                        log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m",
b7dd4d
-                                                        strna(n), id);
b7dd4d
+                                ignore = r == -EDOM;
b7dd4d
+                                if (!ignore || log_missing)
b7dd4d
+                                        log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m",
b7dd4d
+                                                        strna(n), id, ignore ? ", ignoring" : "");
b7dd4d
+                                if (!ignore)
b7dd4d
+                                        return r;
b7dd4d
                         }
b7dd4d
                 }
b7dd4d