From 144fbbac235b6b89d5d31795be1cc0dca9852ccc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 20 Sep 2024 03:52:19 +0900 Subject: seccomp-util: pass negative fds as is to fsync() and friends Closes #34478. Co-authored-by: Mike Yuan --- src/shared/seccomp-util.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/shared') diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 1cd662513b..e2261b0a52 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -879,6 +879,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { .name = "@sync", .help = "Synchronize files and memory to storage", .value = + /* Please also update the list in seccomp_suppress_sync(). */ "fdatasync\0" "fsync\0" "msync\0" @@ -2464,8 +2465,10 @@ int seccomp_suppress_sync(void) { uint32_t arch; int r; - /* This is mostly identical to SystemCallFilter=~@sync:0, but simpler to use, and separately - * manageable, and also masks O_SYNC/O_DSYNC */ + /* This behaves slightly differently from SystemCallFilter=~@sync:0, in that negative fds (which + * we can determine to be invalid) are still refused with EBADF. See #34478. + * + * Additionally, O_SYNC/O_DSYNC are masked. */ SECCOMP_FOREACH_LOCAL_ARCH(arch) { _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; @@ -2483,11 +2486,21 @@ int seccomp_suppress_sync(void) { continue; } - r = seccomp_rule_add_exact( - seccomp, - SCMP_ACT_ERRNO(0), /* success → we want this to be a NOP after all */ - id, - 0); + if (STR_IN_SET(c, "fdatasync", "fsync", "sync_file_range", "sync_file_range2", "syncfs")) + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(0), /* success → we want this to be a NOP after all */ + id, + 1, + SCMP_A0(SCMP_CMP_LE, INT_MAX)); /* The rule handles arguments in unsigned. Hence, this + * means non-negative fd matches the rule, and the negative + * fd passed to the syscall (then it fails with EBADF). */ + else + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(0), /* success → we want this to be a NOP after all */ + id, + 0); if (r < 0) log_debug_errno(r, "Failed to add filter for system call %s, ignoring: %m", c); } -- cgit v1.2.3