}
bool bpf_restrict_fs_supported(bool initialize) {
- _cleanup_(restrict_fs_bpf_freep) struct restrict_fs_bpf *obj = NULL;
static int supported = -1;
int r;
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);
}
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")));