• Andrea Arcangeli's avatar
    userfaultfd: use RCU to free the task struct when fork fails · aa9bb986
    Andrea Arcangeli authored
    commit c3f3ce04 upstream.
    
    The task structure is freed while get_mem_cgroup_from_mm() holds
    rcu_read_lock() and dereferences mm->owner.
    
      get_mem_cgroup_from_mm()                failing fork()
      ----                                    ---
      task = mm->owner
                                              mm->owner = NULL;
                                              free(task)
      if (task) *task; /* use after free */
    
    The fix consists in freeing the task with RCU also in the fork failure
    case, exactly like it always happens for the regular exit(2) path.  That
    is enough to make the rcu_read_lock hold in get_mem_cgroup_from_mm()
    (left side above) effective to avoid a use after free when dereferencing
    the task structure.
    
    An alternate possible fix would be to defer the delivery of the
    userfaultfd contexts to the monitor until after fork() is guaranteed to
    succeed.  Such a change would require more changes because it would
    cre...
    aa9bb986
fork.c 63.9 KB