diff --git a/src/activate/activate.c b/src/activate/activate.c index c07dcb8626..c856c8c100 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -199,15 +199,10 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, if (arg_inetd) { assert(n_fds == 1); - r = dup2(start_fd, STDIN_FILENO); + r = rearrange_stdio(start_fd, start_fd, STDERR_FILENO); /* invalidates start_fd on success + error */ if (r < 0) - return log_error_errno(errno, "Failed to dup connection to stdin: %m"); + return log_error_errno(errno, "Failed to move fd to stdin+stdout: %m"); - r = dup2(start_fd, STDOUT_FILENO); - if (r < 0) - return log_error_errno(errno, "Failed to dup connection to stdout: %m"); - - start_fd = safe_close(start_fd); } else { if (start_fd != SD_LISTEN_FDS_START) { assert(n_fds == 1); diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c index d20e09dc54..e0057a7572 100644 --- a/src/basic/exec-util.c +++ b/src/basic/exec-util.c @@ -62,12 +62,9 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) { char *_argv[2]; if (stdout_fd >= 0) { - /* If the fd happens to be in the right place, go along with that */ - if (stdout_fd != STDOUT_FILENO && - dup2(stdout_fd, STDOUT_FILENO) < 0) + r = rearrange_stdio(STDIN_FILENO, stdout_fd, STDERR_FILENO); + if (r < 0) _exit(EXIT_FAILURE); - - (void) fd_cloexec(STDOUT_FILENO, false); } if (!argv) { diff --git a/src/core/execute.c b/src/core/execute.c index 3c8d47948f..7292b815db 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -765,15 +765,10 @@ static int setup_confirm_stdio(const char *vc, int *_saved_stdin, int *_saved_st if (r < 0) return r; - if (dup2(fd, STDIN_FILENO) < 0) - return -errno; - - if (dup2(fd, STDOUT_FILENO) < 0) - return -errno; - - if (fd >= 2) - safe_close(fd); + r = rearrange_stdio(fd, fd, STDERR_FILENO); fd = -1; + if (r < 0) + return r; *_saved_stdin = saved_stdin; *_saved_stdout = saved_stdout; diff --git a/src/import/import-common.c b/src/import/import-common.c index c24a0b0c86..a3dc1dde8c 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -87,7 +87,6 @@ int import_fork_tar_x(const char *path, pid_t *ret) { if (r < 0) return r; if (r == 0) { - int null_fd; uint64_t retain = (1ULL << CAP_CHOWN) | (1ULL << CAP_FOWNER) | @@ -100,26 +99,12 @@ int import_fork_tar_x(const char *path, pid_t *ret) { pipefd[1] = safe_close(pipefd[1]); - r = move_fd(pipefd[0], STDIN_FILENO, false); + r = rearrange_stdio(pipefd[0], -1, STDERR_FILENO); if (r < 0) { - log_error_errno(r, "Failed to move fd: %m"); + log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); _exit(EXIT_FAILURE); } - null_fd = open("/dev/null", O_WRONLY|O_NOCTTY); - if (null_fd < 0) { - log_error_errno(errno, "Failed to open /dev/null: %m"); - _exit(EXIT_FAILURE); - } - - r = move_fd(null_fd, STDOUT_FILENO, false); - if (r < 0) { - log_error_errno(r, "Failed to move fd: %m"); - _exit(EXIT_FAILURE); - } - - stdio_unset_cloexec(); - if (unshare(CLONE_NEWNET) < 0) log_error_errno(errno, "Failed to lock tar into network namespace, ignoring: %m"); @@ -156,33 +141,18 @@ int import_fork_tar_c(const char *path, pid_t *ret) { if (r < 0) return r; if (r == 0) { - int null_fd; uint64_t retain = (1ULL << CAP_DAC_OVERRIDE); /* Child */ pipefd[0] = safe_close(pipefd[0]); - r = move_fd(pipefd[1], STDOUT_FILENO, false); + r = rearrange_stdio(-1, pipefd[1], STDERR_FILENO); if (r < 0) { - log_error_errno(r, "Failed to move fd: %m"); + log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); _exit(EXIT_FAILURE); } - null_fd = open("/dev/null", O_RDONLY|O_NOCTTY); - if (null_fd < 0) { - log_error_errno(errno, "Failed to open /dev/null: %m"); - _exit(EXIT_FAILURE); - } - - r = move_fd(null_fd, STDIN_FILENO, false); - if (r < 0) { - log_error_errno(errno, "Failed to move fd: %m"); - _exit(EXIT_FAILURE); - } - - stdio_unset_cloexec(); - 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 98ee1a2fab..10f52c7fc1 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -395,57 +395,14 @@ static int transfer_start(Transfer *t) { pipefd[0] = safe_close(pipefd[0]); - if (dup2(pipefd[1], STDERR_FILENO) != STDERR_FILENO) { - log_error_errno(errno, "Failed to dup2() fd: %m"); + r = rearrange_stdio(t->stdin_fd, + t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd, + pipefd[1]); + if (r < 0) { + log_error_errno(r, "Failed to set stdin/stdout/stderr: %m"); _exit(EXIT_FAILURE); } - if (t->stdout_fd >= 0) { - if (dup2(t->stdout_fd, STDOUT_FILENO) != STDOUT_FILENO) { - log_error_errno(errno, "Failed to dup2() fd: %m"); - _exit(EXIT_FAILURE); - } - - if (t->stdout_fd != STDOUT_FILENO) - safe_close(t->stdout_fd); - } else { - if (dup2(pipefd[1], STDOUT_FILENO) != STDOUT_FILENO) { - log_error_errno(errno, "Failed to dup2() fd: %m"); - _exit(EXIT_FAILURE); - } - } - - if (!IN_SET(pipefd[1], STDOUT_FILENO, STDERR_FILENO)) - pipefd[1] = safe_close(pipefd[1]); - - if (t->stdin_fd >= 0) { - if (dup2(t->stdin_fd, STDIN_FILENO) != STDIN_FILENO) { - log_error_errno(errno, "Failed to dup2() fd: %m"); - _exit(EXIT_FAILURE); - } - - if (t->stdin_fd != STDIN_FILENO) - safe_close(t->stdin_fd); - } else { - int null_fd; - - null_fd = open("/dev/null", O_RDONLY|O_NOCTTY); - if (null_fd < 0) { - log_error_errno(errno, "Failed to open /dev/null: %m"); - _exit(EXIT_FAILURE); - } - - if (dup2(null_fd, STDIN_FILENO) != STDIN_FILENO) { - log_error_errno(errno, "Failed to dup2() fd: %m"); - _exit(EXIT_FAILURE); - } - - if (null_fd != STDIN_FILENO) - safe_close(null_fd); - } - - stdio_unset_cloexec(); - 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 ecdcbd2dc2..7651870bf0 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -483,27 +483,14 @@ int pull_verify(PullJob *main_job, NULL /* trailing NULL */ }; unsigned k = ELEMENTSOF(cmd) - 6; - int null_fd; /* Child */ gpg_pipe[1] = safe_close(gpg_pipe[1]); - r = move_fd(gpg_pipe[0], STDIN_FILENO, false); + r = rearrange_stdio(gpg_pipe[0], -1, STDERR_FILENO); if (r < 0) { - log_error_errno(errno, "Failed to move fd: %m"); - _exit(EXIT_FAILURE); - } - - null_fd = open("/dev/null", O_WRONLY|O_NOCTTY); - if (null_fd < 0) { - log_error_errno(errno, "Failed to open /dev/null: %m"); - _exit(EXIT_FAILURE); - } - - r = move_fd(null_fd, STDOUT_FILENO, false); - if (r < 0) { - log_error_errno(errno, "Failed to move fd: %m"); + log_error_errno(r, "Failed to rearrange stdin/stdout: %m"); _exit(EXIT_FAILURE); } @@ -524,8 +511,6 @@ int pull_verify(PullJob *main_job, cmd[k++] = NULL; } - stdio_unset_cloexec(); - execvp("gpg2", (char * const *) cmd); execvp("gpg", (char * const *) cmd); log_error_errno(errno, "Failed to execute gpg: %m"); diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 66d5369a54..428725223d 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -96,23 +96,20 @@ static int spawn_child(const char* child, char** argv) { /* In the child */ if (r == 0) { + safe_close(fd[0]); - r = dup2(fd[1], STDOUT_FILENO); + r = rearrange_stdio(STDIN_FILENO, fd[1], STDERR_FILENO); if (r < 0) { - log_error_errno(errno, "Failed to dup pipe to stdout: %m"); + log_error_errno(r, "Failed to dup pipe to stdout: %m"); _exit(EXIT_FAILURE); } - safe_close_pair(fd); - execvp(child, argv); log_error_errno(errno, "Failed to exec child %s: %m", child); _exit(EXIT_FAILURE); } - r = close(fd[1]); - if (r < 0) - log_warning_errno(errno, "Failed to close write end of pipe: %m"); + safe_close(fd[1]); r = fd_nonblock(fd[0], true); if (r < 0) diff --git a/src/journal/cat.c b/src/journal/cat.c index c87a149a4c..1815d58158 100644 --- a/src/journal/cat.c +++ b/src/journal/cat.c @@ -135,14 +135,13 @@ int main(int argc, char *argv[]) { saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); - if (dup3(fd, STDOUT_FILENO, 0) < 0 || - dup3(fd, STDERR_FILENO, 0) < 0) { - r = log_error_errno(errno, "Failed to duplicate fd: %m"); + r = rearrange_stdio(STDIN_FILENO, fd, fd); /* Invalidates fd on succcess + error! */ + fd = -1; + if (r < 0) { + log_error_errno(r, "Failed to rearrange stdout/stderr: %m"); goto finish; } - fd = safe_close_above_stdio(fd); - if (argc <= optind) (void) execl("/bin/cat", "/bin/cat", NULL); else diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 90132bb87b..168607536d 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -960,14 +960,11 @@ int bus_socket_exec(sd_bus *b) { if (r == 0) { /* Child */ - assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO); - assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO); + safe_close(s[0]); - if (!IN_SET(s[1], STDIN_FILENO, STDOUT_FILENO)) - safe_close(s[1]); + if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0) + _exit(EXIT_FAILURE); - (void) fd_cloexec(STDIN_FILENO, false); - (void) fd_cloexec(STDOUT_FILENO, false); (void) fd_nonblock(STDIN_FILENO, false); (void) fd_nonblock(STDOUT_FILENO, false); diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 46cdcd2e84..2dee5f8ec8 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -54,26 +54,12 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { } if (r == 0) { char *empty_env = NULL; - int nullfd; - if (dup3(pipe_fds[1], STDOUT_FILENO, 0) < 0) + safe_close(pipe_fds[0]); + + if (rearrange_stdio(-1, pipe_fds[1], -1) < 0) _exit(EXIT_FAILURE); - safe_close_above_stdio(pipe_fds[0]); - safe_close_above_stdio(pipe_fds[1]); - - nullfd = open("/dev/null", O_RDWR); - if (nullfd < 0) - _exit(EXIT_FAILURE); - - if (dup3(nullfd, STDIN_FILENO, 0) < 0) - _exit(EXIT_FAILURE); - - if (dup3(nullfd, STDERR_FILENO, 0) < 0) - _exit(EXIT_FAILURE); - - safe_close_above_stdio(nullfd); - close_all_fds(NULL, 0); execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 7405359cc7..90f1c4184f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2582,23 +2582,15 @@ static int outer_child( return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m"); if (interactive) { - close_nointr(STDIN_FILENO); - close_nointr(STDOUT_FILENO); - close_nointr(STDERR_FILENO); + int terminal; - r = open_terminal(console, O_RDWR); - if (r != STDIN_FILENO) { - if (r >= 0) { - safe_close(r); - r = -EINVAL; - } + terminal = open_terminal(console, O_RDWR); + if (terminal < 0) + return log_error_errno(terminal, "Failed to open console: %m"); - return log_error_errno(r, "Failed to open console: %m"); - } - - if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO || - dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) - return log_error_errno(errno, "Failed to duplicate console: %m"); + r = rearrange_stdio(terminal, terminal, terminal); /* invalidates 'terminal' on success and failure */ + if (r < 0) + return log_error_errno(r, "Failed to move console to stdin/stdout/stderr: %m"); } r = reset_audit_loginuid();