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:
+14
-21
@@ -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(¶meters, 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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user