diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index ec5684d1a57..3f713e731fd 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -1439,6 +1439,13 @@ static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p, b return r; } + /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. */ + if (p->exec_fd >= 0 || p->handoff_timestamp_fd >= 0) { + r = seccomp_filter_set_add_by_name(c->syscall_filter, c->syscall_allow_list, "write"); + if (r < 0) + return r; + } + return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false); } @@ -4013,7 +4020,7 @@ static int send_handoff_timestamp( dual_timestamp dt; dual_timestamp_now(&dt); - if (send(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2, 0) < 0) { + if (write(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2) < 0) { if (reterr_exit_status) *reterr_exit_status = EXIT_EXEC; return log_exec_error_errno(c, p, errno, "Failed to send handoff timestamp: %m"); diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 2469e242534..d31d6b494bc 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -2030,39 +2030,43 @@ int parse_syscall_archs(char **l, Set **ret_archs) { return 0; } +int seccomp_filter_set_add_by_name(Hashmap *filter, bool add, const char *name) { + assert(filter); + assert(name); + + if (name[0] == '@') { + const SyscallFilterSet *more; + + more = syscall_filter_set_find(name); + if (!more) + return -ENXIO; + + return seccomp_filter_set_add(filter, add, more); + } + + int id = seccomp_syscall_resolve_name(name); + if (id == __NR_SCMP_ERROR) { + log_debug("System call %s is not known, ignoring.", name); + return 0; + } + + if (add) + return hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(-1)); + + (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); + return 0; +} + int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *set) { int r; + assert(filter); assert(set); NULSTR_FOREACH(i, set->value) { - - if (i[0] == '@') { - const SyscallFilterSet *more; - - more = syscall_filter_set_find(i); - if (!more) - return -ENXIO; - - r = seccomp_filter_set_add(filter, add, more); - if (r < 0) - return r; - } else { - int id; - - id = seccomp_syscall_resolve_name(i); - if (id == __NR_SCMP_ERROR) { - log_debug("System call %s is not known, ignoring.", i); - continue; - } - - if (add) { - r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(-1)); - if (r < 0) - return r; - } else - (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); - } + r = seccomp_filter_set_add_by_name(filter, add, i); + if (r < 0) + return r; } return 0; diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index fbf85556690..64deb5fd5dd 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -70,6 +70,7 @@ extern const SyscallFilterSet syscall_filter_sets[]; const SyscallFilterSet *syscall_filter_set_find(const char *name); +int seccomp_filter_set_add_by_name(Hashmap *s, bool b, const char *name); int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); int seccomp_add_syscall_filter_item( diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 4b8daa46bb8..56f5e340bef 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -832,6 +832,8 @@ static void test_exec_systemcallfilter(Manager *m) { return; } + test(m, "exec-systemcallfilter-writing-handoff-timestamp.service", 0, CLD_EXITED); + test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED); test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED); test(m, "exec-systemcallfilter-not-failing3.service", 0, CLD_EXITED); diff --git a/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service b/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service new file mode 100644 index 00000000000..3bf2a6470cd --- /dev/null +++ b/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=Test for SystemCallFilter + +[Service] +ExecStart=true +Type=oneshot +# For issue #33299 +SystemCallFilter=~@network-io +SystemCallFilter=~write +SystemCallErrorNumber=ENOSYS