block SIGHUP in the same places where SIGCHLD is blocked to protect
authorderaadt <deraadt@openbsd.org>
Sun, 28 Jul 2024 15:31:22 +0000 (15:31 +0000)
committerderaadt <deraadt@openbsd.org>
Sun, 28 Jul 2024 15:31:22 +0000 (15:31 +0000)
the process lists, because the SIGHUP handler looks at them (and
it is very difficult to rewrite the that handler a different way)
ok millert

bin/csh/csh.c
bin/csh/proc.c
bin/csh/sem.c

index c948f5d..db41129 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: csh.c,v 1.50 2023/03/08 04:43:04 guenther Exp $       */
+/*     $OpenBSD: csh.c,v 1.51 2024/07/28 15:31:22 deraadt Exp $        */
 /*     $NetBSD: csh.c,v 1.14 1995/04/29 23:21:28 mycroft Exp $ */
 
 /*-
@@ -900,9 +900,7 @@ exitstat(void)
 static void
 phup(int sig)
 {
-    /* XXX sigh, everything after this is a signal race */
-
-    rechist();
+    rechist(); /* XXX big signal race */
 
     /*
      * We kill the last foreground process group. It then becomes
index 369e1d6..5451db7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.c,v 1.35 2023/03/08 04:43:04 guenther Exp $      */
+/*     $OpenBSD: proc.c,v 1.36 2024/07/28 15:31:22 deraadt Exp $       */
 /*     $NetBSD: proc.c,v 1.9 1995/04/29 23:21:33 mycroft Exp $ */
 
 /*-
@@ -207,6 +207,7 @@ pnote(void)
     neednote = 0;
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) {
        if (pp->p_flags & PNEEDNOTE) {
            sigprocmask(SIG_BLOCK, &sigset, &osigset);
@@ -234,6 +235,7 @@ pwait(void)
      */
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     sigprocmask(SIG_BLOCK, &sigset, &osigset);
     for (pp = (fp = &proclist)->p_next; pp != NULL; pp = (fp = pp)->p_next)
        if (pp->p_pid == 0) {
@@ -276,10 +278,12 @@ pjwait(struct process *pp)
     fp = pp;
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     sigprocmask(SIG_BLOCK, &sigset, &osigset);
     for (;;) {
        sigemptyset(&sigset);
        sigaddset(&sigset, SIGCHLD);
+       sigaddset(&sigset, SIGHUP);
        sigprocmask(SIG_BLOCK, &sigset, NULL);
        jobflags = 0;
        do
@@ -289,6 +293,7 @@ pjwait(struct process *pp)
            break;
        sigset = osigset;
        sigdelset(&sigset, SIGCHLD);
+       sigdelset(&sigset, SIGHUP);
        sigsuspend(&sigset);
     }
     sigprocmask(SIG_SETMASK, &osigset, NULL);
@@ -352,6 +357,7 @@ dowait(Char **v, struct command *t)
     pjobs++;
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     sigprocmask(SIG_BLOCK, &sigset, &osigset);
 loop:
     for (pp = proclist.p_next; pp; pp = pp->p_next)
@@ -1004,6 +1010,7 @@ pkill(Char **v, int signum)
 
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     if (setintr)
        sigaddset(&sigset, SIGINT);
     sigprocmask(SIG_BLOCK, &sigset, NULL);
@@ -1095,6 +1102,7 @@ pstart(struct process *pp, int foregnd)
 
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     sigprocmask(SIG_BLOCK, &sigset, &osigset);
     np = pp;
     do {
@@ -1255,10 +1263,11 @@ pfork(struct command *t, int wanttty)
     if (child == 16)
        stderror(ERR_NESTING, 16);
     /*
-     * Hold SIGCHLD until we have the process installed in our table.
+     * Hold SIGCHLD/SIGHUP until we have the process installed in our table.
      */
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGCHLD);
+    sigaddset(&sigset, SIGHUP);
     sigprocmask(SIG_BLOCK, &sigset, &osigset);
     while ((pid = fork()) == -1)
        if (setintr == 0)
index f9ffff8..bb47e89 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sem.c,v 1.23 2019/06/28 13:34:58 deraadt Exp $        */
+/*     $OpenBSD: sem.c,v 1.24 2024/07/28 15:31:22 deraadt Exp $        */
 /*     $NetBSD: sem.c,v 1.9 1995/09/27 00:38:50 jtc Exp $      */
 
 /*-
@@ -196,12 +196,13 @@ execute(struct command *t, int wanttty, int *pipein, int *pipeout)
                t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
                forked++;
                /*
-                * We need to block SIGCHLD here, so that if the process does
+                * We need to block SIGCHLD/SIGHUP here, so that if the process does
                 * not die before we can set the process group
                 */
                if (wanttty >= 0 && !nosigchld) {
                    sigemptyset(&sigset);
                    sigaddset(&sigset, SIGCHLD);
+                   sigaddset(&sigset, SIGHUP);
                    sigprocmask(SIG_BLOCK, &sigset, &csigset);
                    nosigchld = 1;
                }
@@ -231,11 +232,13 @@ execute(struct command *t, int wanttty, int *pipein, int *pipeout)
                if (wanttty >= 0 && !nosigchld && !noexec) {
                    sigemptyset(&sigset);
                    sigaddset(&sigset, SIGCHLD);
+                   sigaddset(&sigset, SIGHUP);
                    sigprocmask(SIG_BLOCK, &sigset, &csigset);
                    nosigchld = 1;
                }
                sigemptyset(&sigset);
                sigaddset(&sigset, SIGCHLD);
+               sigaddset(&sigset, SIGHUP);
                sigaddset(&sigset, SIGINT);
                sigprocmask(SIG_BLOCK, &sigset, &osigset);
                ochild = child;