locking/rtmutex: Avoid a NULL pointer dereference on deadlock
[firefly-linux-kernel-4.4.55.git] / kernel / pid_namespace.c
index e1bafe3b47bb4af35475754434fdd53ac8337318..a65ba137fd15b42ba840ca1e46243ef44fa6839c 100644 (file)
@@ -191,7 +191,11 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
        /* Don't allow any more processes into the pid namespace */
        disable_pid_allocation(pid_ns);
 
-       /* Ignore SIGCHLD causing any terminated children to autoreap */
+       /*
+        * Ignore SIGCHLD causing any terminated children to autoreap.
+        * This speeds up the namespace shutdown, plus see the comment
+        * below.
+        */
        spin_lock_irq(&me->sighand->siglock);
        me->sighand->action[SIGCHLD - 1].sa.sa_handler = SIG_IGN;
        spin_unlock_irq(&me->sighand->siglock);
@@ -224,15 +228,31 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
        }
        read_unlock(&tasklist_lock);
 
-       /* Firstly reap the EXIT_ZOMBIE children we may have. */
+       /*
+        * Reap the EXIT_ZOMBIE children we had before we ignored SIGCHLD.
+        * sys_wait4() will also block until our children traced from the
+        * parent namespace are detached and become EXIT_DEAD.
+        */
        do {
                clear_thread_flag(TIF_SIGPENDING);
                rc = sys_wait4(-1, NULL, __WALL, NULL);
        } while (rc != -ECHILD);
 
        /*
-        * sys_wait4() above can't reap the TASK_DEAD children.
-        * Make sure they all go away, see free_pid().
+        * sys_wait4() above can't reap the EXIT_DEAD children but we do not
+        * really care, we could reparent them to the global init. We could
+        * exit and reap ->child_reaper even if it is not the last thread in
+        * this pid_ns, free_pid(nr_hashed == 0) calls proc_cleanup_work(),
+        * pid_ns can not go away until proc_kill_sb() drops the reference.
+        *
+        * But this ns can also have other tasks injected by setns()+fork().
+        * Again, ignoring the user visible semantics we do not really need
+        * to wait until they are all reaped, but they can be reparented to
+        * us and thus we need to ensure that pid->child_reaper stays valid
+        * until they all go away. See free_pid()->wake_up_process().
+        *
+        * We rely on ignored SIGCHLD, an injected zombie must be autoreaped
+        * if reparented.
         */
        for (;;) {
                set_current_state(TASK_UNINTERRUPTIBLE);