core: it is not necessary to send message after fsconfig() for bpffs

Instead, let's wait for the helper process being finished.
This commit is contained in:
Yu Watanabe
2025-07-18 20:15:25 +09:00
parent 8509ceea10
commit 9eabf82750
3 changed files with 35 additions and 25 deletions
+14 -21
View File
@@ -2298,9 +2298,6 @@ static int bpffs_helper(const ExecContext *c, int socket_fd) {
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;
}
@@ -3671,7 +3668,9 @@ static int apply_mount_namespace(
bool needs_sandboxing,
uid_t exec_directory_uid,
gid_t exec_directory_gid,
PidRef *bpffs_pidref,
int bpffs_socket_fd,
int bpffs_errno_pipe,
char **reterr_path) {
_cleanup_(verity_settings_done) VeritySettings verity = VERITY_SETTINGS_DEFAULT;
@@ -3886,7 +3885,9 @@ static int apply_mount_namespace(
.proc_subset = needs_sandboxing ? context->proc_subset : PROC_SUBSET_ALL,
.private_bpf = needs_sandboxing ? context->private_bpf : PRIVATE_BPF_NO,
.bpffs_pidref = bpffs_pidref,
.bpffs_socket_fd = bpffs_socket_fd,
.bpffs_errno_pipe = bpffs_errno_pipe,
};
r = setup_namespace(&parameters, reterr_path);
@@ -4527,7 +4528,9 @@ static int setup_delegated_namespaces(
const ExecCommand *command,
bool needs_sandboxing,
bool have_cap_sys_admin,
PidRef *bpffs_pidref,
int bpffs_socket_fd,
int bpffs_errno_pipe,
int *reterr_exit_status) {
int r;
@@ -4650,7 +4653,9 @@ static int setup_delegated_namespaces(
needs_sandboxing,
uid,
gid,
bpffs_pidref,
bpffs_socket_fd,
bpffs_errno_pipe,
&error_path);
if (r < 0) {
*reterr_exit_status = EXIT_NAMESPACE;
@@ -5762,7 +5767,9 @@ int exec_invoke(
command,
needs_sandboxing,
have_cap_sys_admin,
&bpffs_pidref,
bpffs_socket_fd,
bpffs_errno_pipe,
exit_status);
if (r < 0)
return r;
@@ -5822,29 +5829,15 @@ int exec_invoke(
command,
needs_sandboxing,
have_cap_sys_admin,
&bpffs_pidref,
bpffs_socket_fd,
bpffs_errno_pipe,
exit_status);
if (r < 0)
return r;
if (context->private_bpf != PRIVATE_BPF_NO) {
r = pidref_wait_for_terminate_and_check("(sd-bpffs)", &bpffs_pidref, /* flags = */ 0);
if (r < 0) {
*exit_status = EXIT_BPF;
return r;
}
/* If something strange happened with the child, let's consider this fatal, too */
if (r != EXIT_SUCCESS) {
*exit_status = EXIT_BPF;
ssize_t ss = read(bpffs_errno_pipe, &r, sizeof(r));
if (ss == sizeof(r))
return log_debug_errno(r, "bpffs helper exited with error: %m");
if (ss < 0)
return log_debug_errno(errno, "Failed to read from the bpffs helper errno pipe: %m");
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Short read from the bpffs helper errno pipe.");
}
pidref_done(&bpffs_pidref);
}
/* Kill unnecessary process, for the case that e.g. when the bpffs mount point is hidden. */
pidref_done_sigkill_wait(&bpffs_pidref);
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
+19 -4
View File
@@ -1735,11 +1735,13 @@ static int mount_overlay(const MountEntry *m) {
return 1;
}
static int mount_bpffs(const MountEntry *m, int socket_fd) {
static int mount_bpffs(const MountEntry *m, PidRef *pidref, int socket_fd, int errno_pipe) {
int r;
assert(m);
assert(pidref_is_set(pidref));
assert(socket_fd >= 0);
assert(errno_pipe >= 0);
_cleanup_close_ int fs_fd = fsopen("bpf", FSOPEN_CLOEXEC);
if (fs_fd < 0)
@@ -1749,8 +1751,21 @@ static int mount_bpffs(const MountEntry *m, int socket_fd) {
if (r < 0)
return log_debug_errno(r, "Failed to send bpffs fd to child: %m");
if (read(socket_fd, (uint8_t[1]) {}, 1) < 0)
return log_debug_errno(errno, "Failed to receive data from child: %m");
r = pidref_wait_for_terminate_and_check("(sd-bpffs)", pidref, /* flags = */ 0);
if (r < 0)
return r;
/* If something strange happened with the child, let's consider this fatal, too */
if (r != EXIT_SUCCESS) {
ssize_t ss = read(errno_pipe, &r, sizeof(r));
if (ss < 0)
return log_debug_errno(errno, "Failed to read from the bpffs helper errno pipe: %m");
if (ss != sizeof(r))
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Short read from the bpffs helper errno pipe.");
return log_debug_errno(r, "bpffs helper exited with error: %m");
}
pidref_done(pidref);
_cleanup_close_ int mnt_fd = fsmount(fs_fd, /* flags = */ 0, /* mount_attrs = */ 0);
if (mnt_fd < 0)
@@ -2020,7 +2035,7 @@ static int apply_one_mount(
return mount_overlay(m);
case MOUNT_BPFFS:
return mount_bpffs(m, p->bpffs_socket_fd);
return mount_bpffs(m, p->bpffs_pidref, p->bpffs_socket_fd, p->bpffs_errno_pipe);
default:
assert_not_reached();
+2
View File
@@ -200,7 +200,9 @@ typedef struct NamespaceParameters {
PrivateTmp private_var_tmp;
PrivatePIDs private_pids;
PidRef *bpffs_pidref;
int bpffs_socket_fd;
int bpffs_errno_pipe;
} NamespaceParameters;
int setup_namespace(const NamespaceParameters *p, char **reterr_path);