On 10/29, Oleg Nesterov wrote:
>
> On 10/27, Roland McGrath wrote:
> >
> > > + case PTRACE_KILL:
> > > +         ret = 0;
> > > +         if (!child->exit_state) /* already dead */
> > > +                 ret = ptrace_resume(child, engine, request, SIGKILL);
> > > +         break;
> >
> > This could be inside ptrace_resume too.
>
> Yes, and we don't even need to check exit_state.

Damn, this PTRACE_KILL is so weird.

If we move this "case:" into ptrace_resume() path, then we have to
make sure we do not return -ESRCH if request == SIGKILL (or we can
ignore this incompatibility?)

Apart from that, what it should actually do?

If the tracee was STOPPED/TRACED, then it is equivalent to PTRACE_CONT,SIGKILL.
Otherwise it has no effect except it can race with exit() and spoil ->exit_code,
and wake_up_process() is not good if course. (I am talking about upstream).

Perhaps it is better to leave this strange and special case in ptrace_request()
like this patch does?

Otherwise, we can change ptrace_resume() to never return the error if, say,
utrace_set_events() fails, but while this is correct it looks a bit ugly.

Please tell me what do you think, then I'll do other changes you suggested.

---

 kernel/ptrace.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- PU/kernel/ptrace.c~122_PTRACE_KILL  2009-10-26 03:18:12.000000000 +0100
+++ PU/kernel/ptrace.c  2009-10-30 04:00:15.000000000 +0100
@@ -1000,9 +1000,10 @@ int ptrace_request(struct task_struct *c
                break;
 
        case PTRACE_KILL:
+               /* Ugly historical behaviour. */
+               if (task_is_traced(child))
+                       ptrace_resume(child, engine, PTRACE_CONT, SIGKILL);
                ret = 0;
-               if (!child->exit_state) /* already dead */
-                       ret = ptrace_resume(child, engine, request, SIGKILL);
                break;
 
        default:

Reply via email to