From: Eric Wong Date: Mon, 11 Sep 2023 09:41:32 +0000 (+0000) Subject: spawn: do not block ABRT/BUS/ILL/SEGV signals X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b278252cd994a866bd4cf15025033dd8afbd02b;p=thirdparty%2Fpublic-inbox.git spawn: do not block ABRT/BUS/ILL/SEGV signals SIGABRT, SIGBUS, SIGILL, and SIGSEGV may all happen if we introduce bugs in the section where signals are blocked. We can delay handling of SIGFPE, SIGXCPU and SIGXFSZ since there's no floating point operations; while SIGXCPU and SIGXFSZ are safe to delay, especially in the absence of threads in our current code paths. --- diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index 17d87f57c..ed698afc6 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -92,18 +92,23 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref, sigset_t set, old; int ret, perrnum; volatile int cerrnum = 0; /* shared due to vfork */ - int chld_is_member; + int chld_is_member; /* needed due to shared memory w/ vfork */ I32 max_fd = av_len(redir); AV2C_COPY(argv, cmd); AV2C_COPY(envp, env); if (sigfillset(&set)) return -1; + if (sigdelset(&set, SIGABRT)) return -1; + if (sigdelset(&set, SIGBUS)) return -1; + if (sigdelset(&set, SIGFPE)) return -1; + if (sigdelset(&set, SIGILL)) return -1; + if (sigdelset(&set, SIGSEGV)) return -1; + /* no XCPU/XFSZ here */ if (sigprocmask(SIG_SETMASK, &set, &old)) return -1; chld_is_member = sigismember(&old, SIGCHLD); if (chld_is_member < 0) return -1; - if (chld_is_member > 0) - sigdelset(&old, SIGCHLD); + if (chld_is_member > 0 && sigdelset(&old, SIGCHLD)) return -1; pid = vfork(); if (pid == 0) { diff --git a/lib/PublicInbox/SpawnPP.pm b/lib/PublicInbox/SpawnPP.pm index d6c863f81..e7174d6f0 100644 --- a/lib/PublicInbox/SpawnPP.pm +++ b/lib/PublicInbox/SpawnPP.pm @@ -15,6 +15,10 @@ sub pi_fork_exec ($$$$$$$) { my $old = POSIX::SigSet->new(); my $set = POSIX::SigSet->new(); $set->fillset or die "sigfillset: $!"; + for (POSIX::SIGABRT, POSIX::SIGBUS, POSIX::SIGFPE, + POSIX::SIGILL, POSIX::SIGSEGV) { + $set->delset($_) or die "delset($_): $!"; + } sigprocmask(SIG_SETMASK, $set, $old) or die "SIG_SETMASK(set): $!"; my $syserr; pipe(my ($r, $w)) or die "pipe: $!";