• O
    exit: reparent: use ->ptrace_entry rather than ->sibling for EXIT_DEAD tasks · dc2fd4b0
    Oleg Nesterov 提交于
    reparent_leader() reuses ->sibling as a list node to add an EXIT_DEAD task
    into dead_children list we are going to release.  This obviously removes
    the dead task from its real_parent->children list and this is even good;
    the parent can do nothing with the EXIT_DEAD reparented zombie, it only
    makes do_wait() slower.
    
    But, this also means that it can not be reparented once again, so if its
    new parent dies too nobody will update ->parent/real_parent, they can
    point to the freed memory even before release_task() we are going to call,
    this breaks the code which relies on pid_alive() to access
    ->real_parent/parent.
    
    Fortunately this is mostly theoretical, this can only happen if init or
    PR_SET_CHILD_SUBREAPER process ignores SIGCHLD and the new parent
    sub-thread exits right after we drop tasklist_lock.
    
    Change this code to use ->ptrace_entry instead, we know that the child is
    not traced so nobody can ever use this member.  This also allows to unify
    this logic with exit_ptrace(), see the next changes.
    
    Note: we really need to change release_task() to nullify real_parent/
    parent/group_leader pointers, but we need to change the current users
    first somehow.  And it would be better to reap this zombie immediately but
    release_task_locked() we need is complicated by proc_flush_task().
    Signed-off-by: NOleg Nesterov <oleg@redhat.com>
    Cc: Aaron Tomlin <atomlin@redhat.com>
    Cc: Alexey Dobriyan <adobriyan@gmail.com>
    Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
    Cc: Sterling Alexander <stalexan@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Roland McGrath <roland@hack.frob.com>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    dc2fd4b0
exit.c 42.0 KB