]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: it is not necessary to send message after fsconfig() for bpffs
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 17 Jul 2025 18:53:28 +0000 (03:53 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 18 Jul 2025 11:15:25 +0000 (20:15 +0900)
Instead, let's wait for the helper process being finished.

src/core/exec-invoke.c
src/core/namespace.c
src/core/namespace.h

index dcef723b46ceb722dd1658d03cd5df5adb4196de..82a6a12a98485d56fae48c0a28656b6ed49f28f9 100644 (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
index c384d67898a012cd30f72985ad2991a4d49bb8a4..4391c1275544255f7f0eb1ed0c8384e28c9d5a6b 100644 (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();
index 42e146a7e8ee717f293b89044ddb011b2bc86e89..4e9d87e266fda28e82d6403dc1d56951a1e04b75 100644 (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);