core/exec-invoke: negative errno needs to be passed to report_errno_and_exit()

Hence, we cannot pass errno as is to report_errno_and_exit().

This splits out bpffs_helper(), which returns negative errno on failure,
and 0 on success. And make the returned value passed to report_errno_and_exit().

Follow-up for #36134.
This commit is contained in:
Yu Watanabe
2025-07-18 15:17:24 +09:00
parent 58788345d9
commit 8509ceea10

View File

@@ -2270,20 +2270,54 @@ static int setup_private_users_child(int unshare_ready_fd, const char *uid_map,
return 0;
}
static int bpffs_helper(const ExecContext *c, int socket_fd) {
assert(c);
assert(socket_fd >= 0);
_cleanup_close_ int fs_fd = receive_one_fd(socket_fd, /* flags = */ 0);
if (fs_fd < 0)
return log_debug_errno(fs_fd, "Failed to receive file descriptor from parent: %m");
char number[STRLEN("0x") + sizeof(c->bpf_delegate_commands) * 2 + 1];
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_commands);
if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_cmds", number, /* aux = */ 0) < 0)
return log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_maps);
if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_maps", number, /* aux = */ 0) < 0)
return log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_programs);
if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_progs", number, /* aux = */ 0) < 0)
return log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_attachments);
if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_attachs", number, /* aux = */ 0) < 0)
return log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
if (fsconfig(fs_fd, FSCONFIG_CMD_CREATE, /* key = */ NULL, /* value = */ NULL, /* aux = */ 0) < 0)
return log_debug_errno(errno, "Failed to create bpffs superblock: %m");
if (write(socket_fd, (uint8_t[1]) {}, 1) < 0)
return log_debug_errno(errno, "Failed to send data to child: %m");
return 0;
}
static int bpffs_prepare(
const ExecContext *c,
PidRef *ret_pid,
int *ret_sock_fd,
int *ret_errno_pipe) {
_cleanup_close_pair_ int socket_fds[2] = EBADF_PAIR, bpffs_errno_pipe[2] = EBADF_PAIR;
_cleanup_close_pair_ int socket_fds[2] = EBADF_PAIR, errno_pipe[2] = EBADF_PAIR;
int r;
assert(ret_sock_fd);
assert(ret_pid);
assert(ret_errno_pipe);
r = pipe2(bpffs_errno_pipe, O_CLOEXEC|O_NONBLOCK);
r = pipe2(errno_pipe, O_CLOEXEC|O_NONBLOCK);
if (r < 0)
return log_debug_errno(errno, "Failed to create pipe: %m");
@@ -2295,67 +2329,13 @@ static int bpffs_prepare(
if (r < 0)
return log_debug_errno(r, "Failed to fork bpffs privileged helper: %m");
if (r == 0) {
_cleanup_close_ int fs_fd = -EBADF;
char number[STRLEN("0x") + sizeof(c->bpf_delegate_commands) * 2 + 1];
bpffs_errno_pipe[0] = safe_close(bpffs_errno_pipe[0]);
errno_pipe[0] = safe_close(errno_pipe[0]);
socket_fds[0] = safe_close(socket_fds[0]);
fs_fd = receive_one_fd(socket_fds[1], /* flags = */ 0);
if (fs_fd < 0) {
log_debug_errno(fs_fd, "Failed to receive file descriptor from parent: %m");
report_errno_and_exit(bpffs_errno_pipe[1], fs_fd);
}
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_commands);
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_cmds", number, /* aux = */ 0);
if (r < 0) {
log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_maps);
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_maps", number, /* aux = */ 0);
if (r < 0) {
log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_programs);
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_progs", number, /* aux = */ 0);
if (r < 0) {
log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
xsprintf(number, "0x%"PRIx64, c->bpf_delegate_attachments);
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_attachs", number, /* aux = */ 0);
if (r < 0) {
log_debug_errno(errno, "Failed to FSCONFIG_SET_STRING: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
r = fsconfig(fs_fd, FSCONFIG_CMD_CREATE, /* key = */ NULL, /* value = */ NULL, /* aux = */ 0);
if (r < 0) {
log_debug_errno(errno, "Failed to create bpffs superblock: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
if (write(socket_fds[1], (uint8_t[1]) {}, 1) < 0) {
log_debug_errno(errno, "Failed to send data to child: %m");
report_errno_and_exit(bpffs_errno_pipe[1], errno);
}
_exit(EXIT_SUCCESS);
report_errno_and_exit(errno_pipe[1], bpffs_helper(c, socket_fds[1]));
}
*ret_sock_fd = TAKE_FD(socket_fds[0]);
*ret_errno_pipe = TAKE_FD(bpffs_errno_pipe[0]);
*ret_errno_pipe = TAKE_FD(errno_pipe[0]);
return 0;
}