Change ptrace_attach_task() to re-use the self-detaching engine first,
then do utrace_attach_task(UTRACE_ATTACH_CREATE).

Unlike the previous version, ptrace_attach_task() just calls
ptrace_lookup_engine() and changes context->resume. The only caller
which can find the self-attaching engine is ptrace_atttach(), we
can rely on ->cred_guard_mutex.

Todo: re-check this all and cleanup the mess in ptrace_attach_task().

But first I'd like to know if you agree with this approach.     

---

 kernel/ptrace.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

--- PU/kernel/ptrace.c~81_REUSE_DETACHING_ENGINE        2009-10-10 
17:10:07.000000000 +0200
+++ PU/kernel/ptrace.c  2009-10-10 17:13:37.000000000 +0200
@@ -442,6 +442,22 @@ static int ptrace_attach_task(struct tas
        struct utrace_engine *engine;
        int err;
 
+       engine = ptrace_lookup_engine(tracee);
+       if (!IS_ERR(engine)) {
+               context = ptrace_context(engine);
+               if (context->resume == UTRACE_DETACH) {
+                       /* we rely on ->cred_guard_mutex */
+                       context->resume = UTRACE_RESUME;
+                       /*
+                        * Make sure we don't race with ptrace_report_signal()
+                        */
+                       utrace_barrier(tracee, engine);
+                       if (engine->ops == &ptrace_utrace_ops)
+                               goto finish;
+               }
+               utrace_engine_put(engine);
+       }
+
        context = kzalloc(sizeof(*context), GFP_KERNEL);
        if (unlikely(!context))
                return -ENOMEM;
@@ -459,6 +475,7 @@ static int ptrace_attach_task(struct tas
                kfree(context);
                return err;
        }
+finish:
        /*
         * It can fail only if the tracee is dead, the caller
         * must notice this before setting PT_PTRACED.

Reply via email to