diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-12-03 10:01:20 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-12-03 10:01:30 +0100 |
commit | 78b2ad7d67e118355d309fe28938c5d55e2d1263 (patch) | |
tree | 76169eab050e1685ba0f1c7dd6e8d04647a9e1f1 /src/shared/seccomp-util.c | |
parent | seccomp-util: override default action only when the filter is allow-list (diff) | |
download | systemd-78b2ad7d67e118355d309fe28938c5d55e2d1263.tar.xz systemd-78b2ad7d67e118355d309fe28938c5d55e2d1263.zip |
seccomp-util: also use ENOSYS for unknown syscalls in seccomp_load_syscall_filter_set()
Follow-up for 2331c02d06cae97b87637a0fc6bb4961b509ccf2.
Note, currently, the function is always called with SCMP_ACT_ALLOW as
the default action, except for the test. So, this should not change
anything in the runtime code.
Diffstat (limited to 'src/shared/seccomp-util.c')
-rw-r--r-- | src/shared/seccomp-util.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 92a4f5bdd3..00a8cedcb8 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1105,19 +1105,47 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter /* The one-stop solution: allocate a seccomp object, add the specified filter to it, and apply it. Once for * each local arch. */ + default_action_override = override_default_action(default_action); + SECCOMP_FOREACH_LOCAL_ARCH(arch) { _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; + _cleanup_strv_free_ char **added = NULL; log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch)); - r = seccomp_init_for_arch(&seccomp, arch, default_action); + r = seccomp_init_for_arch(&seccomp, arch, default_action_override); if (r < 0) return r; - r = add_syscall_filter_set(seccomp, set, action, NULL, log_missing, NULL); + r = add_syscall_filter_set(seccomp, set, action, NULL, log_missing, &added); if (r < 0) return log_debug_errno(r, "Failed to add filter set: %m"); + if (default_action != default_action_override) + NULSTR_FOREACH(name, syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].value) { + int id; + + id = seccomp_syscall_resolve_name(name); + if (id < 0) + continue; + + /* Ignore the syscall if it was already handled above */ + if (strv_contains(added, name)) + continue; + + r = seccomp_rule_add_exact(seccomp, default_action, id, 0); + if (r < 0 && r != -EDOM) /* EDOM means that the syscall is not available for arch */ + return log_debug_errno(r, "Failed to add rule for system call %s() / %d: %m", + name, id); + } + +#if (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 5) || SCMP_VER_MAJOR > 2 + /* We have a large filter here, so let's turn on the binary tree mode if possible. */ + r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_OPTIMIZE, 2); + if (r < 0) + log_warning_errno(r, "Failed to set SCMP_FLTATR_CTL_OPTIMIZE, ignoring: %m"); +#endif + r = seccomp_load(seccomp); if (ERRNO_IS_NEG_SECCOMP_FATAL(r)) return r; |