bpf: allow adjusted map element values to spill
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / test_verifier.c
1 /*
2  * Testsuite for eBPF verifier
3  *
4  * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  */
10
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <stddef.h>
16 #include <stdbool.h>
17 #include <sched.h>
18
19 #include <sys/resource.h>
20
21 #include <linux/unistd.h>
22 #include <linux/filter.h>
23 #include <linux/bpf_perf_event.h>
24 #include <linux/bpf.h>
25
26 #include "../../../include/linux/filter.h"
27
28 #include "bpf_sys.h"
29
30 #ifndef ARRAY_SIZE
31 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
32 #endif
33
34 #define MAX_INSNS       512
35 #define MAX_FIXUPS      8
36
37 struct bpf_test {
38         const char *descr;
39         struct bpf_insn insns[MAX_INSNS];
40         int fixup_map1[MAX_FIXUPS];
41         int fixup_map2[MAX_FIXUPS];
42         int fixup_prog[MAX_FIXUPS];
43         const char *errstr;
44         const char *errstr_unpriv;
45         enum {
46                 UNDEF,
47                 ACCEPT,
48                 REJECT
49         } result, result_unpriv;
50         enum bpf_prog_type prog_type;
51 };
52
53 /* Note we want this to be 64 bit aligned so that the end of our array is
54  * actually the end of the structure.
55  */
56 #define MAX_ENTRIES 11
57
58 struct test_val {
59         unsigned int index;
60         int foo[MAX_ENTRIES];
61 };
62
63 static struct bpf_test tests[] = {
64         {
65                 "add+sub+mul",
66                 .insns = {
67                         BPF_MOV64_IMM(BPF_REG_1, 1),
68                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
69                         BPF_MOV64_IMM(BPF_REG_2, 3),
70                         BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
71                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
72                         BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
73                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
74                         BPF_EXIT_INSN(),
75                 },
76                 .result = ACCEPT,
77         },
78         {
79                 "unreachable",
80                 .insns = {
81                         BPF_EXIT_INSN(),
82                         BPF_EXIT_INSN(),
83                 },
84                 .errstr = "unreachable",
85                 .result = REJECT,
86         },
87         {
88                 "unreachable2",
89                 .insns = {
90                         BPF_JMP_IMM(BPF_JA, 0, 0, 1),
91                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
92                         BPF_EXIT_INSN(),
93                 },
94                 .errstr = "unreachable",
95                 .result = REJECT,
96         },
97         {
98                 "out of range jump",
99                 .insns = {
100                         BPF_JMP_IMM(BPF_JA, 0, 0, 1),
101                         BPF_EXIT_INSN(),
102                 },
103                 .errstr = "jump out of range",
104                 .result = REJECT,
105         },
106         {
107                 "out of range jump2",
108                 .insns = {
109                         BPF_JMP_IMM(BPF_JA, 0, 0, -2),
110                         BPF_EXIT_INSN(),
111                 },
112                 .errstr = "jump out of range",
113                 .result = REJECT,
114         },
115         {
116                 "test1 ld_imm64",
117                 .insns = {
118                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
119                         BPF_LD_IMM64(BPF_REG_0, 0),
120                         BPF_LD_IMM64(BPF_REG_0, 0),
121                         BPF_LD_IMM64(BPF_REG_0, 1),
122                         BPF_LD_IMM64(BPF_REG_0, 1),
123                         BPF_MOV64_IMM(BPF_REG_0, 2),
124                         BPF_EXIT_INSN(),
125                 },
126                 .errstr = "invalid BPF_LD_IMM insn",
127                 .errstr_unpriv = "R1 pointer comparison",
128                 .result = REJECT,
129         },
130         {
131                 "test2 ld_imm64",
132                 .insns = {
133                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
134                         BPF_LD_IMM64(BPF_REG_0, 0),
135                         BPF_LD_IMM64(BPF_REG_0, 0),
136                         BPF_LD_IMM64(BPF_REG_0, 1),
137                         BPF_LD_IMM64(BPF_REG_0, 1),
138                         BPF_EXIT_INSN(),
139                 },
140                 .errstr = "invalid BPF_LD_IMM insn",
141                 .errstr_unpriv = "R1 pointer comparison",
142                 .result = REJECT,
143         },
144         {
145                 "test3 ld_imm64",
146                 .insns = {
147                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
148                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
149                         BPF_LD_IMM64(BPF_REG_0, 0),
150                         BPF_LD_IMM64(BPF_REG_0, 0),
151                         BPF_LD_IMM64(BPF_REG_0, 1),
152                         BPF_LD_IMM64(BPF_REG_0, 1),
153                         BPF_EXIT_INSN(),
154                 },
155                 .errstr = "invalid bpf_ld_imm64 insn",
156                 .result = REJECT,
157         },
158         {
159                 "test4 ld_imm64",
160                 .insns = {
161                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
162                         BPF_EXIT_INSN(),
163                 },
164                 .errstr = "invalid bpf_ld_imm64 insn",
165                 .result = REJECT,
166         },
167         {
168                 "test5 ld_imm64",
169                 .insns = {
170                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
171                 },
172                 .errstr = "invalid bpf_ld_imm64 insn",
173                 .result = REJECT,
174         },
175         {
176                 "no bpf_exit",
177                 .insns = {
178                         BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
179                 },
180                 .errstr = "jump out of range",
181                 .result = REJECT,
182         },
183         {
184                 "loop (back-edge)",
185                 .insns = {
186                         BPF_JMP_IMM(BPF_JA, 0, 0, -1),
187                         BPF_EXIT_INSN(),
188                 },
189                 .errstr = "back-edge",
190                 .result = REJECT,
191         },
192         {
193                 "loop2 (back-edge)",
194                 .insns = {
195                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
196                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
197                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
198                         BPF_JMP_IMM(BPF_JA, 0, 0, -4),
199                         BPF_EXIT_INSN(),
200                 },
201                 .errstr = "back-edge",
202                 .result = REJECT,
203         },
204         {
205                 "conditional loop",
206                 .insns = {
207                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
208                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
209                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
210                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
211                         BPF_EXIT_INSN(),
212                 },
213                 .errstr = "back-edge",
214                 .result = REJECT,
215         },
216         {
217                 "read uninitialized register",
218                 .insns = {
219                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
220                         BPF_EXIT_INSN(),
221                 },
222                 .errstr = "R2 !read_ok",
223                 .result = REJECT,
224         },
225         {
226                 "read invalid register",
227                 .insns = {
228                         BPF_MOV64_REG(BPF_REG_0, -1),
229                         BPF_EXIT_INSN(),
230                 },
231                 .errstr = "R15 is invalid",
232                 .result = REJECT,
233         },
234         {
235                 "program doesn't init R0 before exit",
236                 .insns = {
237                         BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
238                         BPF_EXIT_INSN(),
239                 },
240                 .errstr = "R0 !read_ok",
241                 .result = REJECT,
242         },
243         {
244                 "program doesn't init R0 before exit in all branches",
245                 .insns = {
246                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
247                         BPF_MOV64_IMM(BPF_REG_0, 1),
248                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
249                         BPF_EXIT_INSN(),
250                 },
251                 .errstr = "R0 !read_ok",
252                 .errstr_unpriv = "R1 pointer comparison",
253                 .result = REJECT,
254         },
255         {
256                 "stack out of bounds",
257                 .insns = {
258                         BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
259                         BPF_EXIT_INSN(),
260                 },
261                 .errstr = "invalid stack",
262                 .result = REJECT,
263         },
264         {
265                 "invalid call insn1",
266                 .insns = {
267                         BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
268                         BPF_EXIT_INSN(),
269                 },
270                 .errstr = "BPF_CALL uses reserved",
271                 .result = REJECT,
272         },
273         {
274                 "invalid call insn2",
275                 .insns = {
276                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
277                         BPF_EXIT_INSN(),
278                 },
279                 .errstr = "BPF_CALL uses reserved",
280                 .result = REJECT,
281         },
282         {
283                 "invalid function call",
284                 .insns = {
285                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
286                         BPF_EXIT_INSN(),
287                 },
288                 .errstr = "invalid func unknown#1234567",
289                 .result = REJECT,
290         },
291         {
292                 "uninitialized stack1",
293                 .insns = {
294                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
295                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
296                         BPF_LD_MAP_FD(BPF_REG_1, 0),
297                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
298                                      BPF_FUNC_map_lookup_elem),
299                         BPF_EXIT_INSN(),
300                 },
301                 .fixup_map1 = { 2 },
302                 .errstr = "invalid indirect read from stack",
303                 .result = REJECT,
304         },
305         {
306                 "uninitialized stack2",
307                 .insns = {
308                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
309                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
310                         BPF_EXIT_INSN(),
311                 },
312                 .errstr = "invalid read from stack",
313                 .result = REJECT,
314         },
315         {
316                 "invalid argument register",
317                 .insns = {
318                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
319                                      BPF_FUNC_get_cgroup_classid),
320                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
321                                      BPF_FUNC_get_cgroup_classid),
322                         BPF_EXIT_INSN(),
323                 },
324                 .errstr = "R1 !read_ok",
325                 .result = REJECT,
326                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
327         },
328         {
329                 "non-invalid argument register",
330                 .insns = {
331                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
332                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
333                                      BPF_FUNC_get_cgroup_classid),
334                         BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
335                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
336                                      BPF_FUNC_get_cgroup_classid),
337                         BPF_EXIT_INSN(),
338                 },
339                 .result = ACCEPT,
340                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
341         },
342         {
343                 "check valid spill/fill",
344                 .insns = {
345                         /* spill R1(ctx) into stack */
346                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
347                         /* fill it back into R2 */
348                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
349                         /* should be able to access R0 = *(R2 + 8) */
350                         /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
351                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
352                         BPF_EXIT_INSN(),
353                 },
354                 .errstr_unpriv = "R0 leaks addr",
355                 .result = ACCEPT,
356                 .result_unpriv = REJECT,
357         },
358         {
359                 "check valid spill/fill, skb mark",
360                 .insns = {
361                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
362                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
363                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
364                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
365                                     offsetof(struct __sk_buff, mark)),
366                         BPF_EXIT_INSN(),
367                 },
368                 .result = ACCEPT,
369                 .result_unpriv = ACCEPT,
370         },
371         {
372                 "check corrupted spill/fill",
373                 .insns = {
374                         /* spill R1(ctx) into stack */
375                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
376                         /* mess up with R1 pointer on stack */
377                         BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
378                         /* fill back into R0 should fail */
379                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
380                         BPF_EXIT_INSN(),
381                 },
382                 .errstr_unpriv = "attempt to corrupt spilled",
383                 .errstr = "corrupted spill",
384                 .result = REJECT,
385         },
386         {
387                 "invalid src register in STX",
388                 .insns = {
389                         BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
390                         BPF_EXIT_INSN(),
391                 },
392                 .errstr = "R15 is invalid",
393                 .result = REJECT,
394         },
395         {
396                 "invalid dst register in STX",
397                 .insns = {
398                         BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
399                         BPF_EXIT_INSN(),
400                 },
401                 .errstr = "R14 is invalid",
402                 .result = REJECT,
403         },
404         {
405                 "invalid dst register in ST",
406                 .insns = {
407                         BPF_ST_MEM(BPF_B, 14, -1, -1),
408                         BPF_EXIT_INSN(),
409                 },
410                 .errstr = "R14 is invalid",
411                 .result = REJECT,
412         },
413         {
414                 "invalid src register in LDX",
415                 .insns = {
416                         BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
417                         BPF_EXIT_INSN(),
418                 },
419                 .errstr = "R12 is invalid",
420                 .result = REJECT,
421         },
422         {
423                 "invalid dst register in LDX",
424                 .insns = {
425                         BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
426                         BPF_EXIT_INSN(),
427                 },
428                 .errstr = "R11 is invalid",
429                 .result = REJECT,
430         },
431         {
432                 "junk insn",
433                 .insns = {
434                         BPF_RAW_INSN(0, 0, 0, 0, 0),
435                         BPF_EXIT_INSN(),
436                 },
437                 .errstr = "invalid BPF_LD_IMM",
438                 .result = REJECT,
439         },
440         {
441                 "junk insn2",
442                 .insns = {
443                         BPF_RAW_INSN(1, 0, 0, 0, 0),
444                         BPF_EXIT_INSN(),
445                 },
446                 .errstr = "BPF_LDX uses reserved fields",
447                 .result = REJECT,
448         },
449         {
450                 "junk insn3",
451                 .insns = {
452                         BPF_RAW_INSN(-1, 0, 0, 0, 0),
453                         BPF_EXIT_INSN(),
454                 },
455                 .errstr = "invalid BPF_ALU opcode f0",
456                 .result = REJECT,
457         },
458         {
459                 "junk insn4",
460                 .insns = {
461                         BPF_RAW_INSN(-1, -1, -1, -1, -1),
462                         BPF_EXIT_INSN(),
463                 },
464                 .errstr = "invalid BPF_ALU opcode f0",
465                 .result = REJECT,
466         },
467         {
468                 "junk insn5",
469                 .insns = {
470                         BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
471                         BPF_EXIT_INSN(),
472                 },
473                 .errstr = "BPF_ALU uses reserved fields",
474                 .result = REJECT,
475         },
476         {
477                 "misaligned read from stack",
478                 .insns = {
479                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
480                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
481                         BPF_EXIT_INSN(),
482                 },
483                 .errstr = "misaligned access",
484                 .result = REJECT,
485         },
486         {
487                 "invalid map_fd for function call",
488                 .insns = {
489                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
490                         BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
491                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
492                         BPF_LD_MAP_FD(BPF_REG_1, 0),
493                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
494                                      BPF_FUNC_map_delete_elem),
495                         BPF_EXIT_INSN(),
496                 },
497                 .errstr = "fd 0 is not pointing to valid bpf_map",
498                 .result = REJECT,
499         },
500         {
501                 "don't check return value before access",
502                 .insns = {
503                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
504                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
505                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
506                         BPF_LD_MAP_FD(BPF_REG_1, 0),
507                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
508                                      BPF_FUNC_map_lookup_elem),
509                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
510                         BPF_EXIT_INSN(),
511                 },
512                 .fixup_map1 = { 3 },
513                 .errstr = "R0 invalid mem access 'map_value_or_null'",
514                 .result = REJECT,
515         },
516         {
517                 "access memory with incorrect alignment",
518                 .insns = {
519                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
520                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
521                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
522                         BPF_LD_MAP_FD(BPF_REG_1, 0),
523                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
524                                      BPF_FUNC_map_lookup_elem),
525                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
526                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
527                         BPF_EXIT_INSN(),
528                 },
529                 .fixup_map1 = { 3 },
530                 .errstr = "misaligned access",
531                 .result = REJECT,
532         },
533         {
534                 "sometimes access memory with incorrect alignment",
535                 .insns = {
536                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
537                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
538                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
539                         BPF_LD_MAP_FD(BPF_REG_1, 0),
540                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
541                                      BPF_FUNC_map_lookup_elem),
542                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
543                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
544                         BPF_EXIT_INSN(),
545                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
546                         BPF_EXIT_INSN(),
547                 },
548                 .fixup_map1 = { 3 },
549                 .errstr = "R0 invalid mem access",
550                 .errstr_unpriv = "R0 leaks addr",
551                 .result = REJECT,
552         },
553         {
554                 "jump test 1",
555                 .insns = {
556                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
557                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
558                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
559                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
560                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
561                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
562                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
563                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
564                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
565                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
566                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
567                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
568                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
569                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
570                         BPF_MOV64_IMM(BPF_REG_0, 0),
571                         BPF_EXIT_INSN(),
572                 },
573                 .errstr_unpriv = "R1 pointer comparison",
574                 .result_unpriv = REJECT,
575                 .result = ACCEPT,
576         },
577         {
578                 "jump test 2",
579                 .insns = {
580                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
581                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
582                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
583                         BPF_JMP_IMM(BPF_JA, 0, 0, 14),
584                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
585                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
586                         BPF_JMP_IMM(BPF_JA, 0, 0, 11),
587                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
588                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
589                         BPF_JMP_IMM(BPF_JA, 0, 0, 8),
590                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
591                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
592                         BPF_JMP_IMM(BPF_JA, 0, 0, 5),
593                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
594                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
595                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
596                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
597                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
598                         BPF_MOV64_IMM(BPF_REG_0, 0),
599                         BPF_EXIT_INSN(),
600                 },
601                 .errstr_unpriv = "R1 pointer comparison",
602                 .result_unpriv = REJECT,
603                 .result = ACCEPT,
604         },
605         {
606                 "jump test 3",
607                 .insns = {
608                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
609                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
610                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
611                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
612                         BPF_JMP_IMM(BPF_JA, 0, 0, 19),
613                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
614                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
615                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
616                         BPF_JMP_IMM(BPF_JA, 0, 0, 15),
617                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
618                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
619                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
620                         BPF_JMP_IMM(BPF_JA, 0, 0, 11),
621                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
622                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
623                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
624                         BPF_JMP_IMM(BPF_JA, 0, 0, 7),
625                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
626                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
627                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
628                         BPF_JMP_IMM(BPF_JA, 0, 0, 3),
629                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
630                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
631                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
632                         BPF_LD_MAP_FD(BPF_REG_1, 0),
633                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
634                                      BPF_FUNC_map_delete_elem),
635                         BPF_EXIT_INSN(),
636                 },
637                 .fixup_map1 = { 24 },
638                 .errstr_unpriv = "R1 pointer comparison",
639                 .result_unpriv = REJECT,
640                 .result = ACCEPT,
641         },
642         {
643                 "jump test 4",
644                 .insns = {
645                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
646                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
647                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
648                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
649                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
650                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
651                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
652                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
653                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
654                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
655                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
656                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
657                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
658                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
659                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
660                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
661                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
662                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
663                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
664                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
665                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
666                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
667                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
668                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
669                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
670                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
671                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
672                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
673                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
674                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
675                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
676                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
677                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
678                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
679                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
680                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
681                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
682                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
683                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
684                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
685                         BPF_MOV64_IMM(BPF_REG_0, 0),
686                         BPF_EXIT_INSN(),
687                 },
688                 .errstr_unpriv = "R1 pointer comparison",
689                 .result_unpriv = REJECT,
690                 .result = ACCEPT,
691         },
692         {
693                 "jump test 5",
694                 .insns = {
695                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
696                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
697                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
698                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
699                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
700                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
701                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
702                         BPF_MOV64_IMM(BPF_REG_0, 0),
703                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
704                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
705                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
706                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
707                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
708                         BPF_MOV64_IMM(BPF_REG_0, 0),
709                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
710                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
711                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
712                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
713                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
714                         BPF_MOV64_IMM(BPF_REG_0, 0),
715                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
716                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
717                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
718                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
719                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
720                         BPF_MOV64_IMM(BPF_REG_0, 0),
721                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
722                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
723                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
724                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
725                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
726                         BPF_MOV64_IMM(BPF_REG_0, 0),
727                         BPF_EXIT_INSN(),
728                 },
729                 .errstr_unpriv = "R1 pointer comparison",
730                 .result_unpriv = REJECT,
731                 .result = ACCEPT,
732         },
733         {
734                 "access skb fields ok",
735                 .insns = {
736                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
737                                     offsetof(struct __sk_buff, len)),
738                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
739                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
740                                     offsetof(struct __sk_buff, mark)),
741                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
742                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
743                                     offsetof(struct __sk_buff, pkt_type)),
744                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
745                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
746                                     offsetof(struct __sk_buff, queue_mapping)),
747                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
748                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
749                                     offsetof(struct __sk_buff, protocol)),
750                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
751                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
752                                     offsetof(struct __sk_buff, vlan_present)),
753                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
754                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
755                                     offsetof(struct __sk_buff, vlan_tci)),
756                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
757                         BPF_EXIT_INSN(),
758                 },
759                 .result = ACCEPT,
760         },
761         {
762                 "access skb fields bad1",
763                 .insns = {
764                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
765                         BPF_EXIT_INSN(),
766                 },
767                 .errstr = "invalid bpf_context access",
768                 .result = REJECT,
769         },
770         {
771                 "access skb fields bad2",
772                 .insns = {
773                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
774                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
775                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
776                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
777                         BPF_LD_MAP_FD(BPF_REG_1, 0),
778                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
779                                      BPF_FUNC_map_lookup_elem),
780                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
781                         BPF_EXIT_INSN(),
782                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
783                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
784                                     offsetof(struct __sk_buff, pkt_type)),
785                         BPF_EXIT_INSN(),
786                 },
787                 .fixup_map1 = { 4 },
788                 .errstr = "different pointers",
789                 .errstr_unpriv = "R1 pointer comparison",
790                 .result = REJECT,
791         },
792         {
793                 "access skb fields bad3",
794                 .insns = {
795                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
796                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
797                                     offsetof(struct __sk_buff, pkt_type)),
798                         BPF_EXIT_INSN(),
799                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
800                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
801                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
802                         BPF_LD_MAP_FD(BPF_REG_1, 0),
803                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
804                                      BPF_FUNC_map_lookup_elem),
805                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
806                         BPF_EXIT_INSN(),
807                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
808                         BPF_JMP_IMM(BPF_JA, 0, 0, -12),
809                 },
810                 .fixup_map1 = { 6 },
811                 .errstr = "different pointers",
812                 .errstr_unpriv = "R1 pointer comparison",
813                 .result = REJECT,
814         },
815         {
816                 "access skb fields bad4",
817                 .insns = {
818                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
819                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
820                                     offsetof(struct __sk_buff, len)),
821                         BPF_MOV64_IMM(BPF_REG_0, 0),
822                         BPF_EXIT_INSN(),
823                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
824                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
825                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
826                         BPF_LD_MAP_FD(BPF_REG_1, 0),
827                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
828                                      BPF_FUNC_map_lookup_elem),
829                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
830                         BPF_EXIT_INSN(),
831                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
832                         BPF_JMP_IMM(BPF_JA, 0, 0, -13),
833                 },
834                 .fixup_map1 = { 7 },
835                 .errstr = "different pointers",
836                 .errstr_unpriv = "R1 pointer comparison",
837                 .result = REJECT,
838         },
839         {
840                 "check skb->mark is not writeable by sockets",
841                 .insns = {
842                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
843                                     offsetof(struct __sk_buff, mark)),
844                         BPF_EXIT_INSN(),
845                 },
846                 .errstr = "invalid bpf_context access",
847                 .errstr_unpriv = "R1 leaks addr",
848                 .result = REJECT,
849         },
850         {
851                 "check skb->tc_index is not writeable by sockets",
852                 .insns = {
853                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
854                                     offsetof(struct __sk_buff, tc_index)),
855                         BPF_EXIT_INSN(),
856                 },
857                 .errstr = "invalid bpf_context access",
858                 .errstr_unpriv = "R1 leaks addr",
859                 .result = REJECT,
860         },
861         {
862                 "check non-u32 access to cb",
863                 .insns = {
864                         BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_1,
865                                     offsetof(struct __sk_buff, cb[0])),
866                         BPF_EXIT_INSN(),
867                 },
868                 .errstr = "invalid bpf_context access",
869                 .errstr_unpriv = "R1 leaks addr",
870                 .result = REJECT,
871         },
872         {
873                 "check out of range skb->cb access",
874                 .insns = {
875                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
876                                     offsetof(struct __sk_buff, cb[0]) + 256),
877                         BPF_EXIT_INSN(),
878                 },
879                 .errstr = "invalid bpf_context access",
880                 .errstr_unpriv = "",
881                 .result = REJECT,
882                 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
883         },
884         {
885                 "write skb fields from socket prog",
886                 .insns = {
887                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
888                                     offsetof(struct __sk_buff, cb[4])),
889                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
890                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
891                                     offsetof(struct __sk_buff, mark)),
892                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
893                                     offsetof(struct __sk_buff, tc_index)),
894                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
895                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
896                                     offsetof(struct __sk_buff, cb[0])),
897                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
898                                     offsetof(struct __sk_buff, cb[2])),
899                         BPF_EXIT_INSN(),
900                 },
901                 .result = ACCEPT,
902                 .errstr_unpriv = "R1 leaks addr",
903                 .result_unpriv = REJECT,
904         },
905         {
906                 "write skb fields from tc_cls_act prog",
907                 .insns = {
908                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
909                                     offsetof(struct __sk_buff, cb[0])),
910                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
911                                     offsetof(struct __sk_buff, mark)),
912                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
913                                     offsetof(struct __sk_buff, tc_index)),
914                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
915                                     offsetof(struct __sk_buff, tc_index)),
916                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
917                                     offsetof(struct __sk_buff, cb[3])),
918                         BPF_EXIT_INSN(),
919                 },
920                 .errstr_unpriv = "",
921                 .result_unpriv = REJECT,
922                 .result = ACCEPT,
923                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
924         },
925         {
926                 "PTR_TO_STACK store/load",
927                 .insns = {
928                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
929                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
930                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
931                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
932                         BPF_EXIT_INSN(),
933                 },
934                 .result = ACCEPT,
935         },
936         {
937                 "PTR_TO_STACK store/load - bad alignment on off",
938                 .insns = {
939                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
940                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
941                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
942                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
943                         BPF_EXIT_INSN(),
944                 },
945                 .result = REJECT,
946                 .errstr = "misaligned access off -6 size 8",
947         },
948         {
949                 "PTR_TO_STACK store/load - bad alignment on reg",
950                 .insns = {
951                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
952                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
953                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
954                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
955                         BPF_EXIT_INSN(),
956                 },
957                 .result = REJECT,
958                 .errstr = "misaligned access off -2 size 8",
959         },
960         {
961                 "PTR_TO_STACK store/load - out of bounds low",
962                 .insns = {
963                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
964                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
965                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
966                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
967                         BPF_EXIT_INSN(),
968                 },
969                 .result = REJECT,
970                 .errstr = "invalid stack off=-79992 size=8",
971         },
972         {
973                 "PTR_TO_STACK store/load - out of bounds high",
974                 .insns = {
975                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
976                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
977                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
978                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
979                         BPF_EXIT_INSN(),
980                 },
981                 .result = REJECT,
982                 .errstr = "invalid stack off=0 size=8",
983         },
984         {
985                 "unpriv: return pointer",
986                 .insns = {
987                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
988                         BPF_EXIT_INSN(),
989                 },
990                 .result = ACCEPT,
991                 .result_unpriv = REJECT,
992                 .errstr_unpriv = "R0 leaks addr",
993         },
994         {
995                 "unpriv: add const to pointer",
996                 .insns = {
997                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
998                         BPF_MOV64_IMM(BPF_REG_0, 0),
999                         BPF_EXIT_INSN(),
1000                 },
1001                 .result = ACCEPT,
1002                 .result_unpriv = REJECT,
1003                 .errstr_unpriv = "R1 pointer arithmetic",
1004         },
1005         {
1006                 "unpriv: add pointer to pointer",
1007                 .insns = {
1008                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1009                         BPF_MOV64_IMM(BPF_REG_0, 0),
1010                         BPF_EXIT_INSN(),
1011                 },
1012                 .result = ACCEPT,
1013                 .result_unpriv = REJECT,
1014                 .errstr_unpriv = "R1 pointer arithmetic",
1015         },
1016         {
1017                 "unpriv: neg pointer",
1018                 .insns = {
1019                         BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1020                         BPF_MOV64_IMM(BPF_REG_0, 0),
1021                         BPF_EXIT_INSN(),
1022                 },
1023                 .result = ACCEPT,
1024                 .result_unpriv = REJECT,
1025                 .errstr_unpriv = "R1 pointer arithmetic",
1026         },
1027         {
1028                 "unpriv: cmp pointer with const",
1029                 .insns = {
1030                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1031                         BPF_MOV64_IMM(BPF_REG_0, 0),
1032                         BPF_EXIT_INSN(),
1033                 },
1034                 .result = ACCEPT,
1035                 .result_unpriv = REJECT,
1036                 .errstr_unpriv = "R1 pointer comparison",
1037         },
1038         {
1039                 "unpriv: cmp pointer with pointer",
1040                 .insns = {
1041                         BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1042                         BPF_MOV64_IMM(BPF_REG_0, 0),
1043                         BPF_EXIT_INSN(),
1044                 },
1045                 .result = ACCEPT,
1046                 .result_unpriv = REJECT,
1047                 .errstr_unpriv = "R10 pointer comparison",
1048         },
1049         {
1050                 "unpriv: check that printk is disallowed",
1051                 .insns = {
1052                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1053                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1054                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1055                         BPF_MOV64_IMM(BPF_REG_2, 8),
1056                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1057                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1058                                      BPF_FUNC_trace_printk),
1059                         BPF_MOV64_IMM(BPF_REG_0, 0),
1060                         BPF_EXIT_INSN(),
1061                 },
1062                 .errstr_unpriv = "unknown func bpf_trace_printk#6",
1063                 .result_unpriv = REJECT,
1064                 .result = ACCEPT,
1065         },
1066         {
1067                 "unpriv: pass pointer to helper function",
1068                 .insns = {
1069                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1070                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1071                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1072                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1073                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1074                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1075                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1076                                      BPF_FUNC_map_update_elem),
1077                         BPF_MOV64_IMM(BPF_REG_0, 0),
1078                         BPF_EXIT_INSN(),
1079                 },
1080                 .fixup_map1 = { 3 },
1081                 .errstr_unpriv = "R4 leaks addr",
1082                 .result_unpriv = REJECT,
1083                 .result = ACCEPT,
1084         },
1085         {
1086                 "unpriv: indirectly pass pointer on stack to helper function",
1087                 .insns = {
1088                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1089                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1090                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1091                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1092                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1093                                      BPF_FUNC_map_lookup_elem),
1094                         BPF_MOV64_IMM(BPF_REG_0, 0),
1095                         BPF_EXIT_INSN(),
1096                 },
1097                 .fixup_map1 = { 3 },
1098                 .errstr = "invalid indirect read from stack off -8+0 size 8",
1099                 .result = REJECT,
1100         },
1101         {
1102                 "unpriv: mangle pointer on stack 1",
1103                 .insns = {
1104                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1105                         BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1106                         BPF_MOV64_IMM(BPF_REG_0, 0),
1107                         BPF_EXIT_INSN(),
1108                 },
1109                 .errstr_unpriv = "attempt to corrupt spilled",
1110                 .result_unpriv = REJECT,
1111                 .result = ACCEPT,
1112         },
1113         {
1114                 "unpriv: mangle pointer on stack 2",
1115                 .insns = {
1116                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1117                         BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1118                         BPF_MOV64_IMM(BPF_REG_0, 0),
1119                         BPF_EXIT_INSN(),
1120                 },
1121                 .errstr_unpriv = "attempt to corrupt spilled",
1122                 .result_unpriv = REJECT,
1123                 .result = ACCEPT,
1124         },
1125         {
1126                 "unpriv: read pointer from stack in small chunks",
1127                 .insns = {
1128                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1129                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1130                         BPF_MOV64_IMM(BPF_REG_0, 0),
1131                         BPF_EXIT_INSN(),
1132                 },
1133                 .errstr = "invalid size",
1134                 .result = REJECT,
1135         },
1136         {
1137                 "unpriv: write pointer into ctx",
1138                 .insns = {
1139                         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1140                         BPF_MOV64_IMM(BPF_REG_0, 0),
1141                         BPF_EXIT_INSN(),
1142                 },
1143                 .errstr_unpriv = "R1 leaks addr",
1144                 .result_unpriv = REJECT,
1145                 .errstr = "invalid bpf_context access",
1146                 .result = REJECT,
1147         },
1148         {
1149                 "unpriv: spill/fill of ctx",
1150                 .insns = {
1151                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1152                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1153                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1154                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1155                         BPF_MOV64_IMM(BPF_REG_0, 0),
1156                         BPF_EXIT_INSN(),
1157                 },
1158                 .result = ACCEPT,
1159         },
1160         {
1161                 "unpriv: spill/fill of ctx 2",
1162                 .insns = {
1163                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1164                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1165                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1166                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1167                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1168                                      BPF_FUNC_get_hash_recalc),
1169                         BPF_EXIT_INSN(),
1170                 },
1171                 .result = ACCEPT,
1172                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1173         },
1174         {
1175                 "unpriv: spill/fill of ctx 3",
1176                 .insns = {
1177                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1178                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1179                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1180                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1181                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1182                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1183                                      BPF_FUNC_get_hash_recalc),
1184                         BPF_EXIT_INSN(),
1185                 },
1186                 .result = REJECT,
1187                 .errstr = "R1 type=fp expected=ctx",
1188                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1189         },
1190         {
1191                 "unpriv: spill/fill of ctx 4",
1192                 .insns = {
1193                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1194                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1195                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1196                         BPF_MOV64_IMM(BPF_REG_0, 1),
1197                         BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
1198                                      BPF_REG_0, -8, 0),
1199                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1200                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1201                                      BPF_FUNC_get_hash_recalc),
1202                         BPF_EXIT_INSN(),
1203                 },
1204                 .result = REJECT,
1205                 .errstr = "R1 type=inv expected=ctx",
1206                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1207         },
1208         {
1209                 "unpriv: spill/fill of different pointers stx",
1210                 .insns = {
1211                         BPF_MOV64_IMM(BPF_REG_3, 42),
1212                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1213                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1214                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1215                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1216                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1217                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1218                         BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1219                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1220                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1221                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
1222                                     offsetof(struct __sk_buff, mark)),
1223                         BPF_MOV64_IMM(BPF_REG_0, 0),
1224                         BPF_EXIT_INSN(),
1225                 },
1226                 .result = REJECT,
1227                 .errstr = "same insn cannot be used with different pointers",
1228                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1229         },
1230         {
1231                 "unpriv: spill/fill of different pointers ldx",
1232                 .insns = {
1233                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1234                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1235                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1236                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1237                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
1238                                       -(__s32)offsetof(struct bpf_perf_event_data,
1239                                                        sample_period) - 8),
1240                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1241                         BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1242                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1243                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1244                         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
1245                                     offsetof(struct bpf_perf_event_data,
1246                                              sample_period)),
1247                         BPF_MOV64_IMM(BPF_REG_0, 0),
1248                         BPF_EXIT_INSN(),
1249                 },
1250                 .result = REJECT,
1251                 .errstr = "same insn cannot be used with different pointers",
1252                 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
1253         },
1254         {
1255                 "unpriv: write pointer into map elem value",
1256                 .insns = {
1257                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1258                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1259                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1260                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1261                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1262                                      BPF_FUNC_map_lookup_elem),
1263                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1264                         BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1265                         BPF_EXIT_INSN(),
1266                 },
1267                 .fixup_map1 = { 3 },
1268                 .errstr_unpriv = "R0 leaks addr",
1269                 .result_unpriv = REJECT,
1270                 .result = ACCEPT,
1271         },
1272         {
1273                 "unpriv: partial copy of pointer",
1274                 .insns = {
1275                         BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1276                         BPF_MOV64_IMM(BPF_REG_0, 0),
1277                         BPF_EXIT_INSN(),
1278                 },
1279                 .errstr_unpriv = "R10 partial copy",
1280                 .result_unpriv = REJECT,
1281                 .result = ACCEPT,
1282         },
1283         {
1284                 "unpriv: pass pointer to tail_call",
1285                 .insns = {
1286                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1287                         BPF_LD_MAP_FD(BPF_REG_2, 0),
1288                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1289                                      BPF_FUNC_tail_call),
1290                         BPF_MOV64_IMM(BPF_REG_0, 0),
1291                         BPF_EXIT_INSN(),
1292                 },
1293                 .fixup_prog = { 1 },
1294                 .errstr_unpriv = "R3 leaks addr into helper",
1295                 .result_unpriv = REJECT,
1296                 .result = ACCEPT,
1297         },
1298         {
1299                 "unpriv: cmp map pointer with zero",
1300                 .insns = {
1301                         BPF_MOV64_IMM(BPF_REG_1, 0),
1302                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1303                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1304                         BPF_MOV64_IMM(BPF_REG_0, 0),
1305                         BPF_EXIT_INSN(),
1306                 },
1307                 .fixup_map1 = { 1 },
1308                 .errstr_unpriv = "R1 pointer comparison",
1309                 .result_unpriv = REJECT,
1310                 .result = ACCEPT,
1311         },
1312         {
1313                 "unpriv: write into frame pointer",
1314                 .insns = {
1315                         BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1316                         BPF_MOV64_IMM(BPF_REG_0, 0),
1317                         BPF_EXIT_INSN(),
1318                 },
1319                 .errstr = "frame pointer is read only",
1320                 .result = REJECT,
1321         },
1322         {
1323                 "unpriv: spill/fill frame pointer",
1324                 .insns = {
1325                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1326                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1327                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1328                         BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
1329                         BPF_MOV64_IMM(BPF_REG_0, 0),
1330                         BPF_EXIT_INSN(),
1331                 },
1332                 .errstr = "frame pointer is read only",
1333                 .result = REJECT,
1334         },
1335         {
1336                 "unpriv: cmp of frame pointer",
1337                 .insns = {
1338                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1339                         BPF_MOV64_IMM(BPF_REG_0, 0),
1340                         BPF_EXIT_INSN(),
1341                 },
1342                 .errstr_unpriv = "R10 pointer comparison",
1343                 .result_unpriv = REJECT,
1344                 .result = ACCEPT,
1345         },
1346         {
1347                 "unpriv: cmp of stack pointer",
1348                 .insns = {
1349                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1350                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1351                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1352                         BPF_MOV64_IMM(BPF_REG_0, 0),
1353                         BPF_EXIT_INSN(),
1354                 },
1355                 .errstr_unpriv = "R2 pointer comparison",
1356                 .result_unpriv = REJECT,
1357                 .result = ACCEPT,
1358         },
1359         {
1360                 "unpriv: obfuscate stack pointer",
1361                 .insns = {
1362                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1363                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1364                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1365                         BPF_MOV64_IMM(BPF_REG_0, 0),
1366                         BPF_EXIT_INSN(),
1367                 },
1368                 .errstr_unpriv = "R2 pointer arithmetic",
1369                 .result_unpriv = REJECT,
1370                 .result = ACCEPT,
1371         },
1372         {
1373                 "raw_stack: no skb_load_bytes",
1374                 .insns = {
1375                         BPF_MOV64_IMM(BPF_REG_2, 4),
1376                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1377                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1378                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1379                         BPF_MOV64_IMM(BPF_REG_4, 8),
1380                         /* Call to skb_load_bytes() omitted. */
1381                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1382                         BPF_EXIT_INSN(),
1383                 },
1384                 .result = REJECT,
1385                 .errstr = "invalid read from stack off -8+0 size 8",
1386                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1387         },
1388         {
1389                 "raw_stack: skb_load_bytes, negative len",
1390                 .insns = {
1391                         BPF_MOV64_IMM(BPF_REG_2, 4),
1392                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1393                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1394                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1395                         BPF_MOV64_IMM(BPF_REG_4, -8),
1396                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1397                                      BPF_FUNC_skb_load_bytes),
1398                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1399                         BPF_EXIT_INSN(),
1400                 },
1401                 .result = REJECT,
1402                 .errstr = "invalid stack type R3",
1403                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1404         },
1405         {
1406                 "raw_stack: skb_load_bytes, negative len 2",
1407                 .insns = {
1408                         BPF_MOV64_IMM(BPF_REG_2, 4),
1409                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1410                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1411                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1412                         BPF_MOV64_IMM(BPF_REG_4, ~0),
1413                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1414                                      BPF_FUNC_skb_load_bytes),
1415                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1416                         BPF_EXIT_INSN(),
1417                 },
1418                 .result = REJECT,
1419                 .errstr = "invalid stack type R3",
1420                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1421         },
1422         {
1423                 "raw_stack: skb_load_bytes, zero len",
1424                 .insns = {
1425                         BPF_MOV64_IMM(BPF_REG_2, 4),
1426                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1427                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1428                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1429                         BPF_MOV64_IMM(BPF_REG_4, 0),
1430                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1431                                      BPF_FUNC_skb_load_bytes),
1432                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1433                         BPF_EXIT_INSN(),
1434                 },
1435                 .result = REJECT,
1436                 .errstr = "invalid stack type R3",
1437                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1438         },
1439         {
1440                 "raw_stack: skb_load_bytes, no init",
1441                 .insns = {
1442                         BPF_MOV64_IMM(BPF_REG_2, 4),
1443                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1444                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1445                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1446                         BPF_MOV64_IMM(BPF_REG_4, 8),
1447                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1448                                      BPF_FUNC_skb_load_bytes),
1449                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1450                         BPF_EXIT_INSN(),
1451                 },
1452                 .result = ACCEPT,
1453                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1454         },
1455         {
1456                 "raw_stack: skb_load_bytes, init",
1457                 .insns = {
1458                         BPF_MOV64_IMM(BPF_REG_2, 4),
1459                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1460                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1461                         BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1462                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1463                         BPF_MOV64_IMM(BPF_REG_4, 8),
1464                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1465                                      BPF_FUNC_skb_load_bytes),
1466                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1467                         BPF_EXIT_INSN(),
1468                 },
1469                 .result = ACCEPT,
1470                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1471         },
1472         {
1473                 "raw_stack: skb_load_bytes, spilled regs around bounds",
1474                 .insns = {
1475                         BPF_MOV64_IMM(BPF_REG_2, 4),
1476                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1477                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1478                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1479                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1480                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1481                         BPF_MOV64_IMM(BPF_REG_4, 8),
1482                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1483                                      BPF_FUNC_skb_load_bytes),
1484                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1485                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
1486                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1487                                     offsetof(struct __sk_buff, mark)),
1488                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1489                                     offsetof(struct __sk_buff, priority)),
1490                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1491                         BPF_EXIT_INSN(),
1492                 },
1493                 .result = ACCEPT,
1494                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1495         },
1496         {
1497                 "raw_stack: skb_load_bytes, spilled regs corruption",
1498                 .insns = {
1499                         BPF_MOV64_IMM(BPF_REG_2, 4),
1500                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1501                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1502                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1503                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1504                         BPF_MOV64_IMM(BPF_REG_4, 8),
1505                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1506                                      BPF_FUNC_skb_load_bytes),
1507                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1508                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1509                                     offsetof(struct __sk_buff, mark)),
1510                         BPF_EXIT_INSN(),
1511                 },
1512                 .result = REJECT,
1513                 .errstr = "R0 invalid mem access 'inv'",
1514                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1515         },
1516         {
1517                 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1518                 .insns = {
1519                         BPF_MOV64_IMM(BPF_REG_2, 4),
1520                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1521                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1522                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1523                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
1524                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1525                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1526                         BPF_MOV64_IMM(BPF_REG_4, 8),
1527                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1528                                      BPF_FUNC_skb_load_bytes),
1529                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1530                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
1531                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
1532                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1533                                     offsetof(struct __sk_buff, mark)),
1534                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1535                                     offsetof(struct __sk_buff, priority)),
1536                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1537                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1538                                     offsetof(struct __sk_buff, pkt_type)),
1539                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1540                         BPF_EXIT_INSN(),
1541                 },
1542                 .result = REJECT,
1543                 .errstr = "R3 invalid mem access 'inv'",
1544                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1545         },
1546         {
1547                 "raw_stack: skb_load_bytes, spilled regs + data",
1548                 .insns = {
1549                         BPF_MOV64_IMM(BPF_REG_2, 4),
1550                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1551                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1552                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1553                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
1554                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1555                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1556                         BPF_MOV64_IMM(BPF_REG_4, 8),
1557                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1558                                      BPF_FUNC_skb_load_bytes),
1559                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1560                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
1561                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
1562                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1563                                     offsetof(struct __sk_buff, mark)),
1564                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1565                                     offsetof(struct __sk_buff, priority)),
1566                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1567                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1568                         BPF_EXIT_INSN(),
1569                 },
1570                 .result = ACCEPT,
1571                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1572         },
1573         {
1574                 "raw_stack: skb_load_bytes, invalid access 1",
1575                 .insns = {
1576                         BPF_MOV64_IMM(BPF_REG_2, 4),
1577                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1578                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
1579                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1580                         BPF_MOV64_IMM(BPF_REG_4, 8),
1581                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1582                                      BPF_FUNC_skb_load_bytes),
1583                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1584                         BPF_EXIT_INSN(),
1585                 },
1586                 .result = REJECT,
1587                 .errstr = "invalid stack type R3 off=-513 access_size=8",
1588                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1589         },
1590         {
1591                 "raw_stack: skb_load_bytes, invalid access 2",
1592                 .insns = {
1593                         BPF_MOV64_IMM(BPF_REG_2, 4),
1594                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1595                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1596                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1597                         BPF_MOV64_IMM(BPF_REG_4, 8),
1598                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1599                                      BPF_FUNC_skb_load_bytes),
1600                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1601                         BPF_EXIT_INSN(),
1602                 },
1603                 .result = REJECT,
1604                 .errstr = "invalid stack type R3 off=-1 access_size=8",
1605                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1606         },
1607         {
1608                 "raw_stack: skb_load_bytes, invalid access 3",
1609                 .insns = {
1610                         BPF_MOV64_IMM(BPF_REG_2, 4),
1611                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1612                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
1613                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1614                         BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
1615                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1616                                      BPF_FUNC_skb_load_bytes),
1617                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1618                         BPF_EXIT_INSN(),
1619                 },
1620                 .result = REJECT,
1621                 .errstr = "invalid stack type R3 off=-1 access_size=-1",
1622                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1623         },
1624         {
1625                 "raw_stack: skb_load_bytes, invalid access 4",
1626                 .insns = {
1627                         BPF_MOV64_IMM(BPF_REG_2, 4),
1628                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1629                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1630                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1631                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1632                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1633                                      BPF_FUNC_skb_load_bytes),
1634                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1635                         BPF_EXIT_INSN(),
1636                 },
1637                 .result = REJECT,
1638                 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
1639                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1640         },
1641         {
1642                 "raw_stack: skb_load_bytes, invalid access 5",
1643                 .insns = {
1644                         BPF_MOV64_IMM(BPF_REG_2, 4),
1645                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1646                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1647                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1648                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1649                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1650                                      BPF_FUNC_skb_load_bytes),
1651                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1652                         BPF_EXIT_INSN(),
1653                 },
1654                 .result = REJECT,
1655                 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
1656                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1657         },
1658         {
1659                 "raw_stack: skb_load_bytes, invalid access 6",
1660                 .insns = {
1661                         BPF_MOV64_IMM(BPF_REG_2, 4),
1662                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1663                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1664                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1665                         BPF_MOV64_IMM(BPF_REG_4, 0),
1666                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1667                                      BPF_FUNC_skb_load_bytes),
1668                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1669                         BPF_EXIT_INSN(),
1670                 },
1671                 .result = REJECT,
1672                 .errstr = "invalid stack type R3 off=-512 access_size=0",
1673                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1674         },
1675         {
1676                 "raw_stack: skb_load_bytes, large access",
1677                 .insns = {
1678                         BPF_MOV64_IMM(BPF_REG_2, 4),
1679                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1680                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1681                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1682                         BPF_MOV64_IMM(BPF_REG_4, 512),
1683                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1684                                      BPF_FUNC_skb_load_bytes),
1685                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1686                         BPF_EXIT_INSN(),
1687                 },
1688                 .result = ACCEPT,
1689                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1690         },
1691         {
1692                 "direct packet access: test1",
1693                 .insns = {
1694                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1695                                     offsetof(struct __sk_buff, data)),
1696                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1697                                     offsetof(struct __sk_buff, data_end)),
1698                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1699                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1700                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1701                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1702                         BPF_MOV64_IMM(BPF_REG_0, 0),
1703                         BPF_EXIT_INSN(),
1704                 },
1705                 .result = ACCEPT,
1706                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1707         },
1708         {
1709                 "direct packet access: test2",
1710                 .insns = {
1711                         BPF_MOV64_IMM(BPF_REG_0, 1),
1712                         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
1713                                     offsetof(struct __sk_buff, data_end)),
1714                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1715                                     offsetof(struct __sk_buff, data)),
1716                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
1717                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
1718                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
1719                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
1720                         BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
1721                         BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
1722                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1723                                     offsetof(struct __sk_buff, data)),
1724                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
1725                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
1726                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
1727                         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
1728                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
1729                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
1730                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1731                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1732                                     offsetof(struct __sk_buff, data_end)),
1733                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
1734                         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
1735                         BPF_MOV64_IMM(BPF_REG_0, 0),
1736                         BPF_EXIT_INSN(),
1737                 },
1738                 .result = ACCEPT,
1739                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1740         },
1741         {
1742                 "direct packet access: test3",
1743                 .insns = {
1744                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1745                                     offsetof(struct __sk_buff, data)),
1746                         BPF_MOV64_IMM(BPF_REG_0, 0),
1747                         BPF_EXIT_INSN(),
1748                 },
1749                 .errstr = "invalid bpf_context access off=76",
1750                 .result = REJECT,
1751                 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
1752         },
1753         {
1754                 "direct packet access: test4 (write)",
1755                 .insns = {
1756                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1757                                     offsetof(struct __sk_buff, data)),
1758                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1759                                     offsetof(struct __sk_buff, data_end)),
1760                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1761                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1762                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1763                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1764                         BPF_MOV64_IMM(BPF_REG_0, 0),
1765                         BPF_EXIT_INSN(),
1766                 },
1767                 .result = ACCEPT,
1768                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1769         },
1770         {
1771                 "direct packet access: test5 (pkt_end >= reg, good access)",
1772                 .insns = {
1773                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1774                                     offsetof(struct __sk_buff, data)),
1775                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1776                                     offsetof(struct __sk_buff, data_end)),
1777                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1778                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1779                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1780                         BPF_MOV64_IMM(BPF_REG_0, 1),
1781                         BPF_EXIT_INSN(),
1782                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1783                         BPF_MOV64_IMM(BPF_REG_0, 0),
1784                         BPF_EXIT_INSN(),
1785                 },
1786                 .result = ACCEPT,
1787                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1788         },
1789         {
1790                 "direct packet access: test6 (pkt_end >= reg, bad access)",
1791                 .insns = {
1792                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1793                                     offsetof(struct __sk_buff, data)),
1794                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1795                                     offsetof(struct __sk_buff, data_end)),
1796                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1797                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1798                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1799                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1800                         BPF_MOV64_IMM(BPF_REG_0, 1),
1801                         BPF_EXIT_INSN(),
1802                         BPF_MOV64_IMM(BPF_REG_0, 0),
1803                         BPF_EXIT_INSN(),
1804                 },
1805                 .errstr = "invalid access to packet",
1806                 .result = REJECT,
1807                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1808         },
1809         {
1810                 "direct packet access: test7 (pkt_end >= reg, both accesses)",
1811                 .insns = {
1812                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1813                                     offsetof(struct __sk_buff, data)),
1814                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1815                                     offsetof(struct __sk_buff, data_end)),
1816                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1817                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1818                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1819                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1820                         BPF_MOV64_IMM(BPF_REG_0, 1),
1821                         BPF_EXIT_INSN(),
1822                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1823                         BPF_MOV64_IMM(BPF_REG_0, 0),
1824                         BPF_EXIT_INSN(),
1825                 },
1826                 .errstr = "invalid access to packet",
1827                 .result = REJECT,
1828                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1829         },
1830         {
1831                 "direct packet access: test8 (double test, variant 1)",
1832                 .insns = {
1833                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1834                                     offsetof(struct __sk_buff, data)),
1835                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1836                                     offsetof(struct __sk_buff, data_end)),
1837                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1838                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1839                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
1840                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1841                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1842                         BPF_MOV64_IMM(BPF_REG_0, 1),
1843                         BPF_EXIT_INSN(),
1844                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1845                         BPF_MOV64_IMM(BPF_REG_0, 0),
1846                         BPF_EXIT_INSN(),
1847                 },
1848                 .result = ACCEPT,
1849                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1850         },
1851         {
1852                 "direct packet access: test9 (double test, variant 2)",
1853                 .insns = {
1854                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1855                                     offsetof(struct __sk_buff, data)),
1856                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1857                                     offsetof(struct __sk_buff, data_end)),
1858                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1859                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1860                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1861                         BPF_MOV64_IMM(BPF_REG_0, 1),
1862                         BPF_EXIT_INSN(),
1863                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1864                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1865                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1866                         BPF_MOV64_IMM(BPF_REG_0, 0),
1867                         BPF_EXIT_INSN(),
1868                 },
1869                 .result = ACCEPT,
1870                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1871         },
1872         {
1873                 "direct packet access: test10 (write invalid)",
1874                 .insns = {
1875                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1876                                     offsetof(struct __sk_buff, data)),
1877                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1878                                     offsetof(struct __sk_buff, data_end)),
1879                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1880                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1881                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1882                         BPF_MOV64_IMM(BPF_REG_0, 0),
1883                         BPF_EXIT_INSN(),
1884                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1885                         BPF_MOV64_IMM(BPF_REG_0, 0),
1886                         BPF_EXIT_INSN(),
1887                 },
1888                 .errstr = "invalid access to packet",
1889                 .result = REJECT,
1890                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1891         },
1892         {
1893                 "helper access to packet: test1, valid packet_ptr range",
1894                 .insns = {
1895                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1896                                     offsetof(struct xdp_md, data)),
1897                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1898                                     offsetof(struct xdp_md, data_end)),
1899                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1900                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1901                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1902                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1903                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1904                         BPF_MOV64_IMM(BPF_REG_4, 0),
1905                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1906                                      BPF_FUNC_map_update_elem),
1907                         BPF_MOV64_IMM(BPF_REG_0, 0),
1908                         BPF_EXIT_INSN(),
1909                 },
1910                 .fixup_map1 = { 5 },
1911                 .result_unpriv = ACCEPT,
1912                 .result = ACCEPT,
1913                 .prog_type = BPF_PROG_TYPE_XDP,
1914         },
1915         {
1916                 "helper access to packet: test2, unchecked packet_ptr",
1917                 .insns = {
1918                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1919                                     offsetof(struct xdp_md, data)),
1920                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1921                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1922                                      BPF_FUNC_map_lookup_elem),
1923                         BPF_MOV64_IMM(BPF_REG_0, 0),
1924                         BPF_EXIT_INSN(),
1925                 },
1926                 .fixup_map1 = { 1 },
1927                 .result = REJECT,
1928                 .errstr = "invalid access to packet",
1929                 .prog_type = BPF_PROG_TYPE_XDP,
1930         },
1931         {
1932                 "helper access to packet: test3, variable add",
1933                 .insns = {
1934                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1935                                         offsetof(struct xdp_md, data)),
1936                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1937                                         offsetof(struct xdp_md, data_end)),
1938                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1939                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1940                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1941                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1942                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1943                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1944                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1945                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1946                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1947                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1948                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1949                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1950                                      BPF_FUNC_map_lookup_elem),
1951                         BPF_MOV64_IMM(BPF_REG_0, 0),
1952                         BPF_EXIT_INSN(),
1953                 },
1954                 .fixup_map1 = { 11 },
1955                 .result = ACCEPT,
1956                 .prog_type = BPF_PROG_TYPE_XDP,
1957         },
1958         {
1959                 "helper access to packet: test4, packet_ptr with bad range",
1960                 .insns = {
1961                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1962                                     offsetof(struct xdp_md, data)),
1963                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1964                                     offsetof(struct xdp_md, data_end)),
1965                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1966                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1967                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1968                         BPF_MOV64_IMM(BPF_REG_0, 0),
1969                         BPF_EXIT_INSN(),
1970                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1971                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1972                                      BPF_FUNC_map_lookup_elem),
1973                         BPF_MOV64_IMM(BPF_REG_0, 0),
1974                         BPF_EXIT_INSN(),
1975                 },
1976                 .fixup_map1 = { 7 },
1977                 .result = REJECT,
1978                 .errstr = "invalid access to packet",
1979                 .prog_type = BPF_PROG_TYPE_XDP,
1980         },
1981         {
1982                 "helper access to packet: test5, packet_ptr with too short range",
1983                 .insns = {
1984                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1985                                     offsetof(struct xdp_md, data)),
1986                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1987                                     offsetof(struct xdp_md, data_end)),
1988                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1989                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1990                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1991                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1992                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1993                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1994                                      BPF_FUNC_map_lookup_elem),
1995                         BPF_MOV64_IMM(BPF_REG_0, 0),
1996                         BPF_EXIT_INSN(),
1997                 },
1998                 .fixup_map1 = { 6 },
1999                 .result = REJECT,
2000                 .errstr = "invalid access to packet",
2001                 .prog_type = BPF_PROG_TYPE_XDP,
2002         },
2003         {
2004                 "helper access to packet: test6, cls valid packet_ptr range",
2005                 .insns = {
2006                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2007                                     offsetof(struct __sk_buff, data)),
2008                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2009                                     offsetof(struct __sk_buff, data_end)),
2010                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2011                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2012                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2013                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2014                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2015                         BPF_MOV64_IMM(BPF_REG_4, 0),
2016                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2017                                      BPF_FUNC_map_update_elem),
2018                         BPF_MOV64_IMM(BPF_REG_0, 0),
2019                         BPF_EXIT_INSN(),
2020                 },
2021                 .fixup_map1 = { 5 },
2022                 .result = ACCEPT,
2023                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2024         },
2025         {
2026                 "helper access to packet: test7, cls unchecked packet_ptr",
2027                 .insns = {
2028                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2029                                     offsetof(struct __sk_buff, data)),
2030                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2031                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2032                                      BPF_FUNC_map_lookup_elem),
2033                         BPF_MOV64_IMM(BPF_REG_0, 0),
2034                         BPF_EXIT_INSN(),
2035                 },
2036                 .fixup_map1 = { 1 },
2037                 .result = REJECT,
2038                 .errstr = "invalid access to packet",
2039                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2040         },
2041         {
2042                 "helper access to packet: test8, cls variable add",
2043                 .insns = {
2044                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2045                                         offsetof(struct __sk_buff, data)),
2046                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2047                                         offsetof(struct __sk_buff, data_end)),
2048                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2049                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2050                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2051                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2052                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2053                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2054                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2055                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2056                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2057                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2058                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
2059                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2060                                      BPF_FUNC_map_lookup_elem),
2061                         BPF_MOV64_IMM(BPF_REG_0, 0),
2062                         BPF_EXIT_INSN(),
2063                 },
2064                 .fixup_map1 = { 11 },
2065                 .result = ACCEPT,
2066                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2067         },
2068         {
2069                 "helper access to packet: test9, cls packet_ptr with bad range",
2070                 .insns = {
2071                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2072                                     offsetof(struct __sk_buff, data)),
2073                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2074                                     offsetof(struct __sk_buff, data_end)),
2075                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2076                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2077                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2078                         BPF_MOV64_IMM(BPF_REG_0, 0),
2079                         BPF_EXIT_INSN(),
2080                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2081                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2082                                      BPF_FUNC_map_lookup_elem),
2083                         BPF_MOV64_IMM(BPF_REG_0, 0),
2084                         BPF_EXIT_INSN(),
2085                 },
2086                 .fixup_map1 = { 7 },
2087                 .result = REJECT,
2088                 .errstr = "invalid access to packet",
2089                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2090         },
2091         {
2092                 "helper access to packet: test10, cls packet_ptr with too short range",
2093                 .insns = {
2094                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2095                                     offsetof(struct __sk_buff, data)),
2096                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2097                                     offsetof(struct __sk_buff, data_end)),
2098                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2099                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2100                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2101                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2102                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2103                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2104                                      BPF_FUNC_map_lookup_elem),
2105                         BPF_MOV64_IMM(BPF_REG_0, 0),
2106                         BPF_EXIT_INSN(),
2107                 },
2108                 .fixup_map1 = { 6 },
2109                 .result = REJECT,
2110                 .errstr = "invalid access to packet",
2111                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2112         },
2113         {
2114                 "helper access to packet: test11, cls unsuitable helper 1",
2115                 .insns = {
2116                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2117                                     offsetof(struct __sk_buff, data)),
2118                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2119                                     offsetof(struct __sk_buff, data_end)),
2120                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2121                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2122                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
2123                         BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
2124                         BPF_MOV64_IMM(BPF_REG_2, 0),
2125                         BPF_MOV64_IMM(BPF_REG_4, 42),
2126                         BPF_MOV64_IMM(BPF_REG_5, 0),
2127                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2128                                      BPF_FUNC_skb_store_bytes),
2129                         BPF_MOV64_IMM(BPF_REG_0, 0),
2130                         BPF_EXIT_INSN(),
2131                 },
2132                 .result = REJECT,
2133                 .errstr = "helper access to the packet",
2134                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2135         },
2136         {
2137                 "helper access to packet: test12, cls unsuitable helper 2",
2138                 .insns = {
2139                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2140                                     offsetof(struct __sk_buff, data)),
2141                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2142                                     offsetof(struct __sk_buff, data_end)),
2143                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2144                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
2145                         BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
2146                         BPF_MOV64_IMM(BPF_REG_2, 0),
2147                         BPF_MOV64_IMM(BPF_REG_4, 4),
2148                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2149                                      BPF_FUNC_skb_load_bytes),
2150                         BPF_MOV64_IMM(BPF_REG_0, 0),
2151                         BPF_EXIT_INSN(),
2152                 },
2153                 .result = REJECT,
2154                 .errstr = "helper access to the packet",
2155                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2156         },
2157         {
2158                 "helper access to packet: test13, cls helper ok",
2159                 .insns = {
2160                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2161                                     offsetof(struct __sk_buff, data)),
2162                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2163                                     offsetof(struct __sk_buff, data_end)),
2164                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2165                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2166                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2167                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2168                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2169                         BPF_MOV64_IMM(BPF_REG_2, 4),
2170                         BPF_MOV64_IMM(BPF_REG_3, 0),
2171                         BPF_MOV64_IMM(BPF_REG_4, 0),
2172                         BPF_MOV64_IMM(BPF_REG_5, 0),
2173                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2174                                      BPF_FUNC_csum_diff),
2175                         BPF_MOV64_IMM(BPF_REG_0, 0),
2176                         BPF_EXIT_INSN(),
2177                 },
2178                 .result = ACCEPT,
2179                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2180         },
2181         {
2182                 "helper access to packet: test14, cls helper fail sub",
2183                 .insns = {
2184                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2185                                     offsetof(struct __sk_buff, data)),
2186                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2187                                     offsetof(struct __sk_buff, data_end)),
2188                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2189                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2190                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2191                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2192                         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2193                         BPF_MOV64_IMM(BPF_REG_2, 4),
2194                         BPF_MOV64_IMM(BPF_REG_3, 0),
2195                         BPF_MOV64_IMM(BPF_REG_4, 0),
2196                         BPF_MOV64_IMM(BPF_REG_5, 0),
2197                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2198                                      BPF_FUNC_csum_diff),
2199                         BPF_MOV64_IMM(BPF_REG_0, 0),
2200                         BPF_EXIT_INSN(),
2201                 },
2202                 .result = REJECT,
2203                 .errstr = "type=inv expected=fp",
2204                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2205         },
2206         {
2207                 "helper access to packet: test15, cls helper fail range 1",
2208                 .insns = {
2209                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2210                                     offsetof(struct __sk_buff, data)),
2211                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2212                                     offsetof(struct __sk_buff, data_end)),
2213                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2214                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2215                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2216                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2217                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2218                         BPF_MOV64_IMM(BPF_REG_2, 8),
2219                         BPF_MOV64_IMM(BPF_REG_3, 0),
2220                         BPF_MOV64_IMM(BPF_REG_4, 0),
2221                         BPF_MOV64_IMM(BPF_REG_5, 0),
2222                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2223                                      BPF_FUNC_csum_diff),
2224                         BPF_MOV64_IMM(BPF_REG_0, 0),
2225                         BPF_EXIT_INSN(),
2226                 },
2227                 .result = REJECT,
2228                 .errstr = "invalid access to packet",
2229                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2230         },
2231         {
2232                 "helper access to packet: test16, cls helper fail range 2",
2233                 .insns = {
2234                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2235                                     offsetof(struct __sk_buff, data)),
2236                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2237                                     offsetof(struct __sk_buff, data_end)),
2238                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2239                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2240                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2241                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2242                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2243                         BPF_MOV64_IMM(BPF_REG_2, -9),
2244                         BPF_MOV64_IMM(BPF_REG_3, 0),
2245                         BPF_MOV64_IMM(BPF_REG_4, 0),
2246                         BPF_MOV64_IMM(BPF_REG_5, 0),
2247                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2248                                      BPF_FUNC_csum_diff),
2249                         BPF_MOV64_IMM(BPF_REG_0, 0),
2250                         BPF_EXIT_INSN(),
2251                 },
2252                 .result = REJECT,
2253                 .errstr = "invalid access to packet",
2254                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2255         },
2256         {
2257                 "helper access to packet: test17, cls helper fail range 3",
2258                 .insns = {
2259                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2260                                     offsetof(struct __sk_buff, data)),
2261                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2262                                     offsetof(struct __sk_buff, data_end)),
2263                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2264                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2265                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2266                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2267                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2268                         BPF_MOV64_IMM(BPF_REG_2, ~0),
2269                         BPF_MOV64_IMM(BPF_REG_3, 0),
2270                         BPF_MOV64_IMM(BPF_REG_4, 0),
2271                         BPF_MOV64_IMM(BPF_REG_5, 0),
2272                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2273                                      BPF_FUNC_csum_diff),
2274                         BPF_MOV64_IMM(BPF_REG_0, 0),
2275                         BPF_EXIT_INSN(),
2276                 },
2277                 .result = REJECT,
2278                 .errstr = "invalid access to packet",
2279                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2280         },
2281         {
2282                 "helper access to packet: test18, cls helper fail range zero",
2283                 .insns = {
2284                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2285                                     offsetof(struct __sk_buff, data)),
2286                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2287                                     offsetof(struct __sk_buff, data_end)),
2288                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2289                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2290                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2291                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2292                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2293                         BPF_MOV64_IMM(BPF_REG_2, 0),
2294                         BPF_MOV64_IMM(BPF_REG_3, 0),
2295                         BPF_MOV64_IMM(BPF_REG_4, 0),
2296                         BPF_MOV64_IMM(BPF_REG_5, 0),
2297                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2298                                      BPF_FUNC_csum_diff),
2299                         BPF_MOV64_IMM(BPF_REG_0, 0),
2300                         BPF_EXIT_INSN(),
2301                 },
2302                 .result = REJECT,
2303                 .errstr = "invalid access to packet",
2304                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2305         },
2306         {
2307                 "helper access to packet: test19, pkt end as input",
2308                 .insns = {
2309                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2310                                     offsetof(struct __sk_buff, data)),
2311                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2312                                     offsetof(struct __sk_buff, data_end)),
2313                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2314                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2315                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2316                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2317                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2318                         BPF_MOV64_IMM(BPF_REG_2, 4),
2319                         BPF_MOV64_IMM(BPF_REG_3, 0),
2320                         BPF_MOV64_IMM(BPF_REG_4, 0),
2321                         BPF_MOV64_IMM(BPF_REG_5, 0),
2322                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2323                                      BPF_FUNC_csum_diff),
2324                         BPF_MOV64_IMM(BPF_REG_0, 0),
2325                         BPF_EXIT_INSN(),
2326                 },
2327                 .result = REJECT,
2328                 .errstr = "R1 type=pkt_end expected=fp",
2329                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2330         },
2331         {
2332                 "helper access to packet: test20, wrong reg",
2333                 .insns = {
2334                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2335                                     offsetof(struct __sk_buff, data)),
2336                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2337                                     offsetof(struct __sk_buff, data_end)),
2338                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2339                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2340                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2341                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2342                         BPF_MOV64_IMM(BPF_REG_2, 4),
2343                         BPF_MOV64_IMM(BPF_REG_3, 0),
2344                         BPF_MOV64_IMM(BPF_REG_4, 0),
2345                         BPF_MOV64_IMM(BPF_REG_5, 0),
2346                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2347                                      BPF_FUNC_csum_diff),
2348                         BPF_MOV64_IMM(BPF_REG_0, 0),
2349                         BPF_EXIT_INSN(),
2350                 },
2351                 .result = REJECT,
2352                 .errstr = "invalid access to packet",
2353                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2354         },
2355         {
2356                 "valid map access into an array with a constant",
2357                 .insns = {
2358                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2359                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2360                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2361                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2362                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2363                                      BPF_FUNC_map_lookup_elem),
2364                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2365                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2366                                    offsetof(struct test_val, foo)),
2367                         BPF_EXIT_INSN(),
2368                 },
2369                 .fixup_map2 = { 3 },
2370                 .errstr_unpriv = "R0 leaks addr",
2371                 .result_unpriv = REJECT,
2372                 .result = ACCEPT,
2373         },
2374         {
2375                 "valid map access into an array with a register",
2376                 .insns = {
2377                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2378                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2379                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2380                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2381                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2382                                      BPF_FUNC_map_lookup_elem),
2383                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2384                         BPF_MOV64_IMM(BPF_REG_1, 4),
2385                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2386                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2387                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2388                                    offsetof(struct test_val, foo)),
2389                         BPF_EXIT_INSN(),
2390                 },
2391                 .fixup_map2 = { 3 },
2392                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2393                 .result_unpriv = REJECT,
2394                 .result = ACCEPT,
2395         },
2396         {
2397                 "valid map access into an array with a variable",
2398                 .insns = {
2399                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2400                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2401                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2402                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2403                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2404                                      BPF_FUNC_map_lookup_elem),
2405                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2406                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2407                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2408                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2409                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2410                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2411                                    offsetof(struct test_val, foo)),
2412                         BPF_EXIT_INSN(),
2413                 },
2414                 .fixup_map2 = { 3 },
2415                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2416                 .result_unpriv = REJECT,
2417                 .result = ACCEPT,
2418         },
2419         {
2420                 "valid map access into an array with a signed variable",
2421                 .insns = {
2422                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2423                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2424                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2425                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2426                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2427                                      BPF_FUNC_map_lookup_elem),
2428                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2429                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2430                         BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2431                         BPF_MOV32_IMM(BPF_REG_1, 0),
2432                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2433                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2434                         BPF_MOV32_IMM(BPF_REG_1, 0),
2435                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2436                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2437                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2438                                    offsetof(struct test_val, foo)),
2439                         BPF_EXIT_INSN(),
2440                 },
2441                 .fixup_map2 = { 3 },
2442                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2443                 .result_unpriv = REJECT,
2444                 .result = ACCEPT,
2445         },
2446         {
2447                 "invalid map access into an array with a constant",
2448                 .insns = {
2449                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2450                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2451                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2452                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2453                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2454                                      BPF_FUNC_map_lookup_elem),
2455                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2456                         BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
2457                                    offsetof(struct test_val, foo)),
2458                         BPF_EXIT_INSN(),
2459                 },
2460                 .fixup_map2 = { 3 },
2461                 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
2462                 .result = REJECT,
2463         },
2464         {
2465                 "invalid map access into an array with a register",
2466                 .insns = {
2467                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2468                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2469                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2470                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2471                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2472                                      BPF_FUNC_map_lookup_elem),
2473                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2474                         BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
2475                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2476                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2477                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2478                                    offsetof(struct test_val, foo)),
2479                         BPF_EXIT_INSN(),
2480                 },
2481                 .fixup_map2 = { 3 },
2482                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2483                 .errstr = "R0 min value is outside of the array range",
2484                 .result_unpriv = REJECT,
2485                 .result = REJECT,
2486         },
2487         {
2488                 "invalid map access into an array with a variable",
2489                 .insns = {
2490                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2491                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2492                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2493                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2494                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2495                                      BPF_FUNC_map_lookup_elem),
2496                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2497                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2498                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2499                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2500                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2501                                    offsetof(struct test_val, foo)),
2502                         BPF_EXIT_INSN(),
2503                 },
2504                 .fixup_map2 = { 3 },
2505                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2506                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2507                 .result_unpriv = REJECT,
2508                 .result = REJECT,
2509         },
2510         {
2511                 "invalid map access into an array with no floor check",
2512                 .insns = {
2513                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2514                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2515                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2516                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2517                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2518                                      BPF_FUNC_map_lookup_elem),
2519                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2520                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2521                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2522                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2523                         BPF_MOV32_IMM(BPF_REG_1, 0),
2524                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2525                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2526                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2527                                    offsetof(struct test_val, foo)),
2528                         BPF_EXIT_INSN(),
2529                 },
2530                 .fixup_map2 = { 3 },
2531                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2532                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2533                 .result_unpriv = REJECT,
2534                 .result = REJECT,
2535         },
2536         {
2537                 "invalid map access into an array with a invalid max check",
2538                 .insns = {
2539                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2540                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2541                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2542                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2543                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2544                                      BPF_FUNC_map_lookup_elem),
2545                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2546                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2547                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
2548                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2549                         BPF_MOV32_IMM(BPF_REG_1, 0),
2550                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2551                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2552                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2553                                    offsetof(struct test_val, foo)),
2554                         BPF_EXIT_INSN(),
2555                 },
2556                 .fixup_map2 = { 3 },
2557                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2558                 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
2559                 .result_unpriv = REJECT,
2560                 .result = REJECT,
2561         },
2562         {
2563                 "invalid map access into an array with a invalid max check",
2564                 .insns = {
2565                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2566                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2567                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2568                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2569                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2570                                      BPF_FUNC_map_lookup_elem),
2571                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
2572                         BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
2573                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2574                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2575                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2576                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2577                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2578                                      BPF_FUNC_map_lookup_elem),
2579                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
2580                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
2581                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2582                                     offsetof(struct test_val, foo)),
2583                         BPF_EXIT_INSN(),
2584                 },
2585                 .fixup_map2 = { 3, 11 },
2586                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2587                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2588                 .result_unpriv = REJECT,
2589                 .result = REJECT,
2590         },
2591         {
2592                 "multiple registers share map_lookup_elem result",
2593                 .insns = {
2594                         BPF_MOV64_IMM(BPF_REG_1, 10),
2595                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
2596                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2597                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2598                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2599                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2600                                      BPF_FUNC_map_lookup_elem),
2601                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2602                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2603                         BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
2604                         BPF_EXIT_INSN(),
2605                 },
2606                 .fixup_map1 = { 4 },
2607                 .result = ACCEPT,
2608                 .prog_type = BPF_PROG_TYPE_SCHED_CLS
2609         },
2610         {
2611                 "invalid memory access with multiple map_lookup_elem calls",
2612                 .insns = {
2613                         BPF_MOV64_IMM(BPF_REG_1, 10),
2614                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
2615                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2616                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2617                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2618                         BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2619                         BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
2620                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2621                                      BPF_FUNC_map_lookup_elem),
2622                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2623                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2624                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2625                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2626                                      BPF_FUNC_map_lookup_elem),
2627                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2628                         BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
2629                         BPF_EXIT_INSN(),
2630                 },
2631                 .fixup_map1 = { 4 },
2632                 .result = REJECT,
2633                 .errstr = "R4 !read_ok",
2634                 .prog_type = BPF_PROG_TYPE_SCHED_CLS
2635         },
2636         {
2637                 "valid indirect map_lookup_elem access with 2nd lookup in branch",
2638                 .insns = {
2639                         BPF_MOV64_IMM(BPF_REG_1, 10),
2640                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
2641                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2642                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2643                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2644                         BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2645                         BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
2646                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2647                                      BPF_FUNC_map_lookup_elem),
2648                         BPF_MOV64_IMM(BPF_REG_2, 10),
2649                         BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
2650                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2651                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2652                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2653                                      BPF_FUNC_map_lookup_elem),
2654                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2655                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2656                         BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
2657                         BPF_EXIT_INSN(),
2658                 },
2659                 .fixup_map1 = { 4 },
2660                 .result = ACCEPT,
2661                 .prog_type = BPF_PROG_TYPE_SCHED_CLS
2662         },
2663         {
2664                 "multiple registers share map_lookup_elem bad reg type",
2665                 .insns = {
2666                         BPF_MOV64_IMM(BPF_REG_1, 10),
2667                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
2668                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2669                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2670                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2671                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2672                                      BPF_FUNC_map_lookup_elem),
2673                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
2674                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
2675                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2676                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
2677                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2678                         BPF_MOV64_IMM(BPF_REG_1, 1),
2679                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2680                         BPF_MOV64_IMM(BPF_REG_1, 2),
2681                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1),
2682                         BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 0),
2683                         BPF_MOV64_IMM(BPF_REG_1, 3),
2684                         BPF_EXIT_INSN(),
2685                 },
2686                 .fixup_map1 = { 4 },
2687                 .result = REJECT,
2688                 .errstr = "R3 invalid mem access 'inv'",
2689                 .prog_type = BPF_PROG_TYPE_SCHED_CLS
2690         },
2691         {
2692                 "invalid map access from else condition",
2693                 .insns = {
2694                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2695                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2696                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2697                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2698                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2699                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
2700                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2701                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
2702                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
2703                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2704                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2705                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2706                         BPF_EXIT_INSN(),
2707                 },
2708                 .fixup_map2 = { 3 },
2709                 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
2710                 .result = REJECT,
2711                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2712                 .result_unpriv = REJECT,
2713         },
2714         {
2715                 "constant register |= constant should keep constant type",
2716                 .insns = {
2717                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2718                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
2719                         BPF_MOV64_IMM(BPF_REG_2, 34),
2720                         BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
2721                         BPF_MOV64_IMM(BPF_REG_3, 0),
2722                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2723                         BPF_EXIT_INSN(),
2724                 },
2725                 .result = ACCEPT,
2726                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2727         },
2728         {
2729                 "constant register |= constant should not bypass stack boundary checks",
2730                 .insns = {
2731                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2732                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
2733                         BPF_MOV64_IMM(BPF_REG_2, 34),
2734                         BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
2735                         BPF_MOV64_IMM(BPF_REG_3, 0),
2736                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2737                         BPF_EXIT_INSN(),
2738                 },
2739                 .errstr = "invalid stack type R1 off=-48 access_size=58",
2740                 .result = REJECT,
2741                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2742         },
2743         {
2744                 "constant register |= constant register should keep constant type",
2745                 .insns = {
2746                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2747                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
2748                         BPF_MOV64_IMM(BPF_REG_2, 34),
2749                         BPF_MOV64_IMM(BPF_REG_4, 13),
2750                         BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
2751                         BPF_MOV64_IMM(BPF_REG_3, 0),
2752                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2753                         BPF_EXIT_INSN(),
2754                 },
2755                 .result = ACCEPT,
2756                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2757         },
2758         {
2759                 "constant register |= constant register should not bypass stack boundary checks",
2760                 .insns = {
2761                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2762                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
2763                         BPF_MOV64_IMM(BPF_REG_2, 34),
2764                         BPF_MOV64_IMM(BPF_REG_4, 24),
2765                         BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
2766                         BPF_MOV64_IMM(BPF_REG_3, 0),
2767                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2768                         BPF_EXIT_INSN(),
2769                 },
2770                 .errstr = "invalid stack type R1 off=-48 access_size=58",
2771                 .result = REJECT,
2772                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2773         },
2774         {
2775                 "invalid direct packet write for LWT_IN",
2776                 .insns = {
2777                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2778                                     offsetof(struct __sk_buff, data)),
2779                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2780                                     offsetof(struct __sk_buff, data_end)),
2781                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2782                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2783                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2784                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2785                         BPF_MOV64_IMM(BPF_REG_0, 0),
2786                         BPF_EXIT_INSN(),
2787                 },
2788                 .errstr = "cannot write into packet",
2789                 .result = REJECT,
2790                 .prog_type = BPF_PROG_TYPE_LWT_IN,
2791         },
2792         {
2793                 "invalid direct packet write for LWT_OUT",
2794                 .insns = {
2795                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2796                                     offsetof(struct __sk_buff, data)),
2797                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2798                                     offsetof(struct __sk_buff, data_end)),
2799                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2800                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2801                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2802                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2803                         BPF_MOV64_IMM(BPF_REG_0, 0),
2804                         BPF_EXIT_INSN(),
2805                 },
2806                 .errstr = "cannot write into packet",
2807                 .result = REJECT,
2808                 .prog_type = BPF_PROG_TYPE_LWT_OUT,
2809         },
2810         {
2811                 "direct packet write for LWT_XMIT",
2812                 .insns = {
2813                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2814                                     offsetof(struct __sk_buff, data)),
2815                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2816                                     offsetof(struct __sk_buff, data_end)),
2817                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2818                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2819                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2820                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2821                         BPF_MOV64_IMM(BPF_REG_0, 0),
2822                         BPF_EXIT_INSN(),
2823                 },
2824                 .result = ACCEPT,
2825                 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
2826         },
2827         {
2828                 "direct packet read for LWT_IN",
2829                 .insns = {
2830                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2831                                     offsetof(struct __sk_buff, data)),
2832                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2833                                     offsetof(struct __sk_buff, data_end)),
2834                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2835                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2836                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2837                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2838                         BPF_MOV64_IMM(BPF_REG_0, 0),
2839                         BPF_EXIT_INSN(),
2840                 },
2841                 .result = ACCEPT,
2842                 .prog_type = BPF_PROG_TYPE_LWT_IN,
2843         },
2844         {
2845                 "direct packet read for LWT_OUT",
2846                 .insns = {
2847                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2848                                     offsetof(struct __sk_buff, data)),
2849                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2850                                     offsetof(struct __sk_buff, data_end)),
2851                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2852                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2853                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2854                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2855                         BPF_MOV64_IMM(BPF_REG_0, 0),
2856                         BPF_EXIT_INSN(),
2857                 },
2858                 .result = ACCEPT,
2859                 .prog_type = BPF_PROG_TYPE_LWT_OUT,
2860         },
2861         {
2862                 "direct packet read for LWT_XMIT",
2863                 .insns = {
2864                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2865                                     offsetof(struct __sk_buff, data)),
2866                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2867                                     offsetof(struct __sk_buff, data_end)),
2868                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2869                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2870                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2871                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2872                         BPF_MOV64_IMM(BPF_REG_0, 0),
2873                         BPF_EXIT_INSN(),
2874                 },
2875                 .result = ACCEPT,
2876                 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
2877         },
2878         {
2879                 "invalid access of tc_classid for LWT_IN",
2880                 .insns = {
2881                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2882                                     offsetof(struct __sk_buff, tc_classid)),
2883                         BPF_EXIT_INSN(),
2884                 },
2885                 .result = REJECT,
2886                 .errstr = "invalid bpf_context access",
2887         },
2888         {
2889                 "invalid access of tc_classid for LWT_OUT",
2890                 .insns = {
2891                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2892                                     offsetof(struct __sk_buff, tc_classid)),
2893                         BPF_EXIT_INSN(),
2894                 },
2895                 .result = REJECT,
2896                 .errstr = "invalid bpf_context access",
2897         },
2898         {
2899                 "invalid access of tc_classid for LWT_XMIT",
2900                 .insns = {
2901                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2902                                     offsetof(struct __sk_buff, tc_classid)),
2903                         BPF_EXIT_INSN(),
2904                 },
2905                 .result = REJECT,
2906                 .errstr = "invalid bpf_context access",
2907         },
2908         {
2909                 "helper access to map: full range",
2910                 .insns = {
2911                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2912                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2913                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
2914                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2915                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2916                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2917                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2918                         BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
2919                         BPF_MOV64_IMM(BPF_REG_3, 0),
2920                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2921                         BPF_EXIT_INSN(),
2922                 },
2923                 .fixup_map2 = { 3 },
2924                 .result = ACCEPT,
2925                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2926         },
2927         {
2928                 "helper access to map: partial range",
2929                 .insns = {
2930                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2931                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2932                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
2933                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2934                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2935                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2936                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2937                         BPF_MOV64_IMM(BPF_REG_2, 8),
2938                         BPF_MOV64_IMM(BPF_REG_3, 0),
2939                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2940                         BPF_EXIT_INSN(),
2941                 },
2942                 .fixup_map2 = { 3 },
2943                 .result = ACCEPT,
2944                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2945         },
2946         {
2947                 "helper access to map: empty range",
2948                 .insns = {
2949                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2950                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2951                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
2952                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2953                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2954                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2955                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2956                         BPF_MOV64_IMM(BPF_REG_2, 0),
2957                         BPF_MOV64_IMM(BPF_REG_3, 0),
2958                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2959                         BPF_EXIT_INSN(),
2960                 },
2961                 .fixup_map2 = { 3 },
2962                 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
2963                 .result = REJECT,
2964                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2965         },
2966         {
2967                 "helper access to map: out-of-bound range",
2968                 .insns = {
2969                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2970                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2971                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
2972                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2973                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2974                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2975                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2976                         BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
2977                         BPF_MOV64_IMM(BPF_REG_3, 0),
2978                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2979                         BPF_EXIT_INSN(),
2980                 },
2981                 .fixup_map2 = { 3 },
2982                 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
2983                 .result = REJECT,
2984                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
2985         },
2986         {
2987                 "helper access to map: negative range",
2988                 .insns = {
2989                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2990                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2991                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
2992                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2993                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2994                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2995                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2996                         BPF_MOV64_IMM(BPF_REG_2, -8),
2997                         BPF_MOV64_IMM(BPF_REG_3, 0),
2998                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
2999                         BPF_EXIT_INSN(),
3000                 },
3001                 .fixup_map2 = { 3 },
3002                 .errstr = "invalid access to map value, value_size=48 off=0 size=-8",
3003                 .result = REJECT,
3004                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3005         },
3006         {
3007                 "helper access to adjusted map (via const imm): full range",
3008                 .insns = {
3009                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3010                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3011                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3012                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3013                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3014                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3015                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3016                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3017                                 offsetof(struct test_val, foo)),
3018                         BPF_MOV64_IMM(BPF_REG_2,
3019                                 sizeof(struct test_val) -
3020                                 offsetof(struct test_val, foo)),
3021                         BPF_MOV64_IMM(BPF_REG_3, 0),
3022                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3023                         BPF_EXIT_INSN(),
3024                 },
3025                 .fixup_map2 = { 3 },
3026                 .result = ACCEPT,
3027                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3028         },
3029         {
3030                 "helper access to adjusted map (via const imm): partial range",
3031                 .insns = {
3032                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3033                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3034                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3035                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3036                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3037                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3038                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3039                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3040                                 offsetof(struct test_val, foo)),
3041                         BPF_MOV64_IMM(BPF_REG_2, 8),
3042                         BPF_MOV64_IMM(BPF_REG_3, 0),
3043                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3044                         BPF_EXIT_INSN(),
3045                 },
3046                 .fixup_map2 = { 3 },
3047                 .result = ACCEPT,
3048                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3049         },
3050         {
3051                 "helper access to adjusted map (via const imm): empty range",
3052                 .insns = {
3053                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3054                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3055                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3056                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3057                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3058                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3059                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3060                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3061                                 offsetof(struct test_val, foo)),
3062                         BPF_MOV64_IMM(BPF_REG_2, 0),
3063                         BPF_MOV64_IMM(BPF_REG_3, 0),
3064                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3065                         BPF_EXIT_INSN(),
3066                 },
3067                 .fixup_map2 = { 3 },
3068                 .errstr = "R1 min value is outside of the array range",
3069                 .result = REJECT,
3070                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3071         },
3072         {
3073                 "helper access to adjusted map (via const imm): out-of-bound range",
3074                 .insns = {
3075                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3076                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3077                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3078                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3079                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3080                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3081                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3082                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3083                                 offsetof(struct test_val, foo)),
3084                         BPF_MOV64_IMM(BPF_REG_2,
3085                                 sizeof(struct test_val) -
3086                                 offsetof(struct test_val, foo) + 8),
3087                         BPF_MOV64_IMM(BPF_REG_3, 0),
3088                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3089                         BPF_EXIT_INSN(),
3090                 },
3091                 .fixup_map2 = { 3 },
3092                 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3093                 .result = REJECT,
3094                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3095         },
3096         {
3097                 "helper access to adjusted map (via const imm): negative range (> adjustment)",
3098                 .insns = {
3099                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3100                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3101                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3102                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3103                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3104                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3105                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3106                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3107                                 offsetof(struct test_val, foo)),
3108                         BPF_MOV64_IMM(BPF_REG_2, -8),
3109                         BPF_MOV64_IMM(BPF_REG_3, 0),
3110                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3111                         BPF_EXIT_INSN(),
3112                 },
3113                 .fixup_map2 = { 3 },
3114                 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3115                 .result = REJECT,
3116                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3117         },
3118         {
3119                 "helper access to adjusted map (via const imm): negative range (< adjustment)",
3120                 .insns = {
3121                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3122                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3123                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3124                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3125                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3126                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3127                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3128                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3129                                 offsetof(struct test_val, foo)),
3130                         BPF_MOV64_IMM(BPF_REG_2, -1),
3131                         BPF_MOV64_IMM(BPF_REG_3, 0),
3132                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3133                         BPF_EXIT_INSN(),
3134                 },
3135                 .fixup_map2 = { 3 },
3136                 .errstr = "R1 min value is outside of the array range",
3137                 .result = REJECT,
3138                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3139         },
3140         {
3141                 "helper access to adjusted map (via const reg): full range",
3142                 .insns = {
3143                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3144                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3145                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3146                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3147                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3148                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3149                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3150                         BPF_MOV64_IMM(BPF_REG_3,
3151                                 offsetof(struct test_val, foo)),
3152                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3153                         BPF_MOV64_IMM(BPF_REG_2,
3154                                 sizeof(struct test_val) -
3155                                 offsetof(struct test_val, foo)),
3156                         BPF_MOV64_IMM(BPF_REG_3, 0),
3157                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3158                         BPF_EXIT_INSN(),
3159                 },
3160                 .fixup_map2 = { 3 },
3161                 .result = ACCEPT,
3162                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3163         },
3164         {
3165                 "helper access to adjusted map (via const reg): partial range",
3166                 .insns = {
3167                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3168                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3169                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3170                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3171                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3172                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3173                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3174                         BPF_MOV64_IMM(BPF_REG_3,
3175                                 offsetof(struct test_val, foo)),
3176                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3177                         BPF_MOV64_IMM(BPF_REG_2, 8),
3178                         BPF_MOV64_IMM(BPF_REG_3, 0),
3179                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3180                         BPF_EXIT_INSN(),
3181                 },
3182                 .fixup_map2 = { 3 },
3183                 .result = ACCEPT,
3184                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3185         },
3186         {
3187                 "helper access to adjusted map (via const reg): empty range",
3188                 .insns = {
3189                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3190                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3191                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3192                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3193                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3194                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3195                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3196                         BPF_MOV64_IMM(BPF_REG_3, 0),
3197                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3198                         BPF_MOV64_IMM(BPF_REG_2, 0),
3199                         BPF_MOV64_IMM(BPF_REG_3, 0),
3200                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3201                         BPF_EXIT_INSN(),
3202                 },
3203                 .fixup_map2 = { 3 },
3204                 .errstr = "R1 min value is outside of the array range",
3205                 .result = REJECT,
3206                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3207         },
3208         {
3209                 "helper access to adjusted map (via const reg): out-of-bound range",
3210                 .insns = {
3211                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3212                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3213                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3214                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3215                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3216                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3217                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3218                         BPF_MOV64_IMM(BPF_REG_3,
3219                                 offsetof(struct test_val, foo)),
3220                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3221                         BPF_MOV64_IMM(BPF_REG_2,
3222                                 sizeof(struct test_val) -
3223                                 offsetof(struct test_val, foo) + 8),
3224                         BPF_MOV64_IMM(BPF_REG_3, 0),
3225                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3226                         BPF_EXIT_INSN(),
3227                 },
3228                 .fixup_map2 = { 3 },
3229                 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3230                 .result = REJECT,
3231                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3232         },
3233         {
3234                 "helper access to adjusted map (via const reg): negative range (> adjustment)",
3235                 .insns = {
3236                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3237                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3238                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3239                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3240                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3241                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3242                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3243                         BPF_MOV64_IMM(BPF_REG_3,
3244                                 offsetof(struct test_val, foo)),
3245                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3246                         BPF_MOV64_IMM(BPF_REG_2, -8),
3247                         BPF_MOV64_IMM(BPF_REG_3, 0),
3248                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3249                         BPF_EXIT_INSN(),
3250                 },
3251                 .fixup_map2 = { 3 },
3252                 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3253                 .result = REJECT,
3254                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3255         },
3256         {
3257                 "helper access to adjusted map (via const reg): negative range (< adjustment)",
3258                 .insns = {
3259                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3260                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3261                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3262                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3263                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3264                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3265                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3266                         BPF_MOV64_IMM(BPF_REG_3,
3267                                 offsetof(struct test_val, foo)),
3268                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3269                         BPF_MOV64_IMM(BPF_REG_2, -1),
3270                         BPF_MOV64_IMM(BPF_REG_3, 0),
3271                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3272                         BPF_EXIT_INSN(),
3273                 },
3274                 .fixup_map2 = { 3 },
3275                 .errstr = "R1 min value is outside of the array range",
3276                 .result = REJECT,
3277                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3278         },
3279         {
3280                 "helper access to adjusted map (via variable): full range",
3281                 .insns = {
3282                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3283                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3284                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3285                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3286                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3287                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3288                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3289                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3290                         BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3291                                 offsetof(struct test_val, foo), 4),
3292                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3293                         BPF_MOV64_IMM(BPF_REG_2,
3294                                 sizeof(struct test_val) -
3295                                 offsetof(struct test_val, foo)),
3296                         BPF_MOV64_IMM(BPF_REG_3, 0),
3297                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3298                         BPF_EXIT_INSN(),
3299                 },
3300                 .fixup_map2 = { 3 },
3301                 .result = ACCEPT,
3302                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3303         },
3304         {
3305                 "helper access to adjusted map (via variable): partial range",
3306                 .insns = {
3307                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3308                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3309                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3310                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3311                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3312                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3313                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3314                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3315                         BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3316                                 offsetof(struct test_val, foo), 4),
3317                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3318                         BPF_MOV64_IMM(BPF_REG_2, 8),
3319                         BPF_MOV64_IMM(BPF_REG_3, 0),
3320                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3321                         BPF_EXIT_INSN(),
3322                 },
3323                 .fixup_map2 = { 3 },
3324                 .result = ACCEPT,
3325                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3326         },
3327         {
3328                 "helper access to adjusted map (via variable): empty range",
3329                 .insns = {
3330                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3331                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3332                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3333                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3334                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3335                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3336                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3337                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3338                         BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3339                                 offsetof(struct test_val, foo), 4),
3340                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3341                         BPF_MOV64_IMM(BPF_REG_2, 0),
3342                         BPF_MOV64_IMM(BPF_REG_3, 0),
3343                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3344                         BPF_EXIT_INSN(),
3345                 },
3346                 .fixup_map2 = { 3 },
3347                 .errstr = "R1 min value is outside of the array range",
3348                 .result = REJECT,
3349                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3350         },
3351         {
3352                 "helper access to adjusted map (via variable): no max check",
3353                 .insns = {
3354                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3355                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3356                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3357                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3358                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3359                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3360                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3361                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3362                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3363                         BPF_MOV64_IMM(BPF_REG_2, 0),
3364                         BPF_MOV64_IMM(BPF_REG_3, 0),
3365                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3366                         BPF_EXIT_INSN(),
3367                 },
3368                 .fixup_map2 = { 3 },
3369                 .errstr = "R1 min value is negative, either use unsigned index or do a if (index >=0) check",
3370                 .result = REJECT,
3371                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3372         },
3373         {
3374                 "helper access to adjusted map (via variable): wrong max check",
3375                 .insns = {
3376                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3377                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3378                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3379                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3380                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3381                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3382                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3383                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3384                         BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3385                                 offsetof(struct test_val, foo), 4),
3386                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3387                         BPF_MOV64_IMM(BPF_REG_2,
3388                                 sizeof(struct test_val) -
3389                                 offsetof(struct test_val, foo) + 1),
3390                         BPF_MOV64_IMM(BPF_REG_3, 0),
3391                         BPF_EMIT_CALL(BPF_FUNC_probe_read),
3392                         BPF_EXIT_INSN(),
3393                 },
3394                 .fixup_map2 = { 3 },
3395                 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
3396                 .result = REJECT,
3397                 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3398         },
3399         {
3400                 "map element value is preserved across register spilling",
3401                 .insns = {
3402                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3403                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3404                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3405                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3406                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3407                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3408                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3409                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3410                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3411                         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3412                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3413                         BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3414                         BPF_EXIT_INSN(),
3415                 },
3416                 .fixup_map2 = { 3 },
3417                 .errstr_unpriv = "R0 leaks addr",
3418                 .result = ACCEPT,
3419                 .result_unpriv = REJECT,
3420         },
3421         {
3422                 "map element value (adjusted) is preserved across register spilling",
3423                 .insns = {
3424                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3425                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3426                         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3427                         BPF_LD_MAP_FD(BPF_REG_1, 0),
3428                         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3429                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3430                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
3431                                 offsetof(struct test_val, foo)),
3432                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3433                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3434                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3435                         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3436                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3437                         BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3438                         BPF_EXIT_INSN(),
3439                 },
3440                 .fixup_map2 = { 3 },
3441                 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3442                 .result = ACCEPT,
3443                 .result_unpriv = REJECT,
3444         },
3445 };
3446
3447 static int probe_filter_length(const struct bpf_insn *fp)
3448 {
3449         int len;
3450
3451         for (len = MAX_INSNS - 1; len > 0; --len)
3452                 if (fp[len].code != 0 || fp[len].imm != 0)
3453                         break;
3454         return len + 1;
3455 }
3456
3457 static int create_map(uint32_t size_value, uint32_t max_elem)
3458 {
3459         int fd;
3460
3461         fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(long long),
3462                             size_value, max_elem, BPF_F_NO_PREALLOC);
3463         if (fd < 0)
3464                 printf("Failed to create hash map '%s'!\n", strerror(errno));
3465
3466         return fd;
3467 }
3468
3469 static int create_prog_array(void)
3470 {
3471         int fd;
3472
3473         fd = bpf_map_create(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
3474                             sizeof(int), 4, 0);
3475         if (fd < 0)
3476                 printf("Failed to create prog array '%s'!\n", strerror(errno));
3477
3478         return fd;
3479 }
3480
3481 static char bpf_vlog[32768];
3482
3483 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
3484                           int *fd_f1, int *fd_f2, int *fd_f3)
3485 {
3486         int *fixup_map1 = test->fixup_map1;
3487         int *fixup_map2 = test->fixup_map2;
3488         int *fixup_prog = test->fixup_prog;
3489
3490         /* Allocating HTs with 1 elem is fine here, since we only test
3491          * for verifier and not do a runtime lookup, so the only thing
3492          * that really matters is value size in this case.
3493          */
3494         if (*fixup_map1) {
3495                 *fd_f1 = create_map(sizeof(long long), 1);
3496                 do {
3497                         prog[*fixup_map1].imm = *fd_f1;
3498                         fixup_map1++;
3499                 } while (*fixup_map1);
3500         }
3501
3502         if (*fixup_map2) {
3503                 *fd_f2 = create_map(sizeof(struct test_val), 1);
3504                 do {
3505                         prog[*fixup_map2].imm = *fd_f2;
3506                         fixup_map2++;
3507                 } while (*fixup_map2);
3508         }
3509
3510         if (*fixup_prog) {
3511                 *fd_f3 = create_prog_array();
3512                 do {
3513                         prog[*fixup_prog].imm = *fd_f3;
3514                         fixup_prog++;
3515                 } while (*fixup_prog);
3516         }
3517 }
3518
3519 static void do_test_single(struct bpf_test *test, bool unpriv,
3520                            int *passes, int *errors)
3521 {
3522         struct bpf_insn *prog = test->insns;
3523         int prog_len = probe_filter_length(prog);
3524         int prog_type = test->prog_type;
3525         int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1;
3526         int fd_prog, expected_ret;
3527         const char *expected_err;
3528
3529         do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3);
3530
3531         fd_prog = bpf_prog_load(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
3532                                 prog, prog_len * sizeof(struct bpf_insn),
3533                                 "GPL", bpf_vlog, sizeof(bpf_vlog));
3534
3535         expected_ret = unpriv && test->result_unpriv != UNDEF ?
3536                        test->result_unpriv : test->result;
3537         expected_err = unpriv && test->errstr_unpriv ?
3538                        test->errstr_unpriv : test->errstr;
3539         if (expected_ret == ACCEPT) {
3540                 if (fd_prog < 0) {
3541                         printf("FAIL\nFailed to load prog '%s'!\n",
3542                                strerror(errno));
3543                         goto fail_log;
3544                 }
3545         } else {
3546                 if (fd_prog >= 0) {
3547                         printf("FAIL\nUnexpected success to load!\n");
3548                         goto fail_log;
3549                 }
3550                 if (!strstr(bpf_vlog, expected_err)) {
3551                         printf("FAIL\nUnexpected error message!\n");
3552                         goto fail_log;
3553                 }
3554         }
3555
3556         (*passes)++;
3557         printf("OK\n");
3558 close_fds:
3559         close(fd_prog);
3560         close(fd_f1);
3561         close(fd_f2);
3562         close(fd_f3);
3563         sched_yield();
3564         return;
3565 fail_log:
3566         (*errors)++;
3567         printf("%s", bpf_vlog);
3568         goto close_fds;
3569 }
3570
3571 static int do_test(bool unpriv, unsigned int from, unsigned int to)
3572 {
3573         int i, passes = 0, errors = 0;
3574
3575         for (i = from; i < to; i++) {
3576                 struct bpf_test *test = &tests[i];
3577
3578                 /* Program types that are not supported by non-root we
3579                  * skip right away.
3580                  */
3581                 if (unpriv && test->prog_type)
3582                         continue;
3583
3584                 printf("#%d %s ", i, test->descr);
3585                 do_test_single(test, unpriv, &passes, &errors);
3586         }
3587
3588         printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
3589         return errors ? -errors : 0;
3590 }
3591
3592 int main(int argc, char **argv)
3593 {
3594         struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
3595         struct rlimit rlim = { 1 << 20, 1 << 20 };
3596         unsigned int from = 0, to = ARRAY_SIZE(tests);
3597         bool unpriv = geteuid() != 0;
3598
3599         if (argc == 3) {
3600                 unsigned int l = atoi(argv[argc - 2]);
3601                 unsigned int u = atoi(argv[argc - 1]);
3602
3603                 if (l < to && u < to) {
3604                         from = l;
3605                         to   = u + 1;
3606                 }
3607         } else if (argc == 2) {
3608                 unsigned int t = atoi(argv[argc - 1]);
3609
3610                 if (t < to) {
3611                         from = t;
3612                         to   = t + 1;
3613                 }
3614         }
3615
3616         setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
3617         return do_test(unpriv, from, to);
3618 }