• Paul Jackson's avatar
    [PATCH] cpuset: fork hook fix · b4b26418
    Paul Jackson authored
    
    
    Fix obscure, never seen in real life, cpuset fork race.  The cpuset_fork()
    call in fork.c was setting up the correct task->cpuset pointer after the
    tasklist_lock was dropped, which briefly exposed the newly forked process with
    an unsafe (copied from parent without locks or usage counter increment) cpuset
    pointer.
    
    In theory, that exposed cpuset pointer could have been pointing at a cpuset
    that was already freed and removed, and in theory another task that had been
    sitting on the tasklist_lock waiting to scan the task list could have raced
    down the entire tasklist, found our new child at the far end, and dereferenced
    that bogus cpuset pointer.
    
    To fix, setup up the correct cpuset pointer in the new child by calling
    cpuset_fork() before the new task is linked into the tasklist, and with that,
    add a fork failure case, to dereference that cpuset, if the fork fails along
    the way, after cpuset_fork() was called.
    
    Had to remove a BUG_ON() from cpuset_exit(), because it was no longer valid -
    the call to cpuset_exit() from a failed fork would not have PF_EXITING set.
    Signed-off-by: default avatarPaul Jackson <pj@sgi.com>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    b4b26418
cpuset.c 59.4 KB