Revision: 23356 http://trac.macosforge.org/projects/launchd/changeset/23356 Author: zarzycki@apple.com Date: 2007-09-05 11:20:21 -0700 (Wed, 05 Sep 2007) Log Message: ----------- <rdar://problem/5461936> signal handling bugs found during code audit SIGTERM might be ignored for a tiny window post fork() and pre execve() in the child. SIGTERM might be ignored for a tiny window of launchd's initialization of itself. Modified Paths: -------------- trunk/launchd/src/launchd.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c trunk/launchd/src/launchd_runtime.h Modified: trunk/launchd/src/launchd.c =================================================================== --- trunk/launchd/src/launchd.c 2007-09-05 15:04:36 UTC (rev 23355) +++ trunk/launchd/src/launchd.c 2007-09-05 18:20:21 UTC (rev 23356) @@ -106,13 +106,7 @@ int main(int argc, char *const *argv) { - static const int sigigns[] = { SIGHUP, SIGINT, SIGPIPE, SIGALRM, - SIGTERM, SIGURG, SIGTSTP, SIGTSTP, SIGCONT, SIGTTIN, - SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, - SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 - }; bool sflag = false; - size_t i; int ch; testfd_or_openfd(STDIN_FILENO, _PATH_DEVNULL, O_RDONLY); @@ -136,10 +130,6 @@ launchd_runtime_init(); - for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { - launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); - } - if (NULL == getenv("PATH")) { setenv("PATH", _PATH_STDPATH, 1); } @@ -152,13 +142,14 @@ monitor_networking_state(); - if (getpid() == 1) { handle_pid1_crashes_separately(); } jobmgr_init(sflag); + launchd_runtime_init2(); + launchd_runtime(); } Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-09-05 15:04:36 UTC (rev 23355) +++ trunk/launchd/src/launchd_core_logic.c 2007-09-05 18:20:21 UTC (rev 23356) @@ -2482,10 +2482,6 @@ job_assumes(j, binpref_out_cnt == j->j_binpref_cnt); } - for (i = 1; i < NSIG; i++) { - signal(i, SIG_DFL); - } - if (j->quarantine_data) { qtn_proc_t qp; Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2007-09-05 15:04:36 UTC (rev 23355) +++ trunk/launchd/src/launchd_runtime.c 2007-09-05 18:20:21 UTC (rev 23356) @@ -54,6 +54,7 @@ #include <stdlib.h> #include <stdbool.h> #include <syslog.h> +#include <signal.h> #include <dlfcn.h> #include "launchd_internalServer.h" @@ -105,6 +106,13 @@ static bool logmsg_add(struct runtime_syslog_attr *attr, int err_num, const char *msg); static void logmsg_remove(struct logmsg_s *lm); + +static const int sigigns[] = { SIGHUP, SIGINT, SIGPIPE, SIGALRM, SIGTERM, + SIGURG, SIGTSTP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, + SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 +}; +static sigset_t sigign_set; + void launchd_runtime_init(void) { @@ -143,6 +151,17 @@ runtime_setlogmask(LOG_UPTO(/* LOG_DEBUG */ LOG_NOTICE)); } +void +launchd_runtime_init2(void) +{ + size_t i; + + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + sigaddset(&sigign_set, sigigns[i]); + launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); + } +} + void * mport_demand_loop(void *arg __attribute__((unused))) { @@ -583,19 +602,33 @@ pid_t runtime_fork(mach_port_t bsport) { + sigset_t emptyset, oset; pid_t r = -1; int saved_errno; + size_t i; + sigemptyset(&emptyset); + launchd_assumes(launchd_mport_make_send(bsport) == KERN_SUCCESS); launchd_assumes(launchd_set_bport(bsport) == KERN_SUCCESS); launchd_assumes(launchd_mport_deallocate(bsport) == KERN_SUCCESS); + launchd_assumes(sigprocmask(SIG_BLOCK, &sigign_set, &oset) != -1); + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + launchd_assumes(signal(sigigns[i], SIG_DFL) != SIG_ERR); + } + r = fork(); - saved_errno = errno; if (r != 0) { + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); + } + launchd_assumes(sigprocmask(SIG_SETMASK, &oset, NULL) != -1); launchd_assumes(launchd_set_bport(MACH_PORT_NULL) == KERN_SUCCESS); + } else { + launchd_assumes(sigprocmask(SIG_SETMASK, &emptyset, NULL) != -1); } errno = saved_errno; Modified: trunk/launchd/src/launchd_runtime.h =================================================================== --- trunk/launchd/src/launchd_runtime.h 2007-09-05 15:04:36 UTC (rev 23355) +++ trunk/launchd/src/launchd_runtime.h 2007-09-05 18:20:21 UTC (rev 23356) @@ -57,6 +57,7 @@ boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); void launchd_runtime_init(void); +void launchd_runtime_init2(void); void launchd_runtime(void) __attribute__((noreturn)); int runtime_close(int fd);