[PATCH bpf-next 07/13] bpf: Add the LSM policy kfunc infrastructure

Justin Suess utilityemal77 at gmail.com
Fri Jul 31 02:20:40 UTC 2026


Prepare kernel/bpf/bpf_lsm.c to host kfuncs that let BPF programs
apply a userspace-created Landlock ruleset to an execution. The
kfuncs will be thin front ends to the generic LSM policy kptr hooks
(security_policy_kptr_from_fd(), security_policy_kptr_put(),
security_bprm_enforce_policy_kptr()), invoked with LSM_ID_LANDLOCK
so that the LSM framework's targeted dispatch only ever reaches
Landlock's hook implementations.

Because of the hook indirection, kernel/bpf/ has no build-time
dependency on Landlock: the kfuncs are registered whenever
CONFIG_BPF_LSM is enabled, and calling them while Landlock is
compiled out or not enabled in the LSM order fails at runtime with
-EOPNOTSUPP through the dispatch miss, keeping BPF program loading
independent of the boot-time LSM configuration.

Add the section hosting the kfuncs: struct bpf_landlock_ruleset, the
opaque BTF-typed handle for a Landlock ruleset that only Landlock
resolves; the kfunc id set, registered for both BPF_PROG_TYPE_LSM and
BPF_PROG_TYPE_SYSCALL; and the kfunc filter.  The two program types
share their kfunc lookup buckets with other program types, so
restricting the kfuncs to them requires a filter.  The set starts
empty and the filter has no per-kfunc rules yet; the following
patches add the kfuncs together with their filter rules.

Signed-off-by: Justin Suess <utilityemal77 at gmail.com>
---

Notes:
    I decided to put the kfunc implementations in kernel/bpf to better
    delineate the separation between the BPF facing interface and the
    LSM framework. Since this file contains things like the BPF contexts
    the kfuncs are allowed to be called from, it's important for BPF to
    control that aspect.
    
    I'm open to moving it if there is a better preferred location for
    these under kernel/bpf/ other than kernel/bpf/bpf_lsm.c.

 kernel/bpf/bpf_lsm.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
index d847a180489f..dd58c5bd0119 100644
--- a/kernel/bpf/bpf_lsm.c
+++ b/kernel/bpf/bpf_lsm.c
@@ -473,3 +473,53 @@ int bpf_lsm_get_retval_range(const struct bpf_prog *prog,
 	}
 	return 0;
 }
+
+/* LSM policy kfuncs */
+
+/*
+ * Opaque handle for a Landlock ruleset.  Only Landlock resolves it.
+ */
+struct bpf_landlock_ruleset {};
+
+BTF_KFUNCS_START(bpf_landlock_kfunc_ids)
+BTF_KFUNCS_END(bpf_landlock_kfunc_ids)
+
+/*
+ * BPF_PROG_TYPE_LSM and BPF_PROG_TYPE_SYSCALL share their kfunc
+ * lookup buckets with other program types, so restricting the LSM
+ * policy kfuncs requires a filter.
+ */
+static int bpf_landlock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
+{
+	if (!btf_id_set8_contains(&bpf_landlock_kfunc_ids, kfunc_id))
+		return 0;
+
+	switch (prog->type) {
+	case BPF_PROG_TYPE_SYSCALL:
+		return 0;
+	case BPF_PROG_TYPE_LSM:
+		return 0;
+	default:
+		return -EACCES;
+	}
+}
+
+static const struct btf_kfunc_id_set bpf_landlock_kfunc_set = {
+	.owner = THIS_MODULE,
+	.set = &bpf_landlock_kfunc_ids,
+	.filter = bpf_landlock_kfunc_filter,
+};
+
+static int __init bpf_lsm_policy_kfunc_init(void)
+{
+	int ret;
+
+	ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM,
+					&bpf_landlock_kfunc_set);
+	if (ret)
+		return ret;
+
+	return register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL,
+					&bpf_landlock_kfunc_set);
+}
+late_initcall(bpf_lsm_policy_kfunc_init);
-- 
2.54.0




More information about the Linux-security-module-archive mailing list