mirror of
https://github.com/systemd/systemd.git
synced 2025-02-04 21:47:31 +03:00
Merge pull request #26349 from yuwata/safe-fork-rearrange-stdio
process-util: introduce FORK_REARRANGE_STDIO
This commit is contained in:
commit
fd4ba8a7db
@ -1134,6 +1134,7 @@ static void restore_sigsetp(sigset_t **ssp) {
|
||||
|
||||
int safe_fork_full(
|
||||
const char *name,
|
||||
const int stdio_fds[3],
|
||||
const int except_fds[],
|
||||
size_t n_except_fds,
|
||||
ForkFlags flags,
|
||||
@ -1292,6 +1293,27 @@ int safe_fork_full(
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_REARRANGE_STDIO) {
|
||||
if (stdio_fds) {
|
||||
r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
|
||||
if (r < 0) {
|
||||
log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
r = make_null_stdio();
|
||||
if (r < 0) {
|
||||
log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
} else if (flags & FORK_STDOUT_TO_STDERR) {
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
||||
log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_CLOSE_ALL_FDS) {
|
||||
/* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
|
||||
log_close();
|
||||
@ -1317,20 +1339,6 @@ int safe_fork_full(
|
||||
log_set_open_when_needed(false);
|
||||
}
|
||||
|
||||
if (flags & FORK_NULL_STDIO) {
|
||||
r = make_null_stdio();
|
||||
if (r < 0) {
|
||||
log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
} else if (flags & FORK_STDOUT_TO_STDERR) {
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
||||
log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_RLIMIT_NOFILE_SAFE) {
|
||||
r = rlimit_nofile_safe();
|
||||
if (r < 0) {
|
||||
@ -1364,7 +1372,10 @@ int namespace_fork(
|
||||
* process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
|
||||
* /proc/self/fd works correctly. */
|
||||
|
||||
r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@ -1379,7 +1390,10 @@ int namespace_fork(
|
||||
}
|
||||
|
||||
/* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
|
||||
r = safe_fork_full(inner_name, except_fds, n_except_fds, flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NULL_STDIO), &pid);
|
||||
r = safe_fork_full(inner_name,
|
||||
NULL,
|
||||
except_fds, n_except_fds,
|
||||
flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO), &pid);
|
||||
if (r < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
if (r == 0) {
|
||||
|
@ -143,7 +143,7 @@ typedef enum ForkFlags {
|
||||
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_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */
|
||||
FORK_NULL_STDIO = 1 << 4, /* Connect 0,1,2 to /dev/null */
|
||||
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 */
|
||||
@ -157,10 +157,16 @@ typedef enum ForkFlags {
|
||||
FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
|
||||
} ForkFlags;
|
||||
|
||||
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
|
||||
int safe_fork_full(
|
||||
const char *name,
|
||||
const int stdio_fds[3],
|
||||
const int except_fds[],
|
||||
size_t n_except_fds,
|
||||
ForkFlags flags,
|
||||
pid_t *ret_pid);
|
||||
|
||||
static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
|
||||
return safe_fork_full(name, NULL, 0, flags, ret_pid);
|
||||
return safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
|
||||
}
|
||||
|
||||
int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
|
||||
|
@ -1180,8 +1180,9 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
|
||||
return -errno;
|
||||
|
||||
r = safe_fork_full("(sd-homework)",
|
||||
(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) {
|
||||
@ -1226,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;
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -994,7 +994,10 @@ int bus_socket_exec(sd_bus *b) {
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
|
||||
r = safe_fork_full("(sd-busexec)",
|
||||
(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;
|
||||
@ -1002,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
|
||||
|
@ -136,7 +136,7 @@ static int brightness_writer_fork(BrightnessWriter *w) {
|
||||
assert(w->child == 0);
|
||||
assert(!w->child_event_source);
|
||||
|
||||
r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
|
||||
r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -147,16 +147,14 @@ static void *tls_dns_server(void *p) {
|
||||
fd_tls = fd[1];
|
||||
}
|
||||
|
||||
r = safe_fork_full("(test-resolved-stream-tls-openssl)", (int[]) { fd_server, fd_tls }, 2,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &openssl_pid);
|
||||
r = safe_fork_full("(test-resolved-stream-tls-openssl)",
|
||||
(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);
|
||||
|
@ -1436,8 +1436,9 @@ static int run_fsck(int node_fd, const char *fstype) {
|
||||
|
||||
r = safe_fork_full(
|
||||
"(fsck)",
|
||||
NULL,
|
||||
&node_fd, 1, /* Leave the node fd open */
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOEXEC_OFF,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to fork off fsck: %m");
|
||||
|
@ -784,6 +784,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha
|
||||
* system call or interacting with the system in any way, besides reading from
|
||||
* the file descriptor and writing into these four pipes. */
|
||||
r = safe_fork_full("(sd-parse-elf)",
|
||||
NULL,
|
||||
(int[]){ fd, error_pipe[1], return_pipe[1], json_pipe[1] },
|
||||
4,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_WAIT|FORK_REOPEN_LOG,
|
||||
|
@ -487,6 +487,7 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
|
||||
/* Spawns a temporary TTY agent, making sure it goes away when we go away */
|
||||
|
||||
r = safe_fork_full(name,
|
||||
NULL,
|
||||
except,
|
||||
n_except,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
|
@ -316,7 +316,7 @@ int show_man_page(const char *desc, bool null_stdio) {
|
||||
} else
|
||||
args[1] = desc;
|
||||
|
||||
r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
@ -618,7 +618,10 @@ static int remount_with_timeout(MountPoint *m, bool last_try) {
|
||||
|
||||
/* Due to the possibility of a remount operation hanging, we fork a child process and set a
|
||||
* timeout. If the timeout lapses, the assumption is that the particular remount failed. */
|
||||
r = safe_fork_full("(sd-remount)", pfd, ELEMENTSOF(pfd), FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
r = safe_fork_full("(sd-remount)",
|
||||
NULL,
|
||||
pfd, ELEMENTSOF(pfd),
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@ -671,7 +674,10 @@ static int umount_with_timeout(MountPoint *m, bool last_try) {
|
||||
|
||||
/* Due to the possibility of a umount operation hanging, we fork a child process and set a
|
||||
* timeout. If the timeout lapses, the assumption is that the particular umount failed. */
|
||||
r = safe_fork_full("(sd-umount)", pfd, ELEMENTSOF(pfd), FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
r = safe_fork_full("(sd-umount)",
|
||||
NULL,
|
||||
pfd, ELEMENTSOF(pfd),
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ TEST(safe_fork) {
|
||||
|
||||
BLOCK_SIGNALS(SIGCHLD);
|
||||
|
||||
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_REOPEN_LOG, &pid);
|
||||
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user