core/exec-invoke: correct size for dont_close array in close_remaining_fds() (#40867)

This commit is contained in:
Yu Watanabe
2026-03-02 13:05:42 +09:00
committed by GitHub
3 changed files with 31 additions and 52 deletions
+1 -1
View File
@@ -1808,7 +1808,7 @@ int namespace_fork_full(
return 0;
}
log_close();
log_forget_fds();
log_set_open_when_needed(true);
(void) close_all_fds(&pidref_inner.fd, 1);
+30 -50
View File
@@ -4274,71 +4274,48 @@ out:
return r;
}
static void append_socket_pair(int *array, size_t *n, const int pair[static 2]) {
assert(array);
assert(n);
assert(pair);
#define FD_PAIR_CONDITION(cond, pair) \
(cond) ? pair[0] : -EBADF, (cond) ? pair[1] : -EBADF
if (pair[0] >= 0)
array[(*n)++] = pair[0];
if (pair[1] >= 0)
array[(*n)++] = pair[1];
}
#define FD_PAIR(pair) FD_PAIR_CONDITION(true, pair)
static int close_remaining_fds(
const ExecParameters *params,
const ExecRuntime *runtime,
int socket_fd,
const int *fds,
const int fds[],
size_t n_fds) {
size_t n_dont_close = 0;
int dont_close[n_fds + 17];
assert(params);
assert(runtime);
assert(fds || n_fds == 0);
if (params->stdin_fd >= 0)
dont_close[n_dont_close++] = params->stdin_fd;
if (params->stdout_fd >= 0)
dont_close[n_dont_close++] = params->stdout_fd;
if (params->stderr_fd >= 0)
dont_close[n_dont_close++] = params->stderr_fd;
/* fds listed here shall be closed before second close_all_fds() call to avoid double close! */
int static_fds[] = {
params->stdin_fd, params->stdout_fd, params->stderr_fd,
socket_fd,
FD_PAIR(runtime->ephemeral_storage_socket),
FD_PAIR_CONDITION(runtime->shared, runtime->shared->userns_storage_socket),
FD_PAIR_CONDITION(runtime->shared, runtime->shared->netns_storage_socket),
FD_PAIR_CONDITION(runtime->shared, runtime->shared->ipcns_storage_socket),
FD_PAIR_CONDITION(runtime->dynamic_creds && runtime->dynamic_creds->user,
runtime->dynamic_creds->user->storage_socket),
FD_PAIR_CONDITION(runtime->dynamic_creds && runtime->dynamic_creds->group,
runtime->dynamic_creds->group->storage_socket),
params->user_lookup_fd,
params->pidref_transport_fd,
};
if (socket_fd >= 0)
dont_close[n_dont_close++] = socket_fd;
_cleanup_free_ int *accum_fds = NULL;
if (n_fds > 0) {
memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
n_dont_close += n_fds;
accum_fds = new(int, ELEMENTSOF(static_fds) + n_fds);
if (!accum_fds)
return -ENOMEM;
memcpy(mempcpy_typesafe(accum_fds, static_fds, ELEMENTSOF(static_fds)), fds, sizeof(int) * n_fds);
}
append_socket_pair(dont_close, &n_dont_close, runtime->ephemeral_storage_socket);
if (runtime->shared) {
append_socket_pair(dont_close, &n_dont_close, runtime->shared->userns_storage_socket);
append_socket_pair(dont_close, &n_dont_close, runtime->shared->netns_storage_socket);
append_socket_pair(dont_close, &n_dont_close, runtime->shared->ipcns_storage_socket);
}
if (runtime->dynamic_creds) {
if (runtime->dynamic_creds->user)
append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->user->storage_socket);
if (runtime->dynamic_creds->group)
append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->group->storage_socket);
}
if (params->user_lookup_fd >= 0)
dont_close[n_dont_close++] = params->user_lookup_fd;
if (params->handoff_timestamp_fd >= 0)
dont_close[n_dont_close++] = params->handoff_timestamp_fd;
if (params->pidref_transport_fd >= 0)
dont_close[n_dont_close++] = params->pidref_transport_fd;
assert(n_dont_close <= ELEMENTSOF(dont_close));
return close_all_fds(dont_close, n_dont_close);
return close_all_fds(accum_fds ?: static_fds, ELEMENTSOF(static_fds) + n_fds);
}
static int send_user_lookup(
@@ -6191,6 +6168,8 @@ int exec_invoke(
/* Kill unnecessary process, for the case that e.g. when the bpffs mount point is hidden. */
pidref_done_sigkill_wait(&bpffs_pidref);
bpffs_socket_fd = safe_close(bpffs_socket_fd);
bpffs_errno_pipe = safe_close(bpffs_errno_pipe);
if (needs_sandboxing && exec_needs_cgroup_namespace(context) && params->cgroup_path) {
/* Move ourselves into the subcgroup now *after* we've unshared the cgroup namespace, which
@@ -6267,6 +6246,7 @@ int exec_invoke(
* them open until the final execve(). But first, close the remaining sockets in the context
* objects. */
socket_fd = safe_close(socket_fd);
exec_runtime_close(runtime);
exec_params_close(params);
-1
View File
@@ -2936,7 +2936,6 @@ void exec_params_deep_clear(ExecParameters *p) {
p->stdin_fd = safe_close(p->stdin_fd);
p->stdout_fd = safe_close(p->stdout_fd);
p->stderr_fd = safe_close(p->stderr_fd);
p->root_directory_fd = safe_close(p->root_directory_fd);
p->notify_socket = mfree(p->notify_socket);