]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/service: only pass socket fds to control processes
authorMike Yuan <me@yhndnzj.com>
Wed, 29 Oct 2025 20:25:42 +0000 (21:25 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 30 Oct 2025 16:47:29 +0000 (17:47 +0100)
If socket is used as stdio, we'd currently imply EXEC_PASS_FDS
and dump the whole set of fds to the control processes. This is
pretty much unexpected and unnecessary though, instead let's
pass only the socket fds.

Yes, this is a compat break, but a relatively minor one I'd
argue. And we can always revisit things if users do complain.

src/core/execute.c
src/core/service.c
src/core/socket.c

index baadad9377140a58569e61bbca92ec66e9d0f2ad..5b01758733aff00259236e91a33729ecc9ae1e7a 100644 (file)
@@ -486,8 +486,8 @@ int exec_spawn(
         assert(command);
         assert(context);
         assert(params);
-        assert(!params->fds || FLAGS_SET(params->flags, EXEC_PASS_FDS));
         assert(params->fds || (params->n_socket_fds + params->n_stashed_fds == 0 && !params->fd_names));
+        assert(params->n_stashed_fds == 0 || FLAGS_SET(params->flags, EXEC_PASS_FDS));
         assert(!params->files_env); /* We fill this field, ensure it comes NULL-initialized to us */
         assert(ret);
 
index 46aabdfe42c4639396d459356e900e4823f648f5..e1cc618fc4d153adedf0fac93d4258247f9686b9 100644 (file)
@@ -1462,7 +1462,6 @@ static int service_collect_fds(
         assert(fds);
         assert(fd_names);
         assert(n_socket_fds);
-        assert(n_stashed_fds);
 
         if (s->socket_fd >= 0) {
                 Socket *sock = ASSERT_PTR(SOCKET(UNIT_DEREF(s->accept_socket)));
@@ -1509,7 +1508,7 @@ static int service_collect_fds(
                 }
         }
 
-        if (s->n_fd_store + s->n_extra_fds > 0) {
+        if (n_stashed_fds && s->n_fd_store + s->n_extra_fds > 0) {
                 int *t = reallocarray(rfds, rn_socket_fds + s->n_fd_store + s->n_extra_fds, sizeof(int));
                 if (!t)
                         return -ENOMEM;
@@ -1546,7 +1545,8 @@ static int service_collect_fds(
         *fds = TAKE_PTR(rfds);
         *fd_names = TAKE_PTR(rfd_names);
         *n_socket_fds = rn_socket_fds;
-        *n_stashed_fds = s->n_fd_store + s->n_extra_fds;
+        if (n_stashed_fds)
+                *n_stashed_fds = s->n_fd_store + s->n_extra_fds;
 
         return 0;
 }
@@ -1730,11 +1730,7 @@ static int service_spawn_internal(
                         exec_params.flags &= ~EXEC_APPLY_CHROOT;
         }
 
-        if (FLAGS_SET(exec_params.flags, EXEC_PASS_FDS) ||
-            s->exec_context.std_input == EXEC_INPUT_SOCKET ||
-            s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
-            s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
-
+        if (FLAGS_SET(exec_params.flags, EXEC_PASS_FDS)) {
                 r = service_collect_fds(s,
                                         &exec_params.fds,
                                         &exec_params.fd_names,
@@ -1743,11 +1739,23 @@ static int service_spawn_internal(
                 if (r < 0)
                         return r;
 
+                log_unit_debug(UNIT(s), "Passing %zu fds to service", exec_params.n_socket_fds + exec_params.n_stashed_fds);
+
                 exec_params.open_files = s->open_files;
 
-                exec_params.flags |= EXEC_PASS_FDS;
+        } else if (s->exec_context.std_input == EXEC_INPUT_SOCKET ||
+                   s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
+                   s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
 
-                log_unit_debug(UNIT(s), "Passing %zu fds to service", exec_params.n_socket_fds + exec_params.n_stashed_fds);
+                r = service_collect_fds(s,
+                                        &exec_params.fds,
+                                        &exec_params.fd_names,
+                                        &exec_params.n_socket_fds,
+                                        /* n_stashed_fds = */ NULL);
+                if (r < 0)
+                        return r;
+
+                log_unit_debug(UNIT(s), "Passing %zu sockets to service", exec_params.n_socket_fds);
         }
 
         if (!FLAGS_SET(exec_params.flags, EXEC_IS_CONTROL) && s->type == SERVICE_EXEC) {
index 1ae3affd0dfebed8553d4aa1c935c25b1889efe4..c946d2572465f31b39cbf657b5bdad29107d98b5 100644 (file)
@@ -2001,7 +2001,6 @@ static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) {
                 if (r < 0)
                         return r;
 
-                exec_params.flags |= EXEC_PASS_FDS;
                 exec_params.fds = TAKE_PTR(fds);
                 exec_params.fd_names = TAKE_PTR(fd_names);
                 exec_params.n_socket_fds = n_fds;