From: Justin Suess <utilityemal77@gmail.com>
To: Alexei Starovoitov <ast@kernel.org>,
Paul Moore <paul@paul-moore.com>,
Xiu Jianfeng <xiujianfeng@huawei.com>
Cc: linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org, bpf@vger.kernel.org,
Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH bpf-next 1/2] lsm: add bpf_security_locked_down() kfunc
Date: Sat, 15 Aug 2026 07:20:40 -0400 [thread overview]
Message-ID: <20260815112041.1248855-2-utilityemal77@gmail.com> (raw)
In-Reply-To: <20260815112041.1248855-1-utilityemal77@gmail.com>
Add a new kfunc bpf_security_locked_down, which calls
security_locked_down and returns the result.
Create a new file security/lsm_kfuncs.c for LSM framework kfuncs.
Reject reasons outside (LOCKDOWN_NONE, LOCKDOWN_CONFIDENTIALITY_MAX)
with -EINVAL before dispatching the hook. Limit the kfunc to
BPF_PROG_TYPE_LSM and BPF_PROG_TYPE_SYSCALL programs, and refuse it
to programs attached to the locked_down hook itself, which would
recurse into the dispatch.
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---
security/Makefile | 1 +
security/lsm_kfuncs.c | 84 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 security/lsm_kfuncs.c
diff --git a/security/Makefile b/security/Makefile
index 4601230ba442..dee8ff218548 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_MMU) += min_addr.o
# Object file lists
obj-$(CONFIG_SECURITY) += security.o lsm_notifier.o lsm_init.o
+obj-$(CONFIG_BPF_SYSCALL) += lsm_kfuncs.o
obj-$(CONFIG_SECURITYFS) += inode.o
obj-$(CONFIG_SECURITY_SELINUX) += selinux/
obj-$(CONFIG_SECURITY_SMACK) += smack/
diff --git a/security/lsm_kfuncs.c b/security/lsm_kfuncs.c
new file mode 100644
index 000000000000..a324e7d978ca
--- /dev/null
+++ b/security/lsm_kfuncs.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * kfuncs exposing LSM interfaces to BPF programs.
+ *
+ * Copyright (C) 2026 Justin Suess
+ */
+#include <linux/bpf.h>
+#include <linux/btf.h>
+#include <linux/btf_ids.h>
+#include <linux/init.h>
+#include <linux/security.h>
+
+__bpf_kfunc_start_defs();
+
+/**
+ * bpf_security_locked_down - Call the security_locked_down() LSM hook
+ * @what: lockdown reason to query
+ *
+ * Return: 0 if @what is not locked down, -EPERM if it is, or -EINVAL if
+ * @what is outside (LOCKDOWN_NONE, LOCKDOWN_CONFIDENTIALITY_MAX).
+ */
+__bpf_kfunc int bpf_security_locked_down(enum lockdown_reason what)
+{
+ if (what <= LOCKDOWN_NONE || what >= LOCKDOWN_CONFIDENTIALITY_MAX)
+ return -EINVAL;
+ return security_locked_down(what);
+}
+
+__bpf_kfunc_end_defs();
+
+BTF_KFUNCS_START(lsm_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_security_locked_down)
+BTF_KFUNCS_END(lsm_kfunc_ids)
+
+#ifdef CONFIG_BPF_LSM
+BTF_ID_LIST_SINGLE(lsm_locked_down_hook_id, func, bpf_lsm_locked_down)
+#endif
+
+static int lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
+{
+ /* Filters run for every kfunc resolved through the hook. */
+ if (!btf_id_set8_contains(&lsm_kfunc_ids, kfunc_id))
+ return 0;
+
+ /*
+ * Raw prog->type: keep out the rest of the shared tracing kfunc
+ * set (incl. perf/NMI) and extension programs.
+ */
+ switch (prog->type) {
+ case BPF_PROG_TYPE_SYSCALL:
+ return 0;
+#ifdef CONFIG_BPF_LSM
+ case BPF_PROG_TYPE_LSM:
+ /*
+ * A locked_down program calling this kfunc would recurse.
+ * Match on attach_btf_id: attach_func_name is not yet set
+ * when the filter runs from check_cfg.
+ */
+ if (prog->aux->attach_btf_id == lsm_locked_down_hook_id[0])
+ return -EACCES;
+ return 0;
+#endif
+ default:
+ return -EACCES;
+ }
+}
+
+static const struct btf_kfunc_id_set lsm_kfunc_set = {
+ .owner = THIS_MODULE,
+ .set = &lsm_kfunc_ids,
+ .filter = lsm_kfunc_filter,
+};
+
+static int __init lsm_kfuncs_init(void)
+{
+ int err;
+
+ err = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &lsm_kfunc_set);
+ err = err ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &lsm_kfunc_set);
+ if (err)
+ pr_warn("lsm_kfuncs: kfunc registration failed: %d\n", err);
+ return err;
+}
+late_initcall(lsm_kfuncs_init);
--
2.54.0
next prev parent reply other threads:[~2026-08-15 11:20 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-15 11:20 [PATCH bpf-next 0/2] lsm: give BPF programs a way to query locked_down state Justin Suess
2026-08-15 11:20 ` Justin Suess [this message]
2026-08-15 12:19 ` [PATCH bpf-next 1/2] lsm: add bpf_security_locked_down() kfunc bot+bpf-ci
2026-08-15 11:20 ` [PATCH bpf-next 2/2] selftests/bpf: Test bpf_security_locked_down kfunc Justin Suess
2026-08-15 12:19 ` bot+bpf-ci
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260815112041.1248855-2-utilityemal77@gmail.com \
--to=utilityemal77@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=xiujianfeng@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).