From 52dc2ef41b18cc7d4ed2d19f125f19af5eba12b5 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 15 Jul 2009 12:05:04 -0700 Subject: [PATCH] process: Fix races on fatal signal handling in process_start(). To prevent fatal signals in a child process from causing the parent process's pidfile, etc. to be deleted, we need to block fatal signals around fork and call fatal_signal_fork() in the child process. This problem was noticed through code inspection; it has not been observed in practice. --- lib/process.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/process.c b/lib/process.c index 7b583cac0..cd7cbcfb2 100644 --- a/lib/process.c +++ b/lib/process.c @@ -27,6 +27,7 @@ #include #include "coverage.h" #include "dynamic-string.h" +#include "fatal-signal.h" #include "list.h" #include "poll-loop.h" #include "socket-util.h" @@ -51,6 +52,7 @@ static int fds[2]; /* All processes. */ static struct list all_processes = LIST_INITIALIZER(&all_processes); +static bool sigchld_is_blocked(void); static void block_sigchld(sigset_t *); static void unblock_sigchld(const sigset_t *); static void sigchld_handler(int signr UNUSED); @@ -158,8 +160,10 @@ process_start(char **argv, free(binary); block_sigchld(&oldsigs); + fatal_signal_block(); pid = fork(); if (pid < 0) { + fatal_signal_unblock(); unblock_sigchld(&oldsigs); VLOG_WARN("fork failed: %s", strerror(errno)); return errno; @@ -176,6 +180,7 @@ process_start(char **argv, list_push_back(&all_processes, &p->node); unblock_sigchld(&oldsigs); + fatal_signal_unblock(); *pp = p; return 0; @@ -184,6 +189,8 @@ process_start(char **argv, int fd_max = get_max_fds(); int fd; + fatal_signal_fork(); + fatal_signal_unblock(); unblock_sigchld(&oldsigs); for (fd = 0; fd < fd_max; fd++) { if (is_member(fd, null_fds, n_null_fds)) { -- 2.43.0