core/service: only pass socket fds to control processes

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.
This commit is contained in:
Mike Yuan
2025-10-29 21:25:42 +01:00
parent d85d98f406
commit c954830fa9
3 changed files with 19 additions and 12 deletions

View 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);

View 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) {

View 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;