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

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

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

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

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
caf345cf 583c7ce5

+161 -99
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 24 24 #include "verifier_int_ptr.skel.h" 25 25 #include "verifier_ld_ind.skel.h" 26 26 #include "verifier_leak_ptr.skel.h" 27 + #include "verifier_map_ptr.skel.h" 27 28 28 29 __maybe_unused 29 30 static void run_tests_aux(const char *skel_name, skel_elf_bytes_fn elf_bytes_factory) ··· 71 70 void test_verifier_int_ptr(void) { RUN(verifier_int_ptr); } 72 71 void test_verifier_ld_ind(void) { RUN(verifier_ld_ind); } 73 72 void test_verifier_leak_ptr(void) { RUN(verifier_leak_ptr); } 73 + void test_verifier_map_ptr(void) { RUN(verifier_map_ptr); }
+159
tools/testing/selftests/bpf/progs/verifier_map_ptr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Converted from tools/testing/selftests/bpf/verifier/map_ptr.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_ARRAY); 17 + __uint(max_entries, 1); 18 + __type(key, int); 19 + __type(value, struct test_val); 20 + } map_array_48b SEC(".maps"); 21 + 22 + struct other_val { 23 + long long foo; 24 + long long bar; 25 + }; 26 + 27 + struct { 28 + __uint(type, BPF_MAP_TYPE_HASH); 29 + __uint(max_entries, 1); 30 + __type(key, long long); 31 + __type(value, struct other_val); 32 + } map_hash_16b SEC(".maps"); 33 + 34 + SEC("socket") 35 + __description("bpf_map_ptr: read with negative offset rejected") 36 + __failure __msg("R1 is bpf_array invalid negative access: off=-8") 37 + __failure_unpriv 38 + __msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN") 39 + __naked void read_with_negative_offset_rejected(void) 40 + { 41 + asm volatile (" \ 42 + r1 = r10; \ 43 + r1 = %[map_array_48b] ll; \ 44 + r6 = *(u64*)(r1 - 8); \ 45 + r0 = 1; \ 46 + exit; \ 47 + " : 48 + : __imm_addr(map_array_48b) 49 + : __clobber_all); 50 + } 51 + 52 + SEC("socket") 53 + __description("bpf_map_ptr: write rejected") 54 + __failure __msg("only read from bpf_array is supported") 55 + __failure_unpriv 56 + __msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN") 57 + __naked void bpf_map_ptr_write_rejected(void) 58 + { 59 + asm volatile (" \ 60 + r0 = 0; \ 61 + *(u64*)(r10 - 8) = r0; \ 62 + r2 = r10; \ 63 + r2 += -8; \ 64 + r1 = %[map_array_48b] ll; \ 65 + *(u64*)(r1 + 0) = r2; \ 66 + r0 = 1; \ 67 + exit; \ 68 + " : 69 + : __imm_addr(map_array_48b) 70 + : __clobber_all); 71 + } 72 + 73 + SEC("socket") 74 + __description("bpf_map_ptr: read non-existent field rejected") 75 + __failure 76 + __msg("cannot access ptr member ops with moff 0 in struct bpf_map with off 1 size 4") 77 + __failure_unpriv 78 + __msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN") 79 + __flag(BPF_F_ANY_ALIGNMENT) 80 + __naked void read_non_existent_field_rejected(void) 81 + { 82 + asm volatile (" \ 83 + r6 = 0; \ 84 + r1 = %[map_array_48b] ll; \ 85 + r6 = *(u32*)(r1 + 1); \ 86 + r0 = 1; \ 87 + exit; \ 88 + " : 89 + : __imm_addr(map_array_48b) 90 + : __clobber_all); 91 + } 92 + 93 + SEC("socket") 94 + __description("bpf_map_ptr: read ops field accepted") 95 + __success __failure_unpriv 96 + __msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN") 97 + __retval(1) 98 + __naked void ptr_read_ops_field_accepted(void) 99 + { 100 + asm volatile (" \ 101 + r6 = 0; \ 102 + r1 = %[map_array_48b] ll; \ 103 + r6 = *(u64*)(r1 + 0); \ 104 + r0 = 1; \ 105 + exit; \ 106 + " : 107 + : __imm_addr(map_array_48b) 108 + : __clobber_all); 109 + } 110 + 111 + SEC("socket") 112 + __description("bpf_map_ptr: r = 0, map_ptr = map_ptr + r") 113 + __success __failure_unpriv 114 + __msg_unpriv("R1 has pointer with unsupported alu operation") 115 + __retval(0) 116 + __naked void map_ptr_map_ptr_r(void) 117 + { 118 + asm volatile (" \ 119 + r0 = 0; \ 120 + *(u64*)(r10 - 8) = r0; \ 121 + r2 = r10; \ 122 + r2 += -8; \ 123 + r0 = 0; \ 124 + r1 = %[map_hash_16b] ll; \ 125 + r1 += r0; \ 126 + call %[bpf_map_lookup_elem]; \ 127 + r0 = 0; \ 128 + exit; \ 129 + " : 130 + : __imm(bpf_map_lookup_elem), 131 + __imm_addr(map_hash_16b) 132 + : __clobber_all); 133 + } 134 + 135 + SEC("socket") 136 + __description("bpf_map_ptr: r = 0, r = r + map_ptr") 137 + __success __failure_unpriv 138 + __msg_unpriv("R0 has pointer with unsupported alu operation") 139 + __retval(0) 140 + __naked void _0_r_r_map_ptr(void) 141 + { 142 + asm volatile (" \ 143 + r0 = 0; \ 144 + *(u64*)(r10 - 8) = r0; \ 145 + r2 = r10; \ 146 + r2 += -8; \ 147 + r1 = 0; \ 148 + r0 = %[map_hash_16b] ll; \ 149 + r1 += r0; \ 150 + call %[bpf_map_lookup_elem]; \ 151 + r0 = 0; \ 152 + exit; \ 153 + " : 154 + : __imm(bpf_map_lookup_elem), 155 + __imm_addr(map_hash_16b) 156 + : __clobber_all); 157 + } 158 + 159 + char _license[] SEC("license") = "GPL";
-99
tools/testing/selftests/bpf/verifier/map_ptr.c
··· 1 - { 2 - "bpf_map_ptr: read with negative offset rejected", 3 - .insns = { 4 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 5 - BPF_LD_MAP_FD(BPF_REG_1, 0), 6 - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), 7 - BPF_MOV64_IMM(BPF_REG_0, 1), 8 - BPF_EXIT_INSN(), 9 - }, 10 - .fixup_map_array_48b = { 1 }, 11 - .result_unpriv = REJECT, 12 - .errstr_unpriv = "access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN", 13 - .result = REJECT, 14 - .errstr = "R1 is bpf_array invalid negative access: off=-8", 15 - }, 16 - { 17 - "bpf_map_ptr: write rejected", 18 - .insns = { 19 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 20 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 21 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 22 - BPF_LD_MAP_FD(BPF_REG_1, 0), 23 - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0), 24 - BPF_MOV64_IMM(BPF_REG_0, 1), 25 - BPF_EXIT_INSN(), 26 - }, 27 - .fixup_map_array_48b = { 3 }, 28 - .result_unpriv = REJECT, 29 - .errstr_unpriv = "access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN", 30 - .result = REJECT, 31 - .errstr = "only read from bpf_array is supported", 32 - }, 33 - { 34 - "bpf_map_ptr: read non-existent field rejected", 35 - .insns = { 36 - BPF_MOV64_IMM(BPF_REG_6, 0), 37 - BPF_LD_MAP_FD(BPF_REG_1, 0), 38 - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 1), 39 - BPF_MOV64_IMM(BPF_REG_0, 1), 40 - BPF_EXIT_INSN(), 41 - }, 42 - .fixup_map_array_48b = { 1 }, 43 - .result_unpriv = REJECT, 44 - .errstr_unpriv = "access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN", 45 - .result = REJECT, 46 - .errstr = "cannot access ptr member ops with moff 0 in struct bpf_map with off 1 size 4", 47 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 48 - }, 49 - { 50 - "bpf_map_ptr: read ops field accepted", 51 - .insns = { 52 - BPF_MOV64_IMM(BPF_REG_6, 0), 53 - BPF_LD_MAP_FD(BPF_REG_1, 0), 54 - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 55 - BPF_MOV64_IMM(BPF_REG_0, 1), 56 - BPF_EXIT_INSN(), 57 - }, 58 - .fixup_map_array_48b = { 1 }, 59 - .result_unpriv = REJECT, 60 - .errstr_unpriv = "access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN", 61 - .result = ACCEPT, 62 - .retval = 1, 63 - }, 64 - { 65 - "bpf_map_ptr: r = 0, map_ptr = map_ptr + r", 66 - .insns = { 67 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 68 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 69 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 70 - BPF_MOV64_IMM(BPF_REG_0, 0), 71 - BPF_LD_MAP_FD(BPF_REG_1, 0), 72 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), 73 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 74 - BPF_MOV64_IMM(BPF_REG_0, 0), 75 - BPF_EXIT_INSN(), 76 - }, 77 - .fixup_map_hash_16b = { 4 }, 78 - .result_unpriv = REJECT, 79 - .errstr_unpriv = "R1 has pointer with unsupported alu operation", 80 - .result = ACCEPT, 81 - }, 82 - { 83 - "bpf_map_ptr: r = 0, r = r + map_ptr", 84 - .insns = { 85 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 86 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 87 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 88 - BPF_MOV64_IMM(BPF_REG_1, 0), 89 - BPF_LD_MAP_FD(BPF_REG_0, 0), 90 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), 91 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 92 - BPF_MOV64_IMM(BPF_REG_0, 0), 93 - BPF_EXIT_INSN(), 94 - }, 95 - .fixup_map_hash_16b = { 4 }, 96 - .result_unpriv = REJECT, 97 - .errstr_unpriv = "R0 has pointer with unsupported alu operation", 98 - .result = ACCEPT, 99 - },