From e3b5a1c59e9271a8464737586503e57ff918cf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 3 Aug 2026 11:31:45 +0200 Subject: [PATCH] Block all signals in the parent before fork Block all signals on the spawning thread before fork, so that the child process setup (descriptor wiring, close-on-exec sweep, chdir) cannot be interrupted by signals (so no call can fail with EINTR). This is hardening: previously, the child's setup was safe only as long as neither the VM nor native code loaded into the process installed disruptive signal handlers. Blocking makes the setup safe by construction. --- native/jni/native-lib/cpproc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/native/jni/native-lib/cpproc.c b/native/jni/native-lib/cpproc.c index 6384aa674..dbce9efa7 100644 --- a/native/jni/native-lib/cpproc.c +++ b/native/jni/native-lib/cpproc.c @@ -88,6 +88,8 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, int fail_fds[2]; const char *path; char **sh_argv; + sigset_t allsigs; + sigset_t savedmask; int errnum; ssize_t n; int argc; @@ -141,6 +143,11 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, return err; } + /* Block all signals before we fork() to ensure that the child's + setup is not interrupted, so no call can fail with EINTR. */ + sigfillset(&allsigs); + pthread_sigmask(SIG_SETMASK, &allsigs, &savedmask); + pid = fork(); switch (pid) @@ -155,6 +162,7 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, { int err = errno; + pthread_sigmask(SIG_SETMASK, &savedmask, NULL); close_fds(local_fds, pipe_count * 2); close(fail_fds[0]); close(fail_fds[1]); @@ -162,6 +170,7 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, return err; } default: + pthread_sigmask(SIG_SETMASK, &savedmask, NULL); free(sh_argv); close(fail_fds[1]);