4bff0a
From da8ea9abbacf381513896a7064a1fa0067b3d549 Mon Sep 17 00:00:00 2001
4bff0a
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
4bff0a
Date: Mon, 24 Sep 2018 16:59:12 +0200
4bff0a
Subject: [PATCH] seccomp: reduce logging about failure to add syscall to
4bff0a
 seccomp
4bff0a
4bff0a
Our logs are full of:
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldstat() / -10037, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call get_thread_area() / -10076, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call set_thread_area() / -10079, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldfstat() / -10034, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldolduname() / -10036, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldlstat() / -10035, ignoring: Numerical argument out of domain
4bff0a
Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call waitpid() / -10073, ignoring: Numerical argument out of domain
4bff0a
...
4bff0a
This is pointless and makes debug logs hard to read. Let's keep the logs
4bff0a
in test code, but disable it in nspawn and pid1. This is done through a function
4bff0a
parameter because those functions operate recursively and it's not possible to
4bff0a
make the caller to log meaningfully.
4bff0a
4bff0a
There should be no functional change, except the skipped debug logs.
4bff0a
4bff0a
(cherry-picked from commit b54f36c604472ffe08830ec4306fa2885b4a5424)
4bff0a
4bff0a
Resolves: #1658691
4bff0a
---
4bff0a
 src/core/execute.c          |  6 ++--
4bff0a
 src/nspawn/nspawn-seccomp.c |  4 +--
4bff0a
 src/shared/seccomp-util.c   | 57 ++++++++++++++++++++-----------------
4bff0a
 src/shared/seccomp-util.h   |  6 ++--
4bff0a
 src/test/test-seccomp.c     | 16 +++++------
4bff0a
 5 files changed, 47 insertions(+), 42 deletions(-)
4bff0a
4bff0a
diff --git a/src/core/execute.c b/src/core/execute.c
4bff0a
index 8ac69d1a0f..ffb92ddfc7 100644
4bff0a
--- a/src/core/execute.c
4bff0a
+++ b/src/core/execute.c
4bff0a
@@ -1415,7 +1415,7 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_
4bff0a
                         return r;
4bff0a
         }
4bff0a
 
4bff0a
-        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action);
4bff0a
+        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false);
4bff0a
 }
4bff0a
 
4bff0a
 static int apply_syscall_archs(const Unit *u, const ExecContext *c) {
4bff0a
@@ -1498,7 +1498,7 @@ static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) {
4bff0a
         if (skip_seccomp_unavailable(u, "ProtectKernelModules="))
4bff0a
                 return 0;
4bff0a
 
4bff0a
-        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM));
4bff0a
+        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM), false);
4bff0a
 }
4bff0a
 
4bff0a
 static int apply_private_devices(const Unit *u, const ExecContext *c) {
4bff0a
@@ -1513,7 +1513,7 @@ static int apply_private_devices(const Unit *u, const ExecContext *c) {
4bff0a
         if (skip_seccomp_unavailable(u, "PrivateDevices="))
4bff0a
                 return 0;
4bff0a
 
4bff0a
-        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM));
4bff0a
+        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM), false);
4bff0a
 }
4bff0a
 
4bff0a
 static int apply_restrict_namespaces(const Unit *u, const ExecContext *c) {
4bff0a
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
4bff0a
index eb1964bb6d..b56c5b04a8 100644
4bff0a
--- a/src/nspawn/nspawn-seccomp.c
4bff0a
+++ b/src/nspawn/nspawn-seccomp.c
4bff0a
@@ -148,7 +148,7 @@ static int seccomp_add_default_syscall_filter(
4bff0a
                 if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0)
4bff0a
                         continue;
4bff0a
 
4bff0a
-                r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist);
4bff0a
+                r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false);
4bff0a
                 if (r < 0)
4bff0a
                         /* If the system call is not known on this architecture, then that's fine, let's ignore it */
4bff0a
                         log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", whitelist[i].name, seccomp_arch_to_string(arch));
4bff0a
@@ -157,7 +157,7 @@ static int seccomp_add_default_syscall_filter(
4bff0a
         }
4bff0a
 
4bff0a
         STRV_FOREACH(p, syscall_whitelist) {
4bff0a
-                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist);
4bff0a
+                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false);
4bff0a
                 if (r < 0)
4bff0a
                         log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch));
4bff0a
                 else
4bff0a
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
4bff0a
index c433cb90dc..92910acf0e 100644
4bff0a
--- a/src/shared/seccomp-util.c
4bff0a
+++ b/src/shared/seccomp-util.c
4bff0a
@@ -857,11 +857,9 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name) {
4bff0a
         return NULL;
4bff0a
 }
4bff0a
 
4bff0a
-static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude);
4bff0a
-
4bff0a
-int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude) {
4bff0a
-        int r;
4bff0a
+static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, bool log_missing);
4bff0a
 
4bff0a
+int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude, bool log_missing) {
4bff0a
         assert(seccomp);
4bff0a
         assert(name);
4bff0a
 
4bff0a
@@ -877,32 +875,36 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name,
4bff0a
                         return -EINVAL;
4bff0a
                 }
4bff0a
 
4bff0a
-                r = seccomp_add_syscall_filter_set(seccomp, other, action, exclude);
4bff0a
-                if (r < 0)
4bff0a
-                        return r;
4bff0a
+                return seccomp_add_syscall_filter_set(seccomp, other, action, exclude, log_missing);
4bff0a
+
4bff0a
         } else {
4bff0a
-                int id;
4bff0a
+                int id, r;
4bff0a
 
4bff0a
                 id = seccomp_syscall_resolve_name(name);
4bff0a
                 if (id == __NR_SCMP_ERROR) {
4bff0a
-                        log_debug("System call %s is not known, ignoring.", name);
4bff0a
+                        if (log_missing)
4bff0a
+                                log_debug("System call %s is not known, ignoring.", name);
4bff0a
                         return 0;
4bff0a
                 }
4bff0a
 
4bff0a
                 r = seccomp_rule_add_exact(seccomp, action, id, 0);
4bff0a
-                if (r < 0)
4bff0a
+                if (r < 0) {
4bff0a
                         /* If the system call is not known on this architecture, then that's fine, let's ignore it */
4bff0a
-                        log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", name, id);
4bff0a
-        }
4bff0a
+                        if (log_missing)
4bff0a
+                                log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m",
4bff0a
+                                                name, id);
4bff0a
+                }
4bff0a
 
4bff0a
-        return 0;
4bff0a
+                return 0;
4bff0a
+        }
4bff0a
 }
4bff0a
 
4bff0a
 static int seccomp_add_syscall_filter_set(
4bff0a
                 scmp_filter_ctx seccomp,
4bff0a
                 const SyscallFilterSet *set,
4bff0a
                 uint32_t action,
4bff0a
-                char **exclude) {
4bff0a
+                char **exclude,
4bff0a
+                bool log_missing) {
4bff0a
 
4bff0a
         const char *sys;
4bff0a
         int r;
4bff0a
@@ -911,7 +913,7 @@ static int seccomp_add_syscall_filter_set(
4bff0a
         assert(set);
4bff0a
 
4bff0a
         NULSTR_FOREACH(sys, set->value) {
4bff0a
-                r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude);
4bff0a
+                r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing);
4bff0a
                 if (r < 0)
4bff0a
                         return r;
4bff0a
         }
4bff0a
@@ -919,7 +921,7 @@ static int seccomp_add_syscall_filter_set(
4bff0a
         return 0;
4bff0a
 }
4bff0a
 
4bff0a
-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) {
4bff0a
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing) {
4bff0a
         uint32_t arch;
4bff0a
         int r;
4bff0a
 
4bff0a
@@ -937,7 +939,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
4bff0a
                 if (r < 0)
4bff0a
                         return r;
4bff0a
 
4bff0a
-                r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL);
4bff0a
+                r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing);
4bff0a
                 if (r < 0) {
4bff0a
                         log_debug_errno(r, "Failed to add filter set, ignoring: %m");
4bff0a
                         continue;
4bff0a
@@ -953,7 +955,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
4bff0a
         return 0;
4bff0a
 }
4bff0a
 
4bff0a
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action) {
4bff0a
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing) {
4bff0a
         uint32_t arch;
4bff0a
         int r;
4bff0a
 
4bff0a
@@ -966,7 +968,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
4bff0a
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
4bff0a
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
4bff0a
                 Iterator i;
4bff0a
-                void *id, *val;
4bff0a
+                void *syscall_id, *val;
4bff0a
 
4bff0a
                 log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
4bff0a
 
4bff0a
@@ -974,20 +976,23 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
4bff0a
                 if (r < 0)
4bff0a
                         return r;
4bff0a
 
4bff0a
-                HASHMAP_FOREACH_KEY(val, id, set, i) {
4bff0a
+                HASHMAP_FOREACH_KEY(val, syscall_id, set, i) {
4bff0a
                         uint32_t a = action;
4bff0a
-                        int e = PTR_TO_INT(val);
4bff0a
+                        int id = PTR_TO_INT(syscall_id) - 1;
4bff0a
+                        int error = PTR_TO_INT(val);
4bff0a
 
4bff0a
-                        if (action != SCMP_ACT_ALLOW && e >= 0)
4bff0a
-                                a = SCMP_ACT_ERRNO(e);
4bff0a
+                        if (action != SCMP_ACT_ALLOW && error >= 0)
4bff0a
+                                a = SCMP_ACT_ERRNO(error);
4bff0a
 
4bff0a
-                        r = seccomp_rule_add_exact(seccomp, a, PTR_TO_INT(id) - 1, 0);
4bff0a
+                        r = seccomp_rule_add_exact(seccomp, a, id, 0);
4bff0a
                         if (r < 0) {
4bff0a
                                 /* If the system call is not known on this architecture, then that's fine, let's ignore it */
4bff0a
                                 _cleanup_free_ char *n = NULL;
4bff0a
 
4bff0a
-                                n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
4bff0a
-                                log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", strna(n), PTR_TO_INT(id) - 1);
4bff0a
+                                n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id);
4bff0a
+                                if (log_missing)
4bff0a
+                                        log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m",
4bff0a
+                                                        strna(n), id);
4bff0a
                         }
4bff0a
                 }
4bff0a
 
4bff0a
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
4bff0a
index eac857afb9..d8a36c4e21 100644
4bff0a
--- a/src/shared/seccomp-util.h
4bff0a
+++ b/src/shared/seccomp-util.h
4bff0a
@@ -58,10 +58,10 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name);
4bff0a
 
4bff0a
 int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set);
4bff0a
 
4bff0a
-int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude);
4bff0a
+int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude, bool log_missing);
4bff0a
 
4bff0a
-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
4bff0a
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action);
4bff0a
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing);
4bff0a
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing);
4bff0a
 
4bff0a
 typedef enum SeccompParseFlags {
4bff0a
         SECCOMP_PARSE_INVERT     = 1 << 0,
4bff0a
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
4bff0a
index d82cb5c1c5..d177515ac7 100644
4bff0a
--- a/src/test/test-seccomp.c
4bff0a
+++ b/src/test/test-seccomp.c
4bff0a
@@ -104,11 +104,11 @@ static void test_filter_sets(void) {
4bff0a
                 if (pid == 0) { /* Child? */
4bff0a
                         int fd;
4bff0a
 
4bff0a
-                        /* if we look at the default set (or one that includes it), whitelist instead of blacklist */
4bff0a
+                        /* If we look at the default set (or one that includes it), whitelist instead of blacklist */
4bff0a
                         if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE))
4bff0a
-                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW);
4bff0a
+                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true);
4bff0a
                         else
4bff0a
-                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN));
4bff0a
+                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true);
4bff0a
                         if (r < 0)
4bff0a
                                 _exit(EXIT_FAILURE);
4bff0a
 
4bff0a
@@ -515,7 +515,7 @@ static void test_load_syscall_filter_set_raw(void) {
4bff0a
                 assert_se(access("/", F_OK) >= 0);
4bff0a
                 assert_se(poll(NULL, 0, 0) == 0);
4bff0a
 
4bff0a
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL) >= 0);
4bff0a
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL, true) >= 0);
4bff0a
                 assert_se(access("/", F_OK) >= 0);
4bff0a
                 assert_se(poll(NULL, 0, 0) == 0);
4bff0a
 
4bff0a
@@ -526,7 +526,7 @@ static void test_load_syscall_filter_set_raw(void) {
4bff0a
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
4bff0a
 #endif
4bff0a
 
4bff0a
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
4bff0a
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
4bff0a
 
4bff0a
                 assert_se(access("/", F_OK) < 0);
4bff0a
                 assert_se(errno == EUCLEAN);
4bff0a
@@ -542,7 +542,7 @@ static void test_load_syscall_filter_set_raw(void) {
4bff0a
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0);
4bff0a
 #endif
4bff0a
 
4bff0a
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
4bff0a
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
4bff0a
 
4bff0a
                 assert_se(access("/", F_OK) < 0);
4bff0a
                 assert_se(errno == EILSEQ);
4bff0a
@@ -558,7 +558,7 @@ static void test_load_syscall_filter_set_raw(void) {
4bff0a
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0);
4bff0a
 #endif
4bff0a
 
4bff0a
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
4bff0a
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
4bff0a
 
4bff0a
                 assert_se(access("/", F_OK) < 0);
4bff0a
                 assert_se(errno == EILSEQ);
4bff0a
@@ -575,7 +575,7 @@ static void test_load_syscall_filter_set_raw(void) {
4bff0a
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0);
4bff0a
 #endif
4bff0a
 
4bff0a
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
4bff0a
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
4bff0a
 
4bff0a
                 assert_se(access("/", F_OK) < 0);
4bff0a
                 assert_se(errno == EILSEQ);