Skip to content

Commit 62ccdb1

Browse files
anakryikoAlexei Starovoitov
authored and
Alexei Starovoitov
committed
selftests/bpf: add edge case backtracking logic test
Add a dedicated selftests to try to set up conditions to have a state with same first and last instruction index, but it actually is a loop 3->4->1->2->3. This confuses mark_chain_precision() if verifier doesn't take into account jump history. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20231110002638.4168352-4-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 4bb7ea9 commit 62ccdb1

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,43 @@ __naked int bpf_end_bswap(void)
9191
}
9292

9393
#endif /* v4 instruction */
94+
95+
SEC("?raw_tp")
96+
__success __log_level(2)
97+
/*
98+
* Without the bug fix there will be no history between "last_idx 3 first_idx 3"
99+
* and "parent state regs=" lines. "R0_w=6" parts are here to help anchor
100+
* expected log messages to the one specific mark_chain_precision operation.
101+
*
102+
* This is quite fragile: if verifier checkpointing heuristic changes, this
103+
* might need adjusting.
104+
*/
105+
__msg("2: (07) r0 += 1 ; R0_w=6")
106+
__msg("3: (35) if r0 >= 0xa goto pc+1")
107+
__msg("mark_precise: frame0: last_idx 3 first_idx 3 subseq_idx -1")
108+
__msg("mark_precise: frame0: regs=r0 stack= before 2: (07) r0 += 1")
109+
__msg("mark_precise: frame0: regs=r0 stack= before 1: (07) r0 += 1")
110+
__msg("mark_precise: frame0: regs=r0 stack= before 4: (05) goto pc-4")
111+
__msg("mark_precise: frame0: regs=r0 stack= before 3: (35) if r0 >= 0xa goto pc+1")
112+
__msg("mark_precise: frame0: parent state regs= stack=: R0_rw=P4")
113+
__msg("3: R0_w=6")
114+
__naked int state_loop_first_last_equal(void)
115+
{
116+
asm volatile (
117+
"r0 = 0;"
118+
"l0_%=:"
119+
"r0 += 1;"
120+
"r0 += 1;"
121+
/* every few iterations we'll have a checkpoint here with
122+
* first_idx == last_idx, potentially confusing precision
123+
* backtracking logic
124+
*/
125+
"if r0 >= 10 goto l1_%=;" /* checkpoint + mark_precise */
126+
"goto l0_%=;"
127+
"l1_%=:"
128+
"exit;"
129+
::: __clobber_common
130+
);
131+
}
132+
133+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)