Skip to content

seccomp: allow fsync, fchmod, ftruncate and epoll_pwait2 at runtime - #109

Open
perbu wants to merge 1 commit into
masterfrom
seccomp-runtime-allowlist
Open

seccomp: allow fsync, fchmod, ftruncate and epoll_pwait2 at runtime#109
perbu wants to merge 1 commit into
masterfrom
seccomp-runtime-allowlist

Conversation

@perbu

@perbu perbu commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

The Runtime filter was missing four syscalls the default emulation layer can issue for an ordinary guest, so each one killed the VMM process with SIGSYS rather than being served:

syscall reached from
fsync handler at system_calls.cpp:1915
fchmod handler at :2051
ftruncate handler at :3228
epoll_pwait2 the epoll_wait handler's preempt_epoll_wait() path, which is on by default

All three handlers are installed before the unsafe_syscalls boundary, so they are in the default safe set.

None of these widens the sandbox: every one operates on an fd the emulation layer already translated, and that fd was approved when it was opened. ftruncate moves out of init_rules(), which no longer needs to name it now that runtime_rules() carries it.

I left fdatasync out even though it pairs naturally with fsync — there is no SYS_fdatasync handler, so allowing it would widen the filter beyond what the emulation layer can actually issue.

Adds four tests, one per syscall, each running the guest under the Runtime filter in a forked child so the SIGSYS is contained. tests/unit/seccomp.cpp goes from 7/11 to 11/11.

This is drift the existing tests structurally could not catch: they only exercised printf/write under the Runtime filter. A generic guard — a smoke guest walking the whole safe syscall surface, or a CI check diffing strace -f -c against runtime_rules() — would be worth adding separately.

🤖 Generated with Claude Code

The Runtime filter omitted four syscalls the default emulation layer can
issue on behalf of an ordinary guest, so each one killed the VMM process
with SIGSYS instead of being served:

  fsync, fchmod, ftruncate  - handlers at system_calls.cpp:1915, :2051
                              and :3228, all in the default safe set
  epoll_pwait2              - the epoll_wait handler takes the
                              preempt_epoll_wait() path, which is on by
                              default, and that path issues epoll_pwait2
                              rather than the epoll_wait the guest asked
                              for

None of these widens the sandbox: all four operate on an fd the emulation
layer already translated, and the fd was approved when it was opened.

ftruncate moves out of init_rules(), which no longer needs to name it
separately now that runtime_rules() carries it.

Adds four tests to tests/unit/seccomp.cpp, one per syscall, each running
the guest under the Runtime filter in a forked child so the SIGSYS is
contained. The suite previously only exercised printf/write under that
filter, which is why the drift went unnoticed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant