From 0000b3cb3c05eebe689ecf96241a1476b28fbf18 Mon Sep 17 00:00:00 2001 From: Yiwei Lin Date: Sun, 19 Apr 2026 00:24:13 +0800 Subject: [PATCH] Block SIGCHLD before booting LKL Before all kernel threads are created, we have to block SIGCHLD and let all childs inherit the blocked mask. Without this, SIGCHLD (from the supervised child process exiting) may be delivered to an LKL thread where the default ignore action silently discards it, causing the signalfd in the supervisor poll loop to never become readable. Change-Id: Ib3256f044c5b8ce9c34c223beb294c207a1f47ab --- src/lkl-wrap.c | 10 ++++++++++ src/seccomp-supervisor.c | 12 ++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lkl-wrap.c b/src/lkl-wrap.c index 2170f74..2ba20f8 100644 --- a/src/lkl-wrap.c +++ b/src/lkl-wrap.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: MIT */ +#include +#include #include #include @@ -21,6 +23,14 @@ int kbox_boot_kernel(const char *cmdline) const char *effective = cmdline; char buf[512]; int ret; + sigset_t mask; + + /* Block SIGCHLD before booting LKL so that all kernel threads created + * by lkl_start_kernel inherit the blocked mask. + */ + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + pthread_sigmask(SIG_BLOCK, &mask, NULL); if (!cmdline || !*cmdline) { effective = "console=null"; diff --git a/src/seccomp-supervisor.c b/src/seccomp-supervisor.c index 08ba24c..5678648 100644 --- a/src/seccomp-supervisor.c +++ b/src/seccomp-supervisor.c @@ -492,16 +492,12 @@ int kbox_run_supervisor(const struct kbox_sysnrs *sysnrs, if (socketpair_create(sp) < 0) return -1; - /* Block SIGCHLD before fork so the parent cannot lose the signal - * in the window between fork and signalfd creation. Save the - * caller's mask so both parent and child can restore it later. + /* Save the caller's mask so both parent and child can + * restore it later. */ { - sigset_t chld_mask; - sigemptyset(&chld_mask); - sigaddset(&chld_mask, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &chld_mask, &old_mask) < 0) { - fprintf(stderr, "sigprocmask(SIG_BLOCK): %s\n", strerror(errno)); + if (sigprocmask(SIG_SETMASK, NULL, &old_mask) < 0) { + fprintf(stderr, "sigprocmask(SIG_SETMASK): %s\n", strerror(errno)); close(sp[0]); close(sp[1]); return -1;