The current implementation of PTRACE_KILL is buggy and has been for
many years as it assumes it's target has stopped in ptrace_stop.  At a
quick skim it looks like this assumption has existed since ptrace
support was added in linux v1.0.

While PTRACE_KILL has been deprecated we can not remove it as
a quick search with google code search reveals many existing
programs calling it.

When the ptracee is not stopped at ptrace_stop some fields would be
set that are ignored except in ptrace_stop.  Making the userspace
visible behavior of PTRACE_KILL a noop in those case.

As the usual rules are not obeyed it is not clear what the
consequences are of calling PTRACE_KILL on a running process.
Presumably userspace does not do this as it achieves nothing.

Replace the implementation of PTRACE_KILL with a simple
send_sig_info(SIGKILL) followed by a return 0.  This changes the
observable user space behavior only in that PTRACE_KILL on a process
not stopped in ptrace_stop will also kill it.  As that has always
been the intent of the code this seems like a reasonable change.

Cc: sta...@vger.kernel.org
Reported-by: Al Viro <v...@zeniv.linux.org.uk>
Suggested-by: Al Viro <v...@zeniv.linux.org.uk>
Signed-off-by: "Eric W. Biederman" <ebied...@xmission.com>
---
 arch/x86/kernel/step.c | 3 +--
 kernel/ptrace.c        | 5 ++---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index 0f3c307b37b3..8e2b2552b5ee 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -180,8 +180,7 @@ void set_task_blockstep(struct task_struct *task, bool on)
         *
         * NOTE: this means that set/clear TIF_BLOCKSTEP is only safe if
         * task is current or it can't be running, otherwise we can race
-        * with __switch_to_xtra(). We rely on ptrace_freeze_traced() but
-        * PTRACE_KILL is not safe.
+        * with __switch_to_xtra(). We rely on ptrace_freeze_traced().
         */
        local_irq_disable();
        debugctl = get_debugctlmsr();
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index da30dcd477a0..7105821595bc 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1236,9 +1236,8 @@ int ptrace_request(struct task_struct *child, long 
request,
                return ptrace_resume(child, request, data);
 
        case PTRACE_KILL:
-               if (child->exit_state)  /* already dead */
-                       return 0;
-               return ptrace_resume(child, request, SIGKILL);
+               send_sig_info(SIGKILL, SEND_SIG_NOINFO, child);
+               return 0;
 
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
        case PTRACE_GETREGSET:
-- 
2.35.3


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

Reply via email to