[GIT PULL 02/19 for v7.4] kernel signal

From: Christian Brauner

Date: Fri Oct 16 2026 - 06:21:13 EST


Hey Linus,

/* Summary */

This stops TIF_NOTIFY_SIGNAL from interrupting work that can't be
restarted and fixes a bunch of coredump and signal bugs.

TIF_NOTIFY_SIGNAL kicks a task out of an uninterruptible sleep so it
returns to userspace, runs its task work and goes back to sleep. That
breaks coredumps. dump_interrupted() only lets fatal signals interrupt
a dump and writes to a regular file ignore TIF_NOTIFY_SIGNAL. But the
pipe and the socket paths check signal_pending() deep down in code that
is shared with regular syscalls and bail. So a crashing process with
io_uring requests in flight loses most of its coredump. In the selftest
an unfixed kernel delivers 357324 of at least 5111808 bytes. And
io_uring isn't the only source. klp_send_signals(),
bpf_task_work_schedule_signal(), landlock's tsync, kthread_stop() and
the printk kunit test raise the bit as well, some of them from irq
context against any task. So this can't be fixed per subsystem and the
state has to be per-task and ambient.

Add PF_NO_NOTIFY_SIGNAL and no_notify_signal_save()/restore() helpers
modelled on memalloc_nofs_save(). Inside such a section
signal_pending() ignores TIF_NOTIFY_SIGNAL. Coredumps, the smb send
path, which hand-rolled its own version of this, and the pid namespace
reaper, which busy-looped when the bit kept getting raised, are
converted.

The second part is a set of fixes that fell out of looking at the
coredump code with kres and modelling it in TLA+:

- coredump_finish() woke the parked threads without holding rcu. A
parked thread can exit on a spurious wakeup and be freed before
wake_up_process() takes its pi_lock.

- Only SIGKILL and the freezers interrupt a dump now and the three
freezers agree. Power management and cgroup v1 freezing aborted a
dump while a cgroup v2 freeze either waited for the dump or cut it
short depending on where the core went.

- io-wq set its exit bit without a barrier against the task work that
creates workers. On weakly ordered architectures exit could hang on
worker_done.

- retarget_shared_pending() slingshotted a shared signal to the dumper
when a zapped sibling restored its signal mask. That set
TIF_SIGPENDING on the dumper and truncated the core.

- A tracer could clear the signal mask of a user worker with
PTRACE_SETSIGMASK and inject a coredump signal. An io-wq worker of an
SQPOLL ring dumping core deadlocks the whole group. PTRACE_SETSIGMASK
is refused for user workers now and __set_task_blocked() enforces the
fork-time mask.

- exec cancels io_uring requests before de_thread() so a worker
creation queued as task work can't add a thread to a thread group
that de_thread() just took down.

- No io threads are created from a PF_SIGNALED or PF_POSTCOREDUMP
creator anymore. Such a worker was invisible to zap_process() but
still decremented threads_remaining on exit so the dumper could leave
coredump_wait_inactive() early.

Also included are a comment that do_each_pid_task() needs
tasklist_lock, a READ_ONCE() in pid_alive() and a regression test for
fork() into a pid namespace whose ancestor lost its init.

/* Testing */

No build failures or warnings were observed.

/* Conflicts */

Merge conflicts with mainline
=============================

No known conflicts.

Merge conflicts with other trees
================================

This conflicts with the cifs tree in fs/smb/client/transport.c between
commit 80f49404968d6 ("smb: client: fast fail sends if need to
reconnect") from the cifs tree and commit d0ae35565f5d5 ("smb: prevent
TIF_NOTIFY_SIGNAL from interrupting") from this tree. The cifs tree
bails out early after sock_sendmsg() when a reconnect is needed and
this tree wraps the call in a no_notify_signal guard and drops the
EINTR special case below it:

diff --cc fs/smb/client/transport.c
index cf11af490b0d,93ff6a4dbb35..60699d2799fb
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@@ -171,26 -170,11 +170,22 @@@ smb_send_kvec(struct TCP_Server_Info *s
* after the retries we will kill the socket and
* reconnect which may clear the network problem.
*
- * Even if regular signals are masked, EINTR might be
- * propagated from sk_stream_wait_memory() to here when
- * TIF_NOTIFY_SIGNAL is used for task work. For example,
- * certain io_uring completions will use that. Treat
- * having EINTR with pending task work the same as EAGAIN
- * to avoid unnecessary reconnects.
+ * Task work must not abort the send, see signal_pending().
*/
- rc = sock_sendmsg(ssocket, smb_msg);
+ scoped_guard(no_notify_signal)
+ rc = sock_sendmsg(ssocket, smb_msg);
+
+ /*
+ * If need to reconnect, blame it for any non-interrupt error
+ * and bail out early, even if -EAGAIN; reconnect will never
+ * happen in parallel as cifs_reconnect() needs server mutex
+ * (which we're already holding), so it's pointless to retry.
+ */
+ if (unlikely(rc <= 0 && !is_interrupt_error(rc) &&
+ READ_ONCE(server->tcpStatus) == CifsNeedReconnect))
+ return -ECONNRESET;
+
- if (rc == -EAGAIN || unlikely(rc == -EINTR && task_work_pending(current))) {
+ if (rc == -EAGAIN) {
retries++;
if (retries >= 14 ||
(!server->noblocksnd && (retries > 2))) {

The following changes since commit cee9395acd8043be0644b25c34bfa86623f2b935:

Linux 7.3-rc1 (2026-08-30 13:34:40 -0700)

are available in the Git repository at:

git@xxxxxxxxxxxxxxxxxxx:pub/scm/linux/kernel/git/vfs/vfs tags/kernel-7.4-rc1.signal

for you to fetch changes up to 12e19bba68ba4ef222033ff9a3b63df07b7fad38:

pid: use READ_ONCE() in pid_alive() (2026-10-12 11:13:01 +0200)

----------------------------------------------------------------
kernel-7.4-rc1.signal

Please consider pulling these changes from the signed kernel-7.4-rc1.signal tag.

Thanks!
Christian

----------------------------------------------------------------
Babanpreet Singh (1):
pid: use READ_ONCE() in pid_alive()

Christian Brauner (20):
signal: allow taks to temporarily block TIF_NOTIFY_SIGNAL
coredump: prevent TIF_NOTIFY_SIGNAL from interrupting coredumps
selftests/coredump: test that TIF_NOTIFY_SIGNAL doesn't truncate a coredump
smb: prevent TIF_NOTIFY_SIGNAL from interrupting
pid_namespace: prevent TIF_NOTIFY_SIGNAL from interrupting the reaper
Merge patch series "Stop TIF_NOTIFY_SIGNAL from interrupting work that can't be restarted"
coredump: hold RCU while releasing parked threads
io-wq: order the exit bit against worker creation task work
signal: don't retarget shared signals in a dying thread group
signal: only SIGKILL and the freezers interrupt a coredumping task
selftests/coredump: test shared signal retargeting during a dump
ptrace: refuse to change the signal mask of a user worker
selftests/coredump: test a user worker as the coredumping thread
selftests/coredump: expect PTRACE_SETSIGMASK to be refused on a user worker
exec: cancel io_uring requests before de_thread()
fork: move the coredump and exec checks into create_io_thread()
fork: don't create io threads once PF_POSTCOREDUMP is set
fork: use SIG_KERNEL_ONLY_MASK for the user worker signal mask
signal: enforce the user worker signal mask in __set_task_blocked()
Merge patch series "coredump & signals: an impossible affair"

Oleg Nesterov (1):
pid: document that do_each_pid_task() needs tasklist_lock

Sahaj Chaudhari (1):
selftests: pid_namespace: test fork with dead ancestor

fs/coredump.c | 18 +-
fs/exec.c | 11 +-
fs/smb/client/transport.c | 13 +-
include/linux/pid.h | 11 +-
include/linux/sched.h | 2 +-
include/linux/sched/signal.h | 27 +-
io_uring/io-wq.c | 2 +
kernel/fork.c | 11 +-
kernel/pid.c | 2 +-
kernel/pid_namespace.c | 3 +-
kernel/ptrace.c | 6 +
kernel/signal.c | 14 +
tools/testing/selftests/coredump/.gitignore | 2 +
tools/testing/selftests/coredump/Makefile | 11 +-
.../selftests/coredump/coredump_notify_signal.h | 29 ++
.../coredump/coredump_notify_signal_helper.c | 46 +++
.../coredump/coredump_notify_signal_test.c | 245 +++++++++++
.../selftests/coredump/coredump_signal_test.c | 238 +++++++++++
tools/testing/selftests/coredump/coredump_test.h | 1 +
.../selftests/coredump/coredump_test_helpers.c | 311 ++++++++++++++
.../selftests/coredump/coredump_worker_test.c | 447 +++++++++++++++++++++
tools/testing/selftests/pid_namespace/.gitignore | 1 +
tools/testing/selftests/pid_namespace/Makefile | 2 +-
.../selftests/pid_namespace/pidns_dead_ancestor.c | 174 ++++++++
24 files changed, 1593 insertions(+), 34 deletions(-)
create mode 100644 tools/testing/selftests/coredump/coredump_notify_signal.h
create mode 100644 tools/testing/selftests/coredump/coredump_notify_signal_helper.c
create mode 100644 tools/testing/selftests/coredump/coredump_notify_signal_test.c
create mode 100644 tools/testing/selftests/coredump/coredump_signal_test.c
create mode 100644 tools/testing/selftests/coredump/coredump_worker_test.c
create mode 100644 tools/testing/selftests/pid_namespace/pidns_dead_ancestor.c