OSDN Git Service

signal: Restore the stop PTRACE_EVENT_EXIT
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Feb 2019 05:27:42 +0000 (23:27 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Feb 2019 09:13:23 +0000 (10:13 +0100)
commit492647b22f997a4ad1b7db790a55c3c3b80fec4b
treec80d46ac4a6370ae6c2b8e4fceaa1069cf7f1a94
parent7212e37cbdf99f48e4a6c689a42f4bda1ae69001
signal: Restore the stop PTRACE_EVENT_EXIT

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 <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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/signal.c