From: Yu Watanabe Date: Tue, 8 Apr 2025 08:26:58 +0000 (+0900) Subject: core/bpf-devices: use bpf_program_supported() X-Git-Tag: v258-rc1~653^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad446c8ceb97c03971f06fd43e97720afe33be5a;p=thirdparty%2Fsystemd.git core/bpf-devices: use bpf_program_supported() 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. --- diff --git a/src/core/bpf-devices.c b/src/core/bpf-devices.c index adaa9293648..4417ab58e94 100644 --- a/src/core/bpf-devices.c +++ b/src/core/bpf-devices.c @@ -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, diff --git a/src/core/bpf-devices.h b/src/core/bpf-devices.h index 5660e1a03a6..a1d261548d8 100644 --- a/src/core/bpf-devices.h +++ b/src/core/bpf-devices.h @@ -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); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 896db2d647a..dbab38c3c08 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -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) diff --git a/src/test/test-bpf-devices.c b/src/test/test-bpf-devices.c index 8b0b744892e..1642673e756 100644 --- a/src/test/test-bpf-devices.c +++ b/src/test/test-bpf-devices.c @@ -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);