Skip to content

Commit

Permalink
signal: Restore the stop PTRACE_EVENT_EXIT
Browse files Browse the repository at this point in the history
commit cf43a757fd49442bc38f76088b70c2299eed2c2f upstream.

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 <[email protected]>
Reported-by: Oleg Nesterov <[email protected]>
Reported-by: Ivan Delalande <[email protected]>
Cc: [email protected]
Fixes: 35634ffa1751 ("signal: Always notice exiting tasks")
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
ebiederm authored and gregkh committed Feb 20, 2019
1 parent 0396cf5 commit a2b3e2c
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2433,9 +2433,12 @@ bool get_signal(struct ksignal *ksig)
}

/* Has this task already been marked for death? */
ksig->info.si_signo = signr = SIGKILL;
if (signal_group_exit(signal))
if (signal_group_exit(signal)) {
ksig->info.si_signo = signr = SIGKILL;
sigdelset(&current->pending.signal, SIGKILL);
recalc_sigpending();
goto fatal;
}

for (;;) {
struct k_sigaction *ka;
Expand Down

0 comments on commit a2b3e2c

Please sign in to comment.