mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 03:59:40 +02:00
selftests/bpf: new cases handled by 32->64 range refinements
1. 32-bit range starts before 64-bit range's low bits in each block, causing intersection to skip entire blocks. 2. 32-bit range crosses the U32_MAX/0 boundary, represented as s32 range crossing sign boundary. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260424-cnums-everywhere-rfc-v1-v3-4-ca434b39a486@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
bbc6310855
commit
4c0710ab01
|
|
@ -2187,4 +2187,84 @@ __naked void tnums_equal_impossible_constant(void *ctx)
|
|||
: __clobber_all);
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit range starts before 64-bit range low bits in each 2^32 block.
|
||||
*
|
||||
* N*2^32 (N+1)*2^32 (N+2)*2^32 (N+3)*2^32
|
||||
* ||----|=====|--|----------||----|=====|-------------||--|-|=====|-------------||
|
||||
* |< b >| | |< b >| | |< b >|
|
||||
* | | | |
|
||||
* |<---------------+- a -+---------------->|
|
||||
* | |
|
||||
* |< t >| refined r0 range
|
||||
*
|
||||
* a = u64 [0x1'00000008, 0x3'00000001]
|
||||
* b = u32 [2, 5]
|
||||
* t = u64 [0x2'00000002, 0x2'00000005]
|
||||
*/
|
||||
SEC("socket")
|
||||
__success
|
||||
__flag(BPF_F_TEST_REG_INVARIANTS)
|
||||
__naked void deduce64_from_32_before_block_start(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r1 = 0x100000008 ll; \
|
||||
if r0 < r1 goto 2f; \
|
||||
r1 = 0x300000001 ll; \
|
||||
if r0 > r1 goto 2f; /* u64: [0x1'00000008, 0x3'00000001] */ \
|
||||
if w0 < 2 goto 2f; \
|
||||
if w0 > 5 goto 2f; /* u32: [2, 5] */ \
|
||||
r2 = 0x200000002 ll; \
|
||||
r3 = 0x200000005 ll; \
|
||||
if r0 >= r2 goto 1f; /* should be always true */ \
|
||||
r10 = 0; /* dead code */ \
|
||||
1: if r0 <= r3 goto 2f; /* should be always true */ \
|
||||
r10 = 0; /* dead code */ \
|
||||
2: exit; \
|
||||
"
|
||||
:: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit range crossing U32_MAX / 0 boundary.
|
||||
*
|
||||
* N*2^32 (N+1)*2^32 (N+2)*2^32 (N+3)*2^32
|
||||
* ||===|---------|------|===||===|----------------|===||===|---------|------|===||
|
||||
* |b >| | |< b||b >| |< b||b >| | |< b|
|
||||
* | | | |
|
||||
* |<-----+----------------- a --------------+-------->|
|
||||
* | |
|
||||
* |<---------------- t ------------->| refined r0 range
|
||||
*
|
||||
* a = u64 [0x1'00000006, 0x2'FFFFFFEF]
|
||||
* b = s32 [-16, 5] (u32 wrapping [0xFFFFFFF0, 0x00000005])
|
||||
* t = u64 [0x1'FFFFFFF0, 0x2'00000005]
|
||||
*/
|
||||
SEC("socket")
|
||||
__success
|
||||
__flag(BPF_F_TEST_REG_INVARIANTS)
|
||||
__naked void deduce64_from_32_wrapping_32bit(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r1 = 0x100000006 ll; \
|
||||
if r0 < r1 goto 2f; \
|
||||
r1 = 0x2ffffffef ll; \
|
||||
if r0 > r1 goto 2f; /* u64: [0x1'00000006, 0x2'FFFFFFEF] */ \
|
||||
if w0 s< -16 goto 2f; \
|
||||
if w0 s> 5 goto 2f; /* s32: [-16, 5] */ \
|
||||
r1 = 0x1fffffff0 ll; \
|
||||
r2 = 0x200000005 ll; \
|
||||
if r0 >= r1 goto 1f; /* should be always true */ \
|
||||
r10 = 0; /* dead code */ \
|
||||
1: if r0 <= r2 goto 2f; /* should be always true */ \
|
||||
r10 = 0; /* dead code */ \
|
||||
2: exit; \
|
||||
"
|
||||
:: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user