After VFS shutdown, init(8) cannot map a missing page that contains
authorbluhm <bluhm@openbsd.org>
Wed, 14 Jul 2021 22:09:24 +0000 (22:09 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 14 Jul 2021 22:09:24 +0000 (22:09 +0000)
the signal handler code.  Traditionally a process would spin in
such a case, but we changed the logic in revision 1.167 trapsignal()
to receive a fatal signal.  If that happens to init(8), the kernel
panics.  In case of reboot, jump between init signal handler and
page fault trap until the kernel resets the machine.
reported and tested weerd@; OK deraadt@

sys/kern/kern_sig.c

index 8095258..f23ffe9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sig.c,v 1.281 2021/05/10 18:01:24 mpi Exp $      */
+/*     $OpenBSD: kern_sig.c,v 1.282 2021/07/14 22:09:24 bluhm Exp $    */
 /*     $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
 
 /*
@@ -842,10 +842,16 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code,
                 * generated by the kernel, be ignorable or blockable.
                 * If it is and we're not being traced, then just kill
                 * the process.
+                * After vfs_shutdown(9), init(8) cannot receive signals
+                * because new code pages of the signal handler cannot be
+                * mapped from halted storage.  init(8) may not die or the
+                * kernel panics.  Better loop between signal handler and
+                * page fault trap until the machine is halted.
                 */
                if ((pr->ps_flags & PS_TRACED) == 0 &&
                    (sigprop[signum] & SA_KILL) &&
-                   ((p->p_sigmask & mask) || (ps->ps_sigignore & mask)))
+                   ((p->p_sigmask & mask) || (ps->ps_sigignore & mask)) &&
+                   pr->ps_pid != 1)
                        sigexit(p, signum);
                ptsignal(p, signum, STHREAD);
        }