From 0c2aedb451c9da0d997e46c84d399c80d7fcb61d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 7 Feb 2023 18:55:39 +0900 Subject: [PATCH] tree-wide: use FORK_REARRANGE_STDIO and FORK_CLOSE_ALL_FDS --- src/home/homed-home.c | 13 +++--------- src/import/import-common.c | 26 ++++++++---------------- src/import/importd.c | 16 ++++----------- src/import/pull-common.c | 14 +++++-------- src/journal-remote/journal-remote-main.c | 13 ++++-------- src/libsystemd/sd-bus/bus-socket.c | 11 +++------- src/nspawn/nspawn-setuid.c | 18 ++++++---------- src/resolve/test-resolved-stream.c | 12 ++++------- src/sysupdate/sysupdate-resource.c | 14 +++++-------- src/test/test-execute.c | 10 ++++----- src/udev/udev-event.c | 12 +++++------ 11 files changed, 51 insertions(+), 108 deletions(-) diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 8b4a81d7e89..413fcf17730 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -1180,9 +1180,9 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord return -errno; r = safe_fork_full("(sd-homework)", - NULL, - (int[]) { stdin_fd, stdout_fd }, 2, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &pid); + (int[]) { stdin_fd, stdout_fd, STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, &pid); if (r < 0) return r; if (r == 0) { @@ -1227,13 +1227,6 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord if (r < 0) log_warning_errno(r, "Failed to update $SYSTEMD_EXEC_PID, ignoring: %m"); - r = rearrange_stdio(TAKE_FD(stdin_fd), TAKE_FD(stdout_fd), STDERR_FILENO); /* fds are invalidated by rearrange_stdio() even on failure */ - if (r < 0) { - log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m"); - _exit(EXIT_FAILURE); - } - - /* Allow overriding the homework path via an environment variable, to make debugging * easier. */ homework = getenv("SYSTEMD_HOMEWORK_PATH") ?: SYSTEMD_HOMEWORK_PATH; diff --git a/src/import/import-common.c b/src/import/import-common.c index 874d27d2920..7227f885a8c 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -36,7 +36,10 @@ int import_fork_tar_x(const char *path, pid_t *ret) { use_selinux = mac_selinux_use(); - r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + r = safe_fork_full("(tar)", + (int[]) { pipefd[0], -EBADF, STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid); if (r < 0) return r; if (r == 0) { @@ -63,14 +66,6 @@ int import_fork_tar_x(const char *path, pid_t *ret) { /* Child */ - pipefd[1] = safe_close(pipefd[1]); - - r = rearrange_stdio(TAKE_FD(pipefd[0]), -EBADF, STDERR_FILENO); - if (r < 0) { - log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); - _exit(EXIT_FAILURE); - } - if (unshare(CLONE_NEWNET) < 0) log_warning_errno(errno, "Failed to lock tar into network namespace, ignoring: %m"); @@ -110,7 +105,10 @@ int import_fork_tar_c(const char *path, pid_t *ret) { use_selinux = mac_selinux_use(); - r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + r = safe_fork_full("(tar)", + (int[]) { -EBADF, pipefd[1], STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid); if (r < 0) return r; if (r == 0) { @@ -129,14 +127,6 @@ int import_fork_tar_c(const char *path, pid_t *ret) { /* Child */ - pipefd[0] = safe_close(pipefd[0]); - - r = rearrange_stdio(-EBADF, TAKE_FD(pipefd[1]), STDERR_FILENO); - if (r < 0) { - log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); - _exit(EXIT_FAILURE); - } - if (unshare(CLONE_NEWNET) < 0) log_error_errno(errno, "Failed to lock tar into network namespace, ignoring: %m"); diff --git a/src/import/importd.c b/src/import/importd.c index 65647a66a63..5f7b9c3163d 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -365,7 +365,10 @@ static int transfer_start(Transfer *t) { if (pipe2(pipefd, O_CLOEXEC) < 0) return -errno; - r = safe_fork("(sd-transfer)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &t->pid); + r = safe_fork_full("(sd-transfer)", + (int[]) { t->stdin_fd, t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd, pipefd[1] }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO, &t->pid); if (r < 0) return r; if (r == 0) { @@ -387,17 +390,6 @@ static int transfer_start(Transfer *t) { /* Child */ - pipefd[0] = safe_close(pipefd[0]); - - r = rearrange_stdio(TAKE_FD(t->stdin_fd), - t->stdout_fd < 0 ? pipefd[1] : TAKE_FD(t->stdout_fd), - pipefd[1]); - TAKE_FD(pipefd[1]); - if (r < 0) { - log_error_errno(r, "Failed to set stdin/stdout/stderr: %m"); - _exit(EXIT_FAILURE); - } - if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 || setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) { log_error_errno(errno, "setenv() failed: %m"); diff --git a/src/import/pull-common.c b/src/import/pull-common.c index c8a3bf370e1..3b80e64b328 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -414,7 +414,11 @@ static int verify_gpg( gpg_home_created = true; - r = safe_fork("(gpg)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid); + r = safe_fork_full("(gpg)", + (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, + &pid); if (r < 0) return r; if (r == 0) { @@ -437,14 +441,6 @@ static int verify_gpg( /* Child */ - gpg_pipe[1] = safe_close(gpg_pipe[1]); - - r = rearrange_stdio(TAKE_FD(gpg_pipe[0]), -EBADF, STDERR_FILENO); - if (r < 0) { - log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); - _exit(EXIT_FAILURE); - } - cmd[k++] = strjoina("--homedir=", gpg_home); /* We add the user keyring only to the command line arguments, if it's around since gpg fails diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index 7df264fb531..e620b60a31a 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -85,7 +85,10 @@ static int spawn_child(const char* child, char** argv) { if (pipe(fd) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - r = safe_fork("(remote)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid); + r = safe_fork_full("(remote)", + (int[]) {STDIN_FILENO, fd[1], STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid); if (r < 0) { safe_close_pair(fd); return r; @@ -93,14 +96,6 @@ static int spawn_child(const char* child, char** argv) { /* In the child */ if (r == 0) { - fd[0] = safe_close(fd[0]); - - r = rearrange_stdio(STDIN_FILENO, TAKE_FD(fd[1]), STDERR_FILENO); - if (r < 0) { - log_error_errno(r, "Failed to dup pipe to stdout: %m"); - _exit(EXIT_FAILURE); - } - execvp(child, argv); log_error_errno(errno, "Failed to exec child %s: %m", child); _exit(EXIT_FAILURE); diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index aca049b052e..33cfeebda7b 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -995,9 +995,9 @@ int bus_socket_exec(sd_bus *b) { return -errno; r = safe_fork_full("(sd-busexec)", - NULL, - s+1, 1, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid); + (int[]) { s[1], s[1], STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid); if (r < 0) { safe_close_pair(s); return r; @@ -1005,11 +1005,6 @@ int bus_socket_exec(sd_bus *b) { if (r == 0) { /* Child */ - r = rearrange_stdio(s[1], s[1], STDERR_FILENO); - TAKE_FD(s[1]); - if (r < 0) - _exit(EXIT_FAILURE); - if (b->exec_argv) execvp(b->exec_path, b->exec_argv); else diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 5772d96b2fa..3c12648b9d7 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -28,23 +28,17 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { if (pipe2(pipe_fds, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to allocate pipe: %m"); - r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid); + r = safe_fork_full("(getent)", + (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, + &pid); if (r < 0) { safe_close_pair(pipe_fds); return r; } if (r == 0) { - char *empty_env = NULL; - - pipe_fds[0] = safe_close(pipe_fds[0]); - - if (rearrange_stdio(-EBADF, TAKE_FD(pipe_fds[1]), -EBADF) < 0) - _exit(EXIT_FAILURE); - - (void) close_all_fds(NULL, 0); - - execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); - execle("/bin/getent", "getent", database, key, NULL, &empty_env); + execle("/usr/bin/getent", "getent", database, key, NULL, &(char*[1]){}); + execle("/bin/getent", "getent", database, key, NULL, &(char*[1]){}); _exit(EXIT_FAILURE); } diff --git a/src/resolve/test-resolved-stream.c b/src/resolve/test-resolved-stream.c index d7fe3c42f53..ae851f67f0c 100644 --- a/src/resolve/test-resolved-stream.c +++ b/src/resolve/test-resolved-stream.c @@ -148,17 +148,13 @@ static void *tls_dns_server(void *p) { } r = safe_fork_full("(test-resolved-stream-tls-openssl)", - NULL, - (int[]) { fd_server, fd_tls }, 2, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &openssl_pid); + (int[]) { fd_tls, fd_tls, STDOUT_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, + &openssl_pid); assert_se(r >= 0); if (r == 0) { /* Child */ - assert_se(dup2(fd_tls, STDIN_FILENO) >= 0); - assert_se(dup2(fd_tls, STDOUT_FILENO) >= 0); - close(TAKE_FD(fd_server)); - close(TAKE_FD(fd_tls)); - execlp("openssl", "openssl", "s_server", "-accept", bind_str, "-key", key_path, "-cert", cert_path, "-quiet", "-naccept", "1", NULL); diff --git a/src/sysupdate/sysupdate-resource.c b/src/sysupdate/sysupdate-resource.c index e1e260addcc..6c05d245f8c 100644 --- a/src/sysupdate/sysupdate-resource.c +++ b/src/sysupdate/sysupdate-resource.c @@ -264,7 +264,11 @@ static int download_manifest( log_info("%s Acquiring manifest file %s%s", special_glyph(SPECIAL_GLYPH_DOWNLOAD), suffixed_url, special_glyph(SPECIAL_GLYPH_ELLIPSIS)); - r = safe_fork("(sd-pull)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + r = safe_fork_full("(sd-pull)", + (int[]) { -EBADF, pfd[1], STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, + &pid); if (r < 0) return r; if (r == 0) { @@ -280,14 +284,6 @@ static int download_manifest( NULL }; - pfd[0] = safe_close(pfd[0]); - - r = rearrange_stdio(-EBADF, pfd[1], STDERR_FILENO); - if (r < 0) { - log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); - _exit(EXIT_FAILURE); - } - (void) unsetenv("NOTIFY_SOCKET"); execv(pull_binary_path(), (char *const*) cmdline); log_error_errno(errno, "Failed to execute %s tool: %m", pull_binary_path()); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index f6d05afc1bd..7363ea95db1 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -583,14 +583,12 @@ static int find_libraries(const char *exec, char ***ret) { assert_se(pipe2(outpipe, O_NONBLOCK|O_CLOEXEC) == 0); assert_se(pipe2(errpipe, O_NONBLOCK|O_CLOEXEC) == 0); - r = safe_fork("(spawn-ldd)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + r = safe_fork_full("(spawn-ldd)", + (int[]) { -EBADF, outpipe[1], errpipe[1] }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid); assert_se(r >= 0); if (r == 0) { - if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[1]), TAKE_FD(errpipe[1])) < 0) - _exit(EXIT_FAILURE); - - (void) close_all_fds(NULL, 0); - execlp("ldd", "ldd", exec, NULL); _exit(EXIT_FAILURE); } diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index ec4ad30824d..a8d7db40b45 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -810,18 +810,16 @@ int udev_event_spawn( log_device_debug(event->dev, "Starting '%s'", cmd); - r = safe_fork("(spawn)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid); + r = safe_fork_full("(spawn)", + (int[]) { -EBADF, outpipe[WRITE_END], errpipe[WRITE_END] }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, + &pid); if (r < 0) return log_device_error_errno(event->dev, r, "Failed to fork() to execute command '%s': %m", cmd); if (r == 0) { - if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[WRITE_END]), TAKE_FD(errpipe[WRITE_END])) < 0) - _exit(EXIT_FAILURE); - - (void) close_all_fds(NULL, 0); - DEVICE_TRACE_POINT(spawn_exec, event->dev, cmd); - execve(argv[0], argv, envp); _exit(EXIT_FAILURE); } -- 2.47.3