Re: [RFC PATCH] ptrace: don't report syscall-exit if the tracee was killed by seccomp

From: Kusaram Devineni

Date: Fri Apr 03 2026 - 13:18:48 EST


On 03-04-2026 21:18, Oleg Nesterov wrote:

> seccomp does force_sig_seccomp() sends the signal to current, current can't
> return to usermode and call signalfd_dequeue(), get_signal() must dequeue
> SIGSYS and notice SA_IMMUTABLE.

> And since this signal is private, signalfd_dequeue() from another thread can't
> dequeue it either.

> No?

Right Oleg, not by returning to userspace and calling signalfd_dequeue() afterward,
and not from another thread.

We identified a case when working on a syzbot bug
https://syzbot.org/bug?extid=0a4c46806941297fecb9 where the forced SIGSYS was
consumed through the signalfd path from task_work on the same task before get_signal()
handled normal fatal delivery. The setup there had an outstanding io_uring-driven signalfd
request, and task_work_run() executed before get_signal() dequeued the fatal SIGSYS.

So the sequence was roughly:
    seccomp -> force_sig_seccomp(..., true) -> pending private SIGSYS
    get_signal() entry -> task_work_run()
    task_work/signalfd path consumes SIGSYS
    get_signal() then no longer sees it to dequeue

That allowed the task to survive 'long enough' to enter another syscall in
SECCOMP_MODE_DEAD and hit the WARN_ON_ONCE() in __secure_computing().

So your point is correct in the normal case: current cannot return to userspace
and then call signalfd_dequeue(), and another thread cannot dequeue this
private signal. The case we hit was narrower and more specific: same-task
consumption via task_work before normal fatal delivery.

For that specific path, one approach that seems to work is making signalfd exclude
SA_IMMUTABLE signals from the mask it passes to next_signal()/dequeue_signal(),
so kernel-forced fatal signals remain pending for normal delivery via get_signal().

Kusaram