signal: Drop signals received after a fatal signal has been processed
authorEric W. Biederman <ebiederm@xmission.com>
Sat, 8 Jan 2022 16:37:00 +0000 (10:37 -0600)
committerEric W. Biederman <ebiederm@xmission.com>
Wed, 20 Jul 2022 15:24:17 +0000 (10:24 -0500)
In 403bad72b67d ("coredump: only SIGKILL should interrupt the
coredumping task") Oleg modified the kernel to drop all signals that
come in during a coredump except SIGKILL, and suggested that it might
be a good idea to generalize that to other cases after the process has
received a fatal signal.

Semantically it does not make sense to perform any signal delivery
after the process has already been killed.

When a signal is sent while a process is dying today the signal is
placed in the signal queue by __send_signal and a single task of the
process is woken up with signal_wake_up, if there are any tasks that
have not set PF_EXITING.

Take things one step farther and have prepare_signal report that all
signals that come after a process has been killed should be ignored.
While retaining the historical exception of allowing SIGKILL to
interrupt coredumps.

Update the comment in fs/coredump.c to make it clear coredumps are
special in being able to receive SIGKILL.

This changes things so that a process stopped in PTRACE_EVENT_EXIT can
not be made to escape it's ptracer and finish exiting by sending it
SIGKILL.  That a process can be made to leave PTRACE_EVENT_EXIT and
escape it's tracer by sending the process a SIGKILL has been
complicating tracer's for no apparent advantage.  If the process needs
to be made to leave PTRACE_EVENT_EXIT all that needs to happen is to
kill the proceses's tracer.  This differs from the coredump code where
there is no other mechanism besides honoring SIGKILL to expedite the
end of coredumping.

Link: https://lkml.kernel.org/r/875yksd4s9.fsf_-_@email.froward.int.ebiederm.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
fs/coredump.c
kernel/signal.c

index ebc43f960b64566055b38c9cefd6f2b6f985ab78..b836948c954318e3be304404e27c4937b97b0dd2 100644 (file)
@@ -354,7 +354,7 @@ static int zap_process(struct task_struct *start, int exit_code)
        struct task_struct *t;
        int nr = 0;
 
-       /* ignore all signals except SIGKILL, see prepare_signal() */
+       /* Allow SIGKILL, see prepare_signal() */
        start->signal->flags = SIGNAL_GROUP_EXIT;
        start->signal->group_exit_code = exit_code;
        start->signal->group_stop_count = 0;
index 6f86fda5e432aeb32ae5dbca2c4264a2781b3dde..8a0f114d00e0f937d5fd4fdee27969c4bd9f7529 100644 (file)
@@ -913,8 +913,9 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
                if (signal->core_state)
                        return sig == SIGKILL;
                /*
-                * The process is in the middle of dying, nothing to do.
+                * The process is in the middle of dying, drop the signal.
                 */
+               return false;
        } else if (sig_kernel_stop(sig)) {
                /*
                 * This is a stop signal.  Remove SIGCONT from all queues.