diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/namespace-util.c | 2 | ||||
-rw-r--r-- | src/basic/process-util.c | 26 | ||||
-rw-r--r-- | src/basic/process-util.h | 31 | ||||
-rw-r--r-- | src/basic/terminal-util.c | 4 | ||||
-rw-r--r-- | src/basic/time-util.c | 2 |
5 files changed, 37 insertions, 28 deletions
diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c index 0a0de85aad..2101f617ad 100644 --- a/src/basic/namespace-util.c +++ b/src/basic/namespace-util.c @@ -219,7 +219,7 @@ int userns_acquire(const char *uid_map, const char *gid_map) { * and then kills the process again. This way we have a userns fd that is not bound to any * process. We can use that for file system mounts and similar. */ - r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NEW_USERNS, &pid); + r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid); if (r < 0) return r; if (r == 0) diff --git a/src/basic/process-util.c b/src/basic/process-util.c index c5883b05d1..201c5596ae 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1380,6 +1380,12 @@ pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) { return pid; } +static int fork_flags_to_signal(ForkFlags flags) { + return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM : + (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : + SIGKILL; +} + int safe_fork_full( const char *name, const int stdio_fds[3], @@ -1409,9 +1415,10 @@ int safe_fork_full( fflush(stderr); /* This one shouldn't be necessary, stderr should be unbuffered anyway, but let's better be safe than sorry */ } - if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG)) { - /* We temporarily block all signals, so that the new child has them blocked initially. This way, we can - * be sure that SIGTERMs are not lost we might send to the child. */ + if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) { + /* We temporarily block all signals, so that the new child has them blocked initially. This + * way, we can be sure that SIGTERMs are not lost we might send to the child. (Note that for + * FORK_DEATHSIG_SIGKILL we don't bother, since it cannot be blocked anyway.) */ assert_se(sigfillset(&ss) >= 0); block_signals = block_all = true; @@ -1512,8 +1519,8 @@ int safe_fork_full( r, "Failed to rename process, ignoring: %m"); } - if (flags & (FORK_DEATHSIG|FORK_DEATHSIG_SIGINT)) - if (prctl(PR_SET_PDEATHSIG, (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : SIGTERM) < 0) { + if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) + if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) { log_full_errno(prio, errno, "Failed to set death signal: %m"); _exit(EXIT_FAILURE); } @@ -1538,7 +1545,7 @@ int safe_fork_full( } } - if (flags & FORK_DEATHSIG) { + if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGINT)) { pid_t ppid; /* Let's see if the parent PID is still the one we started from? If not, then the parent * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */ @@ -1547,8 +1554,9 @@ int safe_fork_full( if (ppid == 0) /* Parent is in a different PID namespace. */; else if (ppid != original_pid) { - log_debug("Parent died early, raising SIGTERM."); - (void) raise(SIGTERM); + int sig = fork_flags_to_signal(flags); + log_debug("Parent died early, raising %s.", signal_to_string(sig)); + (void) raise(sig); _exit(EXIT_FAILURE); } } @@ -1664,7 +1672,7 @@ int namespace_fork( r = safe_fork_full(outer_name, NULL, except_fds, n_except_fds, - (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid); + (flags|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid); if (r < 0) return r; if (r == 0) { diff --git a/src/basic/process-util.h b/src/basic/process-util.h index a18a730936..af6cba13eb 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -160,22 +160,23 @@ pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata); typedef enum ForkFlags { FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */ FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */ - FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */ + FORK_DEATHSIG_SIGTERM = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */ FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */ - FORK_REARRANGE_STDIO = 1 << 4, /* Connect 0,1,2 to specified fds or /dev/null */ - FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */ - FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */ - FORK_WAIT = 1 << 7, /* Wait until child exited */ - FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ - FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */ - FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */ - FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ - FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */ - FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */ - FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ - FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */ - FORK_KEEP_NOTIFY_SOCKET = 1 << 16, /* Unless this specified, $NOTIFY_SOCKET will be unset. */ - FORK_DETACH = 1 << 17, /* Double fork if needed to ensure PID1/subreaper is parent */ + FORK_DEATHSIG_SIGKILL = 1 << 4, /* Set PR_DEATHSIG in the child to SIGKILL */ + FORK_REARRANGE_STDIO = 1 << 5, /* Connect 0,1,2 to specified fds or /dev/null */ + FORK_REOPEN_LOG = 1 << 6, /* Reopen log connection */ + FORK_LOG = 1 << 7, /* Log above LOG_DEBUG log level about failures */ + FORK_WAIT = 1 << 8, /* Wait until child exited */ + FORK_NEW_MOUNTNS = 1 << 9, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_MOUNTNS_SLAVE = 1 << 10, /* Make child's mount namespace MS_SLAVE */ + FORK_PRIVATE_TMP = 1 << 11, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */ + FORK_RLIMIT_NOFILE_SAFE = 1 << 12, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ + FORK_STDOUT_TO_STDERR = 1 << 13, /* Make stdout a copy of stderr */ + FORK_FLUSH_STDIO = 1 << 14, /* fflush() stdout (and stderr) before forking */ + FORK_NEW_USERNS = 1 << 15, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_CLOEXEC_OFF = 1 << 16, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */ + FORK_KEEP_NOTIFY_SOCKET = 1 << 17, /* Unless this specified, $NOTIFY_SOCKET will be unset. */ + FORK_DETACH = 1 << 18, /* Double fork if needed to ensure PID1/subreaper is parent */ } ForkFlags; int safe_fork_full( diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 6cc6ff424a..b505a3ad0e 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -1204,7 +1204,7 @@ int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - r = namespace_fork("(sd-openptns)", "(sd-openpt)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG, + r = namespace_fork("(sd-openptns)", "(sd-openpt)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child); if (r < 0) return r; @@ -1255,7 +1255,7 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - r = namespace_fork("(sd-terminalns)", "(sd-terminal)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG, + r = namespace_fork("(sd-terminalns)", "(sd-terminal)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child); if (r < 0) return r; diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 19d8602faf..695b998b57 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -1044,7 +1044,7 @@ int parse_timestamp(const char *t, usec_t *ret) { if (shared == MAP_FAILED) return negative_errno(); - r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL); + r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL); if (r < 0) { (void) munmap(shared, sizeof *shared); return r; |