Skip to content

Commit a24a2dd

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
selftests/bpf: trigger verifier.c:maybe_exit_scc() for a speculative state
This is a test case minimized from a syzbot reproducer from [1]. The test case triggers verifier.c:maybe_exit_scc() w/o preceding call to verifier.c:maybe_enter_scc() on a speculative symbolic execution path. Here is verifier log for the test case: Live regs before insn: 0: .......... (b7) r0 = 100 1 1: 0......... (7b) *(u64 *)(r10 -512) = r0 1 2: 0......... (b5) if r0 <= 0x0 goto pc-2 3: 0......... (95) exit 0: R1=ctx() R10=fp0 0: (b7) r0 = 100 ; R0_w=100 1: (7b) *(u64 *)(r10 -512) = r0 ; R0_w=100 R10=fp0 fp-512_w=100 2: (b5) if r0 <= 0x0 goto pc-2 mark_precise: ... 2: R0_w=100 3: (95) exit from 2 to 1 (speculative execution): R0_w=scalar() R1=ctx() R10=fp0 fp-512_w=100 1: R0_w=scalar() R1=ctx() R10=fp0 fp-512_w=100 1: (7b) *(u64 *)(r10 -512) = r0 processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 - Non-speculative execution path 0-3 does not allocate any checkpoints (and hence does not call maybe_enter_scc()), and schedules a speculative jump from 2 to 1. - Speculative execution path stops immediately because of an infinite loop detection and triggers verifier.c:update_branch_counts() -> maybe_exit_scc() calls. [1] https://lore.kernel.org/bpf/68c85acd.050a0220.2ff435.03a4.GAE@google.com/ Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20250916212251.3490455-2-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent a3c73d6 commit a24a2dd

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,25 @@ exit_%=: \
283283
: __clobber_all);
284284
}
285285

286+
/*
287+
* This test case triggered a bug in verifier.c:maybe_exit_scc().
288+
* Speculative execution path reaches stack access instruction,
289+
* stops and triggers maybe_exit_scc() w/o accompanying maybe_enter_scc() call.
290+
*/
291+
SEC("socket")
292+
__arch_x86_64
293+
__caps_unpriv(CAP_BPF)
294+
__naked void maybe_exit_scc_bug1(void)
295+
{
296+
asm volatile (
297+
"r0 = 100;"
298+
"1:"
299+
/* Speculative execution path reaches and stops here. */
300+
"*(u64 *)(r10 - 512) = r0;"
301+
/* Condition is always false, but verifier speculatively executes the true branch. */
302+
"if r0 <= 0x0 goto 1b;"
303+
"exit;"
304+
::: __clobber_all);
305+
}
306+
286307
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)