summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-09-19 20:52:19 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-09-19 21:30:53 +0200
commit144fbbac235b6b89d5d31795be1cc0dca9852ccc (patch)
tree18af44cfa9f0b491716e3d50a982da1f18586235 /src/shared
parentMerge pull request #34486 from DaanDeMeyer/test-process-util (diff)
downloadsystemd-144fbbac235b6b89d5d31795be1cc0dca9852ccc.tar.xz
systemd-144fbbac235b6b89d5d31795be1cc0dca9852ccc.zip
seccomp-util: pass negative fds as is to fsync() and friends
Closes #34478. Co-authored-by: Mike Yuan <me@yhndnzj.com>
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/seccomp-util.c27
1 files changed, 20 insertions, 7 deletions
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);
}