From 851ee70a3da1263a8eb9e7f230d2e18462ec2ead Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Sun, 26 Aug 2018 00:27:29 +0200 Subject: [PATCH 1/2] seccomp: improve error reporting Only report OOM if that was actually the error of the operation, explicitly report the possible error that a syscall was already blocked with a different errno and translate that into a more sensible errno (EEXIST only makes sense in connection to the hashmap), and pass through all other potential errors unmodified. Part of #9939. --- src/shared/seccomp-util.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index ade3c656af..5072ceb2d1 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1057,7 +1057,17 @@ int seccomp_parse_syscall_filter_full( if (!(flags & SECCOMP_PARSE_INVERT) == !!(flags & SECCOMP_PARSE_WHITELIST)) { r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num)); if (r < 0) - return flags & SECCOMP_PARSE_LOG ? log_oom() : -ENOMEM; + switch (r) { + case -ENOMEM: + return flags & SECCOMP_PARSE_LOG ? log_oom() : -ENOMEM; + case -EEXIST: + if (flags & SECCOMP_PARSE_LOG) + log_warning("System call %s already blocked with different errno: %d", + name, PTR_TO_INT(hashmap_get(filter, INT_TO_PTR(id + 1)))); + return -EINVAL; + default: + return r; + } } else (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); } From 9d7fe7c65ae26cb59885a95bdcd275b8e3be9554 Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Wed, 29 Aug 2018 21:35:38 +0200 Subject: [PATCH 2/2] seccomp: permit specifying multiple errnos for a syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If more than one errno is specified for a syscall in SystemCallFilter=, use the last one instead of reporting an error. This is especially useful when used with system call sets: SystemCallFilter=@privileged:EPERM @reboot This will block any system call requiring super-user capabilities with EPERM, except for attempts to reboot the system, which will immediately terminate the process. (@reboot is included in @privileged.) This also effectively fixes #9939, since specifying different errnos for “the same syscall” (same pseudo syscall number) is no longer an error. --- src/shared/seccomp-util.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 5072ceb2d1..ff3537c5e9 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1061,10 +1061,8 @@ int seccomp_parse_syscall_filter_full( case -ENOMEM: return flags & SECCOMP_PARSE_LOG ? log_oom() : -ENOMEM; case -EEXIST: - if (flags & SECCOMP_PARSE_LOG) - log_warning("System call %s already blocked with different errno: %d", - name, PTR_TO_INT(hashmap_get(filter, INT_TO_PTR(id + 1)))); - return -EINVAL; + assert_se(hashmap_update(filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num)) == 0); + break; default: return r; }