diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2026-04-16 15:20:27 -0700 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-04-16 15:20:32 -0700 |
| commit | 766bf026d0da242a329b402c436c8e4cfa2008d8 (patch) | |
| tree | ca17da98c05eba692344987c6712f9616e13ebdb | |
| parent | e5f635edd393aeaa7cad9e42831d397e6e2e1eed (diff) | |
| parent | fcd11ff8bd0e526bdd5f43f534ccf7c4e67245ad (diff) | |
| download | linux-766bf026d0da242a329b402c436c8e4cfa2008d8.tar.gz linux-766bf026d0da242a329b402c436c8e4cfa2008d8.zip | |
Merge branch 'bpf-fix-null-deref-when-storing-scalar-into-kptr-slot'
Mykyta Yatsenko says:
====================
bpf: Fix NULL deref when storing scalar into kptr slot
map_kptr_match_type() accesses reg->btf before confirming the register
is PTR_TO_BTF_ID. A scalar store into a kptr slot has no btf, causing
a NULL pointer dereference. Guard base_type() first.
Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
====================
Link: https://patch.msgid.link/20260416-kptr_crash-v1-0-5589356584b4@meta.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
| -rw-r--r-- | kernel/bpf/verifier.c | 5 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/progs/map_kptr_fail.c | 15 |
2 files changed, 19 insertions, 1 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1e36b9e91277..69d75515ed3f 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4549,6 +4549,9 @@ static int map_kptr_match_type(struct bpf_verifier_env *env, int perm_flags; const char *reg_name = ""; + if (base_type(reg->type) != PTR_TO_BTF_ID) + goto bad_type; + if (btf_is_kernel(reg->btf)) { perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU; @@ -4561,7 +4564,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env, perm_flags |= MEM_PERCPU; } - if (base_type(reg->type) != PTR_TO_BTF_ID || (type_flag(reg->type) & ~perm_flags)) + if (type_flag(reg->type) & ~perm_flags) goto bad_type; /* We need to verify reg->type and reg->btf, before accessing reg->btf */ diff --git a/tools/testing/selftests/bpf/progs/map_kptr_fail.c b/tools/testing/selftests/bpf/progs/map_kptr_fail.c index 6443b320c732..ee053b24e6ca 100644 --- a/tools/testing/selftests/bpf/progs/map_kptr_fail.c +++ b/tools/testing/selftests/bpf/progs/map_kptr_fail.c @@ -385,4 +385,19 @@ int kptr_xchg_possibly_null(struct __sk_buff *ctx) return 0; } +SEC("?tc") +__failure __msg("invalid kptr access, R") +int reject_scalar_store_to_kptr(struct __sk_buff *ctx) +{ + struct map_value *v; + int key = 0; + + v = bpf_map_lookup_elem(&array_map, &key); + if (!v) + return 0; + + *(volatile u64 *)&v->unref_ptr = 0xBADC0DE; + return 0; +} + char _license[] SEC("license") = "GPL"; |
