Copy-and-paste.

Roland, ptrace_check_attach()->utrace_control(UTRACE_STOP) is not right.
We should not do mark_engine_wants_stop() and set ->report from
ptrace_check_attach(). It should be "passive", except s/STOPPED/TRACED/.

for this series this is not right too...

---

 kernel/ptrace.c |   42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

--- MINI/kernel/ptrace.c~4_CK_ATTACH    2009-08-25 17:41:47.000000000 +0200
+++ MINI/kernel/ptrace.c        2009-08-25 17:54:50.000000000 +0200
@@ -159,35 +159,29 @@ void __ptrace_unlink(struct task_struct 
  */
 int ptrace_check_attach(struct task_struct *child, int kill)
 {
-       int ret = -ESRCH;
+       struct utrace_engine *engine;
+       struct utrace_examiner exam;
+       int ret;
+
+       if (child->parent != current)
+               return -ESRCH;
+
+       engine = utrace_attach_task(child, UTRACE_ATTACH_MATCH_OPS,
+                                   &ptrace_utrace_ops, NULL);
+       if (IS_ERR(engine))
+               return -ESRCH;
 
        /*
-        * We take the read lock around doing both checks to close a
-        * possible race where someone else was tracing our child and
-        * detached between these two checks.  After this locked check,
-        * we are sure that this is our traced child and that can only
-        * be changed by us so it's not changing right after this.
+        * Make sure our engine has already stopped the child.
+        * Then wait for it to be off the CPU.
         */
-       read_lock(&tasklist_lock);
-       if ((child->ptrace & PT_PTRACED) && child->parent == current) {
-               ret = 0;
-               /*
-                * child->sighand can't be NULL, release_task()
-                * does ptrace_unlink() before __exit_signal().
-                */
-               spin_lock_irq(&child->sighand->siglock);
-               if (task_is_stopped(child))
-                       child->state = TASK_TRACED;
-               else if (!task_is_traced(child) && !kill)
-                       ret = -ESRCH;
-               spin_unlock_irq(&child->sighand->siglock);
-       }
-       read_unlock(&tasklist_lock);
+       ret = 0;
+       if (utrace_control(child, engine, UTRACE_STOP) ||
+           utrace_prepare_examine(child, engine, &exam))
+               ret = -ESRCH;
 
-       if (!ret && !kill)
-               ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
+       utrace_engine_put(engine);
 
-       /* All systems go.. */
        return ret;
 }
 

Reply via email to