Configure PR_SET_PDEATHSIG on Linux and Job Objects on Windows to prevent orphaned subprocesses on program crash

This commit is contained in:
Andrea Mazzoleni 2026-08-01 18:26:01 +02:00
parent 8c128c1bc3
commit 58d75feea4
4 changed files with 76 additions and 7 deletions

View file

@ -765,6 +765,10 @@ int os_script(char** argv, char** envp, const char* run_as_user)
start = os_tick_sec();
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
pid_t ppid = getpid();
#endif
pid = fork();
if (pid < 0) {
os_syslog(OS_LVL_INFO, "failed to fork script=%s, errno=%s(%d)", resolved_path, strerror(errno), errno);
@ -802,6 +806,15 @@ int os_script(char** argv, char** envp, const char* run_as_user)
_exit(126);
}
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
/* Send SIGKILL to child if parent daemon dies unexpectedly */
prctl(PR_SET_PDEATHSIG, SIGKILL);
/* exit if parent died before prctl to avoid becoming orphaned */
if (getppid() != ppid) {
_exit(127);
}
#endif
/* io sandboxing */
int null_fd = open("/dev/null", O_RDWR);
if (null_fd == -1)
@ -933,6 +946,10 @@ int os_command(const char* command, const char* run_as_user, const char* stdin_t
start = os_tick_sec();
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
pid_t ppid = getpid();
#endif
pid = fork();
if (pid < 0) {
os_syslog(OS_LVL_INFO, "failed to fork command=%s, errno=%s(%d)", command, strerror(errno), errno);
@ -976,6 +993,15 @@ int os_command(const char* command, const char* run_as_user, const char* stdin_t
_exit(126);
}
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
/* Send SIGKILL to child if parent daemon dies unexpectedly */
prctl(PR_SET_PDEATHSIG, SIGKILL);
/* exit if parent died before prctl to avoid becoming orphaned */
if (getppid() != ppid) {
_exit(127);
}
#endif
/* io sandboxing */
int null_fd = open("/dev/null", O_RDWR);
if (null_fd == -1)
@ -1157,6 +1183,10 @@ pid_t os_spawn(char** argv, int* stdout_read_fd, int* stderr_read_fd, const char
}
}
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
pid_t ppid = getpid();
#endif
pid = fork();
if (pid < 0) {
os_syslog(OS_LVL_INFO, "failed to fork path=%s, errno=%s(%d)", resolved_path, strerror(errno), errno);
@ -1195,6 +1225,15 @@ pid_t os_spawn(char** argv, int* stdout_read_fd, int* stderr_read_fd, const char
_exit(126);
}
#if defined(__linux__) && defined(PR_SET_PDEATHSIG)
/* Send SIGKILL to child if parent daemon dies unexpectedly */
prctl(PR_SET_PDEATHSIG, SIGKILL);
/* exit if parent died before prctl to avoid becoming orphaned */
if (getppid() != ppid) {
_exit(127);
}
#endif
/* io sandboxing */
int null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (null_fd < 0)