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 10struct test_val { 11 unsigned int index; 12 int foo[MAX_ENTRIES]; 13}; 14 15struct { 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 22SEC("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; \ 39l0_%=: exit; \ 40" : 41 : __imm(bpf_map_lookup_elem), 42 __imm_addr(map_hash_48b) 43 : __clobber_all); 44} 45 46SEC("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; \ 63l0_%=: exit; \ 64" : 65 : __imm(bpf_map_lookup_elem), 66 __imm_addr(map_hash_48b) 67 : __clobber_all); 68} 69 70SEC("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; \ 87l0_%=: exit; \ 88" : 89 : __imm(bpf_map_lookup_elem), 90 __imm_addr(map_hash_48b) 91 : __clobber_all); 92} 93 94SEC("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; \ 112l0_%=: exit; \ 113" : 114 : __imm(bpf_map_lookup_elem), 115 __imm_addr(map_hash_48b) 116 : __clobber_all); 117} 118 119SEC("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; \ 142l0_%=: exit; \ 143" : 144 : __imm(bpf_map_lookup_elem), 145 __imm_addr(map_hash_48b) 146 : __clobber_all); 147} 148 149SEC("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 168char _license[] SEC("license") = "GPL"; 169