From 324a3c8c4fa8ffde0089779a36a18802d9141d5c Mon Sep 17 00:00:00 2001 From: deraadt Date: Sun, 28 Jul 2024 15:31:22 +0000 Subject: [PATCH] block SIGHUP in the same places where SIGCHLD is blocked to protect 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 | 6 ++---- bin/csh/proc.c | 13 +++++++++++-- bin/csh/sem.c | 7 +++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/bin/csh/csh.c b/bin/csh/csh.c index c948f5d7063..db411292cd1 100644 --- a/bin/csh/csh.c +++ b/bin/csh/csh.c @@ -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 diff --git a/bin/csh/proc.c b/bin/csh/proc.c index 369e1d699ab..5451db7a497 100644 --- a/bin/csh/proc.c +++ b/bin/csh/proc.c @@ -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) diff --git a/bin/csh/sem.c b/bin/csh/sem.c index f9ffff8a08d..bb47e8925a6 100644 --- a/bin/csh/sem.c +++ b/bin/csh/sem.c @@ -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; -- 2.20.1