[PATCH bpf-next 2/2] selftests/bpf: Test bpf_security_locked_down kfunc
From: Justin Suess <hidden>
Date: 2026-08-15 11:20:52
Also in:
bpf, lkml
Subsystem:
bpf [general] (safe dynamic programs and tools), bpf [selftests] (test runners & infrastructure), kernel selftest framework, the rest · Maintainers:
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Shuah Khan, Shuah Khan, Linus Torvalds
Test the bpf_security_locked_down() kfunc. An LSM program attached to the locked_down hook denies LOCKDOWN_HIBERNATION, so a syscall program querying the kfunc observes both verdicts deterministically without touching real lockdown state: 0 for LOCKDOWN_KEXEC and -EPERM for LOCKDOWN_HIBERNATION. Out-of-range reasons must return -EINVAL. Programs in denied calling contexts (a tracing program, and an LSM program attached to the locked_down hook itself) must be rejected at load time by the kfunc filter. The selftest config guarantees the verdicts are stable: the bpf LSM is in CONFIG_LSM and the lockdown LSM is not, so the kernel cannot already be locked down. Signed-off-by: Justin Suess <redacted> --- .../selftests/bpf/prog_tests/lsm_kfuncs.c | 28 +++++++++++++++ .../testing/selftests/bpf/progs/lsm_kfuncs.c | 34 +++++++++++++++++++ .../selftests/bpf/progs/lsm_kfuncs_fail.c | 26 ++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/lsm_kfuncs.c create mode 100644 tools/testing/selftests/bpf/progs/lsm_kfuncs.c create mode 100644 tools/testing/selftests/bpf/progs/lsm_kfuncs_fail.c
diff --git a/tools/testing/selftests/bpf/prog_tests/lsm_kfuncs.c b/tools/testing/selftests/bpf/prog_tests/lsm_kfuncs.c
new file mode 100644
index 000000000000..c836851d8397
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/lsm_kfuncs.c@@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <test_progs.h> +#include "lsm_kfuncs.skel.h" +#include "lsm_kfuncs_fail.skel.h" + +void test_lsm_kfuncs(void) +{ + LIBBPF_OPTS(bpf_test_run_opts, opts); + struct lsm_kfuncs *skel; + + RUN_TESTS(lsm_kfuncs_fail); + + skel = lsm_kfuncs__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_and_load")) + return; + if (!ASSERT_OK(lsm_kfuncs__attach(skel), "attach")) + goto out; + + if (!ASSERT_OK(bpf_prog_test_run_opts(bpf_program__fd(skel->progs.query), + &opts), "test_run")) + goto out; + ASSERT_EQ(skel->data->ret_clear, 0, "not locked down"); + ASSERT_EQ(skel->data->ret_denied, -EPERM, "locked down"); + ASSERT_EQ(skel->data->ret_invalid_low, -EINVAL, "LOCKDOWN_NONE invalid"); + ASSERT_EQ(skel->data->ret_invalid_high, -EINVAL, "CONFIDENTIALITY_MAX invalid"); +out: + lsm_kfuncs__destroy(skel); +}
diff --git a/tools/testing/selftests/bpf/progs/lsm_kfuncs.c b/tools/testing/selftests/bpf/progs/lsm_kfuncs.c
new file mode 100644
index 000000000000..2637b9bc9025
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/lsm_kfuncs.c@@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "vmlinux.h" +#include <errno.h> +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> + +char _license[] SEC("license") = "GPL"; + +extern int bpf_security_locked_down(enum lockdown_reason what) __ksym; + +/* Reason nothing in the test environment genuinely queries or locks. */ +#define DENY_REASON LOCKDOWN_HIBERNATION +#define ALLOW_REASON LOCKDOWN_KEXEC + +int ret_clear = 1; +int ret_denied = 1; +int ret_invalid_low = 1; +int ret_invalid_high = 1; + +SEC("lsm/locked_down") +int BPF_PROG(lockdown_hook, enum lockdown_reason what) +{ + return what == DENY_REASON ? -EPERM : 0; +} + +SEC("syscall") +int query(void *ctx) +{ + ret_clear = bpf_security_locked_down(ALLOW_REASON); + ret_denied = bpf_security_locked_down(DENY_REASON); + ret_invalid_low = bpf_security_locked_down(LOCKDOWN_NONE); + ret_invalid_high = bpf_security_locked_down(LOCKDOWN_CONFIDENTIALITY_MAX); + return 0; +}
diff --git a/tools/testing/selftests/bpf/progs/lsm_kfuncs_fail.c b/tools/testing/selftests/bpf/progs/lsm_kfuncs_fail.c
new file mode 100644
index 000000000000..b9861d9c4f16
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/lsm_kfuncs_fail.c@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include "bpf_misc.h" + +char _license[] SEC("license") = "GPL"; + +extern int bpf_security_locked_down(enum lockdown_reason what) __ksym; + +/* Tracing programs must be rejected by the kfunc filter. */ +SEC("fentry/bpf_fentry_test1") +__failure __msg("calling kernel function bpf_security_locked_down is not allowed") +int BPF_PROG(tracing_caller, int a) +{ + bpf_security_locked_down(LOCKDOWN_KEXEC); + return 0; +} + +/* As must locked_down programs, which would recurse into the dispatch. */ +SEC("lsm/locked_down") +__failure __msg("calling kernel function bpf_security_locked_down is not allowed") +int BPF_PROG(recursive_caller, enum lockdown_reason what) +{ + return bpf_security_locked_down(what); +}
--
2.54.0