mirror of
https://github.com/openvswitch/ovs
synced 2025-09-05 00:35:33 +00:00
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.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include <unistd.h>
|
||||
#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)) {
|
||||
|
Reference in New Issue
Block a user