summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorMatt Bobrowski <mattbobrowski@google.com>2026-06-28 20:11:03 +0000
committerDaniel Borkmann <daniel@iogearbox.net>2026-06-30 16:31:56 +0200
commita6f0643e4f63cfaa0d5d4a69de4f132eac4b8fe4 (patch)
treefab0413526fad744beee6f4b72df2ef6eb6296be /security
parent9b51a6155d14389876916726430da30eabb1d4ed (diff)
downloadlinux-2.6-a6f0643e4f63cfaa0d5d4a69de4f132eac4b8fe4.tar.gz
linux-2.6-a6f0643e4f63cfaa0d5d4a69de4f132eac4b8fe4.zip
bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized
When CONFIG_BPF_LSM=y is set, BPF inode storage maps (BPF_MAP_TYPE_INODE_STORAGE) are compiled into the kernel. However, if the BPF LSM is not explicitly enabled at boot time (e.g. omitted from the "lsm=" boot parameter), lsm_prepare() is never executed for the BPF LSM. Consequently, the BPF inode security blob offset (bpf_lsm_blob_sizes.lbs_inode) is never initialized and remains at its default compiled size of 8 bytes instead of being updated to a valid offset past the reserved struct rcu_head (typically 16 bytes or more). When a privileged user creates and updates a BPF_MAP_TYPE_INODE_STORAGE map, bpf_inode() evaluates inode->i_security + 8. This erroneously aliases the struct rcu_head.func callback pointer at the beginning of the inode->i_security blob. During subsequent map element cleanup or inode destruction, writing NULL to owner_storage clears the queued RCU callback pointer. When rcu_do_batch() later executes the queued callback, it attempts an instruction fetch at address 0x0, triggering an immediate kernel panic. Fix this by introducing a global bpf_lsm_initialized boolean flag marked with __ro_after_init. Set this flag to true inside bpf_lsm_init() when the LSM framework successfully registers the BPF LSM. Gate map allocation in inode_storage_map_alloc() on this flag, returning -EOPNOTSUPP if the BPF LSM is in turn uninitialized. This fail-fast approach prevents userspace from allocating inode storage maps when the supporting BPF LSM infrastructure is absent, avoiding zombie map states. Fixes: 8ea636848aca ("bpf: Implement bpf_local_storage for inodes") Reported-by: oxsignal <awo@kakao.com> Signed-off-by: Matt Bobrowski <mattbobrowski@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Reviewed-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/bpf/20260628201103.3624525-1-mattbobrowski@google.com
Diffstat (limited to 'security')
-rw-r--r--security/bpf/hooks.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
index 40efde233f3a..7b98f5d1e2be 100644
--- a/security/bpf/hooks.c
+++ b/security/bpf/hooks.c
@@ -7,6 +7,8 @@
#include <linux/bpf_lsm.h>
#include <uapi/linux/lsm.h>
+bool bpf_lsm_initialized __ro_after_init;
+
static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = {
#define LSM_HOOK(RET, DEFAULT, NAME, ...) \
LSM_HOOK_INIT(NAME, bpf_lsm_##NAME),
@@ -24,6 +26,7 @@ static int __init bpf_lsm_init(void)
{
security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks),
&bpf_lsmid);
+ bpf_lsm_initialized = true;
pr_info("LSM support for eBPF active\n");
return 0;
}