From ce84bc02aa1f32dba14f0ec8c6dbb4d24bd966b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Fri, 31 Jul 2026 12:50:40 +0200 Subject: [PATCH] Reset the child signal mask before exec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When spawning a process via Runtime.exec() or ProcessBuilder, the executed process inherits the signal mask of the JVM thread that spawned it. The JVM's signal mask is an implementation detail of the runtime, and not part of the execution environment a child program expects. The mask must therefore be cleared when spawning child processes: otherwise, they may exhibit unexpected behaviour depending on which signals are blocked (e.g. cannot be interrupted with SIGINT, will not receive SIGPIPE when writing to a closed pipe, etc.). Fix by installing an empty signal mask in the child immediately before executing the target program. Fixes #49 (BZ#126539) Signed-off-by: Guillermo Rodríguez --- native/jni/native-lib/cpproc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/native/jni/native-lib/cpproc.c b/native/jni/native-lib/cpproc.c index 1f8733b26..6384aa674 100644 --- a/native/jni/native-lib/cpproc.c +++ b/native/jni/native-lib/cpproc.c @@ -466,6 +466,7 @@ static void child_process(char * const *commandLine, const char *path, char **sh_argv, const char *wd, int maxfd) { + sigset_t sigmask; int errnum; close(fail_fds[0]); @@ -485,8 +486,16 @@ static void child_process(char * const *commandLine, if (mark_nonstd_fds_cloexec(maxfd) < 0) goto child_error; - if (wd == NULL || chdir(wd) == 0) - cp_execvpe(commandLine[0], commandLine, newEnviron, path, sh_argv); + if (wd != NULL && chdir(wd) != 0) + goto child_error; + + /* Reset the signal mask so that the executed program starts with all + signals unblocked. */ + sigemptyset(&sigmask); + if (sigprocmask(SIG_SETMASK, &sigmask, NULL) < 0) + goto child_error; + + cp_execvpe(commandLine[0], commandLine, newEnviron, path, sh_argv); child_error: /* Child setup or exec itself failed; send our errno to the parent */