From 6ec6ff78fc906177a1f5ef6f432ed1d61409e995 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 27 Sep 2014 11:10:06 +0100 Subject: [PATCH] process: Introduce afterfork() Rework set_default_signals into afterfork, which does the sigprocmask too. This is necessary for processes we fork after setup_signal_handling(), which otherwise inherit our blocking mask and non-default handlers. Call it after each fork() (except the ones we use for daemonising). As a consequence: - hackypar children will die if they get a terminating signal - our subprocesses such as `route' and `ifconfig' will inherit reasonable signal setups - it will be correct to call udp_make_socket during phase RUN (previously any authbind would get a strange signal setup) Signed-off-by: Ian Jackson --- hackypar.c | 1 + process.c | 11 ++++++----- secnet.h | 4 ++++ udp.c | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hackypar.c b/hackypar.c index eb445b0..abc93c4 100644 --- a/hackypar.c +++ b/hackypar.c @@ -55,6 +55,7 @@ static HPState start(void) } if (!child) { /* we are the child */ + afterfork(); return hp_compute; } diff --git a/process.c b/process.c index b75b9c0..edc87ac 100644 --- a/process.c +++ b/process.c @@ -35,8 +35,6 @@ static struct signotify *sigs=NULL; static int spw,spr; /* file descriptors for signal notification pipe */ -static void set_default_signals(void); - /* Long-lived subprocesses can only be started once we've started signal processing so that we can catch SIGCHLD for them and report their exit status using the callback function. We block SIGCHLD @@ -58,8 +56,7 @@ pid_t makesubproc(process_entry_fn *entry, process_callback_fn *cb, p=fork(); if (p==0) { /* Child process */ - set_default_signals(); - sigprocmask(SIG_SETMASK,&emptyset,NULL); + afterfork(); entry(est); abort(); } else if (p==-1) { @@ -155,6 +152,7 @@ int sys_cmd(const char *path, const char *arg, ...) if the execvp() fails this seems somewhat pointless, and increases the chance of the child process failing before it gets to exec(). */ + afterfork(); va_start(ap,arg); args[0]=(char *)arg; /* program name */ i=1; @@ -214,7 +212,7 @@ static void signal_afterpoll(void *st, struct pollfd *fds, int nfds) } } -static void set_default_signals(void) +void afterfork(void) { struct signotify *n; sigset_t done; @@ -229,6 +227,9 @@ static void set_default_signals(void) sa.sa_flags=0; sigaction(n->signum,&sa,NULL); } + + sigemptyset(&emptyset); + sigprocmask(SIG_SETMASK,&emptyset,NULL); } static void signal_handler(int signum) diff --git a/secnet.h b/secnet.h index 4e53208..8fb3610 100644 --- a/secnet.h +++ b/secnet.h @@ -59,6 +59,10 @@ extern struct log_if *system_log; /* from process.c */ extern void start_signal_handling(void); +void afterfork(void); +/* Must be called before exec in every child made after + start_signal_handling. Safe to call in earlier children too. */ + /***** CONFIGURATION support *****/ extern bool_t just_check_config; /* If True then we're going to exit after diff --git a/udp.c b/udp.c index 85de961..3367ab5 100644 --- a/udp.c +++ b/udp.c @@ -223,6 +223,7 @@ bool_t udp_make_socket(struct udpcommon *uc, struct udpsock *us, char *argv[5], addrstr[33], portstr[5]; const char *addrfam; int port; + afterfork(); switch (addr->sa.sa_family) { case AF_INET: sprintf(addrstr,"%08lX",(long)addr->sin.sin_addr.s_addr); -- 2.30.2