From ce30c8dcb41dfe9264f79f30c7f51c0e74576638 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 31 May 2015 23:55:55 +0200 Subject: tree-wide: whenever we fork off a foreign child process reset signal mask/handlers Also, when the child is potentially long-running make sure to set a death signal. Also, ignore the result of the reset operations explicitly by casting them to (void). --- src/activate/activate.c | 5 +++++ src/core/busname.c | 4 ++-- src/core/execute.c | 9 ++++++--- src/core/main.c | 9 ++++----- src/core/socket.c | 4 ++-- src/delta/delta.c | 9 ++++++++- src/fsck/fsck.c | 4 ++-- src/import/export.c | 2 +- src/import/import-common.c | 8 ++++---- src/import/import.c | 2 +- src/import/importd.c | 4 ++-- src/import/pull-common.c | 4 ++-- src/import/pull.c | 2 +- src/journal-remote/journal-remote.c | 4 ++++ src/journal/coredumpctl.c | 3 +++ src/libsystemd/sd-bus/bus-socket.c | 3 ++- src/login/inhibit.c | 4 ++++ src/nspawn/nspawn.c | 7 ++++--- src/quotacheck/quotacheck.c | 8 ++++++++ src/remount-fs/remount-fs.c | 3 +++ src/shared/machine-pool.c | 4 ++-- src/shared/pager.c | 8 ++++++++ src/shared/pty.c | 2 +- src/shared/util.c | 8 ++++---- src/systemctl/systemctl.c | 6 ++++++ src/vconsole/vconsole-setup.c | 9 +++++++++ 26 files changed, 98 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/activate/activate.c b/src/activate/activate.c index d345e28567..5318829442 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -33,6 +33,7 @@ #include "log.h" #include "strv.h" #include "macro.h" +#include "signal-util.h" static char** arg_listen = NULL; static bool arg_accept = false; @@ -192,6 +193,10 @@ static int launch1(const char* child, char** argv, char **env, int fd) { /* In the child */ if (child_pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + r = dup2(fd, STDIN_FILENO); if (r < 0) { log_error_errno(errno, "Failed to dup connection to stdin: %m"); diff --git a/src/core/busname.c b/src/core/busname.c index 3f5abbcb24..2085721546 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -408,8 +408,8 @@ static int busname_make_starter(BusName *n, pid_t *_pid) { if (pid == 0) { int ret; - default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); log_forget_fds(); r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world); diff --git a/src/core/execute.c b/src/core/execute.c index 4120493bda..f13c6936e0 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -823,6 +823,7 @@ static int setup_pam( /* Block SIGTERM, so that we know that it won't get lost in * the child */ + if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 || sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0) @@ -857,6 +858,8 @@ static int setup_pam( if (setresuid(uid, uid, uid) < 0) log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m"); + (void) ignore_signals(SIGPIPE, -1); + /* Wait until our parent died. This will only work if * the above setresuid() succeeds, otherwise the kernel * will not allow unprivileged parents kill their privileged @@ -1324,11 +1327,11 @@ static int exec_child( * others we leave untouched because we set them to * SIG_DFL or a valid handler initially, both of which * will be demoted to SIG_DFL. */ - default_signals(SIGNALS_CRASH_HANDLER, - SIGNALS_IGNORE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, + SIGNALS_IGNORE, -1); if (context->ignore_sigpipe) - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = reset_signal_mask(); if (r < 0) { diff --git a/src/core/main.c b/src/core/main.c index 29ccff7b63..332453a0ea 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1405,9 +1405,8 @@ int main(int argc, char *argv[]) { } /* Reset all signal handlers. */ - assert_se(reset_all_signal_handlers() == 0); - - ignore_signals(SIGNALS_IGNORE, -1); + (void) reset_all_signal_handlers(); + (void) ignore_signals(SIGNALS_IGNORE, -1); if (parse_config_file() < 0) { error_message = "Failed to parse config file"; @@ -1931,8 +1930,8 @@ finish: /* Reenable any blocked signals, especially important * if we switch from initial ramdisk to init=... */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); if (switch_root_init) { args[0] = switch_root_init; diff --git a/src/core/socket.c b/src/core/socket.c index 0239962055..d3178e642b 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1473,8 +1473,8 @@ static int socket_chown(Socket *s, pid_t *_pid) { gid_t gid = GID_INVALID; int ret; - default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); log_forget_fds(); if (!isempty(s->user)) { diff --git a/src/delta/delta.c b/src/delta/delta.c index c764bb4b46..b60aaef734 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "hashmap.h" #include "util.h" @@ -34,6 +35,7 @@ #include "strv.h" #include "process-util.h" #include "terminal-util.h" +#include "signal-util.h" static const char prefixes[] = "/etc\0" @@ -189,9 +191,14 @@ static int found_override(const char *top, const char *bottom) { if (pid < 0) return log_error_errno(errno, "Failed to fork off diff: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + execlp("diff", "diff", "-us", "--", bottom, top, NULL); log_error_errno(errno, "Failed to execute diff: %m"); - _exit(1); + _exit(EXIT_FAILURE); } wait_for_terminate_and_warn("diff", pid, false); diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index f0e5c5f239..30254b6680 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -394,8 +394,8 @@ int main(int argc, char *argv[]) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); /* Close the reading side of the progress pipe */ diff --git a/src/import/export.c b/src/import/export.c index d4bc88e010..e563bee96e 100644 --- a/src/import/export.c +++ b/src/import/export.c @@ -311,7 +311,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = export_main(argc, argv); diff --git a/src/import/import-common.c b/src/import/import-common.c index 9711614000..950c7b4acd 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -97,8 +97,8 @@ int import_fork_tar_x(const char *path, pid_t *ret) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[1] = safe_close(pipefd[1]); @@ -171,8 +171,8 @@ int import_fork_tar_c(const char *path, pid_t *ret) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[0] = safe_close(pipefd[0]); diff --git a/src/import/import.c b/src/import/import.c index fff5a104b1..3091ed1c45 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -328,7 +328,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = import_main(argc, argv); diff --git a/src/import/importd.c b/src/import/importd.c index 50566a6e5c..e2df44ad26 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -390,8 +390,8 @@ static int transfer_start(Transfer *t) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[0] = safe_close(pipefd[0]); diff --git a/src/import/pull-common.c b/src/import/pull-common.c index d2588d4fa0..652277e4be 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -339,8 +339,8 @@ int pull_verify( /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); gpg_pipe[1] = safe_close(gpg_pipe[1]); diff --git a/src/import/pull.c b/src/import/pull.c index eec4583868..03fe3dcaf4 100644 --- a/src/import/pull.c +++ b/src/import/pull.c @@ -440,7 +440,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = pull_main(argc, argv); diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 911e2a178b..ae332d826f 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -96,6 +96,10 @@ static int spawn_child(const char* child, char** argv) { /* In the child */ if (child_pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + r = dup2(fd[1], STDOUT_FILENO); if (r < 0) { log_error_errno(errno, "Failed to dup pipe to stdout: %m"); diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index 381bf72776..fc49b2e174 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -757,6 +757,9 @@ static int run_gdb(sd_journal *j) { goto finish; } if (pid == 0) { + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execlp("gdb", "gdb", exe, path, NULL); log_error_errno(errno, "Failed to invoke gdb: %m"); diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 4fffc6581d..93ebe80b07 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -738,7 +738,8 @@ int bus_socket_exec(sd_bus *b) { if (pid == 0) { /* Child */ - reset_all_signal_handlers(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); close_all_fds(s+1, 1); diff --git a/src/login/inhibit.c b/src/login/inhibit.c index 57cfb5d0b5..0e5dce5925 100644 --- a/src/login/inhibit.c +++ b/src/login/inhibit.c @@ -33,6 +33,7 @@ #include "strv.h" #include "formats-util.h" #include "process-util.h" +#include "signal-util.h" static const char* arg_what = "idle:sleep:shutdown"; static const char* arg_who = NULL; @@ -274,6 +275,9 @@ int main(int argc, char *argv[]) { if (pid == 0) { /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + close_all_fds(NULL, 0); execvp(argv[optind], argv + optind); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4211a3d779..251af4a67c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3656,7 +3656,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { if (nullfd > 2) safe_close(nullfd); - reset_all_signal_handlers(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); close_all_fds(NULL, 0); execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); @@ -4739,8 +4740,8 @@ int main(int argc, char *argv[]) { rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]); pid_socket_pair[0] = safe_close(pid_socket_pair[0]); - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); r = outer_child(&barrier, arg_directory, diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index a729f592cf..cf6a239402 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -23,9 +23,11 @@ #include #include #include +#include #include "util.h" #include "process-util.h" +#include "signal-util.h" static bool arg_skip = false; static bool arg_force = false; @@ -105,7 +107,13 @@ int main(int argc, char *argv[]) { log_error_errno(errno, "fork(): %m"); return EXIT_FAILURE; } else if (pid == 0) { + /* Child */ + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + execv(cmdline[0], (char**) cmdline); _exit(1); /* Operational error */ } diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c index e701fc9fae..f904e48e75 100644 --- a/src/remount-fs/remount-fs.c +++ b/src/remount-fs/remount-fs.c @@ -95,6 +95,9 @@ int main(int argc, char *argv[]) { const char *arguments[5]; /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + arguments[0] = MOUNT_PATH; arguments[1] = me->mnt_dir; arguments[2] = "-o"; diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c index d27931cb4a..8c64908b1a 100644 --- a/src/shared/machine-pool.c +++ b/src/shared/machine-pool.c @@ -109,8 +109,8 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); fd = safe_close(fd); diff --git a/src/shared/pager.c b/src/shared/pager.c index 58b62fdccf..13f03e798b 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -30,6 +30,7 @@ #include "process-util.h" #include "macro.h" #include "terminal-util.h" +#include "signal-util.h" static pid_t pager_pid = 0; @@ -85,6 +86,9 @@ int pager_open(bool jump_to_end) { if (pager_pid == 0) { const char* less_opts; + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + dup2(fd[0], STDIN_FILENO); safe_close_pair(fd); @@ -178,6 +182,10 @@ int show_man_page(const char *desc, bool null_stdio) { if (pid == 0) { /* Child */ + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + if (null_stdio) { r = make_null_stdio(); if (r < 0) { diff --git a/src/shared/pty.c b/src/shared/pty.c index 119d66e9a2..a87b3ce6f0 100644 --- a/src/shared/pty.c +++ b/src/shared/pty.c @@ -239,7 +239,7 @@ int pty_setup_child(Pty *pty) { assert_return(pty_is_child(pty), -EINVAL); assert_return(pty_is_open(pty), -EALREADY); - r = sigprocmask_many(SIG_SETMASK, -1); + r = reset_signal_mask(); if (r < 0) return r; diff --git a/src/shared/util.c b/src/shared/util.c index dc5e938796..a20e7bb2ef 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2301,8 +2301,8 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) { /* We fork this all off from a child process so that we can * somewhat cleanly make use of SIGALRM to set a time limit */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); @@ -3344,8 +3344,8 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa /* Make sure we actually can kill the agent, if we need to, in * case somebody invoked us from a shell script that trapped * SIGTERM or so... */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); /* Check whether our parent died before we were able * to set the death signal and unblock the signals */ diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b3d90d2c33..5075e4e176 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5189,6 +5189,9 @@ static int enable_sysv_units(const char *verb, char **args) { else if (pid == 0) { /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(argv[0], (char**) argv); log_error("Failed to execute %s: %m", argv[0]); _exit(EXIT_FAILURE); @@ -5854,6 +5857,9 @@ static int run_editor(char **paths) { unsigned i = 1; size_t argc; + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + argc = strv_length(paths)/2 + 1; args = newa(const char*, argc + 1); diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 6c782b3130..f7728dcfff 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -37,6 +37,7 @@ #include "fileio.h" #include "process-util.h" #include "terminal-util.h" +#include "signal-util.h" static bool is_vconsole(int fd) { unsigned char data[1]; @@ -122,6 +123,10 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m if (pid < 0) return log_error_errno(errno, "Failed to fork: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(args[0], (char **) args); _exit(EXIT_FAILURE); } @@ -160,6 +165,10 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, if (pid < 0) return log_error_errno(errno, "Failed to fork: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(args[0], (char **) args); _exit(EXIT_FAILURE); } -- cgit v1.2.3-54-g00ecf