The coredump client only accepts SIGKILL. I've massaged away TIF_NOTIFY_SIGNAL in another patch series but it seems that TIF_SIGPENDING also has some warts and causes truncated coredumps: (1) cgroup v2 freezer isn't built on freezing. Instead, cgroup_freeze_task() sets JOBCTL_TRAP_FREEZE and calls signal_wake_up() on every task in the cgroup. That includes the coredump client. The coredump client isn't able to act on the trap. So a freeze that lands in while a coredump is written will block. Moving a coredumping client into a frozen cgroup has the same problem. (2) retarget_shared_pending() doesn't take a coredump into account too. So if a sibling thread is in the middle of changing the signal mask or it exists with a pending signal that helpers points the signals to other threads. While it skips exiting threads it will target it at the coredump client as the coredump client isn't yet exiting. So it's related to PF_NO_NOTIFY_SIGNAL which I have sitting in kernel-7.4.signal. We should be able to fix it this time by making signal_pending() report only SIGKILL for a task that has PF_DUMPCORE set. A cgroup v2 freeze now waits for the dump to finish. The PM and cgroup v1 freezers keep aborting it through dump_interrupted(). Basically, PM should be able to interrupt the dump. cgroup v1 freezers are legacy crap we don't care about and cgroup 2 should wait(?). Fixes: 403bad72b67d ("coredump: only SIGKILL should interrupt the coredumping task") Cc: stable@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) --- include/linux/sched/signal.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 70067ccfe2ba..3a7ff3416e57 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -386,6 +386,11 @@ static inline int task_sigpending(struct task_struct *p) return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); } +static inline int __fatal_signal_pending(struct task_struct *p) +{ + return unlikely(sigismember(&p->pending.signal, SIGKILL)); +} + static inline int signal_pending(struct task_struct *p) { /* @@ -395,12 +400,12 @@ static inline int signal_pending(struct task_struct *p) */ if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL))) return 1; - return task_sigpending(p); -} - -static inline int __fatal_signal_pending(struct task_struct *p) -{ - return unlikely(sigismember(&p->pending.signal, SIGKILL)); + if (!task_sigpending(p)) + return 0; + /* A coredumping task only stops for SIGKILL, see dump_interrupted(). */ + if (unlikely(READ_ONCE(p->flags) & PF_DUMPCORE)) + return __fatal_signal_pending(p); + return 1; } static inline int fatal_signal_pending(struct task_struct *p) -- 2.53.0