diff options
author | Luca Boccassi <bluca@debian.org> | 2023-12-02 02:04:24 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-02 02:04:24 +0000 |
commit | ebaf2821e6928edf0815a0734212863c3c22ec1e (patch) | |
tree | d94a4c677892165784c069ef6ea467589ffaf5e3 | |
parent | core/cgroup: for non-cached attrs, don't return ENODATA blindly (diff) | |
parent | core: turn on higher optimization level in seccomp (diff) | |
download | systemd-ebaf2821e6928edf0815a0734212863c3c22ec1e.tar.xz systemd-ebaf2821e6928edf0815a0734212863c3c22ec1e.zip |
Merge pull request #30291 from keszybz/seccomp-unknown-syscall
Backwardscompatibly handle syscalls unknown to us or libseccomp
-rw-r--r-- | src/core/exec-invoke.c | 2 | ||||
-rw-r--r-- | src/nspawn/nspawn-seccomp.c | 2 | ||||
-rw-r--r-- | src/shared/seccomp-util.c | 32 |
3 files changed, 31 insertions, 5 deletions
diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 0741ce3c3b8..a3e8b8297c0 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -5119,7 +5119,7 @@ int exec_invoke( #endif #if HAVE_SECCOMP - /* This really should remain as close to the execve() as possible, to make sure our own code is unaffected + /* This really should remain as close to the execve() as possible, to make sure our own code is affected * by the filter as little as possible. */ r = apply_syscall_filter(context, params, needs_ambient_hack); if (r < 0) { diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c index 34a86278482..fa05a8a5b4f 100644 --- a/src/nspawn/nspawn-seccomp.c +++ b/src/nspawn/nspawn-seccomp.c @@ -169,7 +169,7 @@ static int add_syscall_filters( /* We have a large filter here, so let's turn on the binary tree mode if possible. */ r = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_OPTIMIZE, 2); if (r < 0) - return r; + log_warning_errno(r, "Failed to set SCMP_FLTATR_CTL_OPTIMIZE, ignoring: %m"); #endif return 0; diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index bb970d52647..cd30e72ad53 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1129,7 +1129,9 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* filter log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch)); - r = seccomp_init_for_arch(&seccomp, arch, default_action); + /* We install ENOSYS as the default action, but it will only apply to syscalls which are not + * in the @known set. */ + r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(ENOSYS)); if (r < 0) return r; @@ -1164,6 +1166,30 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* filter } } + 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 (hashmap_contains(filter, INT_TO_PTR(id + 1))) + 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; @@ -1223,7 +1249,7 @@ int seccomp_parse_syscall_filter( return -EINVAL; log_syntax(unit, FLAGS_SET(flags, SECCOMP_PARSE_LOG) ? LOG_WARNING : LOG_DEBUG, filename, line, 0, - "Failed to parse system call, ignoring: %s", name); + "System call %s is not known, ignoring.", name); return 0; } @@ -1981,7 +2007,7 @@ int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *se id = seccomp_syscall_resolve_name(i); if (id == __NR_SCMP_ERROR) { - log_debug("Couldn't resolve system call, ignoring: %s", i); + log_debug("System call %s is not known, ignoring.", i); continue; } |