[PATCH bpf-next 01/13] bpf: expose signature verdict to LSMs via bpf_prog_aux
KP Singh
kpsingh at kernel.org
Fri May 22 02:32:21 UTC 2026
BPF_PROG_LOAD verifies the loader signature but does not record the
outcome on the prog. LSMs and audit can read attr->signature and
attr->keyring_id to infer "was this signed, against which keyring",
but there is no canonical state for "loader signature + map content
verified". Only the in-kernel kfunc can confirm the latter.
Add prog->aux->sig (verdict + keyring) and prog->aux->is_kernel,
populated by bpf_prog_load before the LSM hook. Failed verifications
reject the load before the hook runs, so it observes only UNSIGNED
or OK. The bpf_loader_verify_metadata kfunc promotes to
METADATA_VERIFIED later.
Signed-off-by: KP Singh <kpsingh at kernel.org>
---
include/linux/bpf.h | 19 +++++++++++++++++++
kernel/bpf/syscall.c | 20 ++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 11bec73db199..14f65259f414 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1656,6 +1656,20 @@ struct bpf_stream_stage {
int len;
};
+enum bpf_sig_verdict {
+ BPF_SIG_UNSIGNED = 0,
+ BPF_SIG_OK, /* loader signature verified */
+ BPF_SIG_METADATA_VERIFIED, /* loader signature + map content verified */
+};
+
+enum bpf_sig_keyring {
+ BPF_SIG_KEYRING_NONE = 0,
+ BPF_SIG_KEYRING_BUILTIN,
+ BPF_SIG_KEYRING_SECONDARY,
+ BPF_SIG_KEYRING_PLATFORM,
+ BPF_SIG_KEYRING_USER,
+};
+
struct bpf_prog_aux {
atomic64_t refcnt;
u32 used_map_cnt;
@@ -1698,6 +1712,11 @@ struct bpf_prog_aux {
bool changes_pkt_data;
bool might_sleep;
bool kprobe_write_ctx;
+ struct {
+ u8 verdict;
+ u8 keyring;
+ } sig;
+ bool is_kernel;
u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
struct bpf_arena *arena;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 630d530782fe..51fe8d77bb39 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2798,6 +2798,20 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
}
}
+static enum bpf_sig_keyring bpf_classify_keyring(s32 keyring_id)
+{
+ switch (keyring_id) {
+ case 0:
+ return BPF_SIG_KEYRING_BUILTIN;
+ case (s32)(unsigned long)VERIFY_USE_SECONDARY_KEYRING:
+ return BPF_SIG_KEYRING_SECONDARY;
+ case (s32)(unsigned long)VERIFY_USE_PLATFORM_KEYRING:
+ return BPF_SIG_KEYRING_PLATFORM;
+ default:
+ return BPF_SIG_KEYRING_USER;
+ }
+}
+
static int bpf_prog_verify_signature(struct bpf_prog *prog, union bpf_attr *attr,
bool is_kernel)
{
@@ -3027,7 +3041,13 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
err = bpf_prog_verify_signature(prog, attr, uattr.is_kernel);
if (err)
goto free_prog;
+ prog->aux->sig.verdict = BPF_SIG_OK;
+ prog->aux->sig.keyring = bpf_classify_keyring(attr->keyring_id);
+ } else {
+ prog->aux->sig.verdict = BPF_SIG_UNSIGNED;
+ prog->aux->sig.keyring = BPF_SIG_KEYRING_NONE;
}
+ prog->aux->is_kernel = uattr.is_kernel;
prog->orig_prog = NULL;
prog->jited = 0;
--
2.53.0
More information about the Linux-security-module-archive
mailing list