1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/value_illegal_alu.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("map element value illegal alu op, 1") 24 __failure __msg("R0 bitwise operator &= on pointer") 25 __failure_unpriv 26 __naked void value_illegal_alu_op_1(void) 27 { 28 asm volatile (" \ 29 r2 = r10; \ 30 r2 += -8; \ 31 r1 = 0; \ 32 *(u64*)(r2 + 0) = r1; \ 33 r1 = %[map_hash_48b] ll; \ 34 call %[bpf_map_lookup_elem]; \ 35 if r0 == 0 goto l0_%=; \ 36 r0 &= 8; \ 37 r1 = 22; \ 38 *(u64*)(r0 + 0) = r1; \ 39 l0_%=: exit; \ 40 " : 41 : __imm(bpf_map_lookup_elem), 42 __imm_addr(map_hash_48b) 43 : __clobber_all); 44 } 45 46 SEC("socket") 47 __description("map element value illegal alu op, 2") 48 __failure __msg("R0 32-bit pointer arithmetic prohibited") 49 __failure_unpriv 50 __naked void value_illegal_alu_op_2(void) 51 { 52 asm volatile (" \ 53 r2 = r10; \ 54 r2 += -8; \ 55 r1 = 0; \ 56 *(u64*)(r2 + 0) = r1; \ 57 r1 = %[map_hash_48b] ll; \ 58 call %[bpf_map_lookup_elem]; \ 59 if r0 == 0 goto l0_%=; \ 60 w0 += 0; \ 61 r1 = 22; \ 62 *(u64*)(r0 + 0) = r1; \ 63 l0_%=: exit; \ 64 " : 65 : __imm(bpf_map_lookup_elem), 66 __imm_addr(map_hash_48b) 67 : __clobber_all); 68 } 69 70 SEC("socket") 71 __description("map element value illegal alu op, 3") 72 __failure __msg("R0 pointer arithmetic with /= operator") 73 __failure_unpriv 74 __naked void value_illegal_alu_op_3(void) 75 { 76 asm volatile (" \ 77 r2 = r10; \ 78 r2 += -8; \ 79 r1 = 0; \ 80 *(u64*)(r2 + 0) = r1; \ 81 r1 = %[map_hash_48b] ll; \ 82 call %[bpf_map_lookup_elem]; \ 83 if r0 == 0 goto l0_%=; \ 84 r0 /= 42; \ 85 r1 = 22; \ 86 *(u64*)(r0 + 0) = r1; \ 87 l0_%=: exit; \ 88 " : 89 : __imm(bpf_map_lookup_elem), 90 __imm_addr(map_hash_48b) 91 : __clobber_all); 92 } 93 94 SEC("socket") 95 __description("map element value illegal alu op, 4") 96 __failure __msg("invalid mem access 'scalar'") 97 __failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited") 98 __flag(BPF_F_ANY_ALIGNMENT) 99 __naked void value_illegal_alu_op_4(void) 100 { 101 asm volatile (" \ 102 r2 = r10; \ 103 r2 += -8; \ 104 r1 = 0; \ 105 *(u64*)(r2 + 0) = r1; \ 106 r1 = %[map_hash_48b] ll; \ 107 call %[bpf_map_lookup_elem]; \ 108 if r0 == 0 goto l0_%=; \ 109 r0 = be64 r0; \ 110 r1 = 22; \ 111 *(u64*)(r0 + 0) = r1; \ 112 l0_%=: exit; \ 113 " : 114 : __imm(bpf_map_lookup_elem), 115 __imm_addr(map_hash_48b) 116 : __clobber_all); 117 } 118 119 SEC("socket") 120 __description("map element value illegal alu op, 5") 121 __failure __msg("R0 invalid mem access 'scalar'") 122 __msg_unpriv("leaking pointer from stack off -8") 123 __flag(BPF_F_ANY_ALIGNMENT) 124 __naked void value_illegal_alu_op_5(void) 125 { 126 asm volatile (" \ 127 r2 = r10; \ 128 r2 += -8; \ 129 r1 = 0; \ 130 *(u64*)(r2 + 0) = r1; \ 131 r1 = %[map_hash_48b] ll; \ 132 call %[bpf_map_lookup_elem]; \ 133 if r0 == 0 goto l0_%=; \ 134 r3 = 4096; \ 135 r2 = r10; \ 136 r2 += -8; \ 137 *(u64*)(r2 + 0) = r0; \ 138 lock *(u64 *)(r2 + 0) += r3; \ 139 r0 = *(u64*)(r2 + 0); \ 140 r1 = 22; \ 141 *(u64*)(r0 + 0) = r1; \ 142 l0_%=: exit; \ 143 " : 144 : __imm(bpf_map_lookup_elem), 145 __imm_addr(map_hash_48b) 146 : __clobber_all); 147 } 148 149 SEC("flow_dissector") 150 __description("flow_keys illegal alu op with variable offset") 151 __failure __msg("R7 pointer arithmetic on flow_keys prohibited") 152 __naked void flow_keys_illegal_variable_offset_alu(void) 153 { 154 asm volatile(" \ 155 r6 = r1; \ 156 r7 = *(u64*)(r6 + %[flow_keys_off]); \ 157 r8 = 8; \ 158 r8 /= 1; \ 159 r8 &= 8; \ 160 r7 += r8; \ 161 r0 = *(u64*)(r7 + 0); \ 162 exit; \ 163 " : 164 : __imm_const(flow_keys_off, offsetof(struct __sk_buff, flow_keys)) 165 : __clobber_all); 166 } 167 168 char _license[] SEC("license") = "GPL"; 169