Skip to content

Commit 8fb335e

Browse files
avagintorvalds
authored andcommitted
kernel/exit.c: release ptraced tasks before zap_pid_ns_processes
Currently, exit_ptrace() adds all ptraced tasks in a dead list, then zap_pid_ns_processes() waits on all tasks in a current pidns, and only then are tasks from the dead list released. zap_pid_ns_processes() can get stuck on waiting tasks from the dead list. In this case, we will have one unkillable process with one or more dead children. Thanks to Oleg for the advice to release tasks in find_child_reaper(). Link: http://lkml.kernel.org/r/20190110175200.12442-1-avagin@gmail.com Fixes: 7c8bd23 ("exit: ptrace: shift "reap dead" code from exit_ptrace() to forget_original_parent()") Signed-off-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a8e911d commit 8fb335e

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

kernel/exit.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,12 +558,14 @@ static struct task_struct *find_alive_thread(struct task_struct *p)
558558
return NULL;
559559
}
560560

561-
static struct task_struct *find_child_reaper(struct task_struct *father)
561+
static struct task_struct *find_child_reaper(struct task_struct *father,
562+
struct list_head *dead)
562563
__releases(&tasklist_lock)
563564
__acquires(&tasklist_lock)
564565
{
565566
struct pid_namespace *pid_ns = task_active_pid_ns(father);
566567
struct task_struct *reaper = pid_ns->child_reaper;
568+
struct task_struct *p, *n;
567569

568570
if (likely(reaper != father))
569571
return reaper;
@@ -579,6 +581,12 @@ static struct task_struct *find_child_reaper(struct task_struct *father)
579581
panic("Attempted to kill init! exitcode=0x%08x\n",
580582
father->signal->group_exit_code ?: father->exit_code);
581583
}
584+
585+
list_for_each_entry_safe(p, n, dead, ptrace_entry) {
586+
list_del_init(&p->ptrace_entry);
587+
release_task(p);
588+
}
589+
582590
zap_pid_ns_processes(pid_ns);
583591
write_lock_irq(&tasklist_lock);
584592

@@ -668,7 +676,7 @@ static void forget_original_parent(struct task_struct *father,
668676
exit_ptrace(father, dead);
669677

670678
/* Can drop and reacquire tasklist_lock */
671-
reaper = find_child_reaper(father);
679+
reaper = find_child_reaper(father, dead);
672680
if (list_empty(&father->children))
673681
return;
674682

0 commit comments

Comments
 (0)