Ananth N Mavinakayanahalli wrote:
>
> --- utrace-6mar.orig/kernel/utrace.c
> +++ utrace-6mar/kernel/utrace.c
> @@ -123,12 +123,15 @@ static inline bool exclude_utrace(struct
>   */
>  static inline int utrace_attach_delay(struct task_struct *target)
>  {
> -     if ((target->flags & PF_STARTING) && target->real_parent != current)
> -             do {
> -                     schedule_timeout_interruptible(1);
> -                     if (signal_pending(current))
> -                             return -ERESTARTNOINTR;
> -             } while (target->flags & PF_STARTING);
> +     if ((target->flags & PF_STARTING) && target->real_parent != current) {
> +             if (target->real_parent != current->real_parent) {

But target->real_parent == current->real_parent doesn't mean current
is a creator? It is possible that current's ->real_parent does fork().
And even with CLONE_THREAD, this doesn't mean we are creator, but the
commment says "The creator gets the first chance to attach".

Perhaps we can intruduce the new UTRACE_ATTACH_XXX, this flags should
be used when utrace_attach_task() is called from ->report_clone(), and
then something like

        --- kernel/utrace.c
        +++ kernel/utrace.c
        @@ -130,12 +130,11 @@ static inline bool exclude_utrace(struct
          */
         static inline int utrace_attach_delay(struct task_struct *target)
         {
        -       if ((target->flags & PF_STARTING) && target->real_parent != 
current)
        -               do {
        -                       schedule_timeout_interruptible(1);
        -                       if (signal_pending(current))
        -                               return -ERESTARTNOINTR;
        -               } while (target->flags & PF_STARTING);
        +       while (unlikely(target->flags & PF_STARTING)) {
        +               schedule_timeout_interruptible(1);
        +               if (signal_pending(current))
        +                       return -ERESTARTNOINTR;
        +       }
         
                return 0;
         }
        @@ -267,7 +266,8 @@ struct utrace_engine *utrace_attach_task
                engine->ops = ops;
                engine->data = data;
         
        -       ret = utrace_attach_delay(target);
        +       if (!(flags & UTRACE_ATTACH_XXX))
        +               ret = utrace_attach_delay(target);
                if (likely(!ret))
                        ret = utrace_add_engine(target, utrace, engine,
                                                flags, ops, data);

when ->report_clone() is called current == creator always.

Yes, this is ugly, I agree.


We can also add "struct task_struct *creator" to "struct utrace". It is
be set by tracehook_finish_clone/utrace_init_task, and it is cleared by
tracehook_report_clone() path. In that case we do not need PF_STARTING.
But this blows task_struct...

Oleg.

Reply via email to