mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-12 07:13:10 -04:00
Add a selftest that verifies the kernel re-evaluates a seccomp filter with the correct (ptrace-modified) first argument after a SECCOMP_RET_TRACE stop. On arm64, syscall_get_arguments() reads the first argument from orig_x0, which may be stale if the tracer modified regs->regs[0] but orig_x0 was not synced. This can cause the filter to see an old argument and incorrectly allow a syscall that it should have rejected. The child installs a filter that: - TRACEs write() when fd == 2 - returns ERRNO(EPERM) when fd == 1 The parent catches the SECCOMP event, changes x0 (fd) from 2 to 1, and resumes the child. If the seccomp re-evaluation sees the stale orig_x0 (fd=2) the filter returns TRACE again and the kernel (with recheck_after_trace=true) allows the syscall to proceed – write succeeds and the child exits 0. If the seccomp re-evaluation sees the new value (fd=1) the filter returns ERRNO(EPERM), write fails and the child exits non-zero. The test passes only when the write fails (child exit != 0). Before the fix: # ./seccomp_ret_trace_x0_bypass TAP version 13 1..1 not ok 1 write succeeded, orig_x0 bypass likely # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0 After the fix: # ./seccomp_ret_trace_x0_bypass TAP version 13 1..1 ok 1 seccomp correctly denied modified syscall # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0 Cc: Kees Cook <kees@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/all/20260717182758.17111-1-will@kernel.org/ Link: https://lore.kernel.org/all/20260716120640.6590-1-will@kernel.org/ Link: https://lore.kernel.org/all/202607152004.DEA95D63@keescook/ Suggested-by: Kees Cook <kees@kernel.org> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Signed-off-by: Will Deacon <will@kernel.org>