diff --git a/src/core/bpf-restrict-fs.c b/src/core/bpf-restrict-fs.c index a0bd4823b0..8db05f4db3 100644 --- a/src/core/bpf-restrict-fs.c +++ b/src/core/bpf-restrict-fs.c @@ -69,7 +69,6 @@ static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) { } bool bpf_restrict_fs_supported(bool initialize) { - _cleanup_(restrict_fs_bpf_freep) struct restrict_fs_bpf *obj = NULL; static int supported = -1; int r; @@ -95,15 +94,13 @@ bool bpf_restrict_fs_supported(bool initialize) { return (supported = false); } - r = prepare_restrict_fs_bpf(&obj); - if (r < 0) - return (supported = false); - - if (!bpf_can_link_lsm_program(obj->progs.restrict_filesystems)) { - log_warning("bpf-restrict-fs: Failed to link program; assuming BPF LSM is not available."); - return (supported = false); - } - + /* We don't try to open/load/attach the BPF program here: that's the expensive part (a real kernel + * verifier pass plus, on the real attach in bpf_restrict_fs_setup(), an LSM link), and doing it + * twice (once here just to throw the result away, once for real in bpf_restrict_fs_setup()) means + * paying that cost twice on every boot for no benefit. If BPF_LSM_MAC attach isn't actually usable + * (e.g. no BPF trampoline support on this architecture/kernel), bpf_restrict_fs_setup()'s own + * attach will fail when it is later called, and that failure is already logged and handled + * gracefully by its caller. */ return (supported = true); } diff --git a/src/test/test-bpf-restrict-fs.c b/src/test/test-bpf-restrict-fs.c index 8e41537f21..810f7af02c 100644 --- a/src/test/test-bpf-restrict-fs.c +++ b/src/test/test-bpf-restrict-fs.c @@ -89,6 +89,13 @@ int main(int argc, char *argv[]) { ASSERT_OK(manager_new(RUNTIME_SCOPE_SYSTEM, MANAGER_TEST_RUN_BASIC, &m)); ASSERT_OK(manager_startup(m, NULL, NULL, NULL, NULL)); + /* bpf_restrict_fs_supported() above only checks that the BPF LSM hook is enabled in the kernel; it + * doesn't verify that the LSM BPF program managed to actually attach (e.g. some architectures/older + * kernels lack BPF trampoline support). If it didn't, manager_startup() already logged a warning + * and continued without enforcement, so skip here rather than hard-failing the assertions below. */ + if (!m->restrict_fs) + return log_tests_skipped("Failed to attach LSM BPF program"); + /* We need to enable access to the filesystem where the binary is so we * add @common-block and @application */ ASSERT_FAIL(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/tracing/printk_formats", STRV_MAKE("@common-block", "@application")));