diff options
| author | Cong Wang <cwang@multikernel.io> | 2026-09-24 13:42:07 -0700 |
|---|---|---|
| committer | Kees Cook <kees@kernel.org> | 2026-10-06 01:43:30 -0700 |
| commit | f7952251ecc37aabecd7e531849f5076483cf23e (patch) | |
| tree | 37a11e004950de54e8b0a088a2d9dc75052adeb3 /tools/include/uapi/linux | |
| parent | 832b9b176be06a20747a267db6bc0010a24b74f4 (diff) | |
| download | linux-next-f7952251ecc37aabecd7e531849f5076483cf23e.tar.gz linux-next-f7952251ecc37aabecd7e531849f5076483cf23e.zip | |
seccomp: allow restarting interrupted unreceived notifications
An interrupted user notification wait returns ERESTARTSYS before the
syscall body has run. If the notifying task's handler for the delivered
signal was installed without SA_RESTART, that task sees EINTR even for
calls whose callers do not expect it. This can make fork fail
unexpectedly or make close report EINTR while leaving the descriptor
open. A leaked pipe write end can prevent readers from seeing EOF.
The supervisor cannot repair this result once the interrupted task
removes the notification. If removal happens before receipt, the
supervisor never receives that request; a reply using its ID would fail
with ENOENT. Receiving notifications eagerly only narrows the scheduling
window. WAIT_KILLABLE_RECV protects supervisor processing after receipt,
but deliberately leaves the pre-receive wait interruptible.
A sandbox also cannot transparently fix this in the target. It cannot
require arbitrary workloads to retry calls such as fork and close.
Retrying close on EINTR is unsafe when the native syscall has already
released the descriptor. Forcing SA_RESTART on application handlers
would change cancellation behavior for other blocking calls.
Sandlock encounters this while mediating process creation to enforce
process limits. For example, dash installs its SIGCHLD handler without
SA_RESTART. While dash is creating a pipeline, an earlier child can exit
and generate SIGCHLD while dash waits for a fork notification to be
received. The interrupted wait then makes fork return EINTR, causing
dash to report "Cannot fork". Removing fork from notification mediation
would bypass the process-limit enforcement that sandlock needs.
Add SECCOMP_FILTER_FLAG_RESTART_BEFORE_RECV, requiring NEW_LISTENER.
Under notify_lock, convert an interrupted wait's ERESTARTSYS to
ERESTARTNOINTR only while the notification remains INIT. The notifying
task's signal handler still runs; if it returns normally, syscall entry
and the filter are evaluated again.
Keep this opt-in because commit c2aa2dfef243 ("seccomp: Add
wait_killable semantic to seccomp user notifier") deliberately preserved
pre-receipt interruption so workloads could abandon requests before the
supervisor starts processing them. The flag can be combined with
WAIT_KILLABLE_RECV to defer non-fatal signals after receipt. Neither
supervisor-supplied errors nor the native syscall's restart behavior is
changed.
Assisted-by: Codex:gpt-6
Signed-off-by: Cong Wang <cwang@multikernel.io>
Link: https://patch.msgid.link/20260924204209.477694-2-xiyou.wangcong@gmail.com
Signed-off-by: Kees Cook <kees@kernel.org>
Diffstat (limited to 'tools/include/uapi/linux')
| -rw-r--r-- | tools/include/uapi/linux/seccomp.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/tools/include/uapi/linux/seccomp.h b/tools/include/uapi/linux/seccomp.h index dbfc9b37fcae..30b76aa48355 100644 --- a/tools/include/uapi/linux/seccomp.h +++ b/tools/include/uapi/linux/seccomp.h @@ -25,6 +25,7 @@ #define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4) /* Received notifications wait in killable state (only respond to fatal signals) */ #define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5) +#define SECCOMP_FILTER_FLAG_RESTART_BEFORE_RECV (1UL << 6) /* * All BPF programs must return a 32-bit value. |
