]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/exit.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[mirror_ubuntu-bionic-kernel.git] / kernel / exit.c
index 580da79e38ee89992a93e6cb61f2c16232d580a6..9960accbf2ab0863643a5ee38b0040043f424d20 100644 (file)
@@ -607,15 +607,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)