FILE
verifier_value_illegal_alu.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/bpf/progs/verifier_value_illegal_alu.c
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 "../../../include/linux/filter.h" 7#include "bpf_misc.h" 8 9#define MAX_ENTRIES 11 10 11struct test_val { 12 unsigned int index; 13 int foo[MAX_ENTRIES]; 14}; 15 16struct { 17 __uint(type, BPF_MAP_TYPE_HASH); 18 __uint(max_entries, 1); 19 __type(key, long long); 20 __type(value, struct test_val); 21} map_hash_48b SEC(".maps"); 22 23SEC("socket") 24__description("map element value illegal alu op, 1") 25__failure __msg("R0 bitwise operator &= on pointer") 26__failure_unpriv 27__naked void value_illegal_alu_op_1(void) 28{ 29 asm volatile (" \ 30 r2 = r10; \ 31 r2 += -8; \ 32 r1 = 0; \ 33 *(u64*)(r2 + 0) = r1; \ 34 r1 = %[map_hash_48b] ll; \ 35 call %[bpf_map_lookup_elem]; \ 36 if r0 == 0 goto l0_%=; \ 37 r0 &= 8; \ 38 r1 = 22; \ 39 *(u64*)(r0 + 0) = r1; \ 40l0_%=: exit; \ 41" : 42 : __imm(bpf_map_lookup_elem), 43 __imm_addr(map_hash_48b) 44 : __clobber_all); 45} 46 47SEC("socket") 48__description("map element value illegal alu op, 2") 49__failure __msg("R0 32-bit pointer arithmetic prohibited") 50__failure_unpriv 51__naked void value_illegal_alu_op_2(void) 52{ 53 asm volatile (" \ 54 r2 = r10; \ 55 r2 += -8; \ 56 r1 = 0; \ 57 *(u64*)(r2 + 0) = r1; \ 58 r1 = %[map_hash_48b] ll; \ 59 call %[bpf_map_lookup_elem]; \ 60 if r0 == 0 goto l0_%=; \ 61 w0 += 0; \ 62 r1 = 22; \ 63 *(u64*)(r0 + 0) = r1; \ 64l0_%=: exit; \ 65" : 66 : __imm(bpf_map_lookup_elem), 67 __imm_addr(map_hash_48b) 68 : __clobber_all); 69} 70 71SEC("socket") 72__description("map element value illegal alu op, 3") 73__failure __msg("R0 pointer arithmetic with /= operator") 74__failure_unpriv 75__naked void value_illegal_alu_op_3(void) 76{ 77 asm volatile (" \ 78 r2 = r10; \ 79 r2 += -8; \ 80 r1 = 0; \ 81 *(u64*)(r2 + 0) = r1; \ 82 r1 = %[map_hash_48b] ll; \ 83 call %[bpf_map_lookup_elem]; \ 84 if r0 == 0 goto l0_%=; \ 85 r0 /= 42; \ 86 r1 = 22; \ 87 *(u64*)(r0 + 0) = r1; \ 88l0_%=: exit; \ 89" : 90 : __imm(bpf_map_lookup_elem), 91 __imm_addr(map_hash_48b) 92 : __clobber_all); 93} 94 95SEC("socket") 96__description("map element value illegal alu op, 4") 97__failure __msg("invalid mem access 'scalar'") 98__failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited") 99__flag(BPF_F_ANY_ALIGNMENT) 100__naked void value_illegal_alu_op_4(void) 101{ 102 asm volatile (" \ 103 r2 = r10; \ 104 r2 += -8; \ 105 r1 = 0; \ 106 *(u64*)(r2 + 0) = r1; \ 107 r1 = %[map_hash_48b] ll; \ 108 call %[bpf_map_lookup_elem]; \ 109 if r0 == 0 goto l0_%=; \ 110 r0 = be64 r0; \ 111 r1 = 22; \ 112 *(u64*)(r0 + 0) = r1; \ 113l0_%=: exit; \ 114" : 115 : __imm(bpf_map_lookup_elem), 116 __imm_addr(map_hash_48b) 117 : __clobber_all); 118} 119 120SEC("socket") 121__description("map element value illegal alu op, 5") 122__failure __msg("R0 invalid mem access 'scalar'") 123__msg_unpriv("leaking pointer from stack off -8") 124__flag(BPF_F_ANY_ALIGNMENT) 125__naked void value_illegal_alu_op_5(void) 126{ 127 asm volatile (" \ 128 r2 = r10; \ 129 r2 += -8; \ 130 r1 = 0; \ 131 *(u64*)(r2 + 0) = r1; \ 132 r1 = %[map_hash_48b] ll; \ 133 call %[bpf_map_lookup_elem]; \ 134 if r0 == 0 goto l0_%=; \ 135 r3 = 4096; \ 136 r2 = r10; \ 137 r2 += -8; \ 138 *(u64*)(r2 + 0) = r0; \ 139 lock *(u64 *)(r2 + 0) += r3; \ 140 r0 = *(u64*)(r2 + 0); \ 141 r1 = 22; \ 142 *(u64*)(r0 + 0) = r1; \ 143l0_%=: exit; \ 144" : 145 : __imm(bpf_map_lookup_elem), 146 __imm_addr(map_hash_48b) 147 : __clobber_all); 148} 149 150SEC("socket") 151__description("map_ptr illegal alu op, map_ptr = -map_ptr") 152__failure __msg("R0 invalid mem access 'scalar'") 153__failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited") 154__flag(BPF_F_ANY_ALIGNMENT) 155__naked void map_ptr_illegal_alu_op(void) 156{ 157 asm volatile (" \ 158 r0 = %[map_hash_48b] ll; \ 159 r0 = -r0; \ 160 r1 = 22; \ 161 *(u64*)(r0 + 0) = r1; \ 162 exit; \ 163" : 164 : __imm_addr(map_hash_48b) 165 : __clobber_all); 166} 167 168SEC("flow_dissector") 169__description("flow_keys illegal alu op with variable offset") 170__failure __msg("R7 pointer arithmetic on flow_keys prohibited") 171__naked void flow_keys_illegal_variable_offset_alu(void) 172{ 173 asm volatile(" \ 174 r6 = r1; \ 175 r7 = *(u64*)(r6 + %[flow_keys_off]); \ 176 r8 = 8; \ 177 r8 /= 1; \ 178 r8 &= 8; \ 179 r7 += r8; \ 180 r0 = *(u64*)(r7 + 0); \ 181 exit; \ 182" : 183 : __imm_const(flow_keys_off, offsetof(struct __sk_buff, flow_keys)) 184 : __clobber_all); 185} 186 187#define DEFINE_BAD_OFFSET_TEST(name, op, off, imm) \ 188 SEC("socket") \ 189 __failure __msg("BPF_ALU uses reserved fields") \ 190 __naked void name(void) \ 191 { \ 192 asm volatile( \ 193 "r0 = 1;" \ 194 ".8byte %[insn];" \ 195 "r0 = 0;" \ 196 "exit;" \ 197 : \ 198 : __imm_insn(insn, BPF_RAW_INSN((op), 0, 0, (off), (imm))) \ 199 : __clobber_all); \ 200 } 201 202/* 203 * Offset fields of 0 and 1 are legal for BPF_{DIV,MOD} instructions. 204 * Offset fields of 0 are legal for the rest of ALU instructions. 205 * Test that error is reported for illegal offsets, assuming that tests 206 * for legal offsets exist. 207 */ 208DEFINE_BAD_OFFSET_TEST(bad_offset_divx, BPF_ALU64 | BPF_DIV | BPF_X, -1, 0) 209DEFINE_BAD_OFFSET_TEST(bad_offset_modk, BPF_ALU64 | BPF_MOD | BPF_K, -1, 1) 210DEFINE_BAD_OFFSET_TEST(bad_offset_addx, BPF_ALU64 | BPF_ADD | BPF_X, -1, 0) 211DEFINE_BAD_OFFSET_TEST(bad_offset_divx2, BPF_ALU64 | BPF_DIV | BPF_X, 2, 0) 212DEFINE_BAD_OFFSET_TEST(bad_offset_modk2, BPF_ALU64 | BPF_MOD | BPF_K, 2, 1) 213DEFINE_BAD_OFFSET_TEST(bad_offset_addx2, BPF_ALU64 | BPF_ADD | BPF_X, 1, 0) 214 215char _license[] SEC("license") = "GPL";
~/
Read-only file preview.