summaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 580da79e38ee..9960accbf2ab 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -607,15 +607,18 @@ static struct task_struct *find_new_reaper(struct task_struct *father,
607 return thread; 607 return thread;
608 608
609 if (father->signal->has_child_subreaper) { 609 if (father->signal->has_child_subreaper) {
610 unsigned int ns_level = task_pid(father)->level;
610 /* 611 /*
611 * Find the first ->is_child_subreaper ancestor in our pid_ns. 612 * Find the first ->is_child_subreaper ancestor in our pid_ns.
612 * We start from father to ensure we can not look into another 613 * We can't check reaper != child_reaper to ensure we do not
613 * namespace, this is safe because all its threads are dead. 614 * cross the namespaces, the exiting parent could be injected
615 * by setns() + fork().
616 * We check pid->level, this is slightly more efficient than
617 * task_active_pid_ns(reaper) != task_active_pid_ns(father).
614 */ 618 */
615 for (reaper = father; 619 for (reaper = father->real_parent;
616 !same_thread_group(reaper, child_reaper); 620 task_pid(reaper)->level == ns_level;
617 reaper = reaper->real_parent) { 621 reaper = reaper->real_parent) {
618 /* call_usermodehelper() descendants need this check */
619 if (reaper == &init_task) 622 if (reaper == &init_task)
620 break; 623 break;
621 if (!reaper->signal->is_child_subreaper) 624 if (!reaper->signal->is_child_subreaper)