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 | |