lkml.org 
[lkml]   [2018]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: KASAN: use-after-free Read in task_is_descendant
    On 10/22, Tetsuo Handa wrote:
    >
    > > However, task_is_descendant() looks unnecessarily complicated, it could be
    > >
    > > static int task_is_descendant(struct task_struct *parent,
    > > struct task_struct *child)
    > > {
    > > int rc = 0;
    > > struct task_struct *walker;
    > >
    > > if (!parent || !child)
    > > return 0;
    > >
    > > rcu_read_lock();
    > > for (walker = child; walker->pid; walker = rcu_dereference(walker->real_parent))
    > > if (same_thread_group(parent, walker)) {
    > > rc = 1;
    > > break;
    > > }
    > > rcu_read_unlock();
    > >
    > > return rc;
    > > }
    > >
    > > And again, I do not know how/if yama ensures that child is rcu-protected, perhaps
    > > task_is_descendant() needs to check pid_alive(child) right after rcu_read_lock() ?
    >
    > Since the caller (ptrace() path) called get_task_struct(child), child itself can't be
    > released. Do we still need pid_alive(child) ?

    get_task_struct(child) can only ensure that this task_struct can't be freed.

    Suppose that this child exits after get_task_struct(), then its real_parent exits
    too and calls call_rcu(delayed_put_task_struct).

    Now, when task_is_descendant() is called, rcu_read_lock() can happen after rcu gp,
    iow child->parent can be already freed/reused/unmapped.

    We need to ensure that child is still protected by RCU.

    Oleg.

    \
     
     \ /
      Last update: 2018-10-22 15:47    [W:2.192 / U:0.196 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site