Skip to content

Commit 423cfa4

Browse files
committed
xspawn: Mask signals before fork()
This prevents signal handlers from running in the child before execve().
1 parent 5865ad2 commit 423cfa4

1 file changed

Lines changed: 29 additions & 8 deletions

File tree

src/xspawn.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
#include "xspawn.h"
66
#include "alloc.h"
77
#include "bfstd.h"
8+
#include "diag.h"
89
#include "list.h"
910
#include <errno.h>
1011
#include <fcntl.h>
12+
#include <signal.h>
1113
#include <stdlib.h>
1214
#include <string.h>
1315
#include <sys/resource.h>
@@ -590,30 +592,49 @@ static pid_t bfs_fork_spawn(struct bfs_resolver *res, const struct bfs_spawn *ct
590592
return -1;
591593
}
592594

595+
// Block signals before fork() so handlers don't run in the child
596+
sigset_t new_mask;
597+
if (sigfillset(&new_mask) != 0) {
598+
goto fail;
599+
}
600+
sigset_t old_mask;
601+
errno = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
602+
if (errno != 0) {
603+
goto fail;
604+
}
605+
593606
pid_t pid = fork();
594-
if (pid < 0) {
595-
close_quietly(pipefd[1]);
596-
close_quietly(pipefd[0]);
597-
return -1;
598-
} else if (pid == 0) {
607+
if (pid == 0) {
599608
// Child
600609
bfs_spawn_exec(res, ctx, argv, envp, pipefd);
601610
}
602611

603-
// Parent
612+
// Restore the original signal mask
613+
int ret = pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
614+
bfs_verify(ret == 0, "pthread_sigmask(): %s", xstrerror(ret));
615+
616+
if (pid < 0) {
617+
// fork() failed
618+
goto fail;
619+
}
620+
604621
xclose(pipefd[1]);
605622

606623
int error;
607624
ssize_t nbytes = xread(pipefd[0], &error, sizeof(error));
608625
xclose(pipefd[0]);
609626
if (nbytes == sizeof(error)) {
610-
int wstatus;
611-
xwaitpid(pid, &wstatus, 0);
627+
xwaitpid(pid, NULL, 0);
612628
errno = error;
613629
return -1;
614630
}
615631

616632
return pid;
633+
634+
fail:
635+
close_quietly(pipefd[1]);
636+
close_quietly(pipefd[0]);
637+
return -1;
617638
}
618639

619640
/** Call the right bfs_spawn() implementation. */

0 commit comments

Comments
 (0)