]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/bpf-devices: use bpf_program_supported()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Apr 2025 08:26:58 +0000 (17:26 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 9 May 2025 15:17:52 +0000 (00:17 +0900)
Note, BPF_PROG_TYPE_CGROUP_DEVICE is supported since kernel v4.15.
As our baseline on the kernel is v5.4, we can assume the bpf type is
always supported.

src/core/bpf-devices.c
src/core/bpf-devices.h
src/core/cgroup.c
src/test/test-bpf-devices.c

index adaa92936483241a21e4b500b0172ef5c667176e..4417ab58e94675e12c98d18c72a17654782b6edd 100644 (file)
@@ -252,51 +252,6 @@ int bpf_devices_apply_policy(
         return 0;
 }
 
-int bpf_devices_supported(void) {
-        const struct bpf_insn trivial[] = {
-                BPF_MOV64_IMM(BPF_REG_0, 1),
-                BPF_EXIT_INSN()
-        };
-
-        _cleanup_(bpf_program_freep) BPFProgram *program = NULL;
-        static int supported = -1;
-        int r;
-
-        /* Checks whether BPF device controller is supported. For this, we check two things:
-         *
-         * a) whether we are privileged
-         * b) the BPF implementation in the kernel supports BPF_PROG_TYPE_CGROUP_DEVICE programs, which we require
-         */
-
-        if (supported >= 0)
-                return supported;
-
-        if (geteuid() != 0) {
-                log_debug("Not enough privileges, BPF device control is not supported.");
-                return supported = 0;
-        }
-
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE, "sd_devices", &program);
-        if (r < 0) {
-                log_debug_errno(r, "Can't allocate CGROUP DEVICE BPF program, BPF device control is not supported: %m");
-                return supported = 0;
-        }
-
-        r = bpf_program_add_instructions(program, trivial, ELEMENTSOF(trivial));
-        if (r < 0) {
-                log_debug_errno(r, "Can't add trivial instructions to CGROUP DEVICE BPF program, BPF device control is not supported: %m");
-                return supported = 0;
-        }
-
-        r = bpf_program_load_kernel(program, NULL, 0);
-        if (r < 0) {
-                log_debug_errno(r, "Can't load kernel CGROUP DEVICE BPF program, BPF device control is not supported: %m");
-                return supported = 0;
-        }
-
-        return supported = 1;
-}
-
 static int allow_list_device_pattern(
                 BPFProgram *prog,
                 const char *path,
index 5660e1a03a60265d3b57fd60ba695c62e5bca0d2..a1d261548d89856ecd9be537795b762fa4d58f3c 100644 (file)
@@ -15,7 +15,6 @@ int bpf_devices_apply_policy(
                 const char *cgroup_path,
                 BPFProgram **prog_installed);
 
-int bpf_devices_supported(void);
 int bpf_devices_allow_list_device(BPFProgram *prog, const char *path, const char *node, CGroupDevicePermissions p);
 int bpf_devices_allow_list_major(BPFProgram *prog, const char *path, const char *name, char type, CGroupDevicePermissions p);
 int bpf_devices_allow_list_static(BPFProgram *prog, const char *path);
index 896db2d647ac62fc22eee7b5317a0f29c3db35b1..dbab38c3c0811f2ab35991436fde793bf2327f9a 100644 (file)
@@ -3259,18 +3259,12 @@ static int cg_bpf_mask_supported(CGroupMask *ret) {
         CGroupMask mask = 0;
         int r;
 
-        /* BPF-based firewall and pinned foreign prog */
+        /* BPF-based firewall, device access control, and pinned foreign prog */
         if (bpf_program_supported() > 0)
                 mask |= CGROUP_MASK_BPF_FIREWALL |
+                        CGROUP_MASK_BPF_DEVICES |
                         CGROUP_MASK_BPF_FOREIGN;
 
-        /* BPF-based device access control */
-        r = bpf_devices_supported();
-        if (r < 0)
-                return r;
-        if (r > 0)
-                mask |= CGROUP_MASK_BPF_DEVICES;
-
         /* BPF-based bind{4|6} hooks */
         r = bpf_socket_bind_supported();
         if (r < 0)
index 8b0b744892e257902420d275f9c492b06ce73040..1642673e756b84cbb63a2a85b5fca1ff28eec8cb 100644 (file)
@@ -257,6 +257,11 @@ int main(int argc, char *argv[]) {
 
         test_setup_logging(LOG_DEBUG);
 
+        r = bpf_program_supported();
+        if (r < 0)
+                return log_tests_skipped_errno(r, "BPF device filter not supported");
+        ASSERT_TRUE(r);
+
         ASSERT_OK(getrlimit(RLIMIT_MEMLOCK, &rl));
         rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE);
         (void) setrlimit(RLIMIT_MEMLOCK, &rl);
@@ -274,11 +279,6 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 return log_tests_skipped_errno(r, "Failed to prepare cgroup subtree");
 
-        r = bpf_devices_supported();
-        if (r == 0)
-                return log_tests_skipped("BPF device filter not supported");
-        ASSERT_EQ(r, 1);
-
         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup, NULL, &controller_path);
         ASSERT_OK(r);