summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/activate/activate.c9
-rw-r--r--src/basic/exec-util.c7
-rw-r--r--src/core/execute.c11
-rw-r--r--src/import/import-common.c38
-rw-r--r--src/import/importd.c53
-rw-r--r--src/import/pull-common.c19
-rw-r--r--src/journal-remote/journal-remote.c11
-rw-r--r--src/journal/cat.c9
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c9
-rw-r--r--src/nspawn/nspawn-setuid.c18
-rw-r--r--src/nspawn/nspawn.c22
11 files changed, 38 insertions, 168 deletions
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)
- _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);
+ safe_close(pipe_fds[0]);
- if (dup3(nullfd, STDIN_FILENO, 0) < 0)
+ if (rearrange_stdio(-1, pipe_fds[1], -1) < 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);
-
- r = open_terminal(console, O_RDWR);
- if (r != STDIN_FILENO) {
- if (r >= 0) {
- safe_close(r);
- r = -EINVAL;
- }
+ int terminal;
- return log_error_errno(r, "Failed to open console: %m");
- }
+ terminal = open_terminal(console, O_RDWR);
+ if (terminal < 0)
+ return log_error_errno(terminal, "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();