From 3de9e4e5db22f065cb5c069cc32a7dfc5141bf5b Mon Sep 17 00:00:00 2001 From: Patrick Stewart Date: Wed, 13 Apr 2016 17:02:33 +0100 Subject: [PATCH] Fix potential race condition/hang for SVC_TYPE_RUN services In service_start() the SIGCHLD handler is reenabled before calling complete(), so the service could be reaped by the SIGCHLD handler leaving service_start() waiting forever Also remove code that duplicates sig_unblock() --- service.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) mode change 100644 => 100755 service.c diff --git a/service.c b/service.c old mode 100644 new mode 100755 index a04b568d..270cdaf9 --- a/service.c +++ b/service.c @@ -162,7 +162,6 @@ static int service_start(svc_t *svc) sigprocmask(SIG_BLOCK, &nmask, &omask); pid = fork(); - sigprocmask(SIG_SETMASK, &omask, NULL); if (pid == 0) { int i = 0; int status; @@ -171,17 +170,8 @@ static int service_start(svc_t *svc) #else int uid = getuser(svc->username); #endif - struct sigaction sa; char *args[MAX_NUM_SVC_ARGS]; - sigemptyset(&nmask); - sigaddset(&nmask, SIGCHLD); - sigprocmask(SIG_UNBLOCK, &nmask, NULL); - - /* Reset signal handlers that were set by the parent process */ - for (i = 1; i < NSIG; i++) - DFLSIG(sa, i, 0); - /* Set desired user */ if (uid >= 0) { setuid(uid); @@ -257,6 +247,8 @@ static int service_start(svc_t *svc) result = WEXITSTATUS(complete(svc->cmd, pid)); svc->pid = 0; } + + sigprocmask(SIG_SETMASK, &omask, NULL); if (!silent) print_result(result);