From 23cf80667a36aaff1865fc50afab3f98a796cf14 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sat, 12 Feb 2022 12:04:57 +0000 Subject: [PATCH] Explicitly initialize sigaction::sa_mask members with sigemptyset(3) Not doing so before calling sigaction(3) is "undefined" according to POSIX[1]: > Applications shall call either sigemptyset() or sigfillset() at least > once for each object of type sigset_t prior to any other use of that > object. If such an object is not initialized in this way, but is > nonetheless supplied as an argument to any of pthread_sigmask(), > sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(), > sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or > sigwaitinfo(), the results are undefined. The use of designated initializers means that sa_mask members were still being initialized, but sigset_t is an opaque type and implicit initialization doesn't necessarily produce the same results as using sigemptyset(3) (although it typically does on most implementations). [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html --- client.c | 3 ++- fdm.c | 2 ++ main.c | 3 ++- slave.c | 3 ++- spawn.c | 4 +++- terminal.c | 7 +++++-- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/client.c b/client.c index df43e7d5..a76d759a 100644 --- a/client.c +++ b/client.c @@ -455,7 +455,8 @@ main(int argc, char *const *argv) } } - const struct sigaction sa = {.sa_handler = &sig_handler}; + struct sigaction sa = {.sa_handler = &sig_handler}; + sigemptyset(&sa.sa_mask); if (sigaction(SIGINT, &sa, NULL) < 0 || sigaction(SIGTERM, &sa, NULL) < 0) { LOG_ERRNO("failed to register signal handlers"); goto err; diff --git a/fdm.c b/fdm.c index c5eaf6c1..ea30443b 100644 --- a/fdm.c +++ b/fdm.c @@ -352,6 +352,7 @@ fdm_signal_add(struct fdm *fdm, int signo, fdm_signal_handler_t handler, void *d } struct sigaction action = {.sa_handler = &signal_handler}; + sigemptyset(&action.sa_mask); if (sigaction(signo, &action, NULL) < 0) { LOG_ERRNO("failed to set signal handler for signal %d", signo); sigprocmask(SIG_SETMASK, &original, NULL); @@ -371,6 +372,7 @@ fdm_signal_del(struct fdm *fdm, int signo) return false; struct sigaction action = {.sa_handler = SIG_DFL}; + sigemptyset(&action.sa_mask); if (sigaction(signo, &action, NULL) < 0) { LOG_ERRNO("failed to restore signal handler for signal %d", signo); return false; diff --git a/main.c b/main.c index 01ee109f..ff839507 100644 --- a/main.c +++ b/main.c @@ -625,7 +625,8 @@ main(int argc, char *const *argv) goto out; } - const struct sigaction sig_ign = {.sa_handler = SIG_IGN}; + struct sigaction sig_ign = {.sa_handler = SIG_IGN}; + sigemptyset(&sig_ign.sa_mask); if (sigaction(SIGHUP, &sig_ign, NULL) < 0 || sigaction(SIGPIPE, &sig_ign, NULL) < 0) { diff --git a/slave.c b/slave.c index c4c6d4d0..4fbd5c9b 100644 --- a/slave.c +++ b/slave.c @@ -275,7 +275,8 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv, } /* Restore signal mask, and SIG_IGN'd signals */ - const struct sigaction dfl = {.sa_handler = SIG_DFL}; + struct sigaction dfl = {.sa_handler = SIG_DFL}; + sigemptyset(&dfl.sa_mask); sigset_t mask; sigemptyset(&mask); diff --git a/spawn.c b/spawn.c index d02ab131..8c5c33d2 100644 --- a/spawn.c +++ b/spawn.c @@ -45,7 +45,9 @@ spawn(struct reaper *reaper, const char *cwd, char *const argv[], goto child_err; /* Restore ignored (SIG_IGN) signals */ - if (sigaction(SIGHUP, &(struct sigaction){.sa_handler = SIG_DFL}, NULL) < 0) + struct sigaction dfl = {.sa_handler = SIG_DFL}; + sigemptyset(&dfl.sa_mask); + if (sigaction(SIGHUP, &dfl, NULL) < 0) goto child_err; if (cwd != NULL && chdir(cwd) < 0) { diff --git a/terminal.c b/terminal.c index 66c523df..f6d8f814 100644 --- a/terminal.c +++ b/terminal.c @@ -1716,7 +1716,9 @@ term_destroy(struct terminal *term) * course only applies to a 'foot --server' instance, where * there might be other terminals running. */ - sigaction(SIGALRM, &(const struct sigaction){.sa_handler = &sig_alarm}, NULL); + struct sigaction action = {.sa_handler = &sig_alarm}; + sigemptyset(&action.sa_mask); + sigaction(SIGALRM, &action, NULL); alarm(60); while (true) { @@ -1740,7 +1742,8 @@ term_destroy(struct terminal *term) /* Cancel alarm */ alarm(0); - sigaction(SIGALRM, &(const struct sigaction){.sa_handler = SIG_DFL}, NULL); + action.sa_handler = SIG_DFL; + sigaction(SIGALRM, &action, NULL); } ret = EXIT_FAILURE;