Commit cf43a757 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

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: default avatarOleg Nesterov <oleg@redhat.com>
Reported-by: default avatarOleg Nesterov <oleg@redhat.com>
Reported-by: default avatarIvan Delalande <colona@arista.com>
Cc: stable@vger.kernel.org
Fixes: 35634ffa ("signal: Always notice exiting tasks")
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 7146db33
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -2436,9 +2436,12 @@ relock:
	}
	}


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


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