Skip to content

Commit 766bf02

Browse files
author
Alexei Starovoitov
committed
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>
2 parents e5f635e + fcd11ff commit 766bf02

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

kernel/bpf/verifier.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4549,6 +4549,9 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
45494549
int perm_flags;
45504550
const char *reg_name = "";
45514551

4552+
if (base_type(reg->type) != PTR_TO_BTF_ID)
4553+
goto bad_type;
4554+
45524555
if (btf_is_kernel(reg->btf)) {
45534556
perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU;
45544557

@@ -4561,7 +4564,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
45614564
perm_flags |= MEM_PERCPU;
45624565
}
45634566

4564-
if (base_type(reg->type) != PTR_TO_BTF_ID || (type_flag(reg->type) & ~perm_flags))
4567+
if (type_flag(reg->type) & ~perm_flags)
45654568
goto bad_type;
45664569

45674570
/* We need to verify reg->type and reg->btf, before accessing reg->btf */

tools/testing/selftests/bpf/progs/map_kptr_fail.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,19 @@ int kptr_xchg_possibly_null(struct __sk_buff *ctx)
385385
return 0;
386386
}
387387

388+
SEC("?tc")
389+
__failure __msg("invalid kptr access, R")
390+
int reject_scalar_store_to_kptr(struct __sk_buff *ctx)
391+
{
392+
struct map_value *v;
393+
int key = 0;
394+
395+
v = bpf_map_lookup_elem(&array_map, &key);
396+
if (!v)
397+
return 0;
398+
399+
*(volatile u64 *)&v->unref_ptr = 0xBADC0DE;
400+
return 0;
401+
}
402+
388403
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)