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

selftests/bpf: Add a selftest for checking subreg equality

Add a selftest to ensure subreg equality if source register
upper 32bit is 0. Without previous patch, the test will
fail verification.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20230417222139.360607-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Yonghong Song and committed by
Alexei Starovoitov
49859de9 3be49f79

+60
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 31 31 #include "verifier_meta_access.skel.h" 32 32 #include "verifier_raw_stack.skel.h" 33 33 #include "verifier_raw_tp_writable.skel.h" 34 + #include "verifier_reg_equal.skel.h" 34 35 #include "verifier_ringbuf.skel.h" 35 36 #include "verifier_spill_fill.skel.h" 36 37 #include "verifier_stack_ptr.skel.h" ··· 96 95 void test_verifier_meta_access(void) { RUN(verifier_meta_access); } 97 96 void test_verifier_raw_stack(void) { RUN(verifier_raw_stack); } 98 97 void test_verifier_raw_tp_writable(void) { RUN(verifier_raw_tp_writable); } 98 + void test_verifier_reg_equal(void) { RUN(verifier_reg_equal); } 99 99 void test_verifier_ringbuf(void) { RUN(verifier_ringbuf); } 100 100 void test_verifier_spill_fill(void) { RUN(verifier_spill_fill); } 101 101 void test_verifier_stack_ptr(void) { RUN(verifier_stack_ptr); }
+58
tools/testing/selftests/bpf/progs/verifier_reg_equal.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/bpf.h> 4 + #include <bpf/bpf_helpers.h> 5 + #include "bpf_misc.h" 6 + 7 + SEC("socket") 8 + __description("check w reg equal if r reg upper32 bits 0") 9 + __success 10 + __naked void subreg_equality_1(void) 11 + { 12 + asm volatile (" \ 13 + call %[bpf_ktime_get_ns]; \ 14 + *(u64 *)(r10 - 8) = r0; \ 15 + r2 = *(u32 *)(r10 - 8); \ 16 + /* At this point upper 4-bytes of r2 are 0, \ 17 + * thus insn w3 = w2 should propagate reg id, \ 18 + * and w2 < 9 comparison would also propagate \ 19 + * the range for r3. \ 20 + */ \ 21 + w3 = w2; \ 22 + if w2 < 9 goto l0_%=; \ 23 + exit; \ 24 + l0_%=: if r3 < 9 goto l1_%=; \ 25 + /* r1 read is illegal at this point */ \ 26 + r0 -= r1; \ 27 + l1_%=: exit; \ 28 + " : 29 + : __imm(bpf_ktime_get_ns) 30 + : __clobber_all); 31 + } 32 + 33 + SEC("socket") 34 + __description("check w reg not equal if r reg upper32 bits not 0") 35 + __failure __msg("R1 !read_ok") 36 + __naked void subreg_equality_2(void) 37 + { 38 + asm volatile (" \ 39 + call %[bpf_ktime_get_ns]; \ 40 + r2 = r0; \ 41 + /* Upper 4-bytes of r2 may not be 0, thus insn \ 42 + * w3 = w2 should not propagate reg id, and \ 43 + * w2 < 9 comparison should not propagate \ 44 + * the range for r3 either. \ 45 + */ \ 46 + w3 = w2; \ 47 + if w2 < 9 goto l0_%=; \ 48 + exit; \ 49 + l0_%=: if r3 < 9 goto l1_%=; \ 50 + /* r1 read is illegal at this point */ \ 51 + r0 -= r1; \ 52 + l1_%=: exit; \ 53 + " : 54 + : __imm(bpf_ktime_get_ns) 55 + : __clobber_all); 56 + } 57 + 58 + char _license[] SEC("license") = "GPL";