1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/helper_packet_access.c */
3
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7
8 struct {
9 __uint(type, BPF_MAP_TYPE_HASH);
10 __uint(max_entries, 1);
11 __type(key, long long);
12 __type(value, long long);
13 } map_hash_8b SEC(".maps");
14
15 SEC("xdp")
16 __description("helper access to packet: test1, valid packet_ptr range")
17 __success __retval(0)
test1_valid_packet_ptr_range(void)18 __naked void test1_valid_packet_ptr_range(void)
19 {
20 asm volatile (" \
21 r2 = *(u32*)(r1 + %[xdp_md_data]); \
22 r3 = *(u32*)(r1 + %[xdp_md_data_end]); \
23 r1 = r2; \
24 r1 += 8; \
25 if r1 > r3 goto l0_%=; \
26 r1 = %[map_hash_8b] ll; \
27 r3 = r2; \
28 r4 = 0; \
29 call %[bpf_map_update_elem]; \
30 l0_%=: r0 = 0; \
31 exit; \
32 " :
33 : __imm(bpf_map_update_elem),
34 __imm_addr(map_hash_8b),
35 __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
36 __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end))
37 : __clobber_all);
38 }
39
40 SEC("xdp")
41 __description("helper access to packet: test2, unchecked packet_ptr")
42 __failure __msg("invalid access to packet")
packet_test2_unchecked_packet_ptr(void)43 __naked void packet_test2_unchecked_packet_ptr(void)
44 {
45 asm volatile (" \
46 r2 = *(u32*)(r1 + %[xdp_md_data]); \
47 r1 = %[map_hash_8b] ll; \
48 call %[bpf_map_lookup_elem]; \
49 r0 = 0; \
50 exit; \
51 " :
52 : __imm(bpf_map_lookup_elem),
53 __imm_addr(map_hash_8b),
54 __imm_const(xdp_md_data, offsetof(struct xdp_md, data))
55 : __clobber_all);
56 }
57
58 SEC("xdp")
59 __description("helper access to packet: test3, variable add")
60 __success __retval(0)
to_packet_test3_variable_add(void)61 __naked void to_packet_test3_variable_add(void)
62 {
63 asm volatile (" \
64 r2 = *(u32*)(r1 + %[xdp_md_data]); \
65 r3 = *(u32*)(r1 + %[xdp_md_data_end]); \
66 r4 = r2; \
67 r4 += 8; \
68 if r4 > r3 goto l0_%=; \
69 r5 = *(u8*)(r2 + 0); \
70 r4 = r2; \
71 r4 += r5; \
72 r5 = r4; \
73 r5 += 8; \
74 if r5 > r3 goto l0_%=; \
75 r1 = %[map_hash_8b] ll; \
76 r2 = r4; \
77 call %[bpf_map_lookup_elem]; \
78 l0_%=: r0 = 0; \
79 exit; \
80 " :
81 : __imm(bpf_map_lookup_elem),
82 __imm_addr(map_hash_8b),
83 __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
84 __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end))
85 : __clobber_all);
86 }
87
88 SEC("xdp")
89 __description("helper access to packet: test4, packet_ptr with bad range")
90 __failure __msg("invalid access to packet")
packet_ptr_with_bad_range_1(void)91 __naked void packet_ptr_with_bad_range_1(void)
92 {
93 asm volatile (" \
94 r2 = *(u32*)(r1 + %[xdp_md_data]); \
95 r3 = *(u32*)(r1 + %[xdp_md_data_end]); \
96 r4 = r2; \
97 r4 += 4; \
98 if r4 > r3 goto l0_%=; \
99 r0 = 0; \
100 exit; \
101 l0_%=: r1 = %[map_hash_8b] ll; \
102 call %[bpf_map_lookup_elem]; \
103 r0 = 0; \
104 exit; \
105 " :
106 : __imm(bpf_map_lookup_elem),
107 __imm_addr(map_hash_8b),
108 __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
109 __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end))
110 : __clobber_all);
111 }
112
113 SEC("xdp")
114 __description("helper access to packet: test5, packet_ptr with too short range")
115 __failure __msg("invalid access to packet")
ptr_with_too_short_range_1(void)116 __naked void ptr_with_too_short_range_1(void)
117 {
118 asm volatile (" \
119 r2 = *(u32*)(r1 + %[xdp_md_data]); \
120 r3 = *(u32*)(r1 + %[xdp_md_data_end]); \
121 r2 += 1; \
122 r4 = r2; \
123 r4 += 7; \
124 if r4 > r3 goto l0_%=; \
125 r1 = %[map_hash_8b] ll; \
126 call %[bpf_map_lookup_elem]; \
127 l0_%=: r0 = 0; \
128 exit; \
129 " :
130 : __imm(bpf_map_lookup_elem),
131 __imm_addr(map_hash_8b),
132 __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
133 __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end))
134 : __clobber_all);
135 }
136
137 SEC("tc")
138 __description("helper access to packet: test6, cls valid packet_ptr range")
139 __success __retval(0)
cls_valid_packet_ptr_range(void)140 __naked void cls_valid_packet_ptr_range(void)
141 {
142 asm volatile (" \
143 r2 = *(u32*)(r1 + %[__sk_buff_data]); \
144 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \
145 r1 = r2; \
146 r1 += 8; \
147 if r1 > r3 goto l0_%=; \
148 r1 = %[map_hash_8b] ll; \
149 r3 = r2; \
150 r4 = 0; \
151 call %[bpf_map_update_elem]; \
152 l0_%=: r0 = 0; \
153 exit; \
154 " :
155 : __imm(bpf_map_update_elem),
156 __imm_addr(map_hash_8b),
157 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
158 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
159 : __clobber_all);
160 }
161
162 SEC("tc")
163 __description("helper access to packet: test7, cls unchecked packet_ptr")
164 __failure __msg("invalid access to packet")
test7_cls_unchecked_packet_ptr(void)165 __naked void test7_cls_unchecked_packet_ptr(void)
166 {
167 asm volatile (" \
168 r2 = *(u32*)(r1 + %[__sk_buff_data]); \
169 r1 = %[map_hash_8b] ll; \
170 call %[bpf_map_lookup_elem]; \
171 r0 = 0; \
172 exit; \
173 " :
174 : __imm(bpf_map_lookup_elem),
175 __imm_addr(map_hash_8b),
176 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data))
177 : __clobber_all);
178 }
179
180 SEC("tc")
181 __description("helper access to packet: test8, cls variable add")
182 __success __retval(0)
packet_test8_cls_variable_add(void)183 __naked void packet_test8_cls_variable_add(void)
184 {
185 asm volatile (" \
186 r2 = *(u32*)(r1 + %[__sk_buff_data]); \
187 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \
188 r4 = r2; \
189 r4 += 8; \
190 if r4 > r3 goto l0_%=; \
191 r5 = *(u8*)(r2 + 0); \
192 r4 = r2; \
193 r4 += r5; \
194 r5 = r4; \
195 r5 += 8; \
196 if r5 > r3 goto l0_%=; \
197 r1 = %[map_hash_8b] ll; \
198 r2 = r4; \
199 call %[bpf_map_lookup_elem]; \
200 l0_%=: r0 = 0; \
201 exit; \
202 " :
203 : __imm(bpf_map_lookup_elem),
204 __imm_addr(map_hash_8b),
205 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
206 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
207 : __clobber_all);
208 }
209
210 SEC("tc")
211 __description("helper access to packet: test9, cls packet_ptr with bad range")
212 __failure __msg("invalid access to packet")
packet_ptr_with_bad_range_2(void)213 __naked void packet_ptr_with_bad_range_2(void)
214 {
215 asm volatile (" \
216 r2 = *(u32*)(r1 + %[__sk_buff_data]); \
217 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \
218 r4 = r2; \
219 r4 += 4; \
220 if r4 > r3 goto l0_%=; \
221 r0 = 0; \
222 exit; \
223 l0_%=: r1 = %[map_hash_8b] ll; \
224 call %[bpf_map_lookup_elem]; \
225 r0 = 0; \
226 exit; \
227 " :
228 : __imm(bpf_map_lookup_elem),
229 __imm_addr(map_hash_8b),
230 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
231 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
232 : __clobber_all);
233 }
234
235 SEC("tc")
236 __description("helper access to packet: test10, cls packet_ptr with too short range")
237 __failure __msg("invalid access to packet")
ptr_with_too_short_range_2(void)238 __naked void ptr_with_too_short_range_2(void)
239 {
240 asm volatile (" \
241 r2 = *(u32*)(r1 + %[__sk_buff_data]); \
242 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \
243 r2 += 1; \
244 r4 = r2; \
245 r4 += 7; \
246 if r4 > r3 goto l0_%=; \
247 r1 = %[map_hash_8b] ll; \
248 call %[bpf_map_lookup_elem]; \
249 l0_%=: r0 = 0; \
250 exit; \
251 " :
252 : __imm(bpf_map_lookup_elem),
253 __imm_addr(map_hash_8b),
254 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
255 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
256 : __clobber_all);
257 }
258
259 SEC("tc")
260 __description("helper access to packet: test11, cls unsuitable helper 1")
261 __failure __msg("helper access to the packet")
test11_cls_unsuitable_helper_1(void)262 __naked void test11_cls_unsuitable_helper_1(void)
263 {
264 asm volatile (" \
265 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
266 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
267 r6 += 1; \
268 r3 = r6; \
269 r3 += 7; \
270 if r3 > r7 goto l0_%=; \
271 r2 = 0; \
272 r4 = 42; \
273 r5 = 0; \
274 call %[bpf_skb_store_bytes]; \
275 l0_%=: r0 = 0; \
276 exit; \
277 " :
278 : __imm(bpf_skb_store_bytes),
279 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
280 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
281 : __clobber_all);
282 }
283
284 SEC("tc")
285 __description("helper access to packet: test12, cls unsuitable helper 2")
286 __failure __msg("helper access to the packet")
test12_cls_unsuitable_helper_2(void)287 __naked void test12_cls_unsuitable_helper_2(void)
288 {
289 asm volatile (" \
290 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
291 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
292 r3 = r6; \
293 r6 += 8; \
294 if r6 > r7 goto l0_%=; \
295 r2 = 0; \
296 r4 = 4; \
297 call %[bpf_skb_load_bytes]; \
298 l0_%=: r0 = 0; \
299 exit; \
300 " :
301 : __imm(bpf_skb_load_bytes),
302 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
303 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
304 : __clobber_all);
305 }
306
307 SEC("tc")
308 __description("helper access to packet: test13, cls helper ok")
309 __success __retval(0)
packet_test13_cls_helper_ok(void)310 __naked void packet_test13_cls_helper_ok(void)
311 {
312 asm volatile (" \
313 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
314 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
315 r6 += 1; \
316 r1 = r6; \
317 r1 += 7; \
318 if r1 > r7 goto l0_%=; \
319 r1 = r6; \
320 r2 = 4; \
321 r3 = 0; \
322 r4 = 0; \
323 r5 = 0; \
324 call %[bpf_csum_diff]; \
325 l0_%=: r0 = 0; \
326 exit; \
327 " :
328 : __imm(bpf_csum_diff),
329 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
330 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
331 : __clobber_all);
332 }
333
334 SEC("tc")
335 __description("helper access to packet: test14, cls helper ok sub")
336 __success __retval(0)
test14_cls_helper_ok_sub(void)337 __naked void test14_cls_helper_ok_sub(void)
338 {
339 asm volatile (" \
340 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
341 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
342 r6 += 1; \
343 r1 = r6; \
344 r1 += 7; \
345 if r1 > r7 goto l0_%=; \
346 r1 -= 4; \
347 r2 = 4; \
348 r3 = 0; \
349 r4 = 0; \
350 r5 = 0; \
351 call %[bpf_csum_diff]; \
352 l0_%=: r0 = 0; \
353 exit; \
354 " :
355 : __imm(bpf_csum_diff),
356 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
357 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
358 : __clobber_all);
359 }
360
361 SEC("tc")
362 __description("helper access to packet: test15, cls helper fail sub")
363 __failure __msg("invalid access to packet")
test15_cls_helper_fail_sub(void)364 __naked void test15_cls_helper_fail_sub(void)
365 {
366 asm volatile (" \
367 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
368 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
369 r6 += 1; \
370 r1 = r6; \
371 r1 += 7; \
372 if r1 > r7 goto l0_%=; \
373 r1 -= 12; \
374 r2 = 4; \
375 r3 = 0; \
376 r4 = 0; \
377 r5 = 0; \
378 call %[bpf_csum_diff]; \
379 l0_%=: r0 = 0; \
380 exit; \
381 " :
382 : __imm(bpf_csum_diff),
383 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
384 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
385 : __clobber_all);
386 }
387
388 SEC("tc")
389 __description("helper access to packet: test16, cls helper fail range 1")
390 __failure __msg("invalid access to packet")
cls_helper_fail_range_1(void)391 __naked void cls_helper_fail_range_1(void)
392 {
393 asm volatile (" \
394 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
395 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
396 r6 += 1; \
397 r1 = r6; \
398 r1 += 7; \
399 if r1 > r7 goto l0_%=; \
400 r1 = r6; \
401 r2 = 8; \
402 r3 = 0; \
403 r4 = 0; \
404 r5 = 0; \
405 call %[bpf_csum_diff]; \
406 l0_%=: r0 = 0; \
407 exit; \
408 " :
409 : __imm(bpf_csum_diff),
410 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
411 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
412 : __clobber_all);
413 }
414
415 SEC("tc")
416 __description("helper access to packet: test17, cls helper fail range 2")
417 __failure __msg("R2 min value is negative")
cls_helper_fail_range_2(void)418 __naked void cls_helper_fail_range_2(void)
419 {
420 asm volatile (" \
421 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
422 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
423 r6 += 1; \
424 r1 = r6; \
425 r1 += 7; \
426 if r1 > r7 goto l0_%=; \
427 r1 = r6; \
428 r2 = -9; \
429 r3 = 0; \
430 r4 = 0; \
431 r5 = 0; \
432 call %[bpf_csum_diff]; \
433 l0_%=: r0 = 0; \
434 exit; \
435 " :
436 : __imm(bpf_csum_diff),
437 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
438 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
439 : __clobber_all);
440 }
441
442 SEC("tc")
443 __description("helper access to packet: test18, cls helper fail range 3")
444 __failure __msg("R2 min value is negative")
cls_helper_fail_range_3(void)445 __naked void cls_helper_fail_range_3(void)
446 {
447 asm volatile (" \
448 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
449 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
450 r6 += 1; \
451 r1 = r6; \
452 r1 += 7; \
453 if r1 > r7 goto l0_%=; \
454 r1 = r6; \
455 r2 = %[__imm_0]; \
456 r3 = 0; \
457 r4 = 0; \
458 r5 = 0; \
459 call %[bpf_csum_diff]; \
460 l0_%=: r0 = 0; \
461 exit; \
462 " :
463 : __imm(bpf_csum_diff),
464 __imm_const(__imm_0, ~0),
465 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
466 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
467 : __clobber_all);
468 }
469
470 SEC("tc")
471 __description("helper access to packet: test19, cls helper range zero")
472 __success __retval(0)
test19_cls_helper_range_zero(void)473 __naked void test19_cls_helper_range_zero(void)
474 {
475 asm volatile (" \
476 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
477 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
478 r6 += 1; \
479 r1 = r6; \
480 r1 += 7; \
481 if r1 > r7 goto l0_%=; \
482 r1 = r6; \
483 r2 = 0; \
484 r3 = 0; \
485 r4 = 0; \
486 r5 = 0; \
487 call %[bpf_csum_diff]; \
488 l0_%=: r0 = 0; \
489 exit; \
490 " :
491 : __imm(bpf_csum_diff),
492 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
493 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
494 : __clobber_all);
495 }
496
497 SEC("tc")
498 __description("helper access to packet: test20, pkt end as input")
499 __failure __msg("R1 type=pkt_end expected=fp")
test20_pkt_end_as_input(void)500 __naked void test20_pkt_end_as_input(void)
501 {
502 asm volatile (" \
503 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
504 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
505 r6 += 1; \
506 r1 = r6; \
507 r1 += 7; \
508 if r1 > r7 goto l0_%=; \
509 r1 = r7; \
510 r2 = 4; \
511 r3 = 0; \
512 r4 = 0; \
513 r5 = 0; \
514 call %[bpf_csum_diff]; \
515 l0_%=: r0 = 0; \
516 exit; \
517 " :
518 : __imm(bpf_csum_diff),
519 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
520 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
521 : __clobber_all);
522 }
523
524 SEC("tc")
525 __description("helper access to packet: test21, wrong reg")
526 __failure __msg("invalid access to packet")
to_packet_test21_wrong_reg(void)527 __naked void to_packet_test21_wrong_reg(void)
528 {
529 asm volatile (" \
530 r6 = *(u32*)(r1 + %[__sk_buff_data]); \
531 r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \
532 r6 += 1; \
533 r1 = r6; \
534 r1 += 7; \
535 if r1 > r7 goto l0_%=; \
536 r2 = 4; \
537 r3 = 0; \
538 r4 = 0; \
539 r5 = 0; \
540 call %[bpf_csum_diff]; \
541 r0 = 0; \
542 l0_%=: exit; \
543 " :
544 : __imm(bpf_csum_diff),
545 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
546 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
547 : __clobber_all);
548 }
549
550 char _license[] SEC("license") = "GPL";
551