diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2019-02-12 00:27:42 -0500 |
|---|---|---|
| committer | Eric W. Biederman <ebiederm@xmission.com> | 2019-02-13 09:31:41 -0500 |
| commit | cf43a757fd49442bc38f76088b70c2299eed2c2f (patch) | |
| tree | d185fedd4ce0e6d8e9cde9d7bd538de030a3c9da | |
| parent | 7146db3317c67b517258cb5e1b08af387da0618b (diff) | |
signal: Restore the stop PTRACE_EVENT_EXIT
In the middle of do_exit() there is there is a call
"ptrace_event(PTRACE_EVENT_EXIT, code);" That call places the process
in TACKED_TRACED aka "(TASK_WAKEKILL | __TASK_TRACED)" and waits for
for the debugger to release the task or SIGKILL to be delivered.
Skipping past dequeue_signal when we know a fatal signal has already
been delivered resulted in SIGKILL remaining pending and
TIF_SIGPENDING remaining set. This in turn caused the
scheduler to not sleep in PTACE_EVENT_EXIT as it figured
a fatal signal was pending. This also caused ptrace_freeze_traced
in ptrace_check_attach to fail because it left a per thread
SIGKILL pending which is what fatal_signal_pending tests for.
This difference in signal state caused strace to report
strace: Exit of unknown pid NNNNN ignored
Therefore update the signal handling state like dequeue_signal
would when removing a per thread SIGKILL, by removing SIGKILL
from the per thread signal mask and clearing TIF_SIGPENDING.
Acked-by: Oleg Nesterov <oleg@redhat.com>
Reported-by: Oleg Nesterov <oleg@redhat.com>
Reported-by: Ivan Delalande <colona@arista.com>
Cc: stable@vger.kernel.org
Fixes: 35634ffa1751 ("signal: Always notice exiting tasks")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
| -rw-r--r-- | kernel/signal.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 99fa8ff06fd9..57b7771e20d7 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -2436,9 +2436,12 @@ relock: | |||
| 2436 | } | 2436 | } |
| 2437 | 2437 | ||
| 2438 | /* Has this task already been marked for death? */ | 2438 | /* Has this task already been marked for death? */ |
| 2439 | ksig->info.si_signo = signr = SIGKILL; | 2439 | if (signal_group_exit(signal)) { |
| 2440 | if (signal_group_exit(signal)) | 2440 | ksig->info.si_signo = signr = SIGKILL; |
| 2441 | sigdelset(¤t->pending.signal, SIGKILL); | ||
| 2442 | recalc_sigpending(); | ||
| 2441 | goto fatal; | 2443 | goto fatal; |
| 2444 | } | ||
| 2442 | 2445 | ||
| 2443 | for (;;) { | 2446 | for (;;) { |
| 2444 | struct k_sigaction *ka; | 2447 | struct k_sigaction *ka; |
