]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: rename FORK_NULL_STDIO -> FORK_REARRANGE_STDIO
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 7 Feb 2023 09:19:55 +0000 (18:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 20 Feb 2023 22:37:51 +0000 (07:37 +0900)
And make safe_fork_full() takes fds to be assigned to stdio.

12 files changed:
src/basic/process-util.c
src/basic/process-util.h
src/home/homed-home.c
src/libsystemd/sd-bus/bus-socket.c
src/login/logind-brightness.c
src/resolve/test-resolved-stream.c
src/shared/dissect-image.c
src/shared/elf-util.c
src/shared/exec-util.c
src/shared/pager.c
src/shutdown/umount.c
src/test/test-process-util.c

index 4df369dd2a153a7f4fcce87d8df66846374a8053..919387f958030053056c59668691c3562221b08c 100644 (file)
@@ -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) {
index 279f5d6e6b70a290311b79aa1c665b41408ab70a..6f6fc7d94e7111f0a39b1630daacd44c16075703 100644 (file)
@@ -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);
index e6b77406000d53bc715ad8829c8f23c72f92992b..8b4a81d7e894b94b77dffc31fa162fea19d6684c 100644 (file)
@@ -1180,6 +1180,7 @@ 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);
         if (r < 0)
index 64037e4fe0595875933899155c20c700e80d1b1b..aca049b052e6c127e068371a6ccbb1874ee327fa 100644 (file)
@@ -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)",
+                           NULL,
+                           s+1, 1,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
         if (r < 0) {
                 safe_close_pair(s);
                 return r;
index 21feaae0c328ebb3cfd6c0a60da1c0a82337ee27..d238cb74c9156440a282b97340d38bbc86dbd579 100644 (file)
@@ -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) {
index c708eb4da8de7b943a6567a02960e67da4e8ccfb..d7fe3c42f537992cfb78bbe2888748217765aab6 100644 (file)
@@ -147,8 +147,10 @@ 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)",
+                           NULL,
+                           (int[]) { fd_server, fd_tls }, 2,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &openssl_pid);
         assert_se(r >= 0);
         if (r == 0) {
                 /* Child */
index 9a4bac99a173308a85956a6c5b3468590300138b..ce37dd31ceb80da27abd5e3862fda6550d47d24a 100644 (file)
@@ -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");
index 8da16f528fe373fc93ff64dd133dff94d6f28be6..98c47d912500c9783cfdd35a6327fe778a0ff630 100644 (file)
@@ -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,
index 2e8f5b85627a6282bc2a948c7d4ec9b80f74b0d5..40e9342cd5211c24a9e065defc97bf06b4e44ac7 100644 (file)
@@ -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,
index 6ed35a3ca9983733206f40a2d037952b453ce56c..7bede85752f26a086c911ba47e49d49daff60281 100644 (file)
@@ -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) {
index 61bd9d26012ae2d0a895fb3e3a6f40c4683295b9..bae4d9d023b0d5c058f4ddf24fa95d2cb55a743c 100644 (file)
@@ -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) {
index 9c24ca8204ff255ef78acdc2e05b040269656938..9a0c15dffe4475307b799f43acb522537102e032 100644 (file)
@@ -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) {