selftests/bpf: Add a test case for 32-bit spill tracking

When a range check is performed on a register that was 32-bit spilled to
the stack, the IDs of the two instances of the register are the same, so
the range should also be the same.

Signed-off-by: Maxim Mikityanskiy <maxim@isovalent.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20240108205209.838365-6-maxtram95@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Maxim Mikityanskiy 2024-01-08 22:51:59 +02:00 committed by Alexei Starovoitov
parent 32f55dd4ad
commit b827eee4c4

View file

@ -735,4 +735,35 @@ __naked void stack_load_preserves_const_precision_subreg(void)
: __clobber_common);
}
SEC("xdp")
__description("32-bit spilled reg range should be tracked")
__success __retval(0)
__naked void spill_32bit_range_track(void)
{
asm volatile(" \
call %[bpf_ktime_get_ns]; \
/* Make r0 bounded. */ \
r0 &= 65535; \
/* Assign an ID to r0. */ \
r1 = r0; \
/* 32-bit spill r0 to stack. */ \
*(u32*)(r10 - 8) = r0; \
/* Boundary check on r0. */ \
if r0 < 1 goto l0_%=; \
/* 32-bit fill r1 from stack. */ \
r1 = *(u32*)(r10 - 8); \
/* r1 == r0 => r1 >= 1 always. */ \
if r1 >= 1 goto l0_%=; \
/* Dead branch: the verifier should prune it. \
* Do an invalid memory access if the verifier \
* follows it. \
*/ \
r0 = *(u64*)(r9 + 0); \
l0_%=: r0 = 0; \
exit; \
" :
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
char _license[] SEC("license") = "GPL";