]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
seccomp: do not ignore deny-listed syscalls with errno when list is allow-list
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 8 Mar 2021 03:00:32 +0000 (12:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 8 Mar 2021 12:28:42 +0000 (21:28 +0900)
Previously, if the hashmap is allow-list and a new deny-listed syscall
is added, seccomp_parse_syscall_filter() simply drop the new syscall
from hashmap even if error number is specified.

This makes 'allow-list' hashmap store two types of entries:
- allow-listed syscalls, which are stored with negative value (-1).
- deny-listed syscalls, which are stored with specified errno.

Fixes #18916.

src/shared/seccomp-util.c

index bfb72ce3eded4599c52e1b3da1e62dd4091803cd..9813d82f9568d749c21bd44988613e2941be9799 100644 (file)
@@ -1090,7 +1090,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* filter
                         else if (action == SCMP_ACT_LOG)
                                 a = SCMP_ACT_LOG;
 #endif
-                        else if (action != SCMP_ACT_ALLOW && error >= 0)
+                        else if (error >= 0)
                                 a = SCMP_ACT_ERRNO(error);
 
                         r = seccomp_rule_add_exact(seccomp, a, id, 0);
@@ -1174,9 +1174,11 @@ int seccomp_parse_syscall_filter(
                         return 0;
                 }
 
-                /* If we previously wanted to forbid a syscall and now
-                 * we want to allow it, then remove it from the list. */
-                if (!(flags & SECCOMP_PARSE_INVERT) == !!(flags & SECCOMP_PARSE_ALLOW_LIST)) {
+                /* If we previously wanted to forbid a syscall and now we want to allow it, then remove
+                 * it from the list. The entries in allow-list with non-negative error value will be
+                 * handled with SCMP_ACT_ERRNO() instead of the default action. */
+                if (!FLAGS_SET(flags, SECCOMP_PARSE_INVERT) == FLAGS_SET(flags, SECCOMP_PARSE_ALLOW_LIST) ||
+                    (FLAGS_SET(flags, SECCOMP_PARSE_INVERT | SECCOMP_PARSE_ALLOW_LIST) && errno_num >= 0)) {
                         r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
                         if (r < 0)
                                 switch (r) {