tracehook: fix CLONE_PTRACE
authorRoland McGrath <roland@redhat.com>
Thu, 7 Aug 2008 23:55:03 +0000 (16:55 -0700)
committerRoland McGrath <roland@redhat.com>
Fri, 8 Aug 2008 00:18:47 +0000 (17:18 -0700)
In the change in commit 09a05394fe2448a4139b014936330af23fa7ec83, I
overlooked two nits in the logic and this broke using CLONE_PTRACE
when PTRACE_O_TRACE* are not being used.

A parent that is itself traced at all but not using PTRACE_O_TRACE*,
using CLONE_PTRACE would have its new child fail to be traced.

A parent that is not itself traced at all that uses CLONE_PTRACE
(which should be a no-op in this case) would confuse the bookkeeping
and lead to a crash at exit time.

This restores the missing checks and fixes both failure modes.

Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Roland McGrath <roland@redhat.com>
include/linux/ptrace.h
include/linux/tracehook.h

index fd31756e1a00f632189022dec352a49fe525ac62..ea7416c901d1ef8923adb2417b236cf8633a09f0 100644 (file)
@@ -172,7 +172,7 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace)
        child->ptrace = 0;
        if (unlikely(ptrace)) {
                child->ptrace = current->ptrace;
-               __ptrace_link(child, current->parent);
+               ptrace_link(child, current->parent);
        }
 }
 
index ab3ef7aefa9593dcfcf3f531666eba2c1c8f2a2f..b48d8196957436284c429e1d196c434459d8f0be 100644 (file)
@@ -280,7 +280,7 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
                                          unsigned long clone_flags,
                                          pid_t pid, struct task_struct *child)
 {
-       if (unlikely(trace)) {
+       if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) {
                /*
                 * The child starts up with an immediate SIGSTOP.
                 */