diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c index c375e59ff28da..6eec6a9463c8e 100644 --- a/tools/testing/selftests/bpf/prog_tests/verifier.c +++ b/tools/testing/selftests/bpf/prog_tests/verifier.c @@ -31,6 +31,7 @@ #include "verifier_int_ptr.skel.h" #include "verifier_jeq_infer_not_null.skel.h" #include "verifier_ld_ind.skel.h" +#include "verifier_ldsx.skel.h" #include "verifier_leak_ptr.skel.h" #include "verifier_loops1.skel.h" #include "verifier_lwt.skel.h" @@ -133,6 +134,7 @@ void test_verifier_helper_value_access(void) { RUN(verifier_helper_value_access void test_verifier_int_ptr(void) { RUN(verifier_int_ptr); } void test_verifier_jeq_infer_not_null(void) { RUN(verifier_jeq_infer_not_null); } void test_verifier_ld_ind(void) { RUN(verifier_ld_ind); } +void test_verifier_ldsx(void) { RUN(verifier_ldsx); } void test_verifier_leak_ptr(void) { RUN(verifier_leak_ptr); } void test_verifier_loops1(void) { RUN(verifier_loops1); } void test_verifier_lwt(void) { RUN(verifier_lwt); } diff --git a/tools/testing/selftests/bpf/progs/verifier_ldsx.c b/tools/testing/selftests/bpf/progs/verifier_ldsx.c new file mode 100644 index 0000000000000..3c3d1bddd67f9 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/verifier_ldsx.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include "bpf_misc.h" + +#if defined(__TARGET_ARCH_x86) && __clang_major__ >= 18 + +SEC("socket") +__description("LDSX, S8") +__success __success_unpriv __retval(-2) +__naked void ldsx_s8(void) +{ + asm volatile (" \ + r1 = 0x3fe; \ + *(u64 *)(r10 - 8) = r1; \ + r0 = *(s8 *)(r10 - 8); \ + exit; \ +" ::: __clobber_all); +} + +SEC("socket") +__description("LDSX, S16") +__success __success_unpriv __retval(-2) +__naked void ldsx_s16(void) +{ + asm volatile (" \ + r1 = 0x3fffe; \ + *(u64 *)(r10 - 8) = r1; \ + r0 = *(s16 *)(r10 - 8); \ + exit; \ +" ::: __clobber_all); +} + +SEC("socket") +__description("LDSX, S32") +__success __success_unpriv __retval(-1) +__naked void ldsx_s32(void) +{ + asm volatile (" \ + r1 = 0xfffffffe; \ + *(u64 *)(r10 - 8) = r1; \ + r0 = *(s32 *)(r10 - 8); \ + r0 >>= 1; \ + exit; \ +" ::: __clobber_all); +} + +SEC("socket") +__description("LDSX, S8 range checking, privileged") +__log_level(2) __success __retval(1) +__msg("R1_w=scalar(smin=-128,smax=127)") +__naked void ldsx_s8_range_priv(void) +{ + asm volatile (" \ + call %[bpf_get_prandom_u32]; \ + *(u64 *)(r10 - 8) = r0; \ + r1 = *(s8 *)(r10 - 8); \ + /* r1 with s8 range */ \ + if r1 s> 0x7f goto l0_%=; \ + if r1 s< -0x80 goto l0_%=; \ + r0 = 1; \ +l1_%=: \ + exit; \ +l0_%=: \ + r0 = 2; \ + goto l1_%=; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +SEC("socket") +__description("LDSX, S16 range checking") +__success __success_unpriv __retval(1) +__naked void ldsx_s16_range(void) +{ + asm volatile (" \ + call %[bpf_get_prandom_u32]; \ + *(u64 *)(r10 - 8) = r0; \ + r1 = *(s16 *)(r10 - 8); \ + /* r1 with s16 range */ \ + if r1 s> 0x7fff goto l0_%=; \ + if r1 s< -0x8000 goto l0_%=; \ + r0 = 1; \ +l1_%=: \ + exit; \ +l0_%=: \ + r0 = 2; \ + goto l1_%=; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +SEC("socket") +__description("LDSX, S32 range checking") +__success __success_unpriv __retval(1) +__naked void ldsx_s32_range(void) +{ + asm volatile (" \ + call %[bpf_get_prandom_u32]; \ + *(u64 *)(r10 - 8) = r0; \ + r1 = *(s32 *)(r10 - 8); \ + /* r1 with s16 range */ \ + if r1 s> 0x7fffFFFF goto l0_%=; \ + if r1 s< -0x80000000 goto l0_%=; \ + r0 = 1; \ +l1_%=: \ + exit; \ +l0_%=: \ + r0 = 2; \ + goto l1_%=; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +#else + +SEC("socket") +__description("cpuv4 is not supported by compiler or jit, use a dummy test") +__success +int dummy_test(void) +{ + return 0; +} + +#endif + +char _license[] SEC("license") = "GPL";