Patch "signal: protect SIGNAL_UNKILLABLE from unintentional clearing." has been added to the 3.18-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
signal: protect SIGNAL_UNKILLABLE from unintentional clearing.
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
signal-protect-signal_unkillable-from-unintentional-clearing.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Aug 9 12:42:27 PDT 2017
From: Jamie Iles <[email protected]>
Date: Tue, 10 Jan 2017 16:57:54 -0800
Subject: signal: protect SIGNAL_UNKILLABLE from unintentional clearing.
From: Jamie Iles <[email protected]>
[ Upstream commit 2d39b3cd34e6d323720d4c61bd714f5ae202c022 ]
Since commit 00cd5c37afd5 ("ptrace: permit ptracing of /sbin/init") we can now trace init processes. init is initially protected with SIGNAL_UNKILLABLE which will prevent fatal signals such as SIGSTOP, but there are a number of paths during tracing where SIGNAL_UNKILLABLE can be implicitly cleared.
This can result in init becoming stoppable/killable after tracing. For example, running:
while true; do kill -STOP 1; done &
strace -p 1
and then stopping strace and the kill loop will result in init being left in state TASK_STOPPED. Sending SIGCONT to init will resume it, but init will now respond to future SIGSTOP signals rather than ignoring them.
Make sure that when setting SIGNAL_STOP_CONTINUED/SIGNAL_STOP_STOPPED that we don't clear SIGNAL_UNKILLABLE.
--- include/linux/sched.h | 10 ++++++++++ kernel/signal.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-)
include/linux/sched.h +10 -0
@@ -729,6 +729,16 @@ struct signal_struct {#define SIGNAL_UNKILLABLE 0x00000040/* for init: ignore fatal signals */ +#define SIGNAL_STOP_MASK (SIGNAL_CLD_MASK | SIGNAL_STOP_STOPPED | \ + SIGNAL_STOP_CONTINUED) + +static inline void signal_set_stop_flags (struct signal_struct *sig, +unsigned int flags) +{ +WARN_ON (sig->flags & (SIGNAL_GROUP_EXIT |SIGNAL_GROUP_COREDUMP )); + sig->flags = (sig->flags & ~SIGNAL_STOP_MASK ) | flags; +} +/* If true, all threads except ->group_exit_task have pending SIGKILL */ static inline int signal_group_exit (const struct signal_struct *sig) {
kernel/signal.c +2 -2
@@ -346,7 +346,7 @@ static bool task_participate_group_stop(* fresh group stop. Read comment in do_signal_stop() for details. */ if (!sig->group_stop_count && !(sig->flags &SIGNAL_STOP_STOPPED )) { - sig->flags =SIGNAL_STOP_STOPPED ; +signal_set_stop_flags (sig,SIGNAL_STOP_STOPPED );return true; }return false;
@@ -896,7 +896,7 @@ static bool prepare_signal(int sig, stru* will take ->siglock, notice SIGNAL_CLD_MASK, and * notify its parent. See get_signal_to_deliver(). */ - signal->flags = why |SIGNAL_STOP_CONTINUED ; +signal_set_stop_flags (signal, why |SIGNAL_STOP_CONTINUED ); signal->group_stop_count =0 ; signal->group_exit_code =0 ; }
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/signal-protect-signal_unkillable-from-unintentional-clearing.patch