selftests/bpf: No non-NULL inference from an imprecise zero register

Check that a register-form NULL check does not lift PTR_MAYBE_NULL on
a path where the compared register is non-zero. W/o the previous patch
the program is accepted.

Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-8-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
Eduard Zingerman 2026-09-04 01:33:25 -07:00 committed by Kumar Kartikeya Dwivedi
parent 6aed0134d3
commit 6b31560c6b
No known key found for this signature in database
GPG Key ID: 472D377B63542F83

View File

@ -418,6 +418,40 @@ __naked void jmp32_ptr_vs_zero_jne(void)
: __clobber_all);
}
/*
* The below program is explored in two paths: r6 == 0 and r6 == 1.
* On the first path comparison "if r0 == r6 goto 2f" should mark r6 as precise,
* otherwise unsafe path with r6 == 1 would be incorrectly pruned.
*/
SEC("socket")
__failure
__flag(BPF_F_TEST_STATE_FREQ)
__msg("error: invalid dereference of R0 (a nullable map value pointer)")
__naked void imprecise_zero_does_not_infer_map_value_non_null(void)
{
asm volatile (" \
call %[bpf_get_prandom_u32]; \
/* r6 is 0 on the path explored first, 1 on the other */\
r6 = 1; \
if r0 == 0 goto 1f; \
r6 = 0; \
/* r0 = bpf_map_lookup_elem(map_hash, &0); */ \
1: *(u64 *)(r10 - 8) = 0; \
r1 = %[map_hash] ll; \
r2 = r10; \
r2 += -8; \
call %[bpf_map_lookup_elem]; \
if r0 == r6 goto 2f; \
r0 = *(u8 *)(r0 + 0); \
2: r0 = 0; \
exit; \
" :
: __imm(bpf_get_prandom_u32),
__imm(bpf_map_lookup_elem),
__imm_addr(map_hash)
: __clobber_all);
}
void kfunc_root(void)
{
bpf_rdonly_cast(0, 0);