|
@@ -578,15 +578,18 @@ static struct task_struct *find_new_reaper(struct task_struct *father,
|
|
|
return thread;
|
|
|
|
|
|
if (father->signal->has_child_subreaper) {
|
|
|
+ unsigned int ns_level = task_pid(father)->level;
|
|
|
/*
|
|
|
* Find the first ->is_child_subreaper ancestor in our pid_ns.
|
|
|
- * We start from father to ensure we can not look into another
|
|
|
- * namespace, this is safe because all its threads are dead.
|
|
|
+ * We can't check reaper != child_reaper to ensure we do not
|
|
|
+ * cross the namespaces, the exiting parent could be injected
|
|
|
+ * by setns() + fork().
|
|
|
+ * We check pid->level, this is slightly more efficient than
|
|
|
+ * task_active_pid_ns(reaper) != task_active_pid_ns(father).
|
|
|
*/
|
|
|
- for (reaper = father;
|
|
|
- !same_thread_group(reaper, child_reaper);
|
|
|
+ for (reaper = father->real_parent;
|
|
|
+ task_pid(reaper)->level == ns_level;
|
|
|
reaper = reaper->real_parent) {
|
|
|
- /* call_usermodehelper() descendants need this check */
|
|
|
if (reaper == &init_task)
|
|
|
break;
|
|
|
if (!reaper->signal->is_child_subreaper)
|