Hi Srikar,

On 08/21, Srikar Dronamraju wrote:
> >
> > --- PU/kernel/ptrace.c~09_MV_PTRACE_CK      2009-08-19 16:49:25.000000000 
> > +0200
> > +++ PU/kernel/ptrace.c      2009-08-20 20:04:59.000000000 +0200
> > @@ -471,35 +471,47 @@ static int ptrace_attach_task(struct tas
> >  {
> >     struct utrace_engine *engine;
> >     unsigned long events;
> > +   int err = -EPERM;
> >
> >     engine = utrace_attach_task(tracee, UTRACE_ATTACH_CREATE |
> >                                             UTRACE_ATTACH_EXCLUSIVE |
> >                                             UTRACE_ATTACH_MATCH_OPS,
> >                                             &ptrace_utrace_ops, NULL);
> >     if (unlikely(IS_ERR(engine))) {
> > -           int err = PTR_ERR(engine);
> > -           if (err != -ESRCH && err != -ERESTARTNOINTR)
> > -                   err = -EPERM ;
> > +           if (PTR_ERR(engine) == -ESRCH ||
> > +               PTR_ERR(engine) == -ERESTARTNOINTR)
> > +                   err = PTR_ERR(engine);
> >             return err;
> >     }
> > +
> >     /*
> > -    * We need QUIESCE for resume handling, CLONE to check
> > -    * for CLONE_PTRACE, other events are always reported.
> > -    */
> > -   events = UTRACE_EVENT(QUIESCE) | UTRACE_EVENT(CLONE) |
> > -            UTRACE_EVENT(EXEC) | UTRACE_EVENT_SIGNAL_ALL;
> > -   /*
> > -    * It can fail only if the tracee is dead, the caller
> > -    * must notice this before setting PT_PTRACED.
> > +    * Check ->ptrace to make sure we don't race with the previous
> > +    * tracer which didn't finish detach. If it is clear, nobody
> > +    * can change it except us due to UTRACE_ATTACH_EXCLUSIVE.
> >      */
> > -   utrace_set_events(tracee, engine, events);
>
>
> > +   if (unlikely(tracee->ptrace)) {
>
> Any reason why we cant move this check before we do utrace_attach_task?

Please note the comment, this check relies on UTRACE_ATTACH_EXCLUSIVE
above. Once we see ->ptrace = 0 after utrace_attach_task(), nobody
can change ->ptrace.

Now suppose ptrace_attach_task() does

        if (tracee->ptrace)
                return;

        /* --- WINDOW --- */

        engine = utrace_attach_task();
        if (IS_ERR(engine))
                return;

        ...complete attach...

In that WINDOW, another tracer can attach to this tracee, then start
the detach and remove the engine, but do not call __ptrace_unlink() yet.

Oleg.

Reply via email to