mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
selftests/bpf: Add test for add_const base_id consistency
Add a test to verifier_linked_scalars that exercises the base_id consistency check for BPF_ADD_CONST linked scalars during state pruning. With the fix, pruning fails and the verifier discovers the true branch's R3 is too wide for the stack access. # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_linked_scalars [...] #613/22 verifier_linked_scalars/scalars_stale_delta_from_cleared_id:OK #613/23 verifier_linked_scalars/scalars_stale_delta_from_cleared_id_alu32:OK #613/24 verifier_linked_scalars/linked scalars: add_const base_id must be consistent for pruning:OK #613 verifier_linked_scalars:OK Summary: 1/24 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20260410232651.559778-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
2f2ec8e773
commit
497fa510ee
|
|
@ -647,4 +647,67 @@ l_exit_%=: \
|
|||
: __clobber_all);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that regsafe() verifies base_id consistency for BPF_ADD_CONST
|
||||
* linked scalars during state pruning.
|
||||
*
|
||||
* The false branch (explored first) links R3 to R2 via ADD_CONST.
|
||||
* The true branch (runtime path) links R3 to R4 (unrelated base_id).
|
||||
* At the merge point, pruning must fail because the linkage topology
|
||||
* differs.
|
||||
*/
|
||||
SEC("socket")
|
||||
__description("linked scalars: add_const base_id must be consistent for pruning")
|
||||
__failure __msg("invalid variable-offset")
|
||||
__flag(BPF_F_TEST_STATE_FREQ)
|
||||
__naked void add_const_base_id_pruning(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u64*)(r10 - 16) = r1; \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r6 = r0; \
|
||||
r6 &= 1; \
|
||||
if r6 >= 1 goto l_true_%=; \
|
||||
\
|
||||
/* False branch (explored first, old state) */ \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r2 = r0; \
|
||||
r2 &= 0xff; /* R2 = scalar(id=A) [0,255] */ \
|
||||
r3 = r2; /* R3 linked to R2 (id=A) */ \
|
||||
r3 += 10; /* R3 id=A|ADD_CONST, delta=10 */\
|
||||
r6 = 0; \
|
||||
goto l_merge_%=; \
|
||||
\
|
||||
l_true_%=: \
|
||||
/* True branch (runtime path, cur state) */ \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r2 = r0; \
|
||||
r2 &= 0xff; /* R2 = scalar [0,255], id=0 */ \
|
||||
r4 = r0; \
|
||||
r4 &= 0xff; /* R4 = scalar [0,255], id=0 */ \
|
||||
r3 = r4; /* R3 linked to R4 (new id=C) */\
|
||||
r3 += 10; /* R3 id=C|ADD_CONST, delta=10 */\
|
||||
r6 = 0; \
|
||||
\
|
||||
l_merge_%=: \
|
||||
/* At merge, old R3 linked to R2, cur R3 linked to R4. */\
|
||||
/* Pruning must fail: base_ids A vs C inconsistent. */ \
|
||||
if r2 >= 6 goto l_exit_%=; \
|
||||
/* sync_linked_regs: R2<6 => R3<16 in old state. */ \
|
||||
/* Without fix: R3 in [10,15] from incorrect pruning. */\
|
||||
/* With fix: R3 in [10,265], not synced from R2. */ \
|
||||
r3 -= 10; /* [0,5] vs [0,255] */ \
|
||||
r9 = r10; \
|
||||
r9 += -16; \
|
||||
r9 += r3; /* fp-16+[0,5] vs fp-16+[0,255] */\
|
||||
*(u8*)(r9 + 0) = r6; /* within 16B vs past fp */ \
|
||||
l_exit_%=: \
|
||||
r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user