1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Converted from tools/testing/selftests/bpf/verifier/cgroup_storage.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 | struct { |
10 | __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); |
11 | __uint(max_entries, 0); |
12 | __type(key, struct bpf_cgroup_storage_key); |
13 | __type(value, char[TEST_DATA_LEN]); |
14 | } cgroup_storage SEC(".maps" ); |
15 | |
16 | struct { |
17 | __uint(type, BPF_MAP_TYPE_HASH); |
18 | __uint(max_entries, 1); |
19 | __type(key, long long); |
20 | __type(value, long long); |
21 | } map_hash_8b SEC(".maps" ); |
22 | |
23 | struct { |
24 | __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); |
25 | __uint(max_entries, 0); |
26 | __type(key, struct bpf_cgroup_storage_key); |
27 | __type(value, char[64]); |
28 | } percpu_cgroup_storage SEC(".maps" ); |
29 | |
30 | SEC("cgroup/skb" ) |
31 | __description("valid cgroup storage access" ) |
32 | __success __success_unpriv __retval(0) |
33 | __naked void valid_cgroup_storage_access(void) |
34 | { |
35 | asm volatile (" \ |
36 | r2 = 0; \ |
37 | r1 = %[cgroup_storage] ll; \ |
38 | call %[bpf_get_local_storage]; \ |
39 | r1 = *(u32*)(r0 + 0); \ |
40 | r0 = r1; \ |
41 | r0 &= 1; \ |
42 | exit; \ |
43 | " : |
44 | : __imm(bpf_get_local_storage), |
45 | __imm_addr(cgroup_storage) |
46 | : __clobber_all); |
47 | } |
48 | |
49 | SEC("cgroup/skb" ) |
50 | __description("invalid cgroup storage access 1" ) |
51 | __failure __msg("cannot pass map_type 1 into func bpf_get_local_storage" ) |
52 | __failure_unpriv |
53 | __naked void invalid_cgroup_storage_access_1(void) |
54 | { |
55 | asm volatile (" \ |
56 | r2 = 0; \ |
57 | r1 = %[map_hash_8b] ll; \ |
58 | call %[bpf_get_local_storage]; \ |
59 | r1 = *(u32*)(r0 + 0); \ |
60 | r0 = r1; \ |
61 | r0 &= 1; \ |
62 | exit; \ |
63 | " : |
64 | : __imm(bpf_get_local_storage), |
65 | __imm_addr(map_hash_8b) |
66 | : __clobber_all); |
67 | } |
68 | |
69 | SEC("cgroup/skb" ) |
70 | __description("invalid cgroup storage access 2" ) |
71 | __failure __msg("fd 1 is not pointing to valid bpf_map" ) |
72 | __failure_unpriv |
73 | __naked void invalid_cgroup_storage_access_2(void) |
74 | { |
75 | asm volatile (" \ |
76 | r2 = 0; \ |
77 | .8byte %[ld_map_fd]; \ |
78 | .8byte 0; \ |
79 | call %[bpf_get_local_storage]; \ |
80 | r0 &= 1; \ |
81 | exit; \ |
82 | " : |
83 | : __imm(bpf_get_local_storage), |
84 | __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1)) |
85 | : __clobber_all); |
86 | } |
87 | |
88 | SEC("cgroup/skb" ) |
89 | __description("invalid cgroup storage access 3" ) |
90 | __failure __msg("invalid access to map value, value_size=64 off=256 size=4" ) |
91 | __failure_unpriv |
92 | __naked void invalid_cgroup_storage_access_3(void) |
93 | { |
94 | asm volatile (" \ |
95 | r2 = 0; \ |
96 | r1 = %[cgroup_storage] ll; \ |
97 | call %[bpf_get_local_storage]; \ |
98 | r1 = *(u32*)(r0 + 256); \ |
99 | r1 += 1; \ |
100 | r0 = 0; \ |
101 | exit; \ |
102 | " : |
103 | : __imm(bpf_get_local_storage), |
104 | __imm_addr(cgroup_storage) |
105 | : __clobber_all); |
106 | } |
107 | |
108 | SEC("cgroup/skb" ) |
109 | __description("invalid cgroup storage access 4" ) |
110 | __failure __msg("invalid access to map value, value_size=64 off=-2 size=4" ) |
111 | __failure_unpriv |
112 | __flag(BPF_F_ANY_ALIGNMENT) |
113 | __naked void invalid_cgroup_storage_access_4(void) |
114 | { |
115 | asm volatile (" \ |
116 | r2 = 0; \ |
117 | r1 = %[cgroup_storage] ll; \ |
118 | call %[bpf_get_local_storage]; \ |
119 | r1 = *(u32*)(r0 - 2); \ |
120 | r0 = r1; \ |
121 | r1 += 1; \ |
122 | exit; \ |
123 | " : |
124 | : __imm(bpf_get_local_storage), |
125 | __imm_addr(cgroup_storage) |
126 | : __clobber_all); |
127 | } |
128 | |
129 | SEC("cgroup/skb" ) |
130 | __description("invalid cgroup storage access 5" ) |
131 | __failure __msg("get_local_storage() doesn't support non-zero flags" ) |
132 | __failure_unpriv |
133 | __naked void invalid_cgroup_storage_access_5(void) |
134 | { |
135 | asm volatile (" \ |
136 | r2 = 7; \ |
137 | r1 = %[cgroup_storage] ll; \ |
138 | call %[bpf_get_local_storage]; \ |
139 | r1 = *(u32*)(r0 + 0); \ |
140 | r0 = r1; \ |
141 | r0 &= 1; \ |
142 | exit; \ |
143 | " : |
144 | : __imm(bpf_get_local_storage), |
145 | __imm_addr(cgroup_storage) |
146 | : __clobber_all); |
147 | } |
148 | |
149 | SEC("cgroup/skb" ) |
150 | __description("invalid cgroup storage access 6" ) |
151 | __failure __msg("get_local_storage() doesn't support non-zero flags" ) |
152 | __msg_unpriv("R2 leaks addr into helper function" ) |
153 | __naked void invalid_cgroup_storage_access_6(void) |
154 | { |
155 | asm volatile (" \ |
156 | r2 = r1; \ |
157 | r1 = %[cgroup_storage] ll; \ |
158 | call %[bpf_get_local_storage]; \ |
159 | r1 = *(u32*)(r0 + 0); \ |
160 | r0 = r1; \ |
161 | r0 &= 1; \ |
162 | exit; \ |
163 | " : |
164 | : __imm(bpf_get_local_storage), |
165 | __imm_addr(cgroup_storage) |
166 | : __clobber_all); |
167 | } |
168 | |
169 | SEC("cgroup/skb" ) |
170 | __description("valid per-cpu cgroup storage access" ) |
171 | __success __success_unpriv __retval(0) |
172 | __naked void per_cpu_cgroup_storage_access(void) |
173 | { |
174 | asm volatile (" \ |
175 | r2 = 0; \ |
176 | r1 = %[percpu_cgroup_storage] ll; \ |
177 | call %[bpf_get_local_storage]; \ |
178 | r1 = *(u32*)(r0 + 0); \ |
179 | r0 = r1; \ |
180 | r0 &= 1; \ |
181 | exit; \ |
182 | " : |
183 | : __imm(bpf_get_local_storage), |
184 | __imm_addr(percpu_cgroup_storage) |
185 | : __clobber_all); |
186 | } |
187 | |
188 | SEC("cgroup/skb" ) |
189 | __description("invalid per-cpu cgroup storage access 1" ) |
190 | __failure __msg("cannot pass map_type 1 into func bpf_get_local_storage" ) |
191 | __failure_unpriv |
192 | __naked void cpu_cgroup_storage_access_1(void) |
193 | { |
194 | asm volatile (" \ |
195 | r2 = 0; \ |
196 | r1 = %[map_hash_8b] ll; \ |
197 | call %[bpf_get_local_storage]; \ |
198 | r1 = *(u32*)(r0 + 0); \ |
199 | r0 = r1; \ |
200 | r0 &= 1; \ |
201 | exit; \ |
202 | " : |
203 | : __imm(bpf_get_local_storage), |
204 | __imm_addr(map_hash_8b) |
205 | : __clobber_all); |
206 | } |
207 | |
208 | SEC("cgroup/skb" ) |
209 | __description("invalid per-cpu cgroup storage access 2" ) |
210 | __failure __msg("fd 1 is not pointing to valid bpf_map" ) |
211 | __failure_unpriv |
212 | __naked void cpu_cgroup_storage_access_2(void) |
213 | { |
214 | asm volatile (" \ |
215 | r2 = 0; \ |
216 | .8byte %[ld_map_fd]; \ |
217 | .8byte 0; \ |
218 | call %[bpf_get_local_storage]; \ |
219 | r0 &= 1; \ |
220 | exit; \ |
221 | " : |
222 | : __imm(bpf_get_local_storage), |
223 | __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1)) |
224 | : __clobber_all); |
225 | } |
226 | |
227 | SEC("cgroup/skb" ) |
228 | __description("invalid per-cpu cgroup storage access 3" ) |
229 | __failure __msg("invalid access to map value, value_size=64 off=256 size=4" ) |
230 | __failure_unpriv |
231 | __naked void cpu_cgroup_storage_access_3(void) |
232 | { |
233 | asm volatile (" \ |
234 | r2 = 0; \ |
235 | r1 = %[percpu_cgroup_storage] ll; \ |
236 | call %[bpf_get_local_storage]; \ |
237 | r1 = *(u32*)(r0 + 256); \ |
238 | r1 += 1; \ |
239 | r0 = 0; \ |
240 | exit; \ |
241 | " : |
242 | : __imm(bpf_get_local_storage), |
243 | __imm_addr(percpu_cgroup_storage) |
244 | : __clobber_all); |
245 | } |
246 | |
247 | SEC("cgroup/skb" ) |
248 | __description("invalid per-cpu cgroup storage access 4" ) |
249 | __failure __msg("invalid access to map value, value_size=64 off=-2 size=4" ) |
250 | __failure_unpriv |
251 | __flag(BPF_F_ANY_ALIGNMENT) |
252 | __naked void cpu_cgroup_storage_access_4(void) |
253 | { |
254 | asm volatile (" \ |
255 | r2 = 0; \ |
256 | r1 = %[cgroup_storage] ll; \ |
257 | call %[bpf_get_local_storage]; \ |
258 | r1 = *(u32*)(r0 - 2); \ |
259 | r0 = r1; \ |
260 | r1 += 1; \ |
261 | exit; \ |
262 | " : |
263 | : __imm(bpf_get_local_storage), |
264 | __imm_addr(cgroup_storage) |
265 | : __clobber_all); |
266 | } |
267 | |
268 | SEC("cgroup/skb" ) |
269 | __description("invalid per-cpu cgroup storage access 5" ) |
270 | __failure __msg("get_local_storage() doesn't support non-zero flags" ) |
271 | __failure_unpriv |
272 | __naked void cpu_cgroup_storage_access_5(void) |
273 | { |
274 | asm volatile (" \ |
275 | r2 = 7; \ |
276 | r1 = %[percpu_cgroup_storage] ll; \ |
277 | call %[bpf_get_local_storage]; \ |
278 | r1 = *(u32*)(r0 + 0); \ |
279 | r0 = r1; \ |
280 | r0 &= 1; \ |
281 | exit; \ |
282 | " : |
283 | : __imm(bpf_get_local_storage), |
284 | __imm_addr(percpu_cgroup_storage) |
285 | : __clobber_all); |
286 | } |
287 | |
288 | SEC("cgroup/skb" ) |
289 | __description("invalid per-cpu cgroup storage access 6" ) |
290 | __failure __msg("get_local_storage() doesn't support non-zero flags" ) |
291 | __msg_unpriv("R2 leaks addr into helper function" ) |
292 | __naked void cpu_cgroup_storage_access_6(void) |
293 | { |
294 | asm volatile (" \ |
295 | r2 = r1; \ |
296 | r1 = %[percpu_cgroup_storage] ll; \ |
297 | call %[bpf_get_local_storage]; \ |
298 | r1 = *(u32*)(r0 + 0); \ |
299 | r0 = r1; \ |
300 | r0 &= 1; \ |
301 | exit; \ |
302 | " : |
303 | : __imm(bpf_get_local_storage), |
304 | __imm_addr(percpu_cgroup_storage) |
305 | : __clobber_all); |
306 | } |
307 | |
308 | char _license[] SEC("license" ) = "GPL" ; |
309 | |