Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Add selftest for may_goto

Added test cases to ensure that programs with stack sizes exceeding 512
bytes are restricted in non-JITed mode, and can be executed normally in
JITed mode, even with stack sizes exceeding 512 bytes due to the presence
of may_goto instructions.

Test result:
echo "0" > /proc/sys/net/core/bpf_jit_enable
./test_progs -t verifier_stack_ptr
...
stack size 512 with may_goto with jit:SKIP
stack size 512 with may_goto without jit:OK
...
Summary: 1/27 PASSED, 25 SKIPPED, 0 FAILED

echo "1" > /proc/sys/net/core/bpf_jit_enable
./test_progs -t verifier_stack_ptr
...
stack size 512 with may_goto with jit:OK
stack size 512 with may_goto without jit:SKIP
...
Summary: 1/27 PASSED, 25 SKIPPED, 0 FAILED

Signed-off-by: Jiayuan Chen <mrpre@163.com>
Link: https://lore.kernel.org/r/20250214091823.46042-4-mrpre@163.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Jiayuan Chen and committed by
Alexei Starovoitov
72266ee8 b38c72ab

+52
+52
tools/testing/selftests/bpf/progs/verifier_stack_ptr.c
··· 481 481 : __clobber_all); 482 482 } 483 483 484 + SEC("socket") 485 + __description("PTR_TO_STACK stack size > 512") 486 + __failure __msg("invalid write to stack R1 off=-520 size=8") 487 + __naked void stack_check_size_gt_512(void) 488 + { 489 + asm volatile (" \ 490 + r1 = r10; \ 491 + r1 += -520; \ 492 + r0 = 42; \ 493 + *(u64*)(r1 + 0) = r0; \ 494 + exit; \ 495 + " ::: __clobber_all); 496 + } 497 + 498 + #ifdef __BPF_FEATURE_MAY_GOTO 499 + SEC("socket") 500 + __description("PTR_TO_STACK stack size 512 with may_goto with jit") 501 + __load_if_JITed() 502 + __success __retval(42) 503 + __naked void stack_check_size_512_with_may_goto_jit(void) 504 + { 505 + asm volatile (" \ 506 + r1 = r10; \ 507 + r1 += -512; \ 508 + r0 = 42; \ 509 + *(u32*)(r1 + 0) = r0; \ 510 + may_goto l0_%=; \ 511 + r2 = 100; \ 512 + l0_%=: \ 513 + exit; \ 514 + " ::: __clobber_all); 515 + } 516 + 517 + SEC("socket") 518 + __description("PTR_TO_STACK stack size 512 with may_goto without jit") 519 + __load_if_no_JITed() 520 + __failure __msg("stack size 520(extra 8) is too large") 521 + __naked void stack_check_size_512_with_may_goto(void) 522 + { 523 + asm volatile (" \ 524 + r1 = r10; \ 525 + r1 += -512; \ 526 + r0 = 42; \ 527 + *(u32*)(r1 + 0) = r0; \ 528 + may_goto l0_%=; \ 529 + r2 = 100; \ 530 + l0_%=: \ 531 + exit; \ 532 + " ::: __clobber_all); 533 + } 534 + #endif 535 + 484 536 char _license[] SEC("license") = "GPL";