From 821756371c77bf0f3293df0aa225842ebaebbb2e Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Thu, 16 Jul 2026 22:50:23 +0200 Subject: [PATCH] Block signal delivery across fork to prevent signal forwarding race condition in main.c --- cmdline/main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cmdline/main.c b/cmdline/main.c index d59edac2..8d1dfc33 100644 --- a/cmdline/main.c +++ b/cmdline/main.c @@ -315,7 +315,7 @@ const char* get_argv0(const char* argv0) } /* global variable to store child PID for signal handler */ -static volatile pid_t child_pid = 0; +static volatile sig_atomic_t child_pid = 0; /* signal handler that forwards signals to child */ /* LCOV_EXCL_START */ @@ -364,6 +364,18 @@ int main(int argc, char* argv[]) sigaction(SIGUSR1, &sa, NULL); /* user-defined 1 */ sigaction(SIGUSR2, &sa, NULL); /* user-defined 2 */ + sigset_t set, oldset; + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGQUIT); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGUSR2); + + /* block signals to prevent signal race before child_pid is set */ + sigprocmask(SIG_BLOCK, &set, &oldset); + pid_t pid = fork(); if (pid == -1) { /* LCOV_EXCL_START */ @@ -383,6 +395,9 @@ int main(int argc, char* argv[]) signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); + /* unblock signals in child */ + sigprocmask(SIG_SETMASK, &oldset, NULL); + execvp(get_argv0(argv[0]), argv); /* here it's an error */ @@ -397,6 +412,9 @@ int main(int argc, char* argv[]) /* store child PID so signal handler can forward signals */ child_pid = pid; + /* unblock signals in parent */ + sigprocmask(SIG_SETMASK, &oldset, NULL); + do { ret = waitpid(pid, &status, 0); } while (ret == -1 && errno == EINTR); /* retry if interrupted by signal */