skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

commit 37e31f79514acfdff8ede65b73542b7abb1e61a5
parent ab9c34c0e7b6a6abc8374b0e5f6515c75342239e
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Wed, 26 Feb 2020 17:18:47 +0000

 Explicitly unblock signals when selfpiped without signalfd

 This is arguably a bugfix, since selfpipe without signalfd
relies on signals being actually delivered, and a process may
have inherited a nonempty sigprocmask.

 Also use SIG_BLOCK instead of SIG_SETMASK when using
selfpipe_trapset() with signalfd, because we shouldn't unblock
signals that may have previously been blocked. This is also
arguably a bugfix.

 This commit is essential for using the version of s6-linux-init
that blocks SIGINT before disablecad on kernels without signalfd.
Without it, SIGINT never gets unblocked, so it's never delivered
to s6-svscan.

Diffstat:
Msrc/libstddjb/selfpipe_trap.c | 2+-
Msrc/libstddjb/selfpipe_trapset.c | 4++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libstddjb/selfpipe_trap.c b/src/libstddjb/selfpipe_trap.c @@ -38,7 +38,7 @@ int selfpipe_trap (int sig) { if (selfpipe_fd < 0) return (errno = EBADF, -1) ; if (sig_catcha(sig, &selfpipe_ssa) < 0) return -1 ; - if (sigaddset(&selfpipe_caught, sig) < 0) + if (sigprocmask(SIG_UNBLOCK, sig, 0) < 0 || sigaddset(&selfpipe_caught, sig) < 0) { int e = errno ; sig_restore(sig) ; diff --git a/src/libstddjb/selfpipe_trapset.c b/src/libstddjb/selfpipe_trapset.c @@ -14,7 +14,7 @@ int selfpipe_trapset (sigset_t const *set) { sigset_t old ; if (selfpipe_fd < 0) return (errno = EBADF, -1) ; - if (sigprocmask(SIG_SETMASK, set, &old) < 0) return -1 ; + if (sigprocmask(SIG_BLOCK, set, &old) < 0) return -1 ; if (signalfd(selfpipe_fd, set, SFD_NONBLOCK | SFD_CLOEXEC) < 0) { int e = errno ; @@ -53,7 +53,7 @@ int selfpipe_trapset (sigset_t const *set) if (sig_restore(i) < 0) break ; } } - if (i < SKALIBS_NSIG) + if (i < SKALIBS_NSIG || sigprocmask(SIG_UNBLOCK, set, 0) < 0) { int e = errno ; sig_restoreto(set, i) ;