selftests/bpf: test if state loops are detected in a tricky case
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / iters.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3
4 #include <stdbool.h>
5 #include <linux/bpf.h>
6 #include <bpf/bpf_helpers.h>
7 #include "bpf_misc.h"
8
9 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
10
11 static volatile int zero = 0;
12
13 int my_pid;
14 int arr[256];
15 int small_arr[16] SEC(".data.small_arr");
16
17 struct {
18         __uint(type, BPF_MAP_TYPE_HASH);
19         __uint(max_entries, 10);
20         __type(key, int);
21         __type(value, int);
22 } amap SEC(".maps");
23
24 #ifdef REAL_TEST
25 #define MY_PID_GUARD() if (my_pid != (bpf_get_current_pid_tgid() >> 32)) return 0
26 #else
27 #define MY_PID_GUARD() ({ })
28 #endif
29
30 SEC("?raw_tp")
31 __failure __msg("math between map_value pointer and register with unbounded min value is not allowed")
32 int iter_err_unsafe_c_loop(const void *ctx)
33 {
34         struct bpf_iter_num it;
35         int *v, i = zero; /* obscure initial value of i */
36
37         MY_PID_GUARD();
38
39         bpf_iter_num_new(&it, 0, 1000);
40         while ((v = bpf_iter_num_next(&it))) {
41                 i++;
42         }
43         bpf_iter_num_destroy(&it);
44
45         small_arr[i] = 123; /* invalid */
46
47         return 0;
48 }
49
50 SEC("?raw_tp")
51 __failure __msg("unbounded memory access")
52 int iter_err_unsafe_asm_loop(const void *ctx)
53 {
54         struct bpf_iter_num it;
55
56         MY_PID_GUARD();
57
58         asm volatile (
59                 "r6 = %[zero];" /* iteration counter */
60                 "r1 = %[it];" /* iterator state */
61                 "r2 = 0;"
62                 "r3 = 1000;"
63                 "r4 = 1;"
64                 "call %[bpf_iter_num_new];"
65         "loop:"
66                 "r1 = %[it];"
67                 "call %[bpf_iter_num_next];"
68                 "if r0 == 0 goto out;"
69                 "r6 += 1;"
70                 "goto loop;"
71         "out:"
72                 "r1 = %[it];"
73                 "call %[bpf_iter_num_destroy];"
74                 "r1 = %[small_arr];"
75                 "r2 = r6;"
76                 "r2 <<= 2;"
77                 "r1 += r2;"
78                 "*(u32 *)(r1 + 0) = r6;" /* invalid */
79                 :
80                 : [it]"r"(&it),
81                   [small_arr]"p"(small_arr),
82                   [zero]"p"(zero),
83                   __imm(bpf_iter_num_new),
84                   __imm(bpf_iter_num_next),
85                   __imm(bpf_iter_num_destroy)
86                 : __clobber_common, "r6"
87         );
88
89         return 0;
90 }
91
92 SEC("raw_tp")
93 __success
94 int iter_while_loop(const void *ctx)
95 {
96         struct bpf_iter_num it;
97         int *v;
98
99         MY_PID_GUARD();
100
101         bpf_iter_num_new(&it, 0, 3);
102         while ((v = bpf_iter_num_next(&it))) {
103                 bpf_printk("ITER_BASIC: E1 VAL: v=%d", *v);
104         }
105         bpf_iter_num_destroy(&it);
106
107         return 0;
108 }
109
110 SEC("raw_tp")
111 __success
112 int iter_while_loop_auto_cleanup(const void *ctx)
113 {
114         __attribute__((cleanup(bpf_iter_num_destroy))) struct bpf_iter_num it;
115         int *v;
116
117         MY_PID_GUARD();
118
119         bpf_iter_num_new(&it, 0, 3);
120         while ((v = bpf_iter_num_next(&it))) {
121                 bpf_printk("ITER_BASIC: E1 VAL: v=%d", *v);
122         }
123         /* (!) no explicit bpf_iter_num_destroy() */
124
125         return 0;
126 }
127
128 SEC("raw_tp")
129 __success
130 int iter_for_loop(const void *ctx)
131 {
132         struct bpf_iter_num it;
133         int *v;
134
135         MY_PID_GUARD();
136
137         bpf_iter_num_new(&it, 5, 10);
138         for (v = bpf_iter_num_next(&it); v; v = bpf_iter_num_next(&it)) {
139                 bpf_printk("ITER_BASIC: E2 VAL: v=%d", *v);
140         }
141         bpf_iter_num_destroy(&it);
142
143         return 0;
144 }
145
146 SEC("raw_tp")
147 __success
148 int iter_bpf_for_each_macro(const void *ctx)
149 {
150         int *v;
151
152         MY_PID_GUARD();
153
154         bpf_for_each(num, v, 5, 10) {
155                 bpf_printk("ITER_BASIC: E2 VAL: v=%d", *v);
156         }
157
158         return 0;
159 }
160
161 SEC("raw_tp")
162 __success
163 int iter_bpf_for_macro(const void *ctx)
164 {
165         int i;
166
167         MY_PID_GUARD();
168
169         bpf_for(i, 5, 10) {
170                 bpf_printk("ITER_BASIC: E2 VAL: v=%d", i);
171         }
172
173         return 0;
174 }
175
176 SEC("raw_tp")
177 __success
178 int iter_pragma_unroll_loop(const void *ctx)
179 {
180         struct bpf_iter_num it;
181         int *v, i;
182
183         MY_PID_GUARD();
184
185         bpf_iter_num_new(&it, 0, 2);
186 #pragma nounroll
187         for (i = 0; i < 3; i++) {
188                 v = bpf_iter_num_next(&it);
189                 bpf_printk("ITER_BASIC: E3 VAL: i=%d v=%d", i, v ? *v : -1);
190         }
191         bpf_iter_num_destroy(&it);
192
193         return 0;
194 }
195
196 SEC("raw_tp")
197 __success
198 int iter_manual_unroll_loop(const void *ctx)
199 {
200         struct bpf_iter_num it;
201         int *v;
202
203         MY_PID_GUARD();
204
205         bpf_iter_num_new(&it, 100, 200);
206         v = bpf_iter_num_next(&it);
207         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
208         v = bpf_iter_num_next(&it);
209         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
210         v = bpf_iter_num_next(&it);
211         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
212         v = bpf_iter_num_next(&it);
213         bpf_printk("ITER_BASIC: E4 VAL: v=%d\n", v ? *v : -1);
214         bpf_iter_num_destroy(&it);
215
216         return 0;
217 }
218
219 SEC("raw_tp")
220 __success
221 int iter_multiple_sequential_loops(const void *ctx)
222 {
223         struct bpf_iter_num it;
224         int *v, i;
225
226         MY_PID_GUARD();
227
228         bpf_iter_num_new(&it, 0, 3);
229         while ((v = bpf_iter_num_next(&it))) {
230                 bpf_printk("ITER_BASIC: E1 VAL: v=%d", *v);
231         }
232         bpf_iter_num_destroy(&it);
233
234         bpf_iter_num_new(&it, 5, 10);
235         for (v = bpf_iter_num_next(&it); v; v = bpf_iter_num_next(&it)) {
236                 bpf_printk("ITER_BASIC: E2 VAL: v=%d", *v);
237         }
238         bpf_iter_num_destroy(&it);
239
240         bpf_iter_num_new(&it, 0, 2);
241 #pragma nounroll
242         for (i = 0; i < 3; i++) {
243                 v = bpf_iter_num_next(&it);
244                 bpf_printk("ITER_BASIC: E3 VAL: i=%d v=%d", i, v ? *v : -1);
245         }
246         bpf_iter_num_destroy(&it);
247
248         bpf_iter_num_new(&it, 100, 200);
249         v = bpf_iter_num_next(&it);
250         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
251         v = bpf_iter_num_next(&it);
252         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
253         v = bpf_iter_num_next(&it);
254         bpf_printk("ITER_BASIC: E4 VAL: v=%d", v ? *v : -1);
255         v = bpf_iter_num_next(&it);
256         bpf_printk("ITER_BASIC: E4 VAL: v=%d\n", v ? *v : -1);
257         bpf_iter_num_destroy(&it);
258
259         return 0;
260 }
261
262 SEC("raw_tp")
263 __success
264 int iter_limit_cond_break_loop(const void *ctx)
265 {
266         struct bpf_iter_num it;
267         int *v, i = 0, sum = 0;
268
269         MY_PID_GUARD();
270
271         bpf_iter_num_new(&it, 0, 10);
272         while ((v = bpf_iter_num_next(&it))) {
273                 bpf_printk("ITER_SIMPLE: i=%d v=%d", i, *v);
274                 sum += *v;
275
276                 i++;
277                 if (i > 3)
278                         break;
279         }
280         bpf_iter_num_destroy(&it);
281
282         bpf_printk("ITER_SIMPLE: sum=%d\n", sum);
283
284         return 0;
285 }
286
287 SEC("raw_tp")
288 __success
289 int iter_obfuscate_counter(const void *ctx)
290 {
291         struct bpf_iter_num it;
292         int *v, sum = 0;
293         /* Make i's initial value unknowable for verifier to prevent it from
294          * pruning if/else branch inside the loop body and marking i as precise.
295          */
296         int i = zero;
297
298         MY_PID_GUARD();
299
300         bpf_iter_num_new(&it, 0, 10);
301         while ((v = bpf_iter_num_next(&it))) {
302                 int x;
303
304                 i += 1;
305
306                 /* If we initialized i as `int i = 0;` above, verifier would
307                  * track that i becomes 1 on first iteration after increment
308                  * above, and here verifier would eagerly prune else branch
309                  * and mark i as precise, ruining open-coded iterator logic
310                  * completely, as each next iteration would have a different
311                  * *precise* value of i, and thus there would be no
312                  * convergence of state. This would result in reaching maximum
313                  * instruction limit, no matter what the limit is.
314                  */
315                 if (i == 1)
316                         x = 123;
317                 else
318                         x = i * 3 + 1;
319
320                 bpf_printk("ITER_OBFUSCATE_COUNTER: i=%d v=%d x=%d", i, *v, x);
321
322                 sum += x;
323         }
324         bpf_iter_num_destroy(&it);
325
326         bpf_printk("ITER_OBFUSCATE_COUNTER: sum=%d\n", sum);
327
328         return 0;
329 }
330
331 SEC("raw_tp")
332 __success
333 int iter_search_loop(const void *ctx)
334 {
335         struct bpf_iter_num it;
336         int *v, *elem = NULL;
337         bool found = false;
338
339         MY_PID_GUARD();
340
341         bpf_iter_num_new(&it, 0, 10);
342
343         while ((v = bpf_iter_num_next(&it))) {
344                 bpf_printk("ITER_SEARCH_LOOP: v=%d", *v);
345
346                 if (*v == 2) {
347                         found = true;
348                         elem = v;
349                         barrier_var(elem);
350                 }
351         }
352
353         /* should fail to verify if bpf_iter_num_destroy() is here */
354
355         if (found)
356                 /* here found element will be wrong, we should have copied
357                  * value to a variable, but here we want to make sure we can
358                  * access memory after the loop anyways
359                  */
360                 bpf_printk("ITER_SEARCH_LOOP: FOUND IT = %d!\n", *elem);
361         else
362                 bpf_printk("ITER_SEARCH_LOOP: NOT FOUND IT!\n");
363
364         bpf_iter_num_destroy(&it);
365
366         return 0;
367 }
368
369 SEC("raw_tp")
370 __success
371 int iter_array_fill(const void *ctx)
372 {
373         int sum, i;
374
375         MY_PID_GUARD();
376
377         bpf_for(i, 0, ARRAY_SIZE(arr)) {
378                 arr[i] = i * 2;
379         }
380
381         sum = 0;
382         bpf_for(i, 0, ARRAY_SIZE(arr)) {
383                 sum += arr[i];
384         }
385
386         bpf_printk("ITER_ARRAY_FILL: sum=%d (should be %d)\n", sum, 255 * 256);
387
388         return 0;
389 }
390
391 static int arr2d[4][5];
392 static int arr2d_row_sums[4];
393 static int arr2d_col_sums[5];
394
395 SEC("raw_tp")
396 __success
397 int iter_nested_iters(const void *ctx)
398 {
399         int sum, row, col;
400
401         MY_PID_GUARD();
402
403         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
404                 bpf_for( col, 0, ARRAY_SIZE(arr2d[0])) {
405                         arr2d[row][col] = row * col;
406                 }
407         }
408
409         /* zero-initialize sums */
410         sum = 0;
411         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
412                 arr2d_row_sums[row] = 0;
413         }
414         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
415                 arr2d_col_sums[col] = 0;
416         }
417
418         /* calculate sums */
419         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
420                 bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
421                         sum += arr2d[row][col];
422                         arr2d_row_sums[row] += arr2d[row][col];
423                         arr2d_col_sums[col] += arr2d[row][col];
424                 }
425         }
426
427         bpf_printk("ITER_NESTED_ITERS: total sum=%d", sum);
428         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
429                 bpf_printk("ITER_NESTED_ITERS: row #%d sum=%d", row, arr2d_row_sums[row]);
430         }
431         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
432                 bpf_printk("ITER_NESTED_ITERS: col #%d sum=%d%s",
433                            col, arr2d_col_sums[col],
434                            col == ARRAY_SIZE(arr2d[0]) - 1 ? "\n" : "");
435         }
436
437         return 0;
438 }
439
440 SEC("raw_tp")
441 __success
442 int iter_nested_deeply_iters(const void *ctx)
443 {
444         int sum = 0;
445
446         MY_PID_GUARD();
447
448         bpf_repeat(10) {
449                 bpf_repeat(10) {
450                         bpf_repeat(10) {
451                                 bpf_repeat(10) {
452                                         bpf_repeat(10) {
453                                                 sum += 1;
454                                         }
455                                 }
456                         }
457                 }
458                 /* validate that we can break from inside bpf_repeat() */
459                 break;
460         }
461
462         return sum;
463 }
464
465 static __noinline void fill_inner_dimension(int row)
466 {
467         int col;
468
469         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
470                 arr2d[row][col] = row * col;
471         }
472 }
473
474 static __noinline int sum_inner_dimension(int row)
475 {
476         int sum = 0, col;
477
478         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
479                 sum += arr2d[row][col];
480                 arr2d_row_sums[row] += arr2d[row][col];
481                 arr2d_col_sums[col] += arr2d[row][col];
482         }
483
484         return sum;
485 }
486
487 SEC("raw_tp")
488 __success
489 int iter_subprog_iters(const void *ctx)
490 {
491         int sum, row, col;
492
493         MY_PID_GUARD();
494
495         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
496                 fill_inner_dimension(row);
497         }
498
499         /* zero-initialize sums */
500         sum = 0;
501         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
502                 arr2d_row_sums[row] = 0;
503         }
504         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
505                 arr2d_col_sums[col] = 0;
506         }
507
508         /* calculate sums */
509         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
510                 sum += sum_inner_dimension(row);
511         }
512
513         bpf_printk("ITER_SUBPROG_ITERS: total sum=%d", sum);
514         bpf_for(row, 0, ARRAY_SIZE(arr2d)) {
515                 bpf_printk("ITER_SUBPROG_ITERS: row #%d sum=%d",
516                            row, arr2d_row_sums[row]);
517         }
518         bpf_for(col, 0, ARRAY_SIZE(arr2d[0])) {
519                 bpf_printk("ITER_SUBPROG_ITERS: col #%d sum=%d%s",
520                            col, arr2d_col_sums[col],
521                            col == ARRAY_SIZE(arr2d[0]) - 1 ? "\n" : "");
522         }
523
524         return 0;
525 }
526
527 struct {
528         __uint(type, BPF_MAP_TYPE_ARRAY);
529         __type(key, int);
530         __type(value, int);
531         __uint(max_entries, 1000);
532 } arr_map SEC(".maps");
533
534 SEC("?raw_tp")
535 __failure __msg("invalid mem access 'scalar'")
536 int iter_err_too_permissive1(const void *ctx)
537 {
538         int *map_val = NULL;
539         int key = 0;
540
541         MY_PID_GUARD();
542
543         map_val = bpf_map_lookup_elem(&arr_map, &key);
544         if (!map_val)
545                 return 0;
546
547         bpf_repeat(1000000) {
548                 map_val = NULL;
549         }
550
551         *map_val = 123;
552
553         return 0;
554 }
555
556 SEC("?raw_tp")
557 __failure __msg("invalid mem access 'map_value_or_null'")
558 int iter_err_too_permissive2(const void *ctx)
559 {
560         int *map_val = NULL;
561         int key = 0;
562
563         MY_PID_GUARD();
564
565         map_val = bpf_map_lookup_elem(&arr_map, &key);
566         if (!map_val)
567                 return 0;
568
569         bpf_repeat(1000000) {
570                 map_val = bpf_map_lookup_elem(&arr_map, &key);
571         }
572
573         *map_val = 123;
574
575         return 0;
576 }
577
578 SEC("?raw_tp")
579 __failure __msg("invalid mem access 'map_value_or_null'")
580 int iter_err_too_permissive3(const void *ctx)
581 {
582         int *map_val = NULL;
583         int key = 0;
584         bool found = false;
585
586         MY_PID_GUARD();
587
588         bpf_repeat(1000000) {
589                 map_val = bpf_map_lookup_elem(&arr_map, &key);
590                 found = true;
591         }
592
593         if (found)
594                 *map_val = 123;
595
596         return 0;
597 }
598
599 SEC("raw_tp")
600 __success
601 int iter_tricky_but_fine(const void *ctx)
602 {
603         int *map_val = NULL;
604         int key = 0;
605         bool found = false;
606
607         MY_PID_GUARD();
608
609         bpf_repeat(1000000) {
610                 map_val = bpf_map_lookup_elem(&arr_map, &key);
611                 if (map_val) {
612                         found = true;
613                         break;
614                 }
615         }
616
617         if (found)
618                 *map_val = 123;
619
620         return 0;
621 }
622
623 #define __bpf_memzero(p, sz) bpf_probe_read_kernel((p), (sz), 0)
624
625 SEC("raw_tp")
626 __success
627 int iter_stack_array_loop(const void *ctx)
628 {
629         long arr1[16], arr2[16], sum = 0;
630         int i;
631
632         MY_PID_GUARD();
633
634         /* zero-init arr1 and arr2 in such a way that verifier doesn't know
635          * it's all zeros; if we don't do that, we'll make BPF verifier track
636          * all combination of zero/non-zero stack slots for arr1/arr2, which
637          * will lead to O(2^(ARRAY_SIZE(arr1)+ARRAY_SIZE(arr2))) different
638          * states
639          */
640         __bpf_memzero(arr1, sizeof(arr1));
641         __bpf_memzero(arr2, sizeof(arr1));
642
643         /* validate that we can break and continue when using bpf_for() */
644         bpf_for(i, 0, ARRAY_SIZE(arr1)) {
645                 if (i & 1) {
646                         arr1[i] = i;
647                         continue;
648                 } else {
649                         arr2[i] = i;
650                         break;
651                 }
652         }
653
654         bpf_for(i, 0, ARRAY_SIZE(arr1)) {
655                 sum += arr1[i] + arr2[i];
656         }
657
658         return sum;
659 }
660
661 static __noinline void fill(struct bpf_iter_num *it, int *arr, __u32 n, int mul)
662 {
663         int *t, i;
664
665         while ((t = bpf_iter_num_next(it))) {
666                 i = *t;
667                 if (i >= n)
668                         break;
669                 arr[i] =  i * mul;
670         }
671 }
672
673 static __noinline int sum(struct bpf_iter_num *it, int *arr, __u32 n)
674 {
675         int *t, i, sum = 0;;
676
677         while ((t = bpf_iter_num_next(it))) {
678                 i = *t;
679                 if (i >= n)
680                         break;
681                 sum += arr[i];
682         }
683
684         return sum;
685 }
686
687 SEC("raw_tp")
688 __success
689 int iter_pass_iter_ptr_to_subprog(const void *ctx)
690 {
691         int arr1[16], arr2[32];
692         struct bpf_iter_num it;
693         int n, sum1, sum2;
694
695         MY_PID_GUARD();
696
697         /* fill arr1 */
698         n = ARRAY_SIZE(arr1);
699         bpf_iter_num_new(&it, 0, n);
700         fill(&it, arr1, n, 2);
701         bpf_iter_num_destroy(&it);
702
703         /* fill arr2 */
704         n = ARRAY_SIZE(arr2);
705         bpf_iter_num_new(&it, 0, n);
706         fill(&it, arr2, n, 10);
707         bpf_iter_num_destroy(&it);
708
709         /* sum arr1 */
710         n = ARRAY_SIZE(arr1);
711         bpf_iter_num_new(&it, 0, n);
712         sum1 = sum(&it, arr1, n);
713         bpf_iter_num_destroy(&it);
714
715         /* sum arr2 */
716         n = ARRAY_SIZE(arr2);
717         bpf_iter_num_new(&it, 0, n);
718         sum2 = sum(&it, arr2, n);
719         bpf_iter_num_destroy(&it);
720
721         bpf_printk("sum1=%d, sum2=%d", sum1, sum2);
722
723         return 0;
724 }
725
726 SEC("?raw_tp")
727 __failure
728 __msg("R1 type=scalar expected=fp")
729 __naked int delayed_read_mark(void)
730 {
731         /* This is equivalent to C program below.
732          * The call to bpf_iter_num_next() is reachable with r7 values &fp[-16] and 0xdead.
733          * State with r7=&fp[-16] is visited first and follows r6 != 42 ... continue branch.
734          * At this point iterator next() call is reached with r7 that has no read mark.
735          * Loop body with r7=0xdead would only be visited if verifier would decide to continue
736          * with second loop iteration. Absence of read mark on r7 might affect state
737          * equivalent logic used for iterator convergence tracking.
738          *
739          * r7 = &fp[-16]
740          * fp[-16] = 0
741          * r6 = bpf_get_prandom_u32()
742          * bpf_iter_num_new(&fp[-8], 0, 10)
743          * while (bpf_iter_num_next(&fp[-8])) {
744          *   r6++
745          *   if (r6 != 42) {
746          *     r7 = 0xdead
747          *     continue;
748          *   }
749          *   bpf_probe_read_user(r7, 8, 0xdeadbeef); // this is not safe
750          * }
751          * bpf_iter_num_destroy(&fp[-8])
752          * return 0
753          */
754         asm volatile (
755                 "r7 = r10;"
756                 "r7 += -16;"
757                 "r0 = 0;"
758                 "*(u64 *)(r7 + 0) = r0;"
759                 "call %[bpf_get_prandom_u32];"
760                 "r6 = r0;"
761                 "r1 = r10;"
762                 "r1 += -8;"
763                 "r2 = 0;"
764                 "r3 = 10;"
765                 "call %[bpf_iter_num_new];"
766         "1:"
767                 "r1 = r10;"
768                 "r1 += -8;"
769                 "call %[bpf_iter_num_next];"
770                 "if r0 == 0 goto 2f;"
771                 "r6 += 1;"
772                 "if r6 != 42 goto 3f;"
773                 "r7 = 0xdead;"
774                 "goto 1b;"
775         "3:"
776                 "r1 = r7;"
777                 "r2 = 8;"
778                 "r3 = 0xdeadbeef;"
779                 "call %[bpf_probe_read_user];"
780                 "goto 1b;"
781         "2:"
782                 "r1 = r10;"
783                 "r1 += -8;"
784                 "call %[bpf_iter_num_destroy];"
785                 "r0 = 0;"
786                 "exit;"
787                 :
788                 : __imm(bpf_get_prandom_u32),
789                   __imm(bpf_iter_num_new),
790                   __imm(bpf_iter_num_next),
791                   __imm(bpf_iter_num_destroy),
792                   __imm(bpf_probe_read_user)
793                 : __clobber_all
794         );
795 }
796
797 SEC("?raw_tp")
798 __failure
799 __msg("math between fp pointer and register with unbounded")
800 __naked int delayed_precision_mark(void)
801 {
802         /* This is equivalent to C program below.
803          * The test is similar to delayed_iter_mark but verifies that incomplete
804          * precision don't fool verifier.
805          * The call to bpf_iter_num_next() is reachable with r7 values -16 and -32.
806          * State with r7=-16 is visited first and follows r6 != 42 ... continue branch.
807          * At this point iterator next() call is reached with r7 that has no read
808          * and precision marks.
809          * Loop body with r7=-32 would only be visited if verifier would decide to continue
810          * with second loop iteration. Absence of precision mark on r7 might affect state
811          * equivalent logic used for iterator convergence tracking.
812          *
813          * r8 = 0
814          * fp[-16] = 0
815          * r7 = -16
816          * r6 = bpf_get_prandom_u32()
817          * bpf_iter_num_new(&fp[-8], 0, 10)
818          * while (bpf_iter_num_next(&fp[-8])) {
819          *   if (r6 != 42) {
820          *     r7 = -32
821          *     r6 = bpf_get_prandom_u32()
822          *     continue;
823          *   }
824          *   r0 = r10
825          *   r0 += r7
826          *   r8 = *(u64 *)(r0 + 0)           // this is not safe
827          *   r6 = bpf_get_prandom_u32()
828          * }
829          * bpf_iter_num_destroy(&fp[-8])
830          * return r8
831          */
832         asm volatile (
833                 "r8 = 0;"
834                 "*(u64 *)(r10 - 16) = r8;"
835                 "r7 = -16;"
836                 "call %[bpf_get_prandom_u32];"
837                 "r6 = r0;"
838                 "r1 = r10;"
839                 "r1 += -8;"
840                 "r2 = 0;"
841                 "r3 = 10;"
842                 "call %[bpf_iter_num_new];"
843         "1:"
844                 "r1 = r10;"
845                 "r1 += -8;\n"
846                 "call %[bpf_iter_num_next];"
847                 "if r0 == 0 goto 2f;"
848                 "if r6 != 42 goto 3f;"
849                 "r7 = -32;"
850                 "call %[bpf_get_prandom_u32];"
851                 "r6 = r0;"
852                 "goto 1b;\n"
853         "3:"
854                 "r0 = r10;"
855                 "r0 += r7;"
856                 "r8 = *(u64 *)(r0 + 0);"
857                 "call %[bpf_get_prandom_u32];"
858                 "r6 = r0;"
859                 "goto 1b;\n"
860         "2:"
861                 "r1 = r10;"
862                 "r1 += -8;"
863                 "call %[bpf_iter_num_destroy];"
864                 "r0 = r8;"
865                 "exit;"
866                 :
867                 : __imm(bpf_get_prandom_u32),
868                   __imm(bpf_iter_num_new),
869                   __imm(bpf_iter_num_next),
870                   __imm(bpf_iter_num_destroy),
871                   __imm(bpf_probe_read_user)
872                 : __clobber_all
873         );
874 }
875
876 SEC("?raw_tp")
877 __failure
878 __msg("math between fp pointer and register with unbounded")
879 __flag(BPF_F_TEST_STATE_FREQ)
880 __naked int loop_state_deps1(void)
881 {
882         /* This is equivalent to C program below.
883          *
884          * The case turns out to be tricky in a sense that:
885          * - states with c=-25 are explored only on a second iteration
886          *   of the outer loop;
887          * - states with read+precise mark on c are explored only on
888          *   second iteration of the inner loop and in a state which
889          *   is pushed to states stack first.
890          *
891          * Depending on the details of iterator convergence logic
892          * verifier might stop states traversal too early and miss
893          * unsafe c=-25 memory access.
894          *
895          *   j = iter_new();             // fp[-16]
896          *   a = 0;                      // r6
897          *   b = 0;                      // r7
898          *   c = -24;                    // r8
899          *   while (iter_next(j)) {
900          *     i = iter_new();           // fp[-8]
901          *     a = 0;                    // r6
902          *     b = 0;                    // r7
903          *     while (iter_next(i)) {
904          *       if (a == 1) {
905          *         a = 0;
906          *         b = 1;
907          *       } else if (a == 0) {
908          *         a = 1;
909          *         if (random() == 42)
910          *           continue;
911          *         if (b == 1) {
912          *           *(r10 + c) = 7;  // this is not safe
913          *           iter_destroy(i);
914          *           iter_destroy(j);
915          *           return;
916          *         }
917          *       }
918          *     }
919          *     iter_destroy(i);
920          *     a = 0;
921          *     b = 0;
922          *     c = -25;
923          *   }
924          *   iter_destroy(j);
925          *   return;
926          */
927         asm volatile (
928                 "r1 = r10;"
929                 "r1 += -16;"
930                 "r2 = 0;"
931                 "r3 = 10;"
932                 "call %[bpf_iter_num_new];"
933                 "r6 = 0;"
934                 "r7 = 0;"
935                 "r8 = -24;"
936         "j_loop_%=:"
937                 "r1 = r10;"
938                 "r1 += -16;"
939                 "call %[bpf_iter_num_next];"
940                 "if r0 == 0 goto j_loop_end_%=;"
941                 "r1 = r10;"
942                 "r1 += -8;"
943                 "r2 = 0;"
944                 "r3 = 10;"
945                 "call %[bpf_iter_num_new];"
946                 "r6 = 0;"
947                 "r7 = 0;"
948         "i_loop_%=:"
949                 "r1 = r10;"
950                 "r1 += -8;"
951                 "call %[bpf_iter_num_next];"
952                 "if r0 == 0 goto i_loop_end_%=;"
953         "check_one_r6_%=:"
954                 "if r6 != 1 goto check_zero_r6_%=;"
955                 "r6 = 0;"
956                 "r7 = 1;"
957                 "goto i_loop_%=;"
958         "check_zero_r6_%=:"
959                 "if r6 != 0 goto i_loop_%=;"
960                 "r6 = 1;"
961                 "call %[bpf_get_prandom_u32];"
962                 "if r0 != 42 goto check_one_r7_%=;"
963                 "goto i_loop_%=;"
964         "check_one_r7_%=:"
965                 "if r7 != 1 goto i_loop_%=;"
966                 "r0 = r10;"
967                 "r0 += r8;"
968                 "r1 = 7;"
969                 "*(u64 *)(r0 + 0) = r1;"
970                 "r1 = r10;"
971                 "r1 += -8;"
972                 "call %[bpf_iter_num_destroy];"
973                 "r1 = r10;"
974                 "r1 += -16;"
975                 "call %[bpf_iter_num_destroy];"
976                 "r0 = 0;"
977                 "exit;"
978         "i_loop_end_%=:"
979                 "r1 = r10;"
980                 "r1 += -8;"
981                 "call %[bpf_iter_num_destroy];"
982                 "r6 = 0;"
983                 "r7 = 0;"
984                 "r8 = -25;"
985                 "goto j_loop_%=;"
986         "j_loop_end_%=:"
987                 "r1 = r10;"
988                 "r1 += -16;"
989                 "call %[bpf_iter_num_destroy];"
990                 "r0 = 0;"
991                 "exit;"
992                 :
993                 : __imm(bpf_get_prandom_u32),
994                   __imm(bpf_iter_num_new),
995                   __imm(bpf_iter_num_next),
996                   __imm(bpf_iter_num_destroy)
997                 : __clobber_all
998         );
999 }
1000
1001 SEC("?raw_tp")
1002 __failure
1003 __msg("math between fp pointer and register with unbounded")
1004 __flag(BPF_F_TEST_STATE_FREQ)
1005 __naked int loop_state_deps2(void)
1006 {
1007         /* This is equivalent to C program below.
1008          *
1009          * The case turns out to be tricky in a sense that:
1010          * - states with read+precise mark on c are explored only on a second
1011          *   iteration of the first inner loop and in a state which is pushed to
1012          *   states stack first.
1013          * - states with c=-25 are explored only on a second iteration of the
1014          *   second inner loop and in a state which is pushed to states stack
1015          *   first.
1016          *
1017          * Depending on the details of iterator convergence logic
1018          * verifier might stop states traversal too early and miss
1019          * unsafe c=-25 memory access.
1020          *
1021          *   j = iter_new();             // fp[-16]
1022          *   a = 0;                      // r6
1023          *   b = 0;                      // r7
1024          *   c = -24;                    // r8
1025          *   while (iter_next(j)) {
1026          *     i = iter_new();           // fp[-8]
1027          *     a = 0;                    // r6
1028          *     b = 0;                    // r7
1029          *     while (iter_next(i)) {
1030          *       if (a == 1) {
1031          *         a = 0;
1032          *         b = 1;
1033          *       } else if (a == 0) {
1034          *         a = 1;
1035          *         if (random() == 42)
1036          *           continue;
1037          *         if (b == 1) {
1038          *           *(r10 + c) = 7;     // this is not safe
1039          *           iter_destroy(i);
1040          *           iter_destroy(j);
1041          *           return;
1042          *         }
1043          *       }
1044          *     }
1045          *     iter_destroy(i);
1046          *     i = iter_new();           // fp[-8]
1047          *     a = 0;                    // r6
1048          *     b = 0;                    // r7
1049          *     while (iter_next(i)) {
1050          *       if (a == 1) {
1051          *         a = 0;
1052          *         b = 1;
1053          *       } else if (a == 0) {
1054          *         a = 1;
1055          *         if (random() == 42)
1056          *           continue;
1057          *         if (b == 1) {
1058          *           a = 0;
1059          *           c = -25;
1060          *         }
1061          *       }
1062          *     }
1063          *     iter_destroy(i);
1064          *   }
1065          *   iter_destroy(j);
1066          *   return;
1067          */
1068         asm volatile (
1069                 "r1 = r10;"
1070                 "r1 += -16;"
1071                 "r2 = 0;"
1072                 "r3 = 10;"
1073                 "call %[bpf_iter_num_new];"
1074                 "r6 = 0;"
1075                 "r7 = 0;"
1076                 "r8 = -24;"
1077         "j_loop_%=:"
1078                 "r1 = r10;"
1079                 "r1 += -16;"
1080                 "call %[bpf_iter_num_next];"
1081                 "if r0 == 0 goto j_loop_end_%=;"
1082
1083                 /* first inner loop */
1084                 "r1 = r10;"
1085                 "r1 += -8;"
1086                 "r2 = 0;"
1087                 "r3 = 10;"
1088                 "call %[bpf_iter_num_new];"
1089                 "r6 = 0;"
1090                 "r7 = 0;"
1091         "i_loop_%=:"
1092                 "r1 = r10;"
1093                 "r1 += -8;"
1094                 "call %[bpf_iter_num_next];"
1095                 "if r0 == 0 goto i_loop_end_%=;"
1096         "check_one_r6_%=:"
1097                 "if r6 != 1 goto check_zero_r6_%=;"
1098                 "r6 = 0;"
1099                 "r7 = 1;"
1100                 "goto i_loop_%=;"
1101         "check_zero_r6_%=:"
1102                 "if r6 != 0 goto i_loop_%=;"
1103                 "r6 = 1;"
1104                 "call %[bpf_get_prandom_u32];"
1105                 "if r0 != 42 goto check_one_r7_%=;"
1106                 "goto i_loop_%=;"
1107         "check_one_r7_%=:"
1108                 "if r7 != 1 goto i_loop_%=;"
1109                 "r0 = r10;"
1110                 "r0 += r8;"
1111                 "r1 = 7;"
1112                 "*(u64 *)(r0 + 0) = r1;"
1113                 "r1 = r10;"
1114                 "r1 += -8;"
1115                 "call %[bpf_iter_num_destroy];"
1116                 "r1 = r10;"
1117                 "r1 += -16;"
1118                 "call %[bpf_iter_num_destroy];"
1119                 "r0 = 0;"
1120                 "exit;"
1121         "i_loop_end_%=:"
1122                 "r1 = r10;"
1123                 "r1 += -8;"
1124                 "call %[bpf_iter_num_destroy];"
1125
1126                 /* second inner loop */
1127                 "r1 = r10;"
1128                 "r1 += -8;"
1129                 "r2 = 0;"
1130                 "r3 = 10;"
1131                 "call %[bpf_iter_num_new];"
1132                 "r6 = 0;"
1133                 "r7 = 0;"
1134         "i2_loop_%=:"
1135                 "r1 = r10;"
1136                 "r1 += -8;"
1137                 "call %[bpf_iter_num_next];"
1138                 "if r0 == 0 goto i2_loop_end_%=;"
1139         "check2_one_r6_%=:"
1140                 "if r6 != 1 goto check2_zero_r6_%=;"
1141                 "r6 = 0;"
1142                 "r7 = 1;"
1143                 "goto i2_loop_%=;"
1144         "check2_zero_r6_%=:"
1145                 "if r6 != 0 goto i2_loop_%=;"
1146                 "r6 = 1;"
1147                 "call %[bpf_get_prandom_u32];"
1148                 "if r0 != 42 goto check2_one_r7_%=;"
1149                 "goto i2_loop_%=;"
1150         "check2_one_r7_%=:"
1151                 "if r7 != 1 goto i2_loop_%=;"
1152                 "r6 = 0;"
1153                 "r8 = -25;"
1154                 "goto i2_loop_%=;"
1155         "i2_loop_end_%=:"
1156                 "r1 = r10;"
1157                 "r1 += -8;"
1158                 "call %[bpf_iter_num_destroy];"
1159
1160                 "r6 = 0;"
1161                 "r7 = 0;"
1162                 "goto j_loop_%=;"
1163         "j_loop_end_%=:"
1164                 "r1 = r10;"
1165                 "r1 += -16;"
1166                 "call %[bpf_iter_num_destroy];"
1167                 "r0 = 0;"
1168                 "exit;"
1169                 :
1170                 : __imm(bpf_get_prandom_u32),
1171                   __imm(bpf_iter_num_new),
1172                   __imm(bpf_iter_num_next),
1173                   __imm(bpf_iter_num_destroy)
1174                 : __clobber_all
1175         );
1176 }
1177
1178 SEC("?raw_tp")
1179 __success
1180 __naked int triple_continue(void)
1181 {
1182         /* This is equivalent to C program below.
1183          * High branching factor of the loop body turned out to be
1184          * problematic for one of the iterator convergence tracking
1185          * algorithms explored.
1186          *
1187          * r6 = bpf_get_prandom_u32()
1188          * bpf_iter_num_new(&fp[-8], 0, 10)
1189          * while (bpf_iter_num_next(&fp[-8])) {
1190          *   if (bpf_get_prandom_u32() != 42)
1191          *     continue;
1192          *   if (bpf_get_prandom_u32() != 42)
1193          *     continue;
1194          *   if (bpf_get_prandom_u32() != 42)
1195          *     continue;
1196          *   r0 += 0;
1197          * }
1198          * bpf_iter_num_destroy(&fp[-8])
1199          * return 0
1200          */
1201         asm volatile (
1202                 "r1 = r10;"
1203                 "r1 += -8;"
1204                 "r2 = 0;"
1205                 "r3 = 10;"
1206                 "call %[bpf_iter_num_new];"
1207         "loop_%=:"
1208                 "r1 = r10;"
1209                 "r1 += -8;"
1210                 "call %[bpf_iter_num_next];"
1211                 "if r0 == 0 goto loop_end_%=;"
1212                 "call %[bpf_get_prandom_u32];"
1213                 "if r0 != 42 goto loop_%=;"
1214                 "call %[bpf_get_prandom_u32];"
1215                 "if r0 != 42 goto loop_%=;"
1216                 "call %[bpf_get_prandom_u32];"
1217                 "if r0 != 42 goto loop_%=;"
1218                 "r0 += 0;"
1219                 "goto loop_%=;"
1220         "loop_end_%=:"
1221                 "r1 = r10;"
1222                 "r1 += -8;"
1223                 "call %[bpf_iter_num_destroy];"
1224                 "r0 = 0;"
1225                 "exit;"
1226                 :
1227                 : __imm(bpf_get_prandom_u32),
1228                   __imm(bpf_iter_num_new),
1229                   __imm(bpf_iter_num_next),
1230                   __imm(bpf_iter_num_destroy)
1231                 : __clobber_all
1232         );
1233 }
1234
1235 SEC("?raw_tp")
1236 __success
1237 __naked int widen_spill(void)
1238 {
1239         /* This is equivalent to C program below.
1240          * The counter is stored in fp[-16], if this counter is not widened
1241          * verifier states representing loop iterations would never converge.
1242          *
1243          * fp[-16] = 0
1244          * bpf_iter_num_new(&fp[-8], 0, 10)
1245          * while (bpf_iter_num_next(&fp[-8])) {
1246          *   r0 = fp[-16];
1247          *   r0 += 1;
1248          *   fp[-16] = r0;
1249          * }
1250          * bpf_iter_num_destroy(&fp[-8])
1251          * return 0
1252          */
1253         asm volatile (
1254                 "r0 = 0;"
1255                 "*(u64 *)(r10 - 16) = r0;"
1256                 "r1 = r10;"
1257                 "r1 += -8;"
1258                 "r2 = 0;"
1259                 "r3 = 10;"
1260                 "call %[bpf_iter_num_new];"
1261         "loop_%=:"
1262                 "r1 = r10;"
1263                 "r1 += -8;"
1264                 "call %[bpf_iter_num_next];"
1265                 "if r0 == 0 goto loop_end_%=;"
1266                 "r0 = *(u64 *)(r10 - 16);"
1267                 "r0 += 1;"
1268                 "*(u64 *)(r10 - 16) = r0;"
1269                 "goto loop_%=;"
1270         "loop_end_%=:"
1271                 "r1 = r10;"
1272                 "r1 += -8;"
1273                 "call %[bpf_iter_num_destroy];"
1274                 "r0 = 0;"
1275                 "exit;"
1276                 :
1277                 : __imm(bpf_iter_num_new),
1278                   __imm(bpf_iter_num_next),
1279                   __imm(bpf_iter_num_destroy)
1280                 : __clobber_all
1281         );
1282 }
1283
1284 SEC("raw_tp")
1285 __success
1286 __naked int checkpoint_states_deletion(void)
1287 {
1288         /* This is equivalent to C program below.
1289          *
1290          *   int *a, *b, *c, *d, *e, *f;
1291          *   int i, sum = 0;
1292          *   bpf_for(i, 0, 10) {
1293          *     a = bpf_map_lookup_elem(&amap, &i);
1294          *     b = bpf_map_lookup_elem(&amap, &i);
1295          *     c = bpf_map_lookup_elem(&amap, &i);
1296          *     d = bpf_map_lookup_elem(&amap, &i);
1297          *     e = bpf_map_lookup_elem(&amap, &i);
1298          *     f = bpf_map_lookup_elem(&amap, &i);
1299          *     if (a) sum += 1;
1300          *     if (b) sum += 1;
1301          *     if (c) sum += 1;
1302          *     if (d) sum += 1;
1303          *     if (e) sum += 1;
1304          *     if (f) sum += 1;
1305          *   }
1306          *   return 0;
1307          *
1308          * The body of the loop spawns multiple simulation paths
1309          * with different combination of NULL/non-NULL information for a/b/c/d/e/f.
1310          * Each combination is unique from states_equal() point of view.
1311          * Explored states checkpoint is created after each iterator next call.
1312          * Iterator convergence logic expects that eventually current state
1313          * would get equal to one of the explored states and thus loop
1314          * exploration would be finished (at-least for a specific path).
1315          * Verifier evicts explored states with high miss to hit ratio
1316          * to to avoid comparing current state with too many explored
1317          * states per instruction.
1318          * This test is designed to "stress test" eviction policy defined using formula:
1319          *
1320          *    sl->miss_cnt > sl->hit_cnt * N + N // if true sl->state is evicted
1321          *
1322          * Currently N is set to 64, which allows for 6 variables in this test.
1323          */
1324         asm volatile (
1325                 "r6 = 0;"                  /* a */
1326                 "r7 = 0;"                  /* b */
1327                 "r8 = 0;"                  /* c */
1328                 "*(u64 *)(r10 - 24) = r6;" /* d */
1329                 "*(u64 *)(r10 - 32) = r6;" /* e */
1330                 "*(u64 *)(r10 - 40) = r6;" /* f */
1331                 "r9 = 0;"                  /* sum */
1332                 "r1 = r10;"
1333                 "r1 += -8;"
1334                 "r2 = 0;"
1335                 "r3 = 10;"
1336                 "call %[bpf_iter_num_new];"
1337         "loop_%=:"
1338                 "r1 = r10;"
1339                 "r1 += -8;"
1340                 "call %[bpf_iter_num_next];"
1341                 "if r0 == 0 goto loop_end_%=;"
1342
1343                 "*(u64 *)(r10 - 16) = r0;"
1344
1345                 "r1 = %[amap] ll;"
1346                 "r2 = r10;"
1347                 "r2 += -16;"
1348                 "call %[bpf_map_lookup_elem];"
1349                 "r6 = r0;"
1350
1351                 "r1 = %[amap] ll;"
1352                 "r2 = r10;"
1353                 "r2 += -16;"
1354                 "call %[bpf_map_lookup_elem];"
1355                 "r7 = r0;"
1356
1357                 "r1 = %[amap] ll;"
1358                 "r2 = r10;"
1359                 "r2 += -16;"
1360                 "call %[bpf_map_lookup_elem];"
1361                 "r8 = r0;"
1362
1363                 "r1 = %[amap] ll;"
1364                 "r2 = r10;"
1365                 "r2 += -16;"
1366                 "call %[bpf_map_lookup_elem];"
1367                 "*(u64 *)(r10 - 24) = r0;"
1368
1369                 "r1 = %[amap] ll;"
1370                 "r2 = r10;"
1371                 "r2 += -16;"
1372                 "call %[bpf_map_lookup_elem];"
1373                 "*(u64 *)(r10 - 32) = r0;"
1374
1375                 "r1 = %[amap] ll;"
1376                 "r2 = r10;"
1377                 "r2 += -16;"
1378                 "call %[bpf_map_lookup_elem];"
1379                 "*(u64 *)(r10 - 40) = r0;"
1380
1381                 "if r6 == 0 goto +1;"
1382                 "r9 += 1;"
1383                 "if r7 == 0 goto +1;"
1384                 "r9 += 1;"
1385                 "if r8 == 0 goto +1;"
1386                 "r9 += 1;"
1387                 "r0 = *(u64 *)(r10 - 24);"
1388                 "if r0 == 0 goto +1;"
1389                 "r9 += 1;"
1390                 "r0 = *(u64 *)(r10 - 32);"
1391                 "if r0 == 0 goto +1;"
1392                 "r9 += 1;"
1393                 "r0 = *(u64 *)(r10 - 40);"
1394                 "if r0 == 0 goto +1;"
1395                 "r9 += 1;"
1396
1397                 "goto loop_%=;"
1398         "loop_end_%=:"
1399                 "r1 = r10;"
1400                 "r1 += -8;"
1401                 "call %[bpf_iter_num_destroy];"
1402                 "r0 = 0;"
1403                 "exit;"
1404                 :
1405                 : __imm(bpf_map_lookup_elem),
1406                   __imm(bpf_iter_num_new),
1407                   __imm(bpf_iter_num_next),
1408                   __imm(bpf_iter_num_destroy),
1409                   __imm_addr(amap)
1410                 : __clobber_all
1411         );
1412 }
1413
1414 char _license[] SEC("license") = "GPL";