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

selftests/bpf: verifier/and.c converted to inline assembly

Test verifier/and.c automatically converted to use inline assembly.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20230325025524.144043-7-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
9d0f1568 55108621

+110 -68
+3
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 3 3 #include <test_progs.h> 4 4 5 5 #include "cap_helpers.h" 6 + #include "verifier_and.skel.h" 6 7 7 8 __maybe_unused 8 9 static void run_tests_aux(const char *skel_name, skel_elf_bytes_fn elf_bytes_factory) ··· 28 27 } 29 28 30 29 #define RUN(skel) run_tests_aux(#skel, skel##__elf_bytes) 30 + 31 + void test_verifier_and(void) { RUN(verifier_and); }
+107
tools/testing/selftests/bpf/progs/verifier_and.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Converted from tools/testing/selftests/bpf/verifier/and.c */ 3 + 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include "bpf_misc.h" 7 + 8 + #define MAX_ENTRIES 11 9 + 10 + struct test_val { 11 + unsigned int index; 12 + int foo[MAX_ENTRIES]; 13 + }; 14 + 15 + struct { 16 + __uint(type, BPF_MAP_TYPE_HASH); 17 + __uint(max_entries, 1); 18 + __type(key, long long); 19 + __type(value, struct test_val); 20 + } map_hash_48b SEC(".maps"); 21 + 22 + SEC("socket") 23 + __description("invalid and of negative number") 24 + __failure __msg("R0 max value is outside of the allowed memory range") 25 + __failure_unpriv 26 + __flag(BPF_F_ANY_ALIGNMENT) 27 + __naked void invalid_and_of_negative_number(void) 28 + { 29 + asm volatile (" \ 30 + r1 = 0; \ 31 + *(u64*)(r10 - 8) = r1; \ 32 + r2 = r10; \ 33 + r2 += -8; \ 34 + r1 = %[map_hash_48b] ll; \ 35 + call %[bpf_map_lookup_elem]; \ 36 + if r0 == 0 goto l0_%=; \ 37 + r1 = *(u8*)(r0 + 0); \ 38 + r1 &= -4; \ 39 + r1 <<= 2; \ 40 + r0 += r1; \ 41 + l0_%=: r1 = %[test_val_foo]; \ 42 + *(u64*)(r0 + 0) = r1; \ 43 + exit; \ 44 + " : 45 + : __imm(bpf_map_lookup_elem), 46 + __imm_addr(map_hash_48b), 47 + __imm_const(test_val_foo, offsetof(struct test_val, foo)) 48 + : __clobber_all); 49 + } 50 + 51 + SEC("socket") 52 + __description("invalid range check") 53 + __failure __msg("R0 max value is outside of the allowed memory range") 54 + __failure_unpriv 55 + __flag(BPF_F_ANY_ALIGNMENT) 56 + __naked void invalid_range_check(void) 57 + { 58 + asm volatile (" \ 59 + r1 = 0; \ 60 + *(u64*)(r10 - 8) = r1; \ 61 + r2 = r10; \ 62 + r2 += -8; \ 63 + r1 = %[map_hash_48b] ll; \ 64 + call %[bpf_map_lookup_elem]; \ 65 + if r0 == 0 goto l0_%=; \ 66 + r1 = *(u32*)(r0 + 0); \ 67 + r9 = 1; \ 68 + w1 %%= 2; \ 69 + w1 += 1; \ 70 + w9 &= w1; \ 71 + w9 += 1; \ 72 + w9 >>= 1; \ 73 + w3 = 1; \ 74 + w3 -= w9; \ 75 + w3 *= 0x10000000; \ 76 + r0 += r3; \ 77 + *(u32*)(r0 + 0) = r3; \ 78 + l0_%=: r0 = r0; \ 79 + exit; \ 80 + " : 81 + : __imm(bpf_map_lookup_elem), 82 + __imm_addr(map_hash_48b) 83 + : __clobber_all); 84 + } 85 + 86 + SEC("socket") 87 + __description("check known subreg with unknown reg") 88 + __success __failure_unpriv __msg_unpriv("R1 !read_ok") 89 + __retval(0) 90 + __naked void known_subreg_with_unknown_reg(void) 91 + { 92 + asm volatile (" \ 93 + call %[bpf_get_prandom_u32]; \ 94 + r0 <<= 32; \ 95 + r0 += 1; \ 96 + r0 &= 0xFFFF1234; \ 97 + /* Upper bits are unknown but AND above masks out 1 zero'ing lower bits */\ 98 + if w0 < 1 goto l0_%=; \ 99 + r1 = *(u32*)(r1 + 512); \ 100 + l0_%=: r0 = 0; \ 101 + exit; \ 102 + " : 103 + : __imm(bpf_get_prandom_u32) 104 + : __clobber_all); 105 + } 106 + 107 + char _license[] SEC("license") = "GPL";
-68
tools/testing/selftests/bpf/verifier/and.c
··· 1 - { 2 - "invalid and of negative number", 3 - .insns = { 4 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 5 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 6 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 7 - BPF_LD_MAP_FD(BPF_REG_1, 0), 8 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 9 - BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), 10 - BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), 11 - BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4), 12 - BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 13 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 14 - BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)), 15 - BPF_EXIT_INSN(), 16 - }, 17 - .fixup_map_hash_48b = { 3 }, 18 - .errstr = "R0 max value is outside of the allowed memory range", 19 - .result = REJECT, 20 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 21 - }, 22 - { 23 - "invalid range check", 24 - .insns = { 25 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 26 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 27 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 28 - BPF_LD_MAP_FD(BPF_REG_1, 0), 29 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 30 - BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12), 31 - BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 32 - BPF_MOV64_IMM(BPF_REG_9, 1), 33 - BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2), 34 - BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1), 35 - BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1), 36 - BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1), 37 - BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1), 38 - BPF_MOV32_IMM(BPF_REG_3, 1), 39 - BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9), 40 - BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000), 41 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3), 42 - BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0), 43 - BPF_MOV64_REG(BPF_REG_0, 0), 44 - BPF_EXIT_INSN(), 45 - }, 46 - .fixup_map_hash_48b = { 3 }, 47 - .errstr = "R0 max value is outside of the allowed memory range", 48 - .result = REJECT, 49 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 50 - }, 51 - { 52 - "check known subreg with unknown reg", 53 - .insns = { 54 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 55 - BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32), 56 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 57 - BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xFFFF1234), 58 - /* Upper bits are unknown but AND above masks out 1 zero'ing lower bits */ 59 - BPF_JMP32_IMM(BPF_JLT, BPF_REG_0, 1, 1), 60 - BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 512), 61 - BPF_MOV64_IMM(BPF_REG_0, 0), 62 - BPF_EXIT_INSN(), 63 - }, 64 - .errstr_unpriv = "R1 !read_ok", 65 - .result_unpriv = REJECT, 66 - .result = ACCEPT, 67 - .retval = 0 68 - },