Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[cascardo/linux.git] / samples / 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 #include <stdio.h>
11 #include <unistd.h>
12 #include <linux/bpf.h>
13 #include <errno.h>
14 #include <linux/unistd.h>
15 #include <string.h>
16 #include <linux/filter.h>
17 #include <stddef.h>
18 #include <stdbool.h>
19 #include <sys/resource.h>
20 #include "libbpf.h"
21
22 #define MAX_INSNS 512
23 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
24
25 #define MAX_FIXUPS 8
26
27 struct bpf_test {
28         const char *descr;
29         struct bpf_insn insns[MAX_INSNS];
30         int fixup[MAX_FIXUPS];
31         int prog_array_fixup[MAX_FIXUPS];
32         int test_val_map_fixup[MAX_FIXUPS];
33         const char *errstr;
34         const char *errstr_unpriv;
35         enum {
36                 UNDEF,
37                 ACCEPT,
38                 REJECT
39         } result, result_unpriv;
40         enum bpf_prog_type prog_type;
41 };
42
43 /* Note we want this to be 64 bit aligned so that the end of our array is
44  * actually the end of the structure.
45  */
46 #define MAX_ENTRIES 11
47 struct test_val {
48         unsigned index;
49         int foo[MAX_ENTRIES];
50 };
51
52 struct other_val {
53         unsigned int action[32];
54 };
55
56 static struct bpf_test tests[] = {
57         {
58                 "add+sub+mul",
59                 .insns = {
60                         BPF_MOV64_IMM(BPF_REG_1, 1),
61                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
62                         BPF_MOV64_IMM(BPF_REG_2, 3),
63                         BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
64                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
65                         BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
66                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
67                         BPF_EXIT_INSN(),
68                 },
69                 .result = ACCEPT,
70         },
71         {
72                 "unreachable",
73                 .insns = {
74                         BPF_EXIT_INSN(),
75                         BPF_EXIT_INSN(),
76                 },
77                 .errstr = "unreachable",
78                 .result = REJECT,
79         },
80         {
81                 "unreachable2",
82                 .insns = {
83                         BPF_JMP_IMM(BPF_JA, 0, 0, 1),
84                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
85                         BPF_EXIT_INSN(),
86                 },
87                 .errstr = "unreachable",
88                 .result = REJECT,
89         },
90         {
91                 "out of range jump",
92                 .insns = {
93                         BPF_JMP_IMM(BPF_JA, 0, 0, 1),
94                         BPF_EXIT_INSN(),
95                 },
96                 .errstr = "jump out of range",
97                 .result = REJECT,
98         },
99         {
100                 "out of range jump2",
101                 .insns = {
102                         BPF_JMP_IMM(BPF_JA, 0, 0, -2),
103                         BPF_EXIT_INSN(),
104                 },
105                 .errstr = "jump out of range",
106                 .result = REJECT,
107         },
108         {
109                 "test1 ld_imm64",
110                 .insns = {
111                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
112                         BPF_LD_IMM64(BPF_REG_0, 0),
113                         BPF_LD_IMM64(BPF_REG_0, 0),
114                         BPF_LD_IMM64(BPF_REG_0, 1),
115                         BPF_LD_IMM64(BPF_REG_0, 1),
116                         BPF_MOV64_IMM(BPF_REG_0, 2),
117                         BPF_EXIT_INSN(),
118                 },
119                 .errstr = "invalid BPF_LD_IMM insn",
120                 .errstr_unpriv = "R1 pointer comparison",
121                 .result = REJECT,
122         },
123         {
124                 "test2 ld_imm64",
125                 .insns = {
126                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
127                         BPF_LD_IMM64(BPF_REG_0, 0),
128                         BPF_LD_IMM64(BPF_REG_0, 0),
129                         BPF_LD_IMM64(BPF_REG_0, 1),
130                         BPF_LD_IMM64(BPF_REG_0, 1),
131                         BPF_EXIT_INSN(),
132                 },
133                 .errstr = "invalid BPF_LD_IMM insn",
134                 .errstr_unpriv = "R1 pointer comparison",
135                 .result = REJECT,
136         },
137         {
138                 "test3 ld_imm64",
139                 .insns = {
140                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
141                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
142                         BPF_LD_IMM64(BPF_REG_0, 0),
143                         BPF_LD_IMM64(BPF_REG_0, 0),
144                         BPF_LD_IMM64(BPF_REG_0, 1),
145                         BPF_LD_IMM64(BPF_REG_0, 1),
146                         BPF_EXIT_INSN(),
147                 },
148                 .errstr = "invalid bpf_ld_imm64 insn",
149                 .result = REJECT,
150         },
151         {
152                 "test4 ld_imm64",
153                 .insns = {
154                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
155                         BPF_EXIT_INSN(),
156                 },
157                 .errstr = "invalid bpf_ld_imm64 insn",
158                 .result = REJECT,
159         },
160         {
161                 "test5 ld_imm64",
162                 .insns = {
163                         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
164                 },
165                 .errstr = "invalid bpf_ld_imm64 insn",
166                 .result = REJECT,
167         },
168         {
169                 "no bpf_exit",
170                 .insns = {
171                         BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
172                 },
173                 .errstr = "jump out of range",
174                 .result = REJECT,
175         },
176         {
177                 "loop (back-edge)",
178                 .insns = {
179                         BPF_JMP_IMM(BPF_JA, 0, 0, -1),
180                         BPF_EXIT_INSN(),
181                 },
182                 .errstr = "back-edge",
183                 .result = REJECT,
184         },
185         {
186                 "loop2 (back-edge)",
187                 .insns = {
188                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
189                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
190                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
191                         BPF_JMP_IMM(BPF_JA, 0, 0, -4),
192                         BPF_EXIT_INSN(),
193                 },
194                 .errstr = "back-edge",
195                 .result = REJECT,
196         },
197         {
198                 "conditional loop",
199                 .insns = {
200                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
201                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
202                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
203                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
204                         BPF_EXIT_INSN(),
205                 },
206                 .errstr = "back-edge",
207                 .result = REJECT,
208         },
209         {
210                 "read uninitialized register",
211                 .insns = {
212                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
213                         BPF_EXIT_INSN(),
214                 },
215                 .errstr = "R2 !read_ok",
216                 .result = REJECT,
217         },
218         {
219                 "read invalid register",
220                 .insns = {
221                         BPF_MOV64_REG(BPF_REG_0, -1),
222                         BPF_EXIT_INSN(),
223                 },
224                 .errstr = "R15 is invalid",
225                 .result = REJECT,
226         },
227         {
228                 "program doesn't init R0 before exit",
229                 .insns = {
230                         BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
231                         BPF_EXIT_INSN(),
232                 },
233                 .errstr = "R0 !read_ok",
234                 .result = REJECT,
235         },
236         {
237                 "program doesn't init R0 before exit in all branches",
238                 .insns = {
239                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
240                         BPF_MOV64_IMM(BPF_REG_0, 1),
241                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
242                         BPF_EXIT_INSN(),
243                 },
244                 .errstr = "R0 !read_ok",
245                 .errstr_unpriv = "R1 pointer comparison",
246                 .result = REJECT,
247         },
248         {
249                 "stack out of bounds",
250                 .insns = {
251                         BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
252                         BPF_EXIT_INSN(),
253                 },
254                 .errstr = "invalid stack",
255                 .result = REJECT,
256         },
257         {
258                 "invalid call insn1",
259                 .insns = {
260                         BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
261                         BPF_EXIT_INSN(),
262                 },
263                 .errstr = "BPF_CALL uses reserved",
264                 .result = REJECT,
265         },
266         {
267                 "invalid call insn2",
268                 .insns = {
269                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
270                         BPF_EXIT_INSN(),
271                 },
272                 .errstr = "BPF_CALL uses reserved",
273                 .result = REJECT,
274         },
275         {
276                 "invalid function call",
277                 .insns = {
278                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
279                         BPF_EXIT_INSN(),
280                 },
281                 .errstr = "invalid func 1234567",
282                 .result = REJECT,
283         },
284         {
285                 "uninitialized stack1",
286                 .insns = {
287                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
288                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
289                         BPF_LD_MAP_FD(BPF_REG_1, 0),
290                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
291                         BPF_EXIT_INSN(),
292                 },
293                 .fixup = {2},
294                 .errstr = "invalid indirect read from stack",
295                 .result = REJECT,
296         },
297         {
298                 "uninitialized stack2",
299                 .insns = {
300                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
301                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
302                         BPF_EXIT_INSN(),
303                 },
304                 .errstr = "invalid read from stack",
305                 .result = REJECT,
306         },
307         {
308                 "invalid argument register",
309                 .insns = {
310                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
311                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
312                         BPF_EXIT_INSN(),
313                 },
314                 .errstr = "R1 !read_ok",
315                 .result = REJECT,
316                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
317         },
318         {
319                 "non-invalid argument register",
320                 .insns = {
321                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
322                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
323                         BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
324                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
325                         BPF_EXIT_INSN(),
326                 },
327                 .result = ACCEPT,
328                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
329         },
330         {
331                 "check valid spill/fill",
332                 .insns = {
333                         /* spill R1(ctx) into stack */
334                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
335
336                         /* fill it back into R2 */
337                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
338
339                         /* should be able to access R0 = *(R2 + 8) */
340                         /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
341                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
342                         BPF_EXIT_INSN(),
343                 },
344                 .errstr_unpriv = "R0 leaks addr",
345                 .result = ACCEPT,
346                 .result_unpriv = REJECT,
347         },
348         {
349                 "check valid spill/fill, skb mark",
350                 .insns = {
351                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
352                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
353                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
354                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
355                                     offsetof(struct __sk_buff, mark)),
356                         BPF_EXIT_INSN(),
357                 },
358                 .result = ACCEPT,
359                 .result_unpriv = ACCEPT,
360         },
361         {
362                 "check corrupted spill/fill",
363                 .insns = {
364                         /* spill R1(ctx) into stack */
365                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
366
367                         /* mess up with R1 pointer on stack */
368                         BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
369
370                         /* fill back into R0 should fail */
371                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
372
373                         BPF_EXIT_INSN(),
374                 },
375                 .errstr_unpriv = "attempt to corrupt spilled",
376                 .errstr = "corrupted spill",
377                 .result = REJECT,
378         },
379         {
380                 "invalid src register in STX",
381                 .insns = {
382                         BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
383                         BPF_EXIT_INSN(),
384                 },
385                 .errstr = "R15 is invalid",
386                 .result = REJECT,
387         },
388         {
389                 "invalid dst register in STX",
390                 .insns = {
391                         BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
392                         BPF_EXIT_INSN(),
393                 },
394                 .errstr = "R14 is invalid",
395                 .result = REJECT,
396         },
397         {
398                 "invalid dst register in ST",
399                 .insns = {
400                         BPF_ST_MEM(BPF_B, 14, -1, -1),
401                         BPF_EXIT_INSN(),
402                 },
403                 .errstr = "R14 is invalid",
404                 .result = REJECT,
405         },
406         {
407                 "invalid src register in LDX",
408                 .insns = {
409                         BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
410                         BPF_EXIT_INSN(),
411                 },
412                 .errstr = "R12 is invalid",
413                 .result = REJECT,
414         },
415         {
416                 "invalid dst register in LDX",
417                 .insns = {
418                         BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
419                         BPF_EXIT_INSN(),
420                 },
421                 .errstr = "R11 is invalid",
422                 .result = REJECT,
423         },
424         {
425                 "junk insn",
426                 .insns = {
427                         BPF_RAW_INSN(0, 0, 0, 0, 0),
428                         BPF_EXIT_INSN(),
429                 },
430                 .errstr = "invalid BPF_LD_IMM",
431                 .result = REJECT,
432         },
433         {
434                 "junk insn2",
435                 .insns = {
436                         BPF_RAW_INSN(1, 0, 0, 0, 0),
437                         BPF_EXIT_INSN(),
438                 },
439                 .errstr = "BPF_LDX uses reserved fields",
440                 .result = REJECT,
441         },
442         {
443                 "junk insn3",
444                 .insns = {
445                         BPF_RAW_INSN(-1, 0, 0, 0, 0),
446                         BPF_EXIT_INSN(),
447                 },
448                 .errstr = "invalid BPF_ALU opcode f0",
449                 .result = REJECT,
450         },
451         {
452                 "junk insn4",
453                 .insns = {
454                         BPF_RAW_INSN(-1, -1, -1, -1, -1),
455                         BPF_EXIT_INSN(),
456                 },
457                 .errstr = "invalid BPF_ALU opcode f0",
458                 .result = REJECT,
459         },
460         {
461                 "junk insn5",
462                 .insns = {
463                         BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
464                         BPF_EXIT_INSN(),
465                 },
466                 .errstr = "BPF_ALU uses reserved fields",
467                 .result = REJECT,
468         },
469         {
470                 "misaligned read from stack",
471                 .insns = {
472                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
473                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
474                         BPF_EXIT_INSN(),
475                 },
476                 .errstr = "misaligned access",
477                 .result = REJECT,
478         },
479         {
480                 "invalid map_fd for function call",
481                 .insns = {
482                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
483                         BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
484                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
485                         BPF_LD_MAP_FD(BPF_REG_1, 0),
486                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem),
487                         BPF_EXIT_INSN(),
488                 },
489                 .errstr = "fd 0 is not pointing to valid bpf_map",
490                 .result = REJECT,
491         },
492         {
493                 "don't check return value before access",
494                 .insns = {
495                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
496                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
497                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
498                         BPF_LD_MAP_FD(BPF_REG_1, 0),
499                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
500                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
501                         BPF_EXIT_INSN(),
502                 },
503                 .fixup = {3},
504                 .errstr = "R0 invalid mem access 'map_value_or_null'",
505                 .result = REJECT,
506         },
507         {
508                 "access memory with incorrect alignment",
509                 .insns = {
510                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
511                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
512                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
513                         BPF_LD_MAP_FD(BPF_REG_1, 0),
514                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
515                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
516                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
517                         BPF_EXIT_INSN(),
518                 },
519                 .fixup = {3},
520                 .errstr = "misaligned access",
521                 .result = REJECT,
522         },
523         {
524                 "sometimes access memory with incorrect alignment",
525                 .insns = {
526                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
527                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
528                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
529                         BPF_LD_MAP_FD(BPF_REG_1, 0),
530                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
531                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
532                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
533                         BPF_EXIT_INSN(),
534                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
535                         BPF_EXIT_INSN(),
536                 },
537                 .fixup = {3},
538                 .errstr = "R0 invalid mem access",
539                 .errstr_unpriv = "R0 leaks addr",
540                 .result = REJECT,
541         },
542         {
543                 "jump test 1",
544                 .insns = {
545                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
546                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
547                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
548                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
549                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
550                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
551                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
552                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
553                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
554                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
555                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
556                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
557                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
558                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
559                         BPF_MOV64_IMM(BPF_REG_0, 0),
560                         BPF_EXIT_INSN(),
561                 },
562                 .errstr_unpriv = "R1 pointer comparison",
563                 .result_unpriv = REJECT,
564                 .result = ACCEPT,
565         },
566         {
567                 "jump test 2",
568                 .insns = {
569                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
570                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
571                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
572                         BPF_JMP_IMM(BPF_JA, 0, 0, 14),
573                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
574                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
575                         BPF_JMP_IMM(BPF_JA, 0, 0, 11),
576                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
577                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
578                         BPF_JMP_IMM(BPF_JA, 0, 0, 8),
579                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
580                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
581                         BPF_JMP_IMM(BPF_JA, 0, 0, 5),
582                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
583                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
584                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
585                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
586                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
587                         BPF_MOV64_IMM(BPF_REG_0, 0),
588                         BPF_EXIT_INSN(),
589                 },
590                 .errstr_unpriv = "R1 pointer comparison",
591                 .result_unpriv = REJECT,
592                 .result = ACCEPT,
593         },
594         {
595                 "jump test 3",
596                 .insns = {
597                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
598                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
599                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
600                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
601                         BPF_JMP_IMM(BPF_JA, 0, 0, 19),
602                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
603                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
604                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
605                         BPF_JMP_IMM(BPF_JA, 0, 0, 15),
606                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
607                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
608                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
609                         BPF_JMP_IMM(BPF_JA, 0, 0, 11),
610                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
611                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
612                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
613                         BPF_JMP_IMM(BPF_JA, 0, 0, 7),
614                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
615                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
616                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
617                         BPF_JMP_IMM(BPF_JA, 0, 0, 3),
618                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
619                         BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
620                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
621                         BPF_LD_MAP_FD(BPF_REG_1, 0),
622                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem),
623                         BPF_EXIT_INSN(),
624                 },
625                 .fixup = {24},
626                 .errstr_unpriv = "R1 pointer comparison",
627                 .result_unpriv = REJECT,
628                 .result = ACCEPT,
629         },
630         {
631                 "jump test 4",
632                 .insns = {
633                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
634                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
635                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
636                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
637                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
638                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
639                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
640                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
641                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
642                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
643                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
644                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
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, 0),
670                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
671                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
672                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
673                         BPF_MOV64_IMM(BPF_REG_0, 0),
674                         BPF_EXIT_INSN(),
675                 },
676                 .errstr_unpriv = "R1 pointer comparison",
677                 .result_unpriv = REJECT,
678                 .result = ACCEPT,
679         },
680         {
681                 "jump test 5",
682                 .insns = {
683                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
684                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
685                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
686                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
687                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
688                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
689                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
690                         BPF_MOV64_IMM(BPF_REG_0, 0),
691                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
692                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
693                         BPF_JMP_IMM(BPF_JA, 0, 0, 2),
694                         BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
695                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
696                         BPF_MOV64_IMM(BPF_REG_0, 0),
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_EXIT_INSN(),
716                 },
717                 .errstr_unpriv = "R1 pointer comparison",
718                 .result_unpriv = REJECT,
719                 .result = ACCEPT,
720         },
721         {
722                 "access skb fields ok",
723                 .insns = {
724                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
725                                     offsetof(struct __sk_buff, len)),
726                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
727                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
728                                     offsetof(struct __sk_buff, mark)),
729                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
730                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
731                                     offsetof(struct __sk_buff, pkt_type)),
732                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
733                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
734                                     offsetof(struct __sk_buff, queue_mapping)),
735                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
736                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
737                                     offsetof(struct __sk_buff, protocol)),
738                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
739                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
740                                     offsetof(struct __sk_buff, vlan_present)),
741                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
742                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
743                                     offsetof(struct __sk_buff, vlan_tci)),
744                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
745                         BPF_EXIT_INSN(),
746                 },
747                 .result = ACCEPT,
748         },
749         {
750                 "access skb fields bad1",
751                 .insns = {
752                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
753                         BPF_EXIT_INSN(),
754                 },
755                 .errstr = "invalid bpf_context access",
756                 .result = REJECT,
757         },
758         {
759                 "access skb fields bad2",
760                 .insns = {
761                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
762                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
763                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
764                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
765                         BPF_LD_MAP_FD(BPF_REG_1, 0),
766                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
767                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
768                         BPF_EXIT_INSN(),
769                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
770                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
771                                     offsetof(struct __sk_buff, pkt_type)),
772                         BPF_EXIT_INSN(),
773                 },
774                 .fixup = {4},
775                 .errstr = "different pointers",
776                 .errstr_unpriv = "R1 pointer comparison",
777                 .result = REJECT,
778         },
779         {
780                 "access skb fields bad3",
781                 .insns = {
782                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
783                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
784                                     offsetof(struct __sk_buff, pkt_type)),
785                         BPF_EXIT_INSN(),
786                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
787                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
788                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
789                         BPF_LD_MAP_FD(BPF_REG_1, 0),
790                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
791                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
792                         BPF_EXIT_INSN(),
793                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
794                         BPF_JMP_IMM(BPF_JA, 0, 0, -12),
795                 },
796                 .fixup = {6},
797                 .errstr = "different pointers",
798                 .errstr_unpriv = "R1 pointer comparison",
799                 .result = REJECT,
800         },
801         {
802                 "access skb fields bad4",
803                 .insns = {
804                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
805                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
806                                     offsetof(struct __sk_buff, len)),
807                         BPF_MOV64_IMM(BPF_REG_0, 0),
808                         BPF_EXIT_INSN(),
809                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
810                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
811                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
812                         BPF_LD_MAP_FD(BPF_REG_1, 0),
813                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
814                         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
815                         BPF_EXIT_INSN(),
816                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
817                         BPF_JMP_IMM(BPF_JA, 0, 0, -13),
818                 },
819                 .fixup = {7},
820                 .errstr = "different pointers",
821                 .errstr_unpriv = "R1 pointer comparison",
822                 .result = REJECT,
823         },
824         {
825                 "check skb->mark is not writeable by sockets",
826                 .insns = {
827                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
828                                     offsetof(struct __sk_buff, mark)),
829                         BPF_EXIT_INSN(),
830                 },
831                 .errstr = "invalid bpf_context access",
832                 .errstr_unpriv = "R1 leaks addr",
833                 .result = REJECT,
834         },
835         {
836                 "check skb->tc_index is not writeable by sockets",
837                 .insns = {
838                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
839                                     offsetof(struct __sk_buff, tc_index)),
840                         BPF_EXIT_INSN(),
841                 },
842                 .errstr = "invalid bpf_context access",
843                 .errstr_unpriv = "R1 leaks addr",
844                 .result = REJECT,
845         },
846         {
847                 "check non-u32 access to cb",
848                 .insns = {
849                         BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_1,
850                                     offsetof(struct __sk_buff, cb[0])),
851                         BPF_EXIT_INSN(),
852                 },
853                 .errstr = "invalid bpf_context access",
854                 .errstr_unpriv = "R1 leaks addr",
855                 .result = REJECT,
856         },
857         {
858                 "check out of range skb->cb access",
859                 .insns = {
860                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
861                                     offsetof(struct __sk_buff, cb[0]) + 256),
862                         BPF_EXIT_INSN(),
863                 },
864                 .errstr = "invalid bpf_context access",
865                 .errstr_unpriv = "",
866                 .result = REJECT,
867                 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
868         },
869         {
870                 "write skb fields from socket prog",
871                 .insns = {
872                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
873                                     offsetof(struct __sk_buff, cb[4])),
874                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
875                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
876                                     offsetof(struct __sk_buff, mark)),
877                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
878                                     offsetof(struct __sk_buff, tc_index)),
879                         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
880                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
881                                     offsetof(struct __sk_buff, cb[0])),
882                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
883                                     offsetof(struct __sk_buff, cb[2])),
884                         BPF_EXIT_INSN(),
885                 },
886                 .result = ACCEPT,
887                 .errstr_unpriv = "R1 leaks addr",
888                 .result_unpriv = REJECT,
889         },
890         {
891                 "write skb fields from tc_cls_act prog",
892                 .insns = {
893                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
894                                     offsetof(struct __sk_buff, cb[0])),
895                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
896                                     offsetof(struct __sk_buff, mark)),
897                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
898                                     offsetof(struct __sk_buff, tc_index)),
899                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
900                                     offsetof(struct __sk_buff, tc_index)),
901                         BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
902                                     offsetof(struct __sk_buff, cb[3])),
903                         BPF_EXIT_INSN(),
904                 },
905                 .errstr_unpriv = "",
906                 .result_unpriv = REJECT,
907                 .result = ACCEPT,
908                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
909         },
910         {
911                 "PTR_TO_STACK store/load",
912                 .insns = {
913                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
914                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
915                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
916                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
917                         BPF_EXIT_INSN(),
918                 },
919                 .result = ACCEPT,
920         },
921         {
922                 "PTR_TO_STACK store/load - bad alignment on off",
923                 .insns = {
924                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
925                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
926                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
927                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
928                         BPF_EXIT_INSN(),
929                 },
930                 .result = REJECT,
931                 .errstr = "misaligned access off -6 size 8",
932         },
933         {
934                 "PTR_TO_STACK store/load - bad alignment on reg",
935                 .insns = {
936                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
937                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
938                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
939                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
940                         BPF_EXIT_INSN(),
941                 },
942                 .result = REJECT,
943                 .errstr = "misaligned access off -2 size 8",
944         },
945         {
946                 "PTR_TO_STACK store/load - out of bounds low",
947                 .insns = {
948                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
949                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
950                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
951                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
952                         BPF_EXIT_INSN(),
953                 },
954                 .result = REJECT,
955                 .errstr = "invalid stack off=-79992 size=8",
956         },
957         {
958                 "PTR_TO_STACK store/load - out of bounds high",
959                 .insns = {
960                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
961                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
962                         BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
963                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
964                         BPF_EXIT_INSN(),
965                 },
966                 .result = REJECT,
967                 .errstr = "invalid stack off=0 size=8",
968         },
969         {
970                 "unpriv: return pointer",
971                 .insns = {
972                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
973                         BPF_EXIT_INSN(),
974                 },
975                 .result = ACCEPT,
976                 .result_unpriv = REJECT,
977                 .errstr_unpriv = "R0 leaks addr",
978         },
979         {
980                 "unpriv: add const to pointer",
981                 .insns = {
982                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
983                         BPF_MOV64_IMM(BPF_REG_0, 0),
984                         BPF_EXIT_INSN(),
985                 },
986                 .result = ACCEPT,
987                 .result_unpriv = REJECT,
988                 .errstr_unpriv = "R1 pointer arithmetic",
989         },
990         {
991                 "unpriv: add pointer to pointer",
992                 .insns = {
993                         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
994                         BPF_MOV64_IMM(BPF_REG_0, 0),
995                         BPF_EXIT_INSN(),
996                 },
997                 .result = ACCEPT,
998                 .result_unpriv = REJECT,
999                 .errstr_unpriv = "R1 pointer arithmetic",
1000         },
1001         {
1002                 "unpriv: neg pointer",
1003                 .insns = {
1004                         BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1005                         BPF_MOV64_IMM(BPF_REG_0, 0),
1006                         BPF_EXIT_INSN(),
1007                 },
1008                 .result = ACCEPT,
1009                 .result_unpriv = REJECT,
1010                 .errstr_unpriv = "R1 pointer arithmetic",
1011         },
1012         {
1013                 "unpriv: cmp pointer with const",
1014                 .insns = {
1015                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1016                         BPF_MOV64_IMM(BPF_REG_0, 0),
1017                         BPF_EXIT_INSN(),
1018                 },
1019                 .result = ACCEPT,
1020                 .result_unpriv = REJECT,
1021                 .errstr_unpriv = "R1 pointer comparison",
1022         },
1023         {
1024                 "unpriv: cmp pointer with pointer",
1025                 .insns = {
1026                         BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1027                         BPF_MOV64_IMM(BPF_REG_0, 0),
1028                         BPF_EXIT_INSN(),
1029                 },
1030                 .result = ACCEPT,
1031                 .result_unpriv = REJECT,
1032                 .errstr_unpriv = "R10 pointer comparison",
1033         },
1034         {
1035                 "unpriv: check that printk is disallowed",
1036                 .insns = {
1037                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1038                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1039                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1040                         BPF_MOV64_IMM(BPF_REG_2, 8),
1041                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1042                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_trace_printk),
1043                         BPF_MOV64_IMM(BPF_REG_0, 0),
1044                         BPF_EXIT_INSN(),
1045                 },
1046                 .errstr_unpriv = "unknown func 6",
1047                 .result_unpriv = REJECT,
1048                 .result = ACCEPT,
1049         },
1050         {
1051                 "unpriv: pass pointer to helper function",
1052                 .insns = {
1053                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1054                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1055                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1056                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1057                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1058                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1059                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1060                         BPF_MOV64_IMM(BPF_REG_0, 0),
1061                         BPF_EXIT_INSN(),
1062                 },
1063                 .fixup = {3},
1064                 .errstr_unpriv = "R4 leaks addr",
1065                 .result_unpriv = REJECT,
1066                 .result = ACCEPT,
1067         },
1068         {
1069                 "unpriv: indirectly pass pointer on stack to helper function",
1070                 .insns = {
1071                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1072                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1073                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1074                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1075                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1076                         BPF_MOV64_IMM(BPF_REG_0, 0),
1077                         BPF_EXIT_INSN(),
1078                 },
1079                 .fixup = {3},
1080                 .errstr = "invalid indirect read from stack off -8+0 size 8",
1081                 .result = REJECT,
1082         },
1083         {
1084                 "unpriv: mangle pointer on stack 1",
1085                 .insns = {
1086                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1087                         BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1088                         BPF_MOV64_IMM(BPF_REG_0, 0),
1089                         BPF_EXIT_INSN(),
1090                 },
1091                 .errstr_unpriv = "attempt to corrupt spilled",
1092                 .result_unpriv = REJECT,
1093                 .result = ACCEPT,
1094         },
1095         {
1096                 "unpriv: mangle pointer on stack 2",
1097                 .insns = {
1098                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1099                         BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1100                         BPF_MOV64_IMM(BPF_REG_0, 0),
1101                         BPF_EXIT_INSN(),
1102                 },
1103                 .errstr_unpriv = "attempt to corrupt spilled",
1104                 .result_unpriv = REJECT,
1105                 .result = ACCEPT,
1106         },
1107         {
1108                 "unpriv: read pointer from stack in small chunks",
1109                 .insns = {
1110                         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1111                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1112                         BPF_MOV64_IMM(BPF_REG_0, 0),
1113                         BPF_EXIT_INSN(),
1114                 },
1115                 .errstr = "invalid size",
1116                 .result = REJECT,
1117         },
1118         {
1119                 "unpriv: write pointer into ctx",
1120                 .insns = {
1121                         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1122                         BPF_MOV64_IMM(BPF_REG_0, 0),
1123                         BPF_EXIT_INSN(),
1124                 },
1125                 .errstr_unpriv = "R1 leaks addr",
1126                 .result_unpriv = REJECT,
1127                 .errstr = "invalid bpf_context access",
1128                 .result = REJECT,
1129         },
1130         {
1131                 "unpriv: write pointer into map elem value",
1132                 .insns = {
1133                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1134                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1135                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1136                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1137                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1138                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1139                         BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1140                         BPF_EXIT_INSN(),
1141                 },
1142                 .fixup = {3},
1143                 .errstr_unpriv = "R0 leaks addr",
1144                 .result_unpriv = REJECT,
1145                 .result = ACCEPT,
1146         },
1147         {
1148                 "unpriv: partial copy of pointer",
1149                 .insns = {
1150                         BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1151                         BPF_MOV64_IMM(BPF_REG_0, 0),
1152                         BPF_EXIT_INSN(),
1153                 },
1154                 .errstr_unpriv = "R10 partial copy",
1155                 .result_unpriv = REJECT,
1156                 .result = ACCEPT,
1157         },
1158         {
1159                 "unpriv: pass pointer to tail_call",
1160                 .insns = {
1161                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1162                         BPF_LD_MAP_FD(BPF_REG_2, 0),
1163                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1164                         BPF_MOV64_IMM(BPF_REG_0, 0),
1165                         BPF_EXIT_INSN(),
1166                 },
1167                 .prog_array_fixup = {1},
1168                 .errstr_unpriv = "R3 leaks addr into helper",
1169                 .result_unpriv = REJECT,
1170                 .result = ACCEPT,
1171         },
1172         {
1173                 "unpriv: cmp map pointer with zero",
1174                 .insns = {
1175                         BPF_MOV64_IMM(BPF_REG_1, 0),
1176                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1177                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1178                         BPF_MOV64_IMM(BPF_REG_0, 0),
1179                         BPF_EXIT_INSN(),
1180                 },
1181                 .fixup = {1},
1182                 .errstr_unpriv = "R1 pointer comparison",
1183                 .result_unpriv = REJECT,
1184                 .result = ACCEPT,
1185         },
1186         {
1187                 "unpriv: write into frame pointer",
1188                 .insns = {
1189                         BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1190                         BPF_MOV64_IMM(BPF_REG_0, 0),
1191                         BPF_EXIT_INSN(),
1192                 },
1193                 .errstr = "frame pointer is read only",
1194                 .result = REJECT,
1195         },
1196         {
1197                 "unpriv: cmp of frame pointer",
1198                 .insns = {
1199                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1200                         BPF_MOV64_IMM(BPF_REG_0, 0),
1201                         BPF_EXIT_INSN(),
1202                 },
1203                 .errstr_unpriv = "R10 pointer comparison",
1204                 .result_unpriv = REJECT,
1205                 .result = ACCEPT,
1206         },
1207         {
1208                 "unpriv: cmp of stack pointer",
1209                 .insns = {
1210                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1211                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1212                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1213                         BPF_MOV64_IMM(BPF_REG_0, 0),
1214                         BPF_EXIT_INSN(),
1215                 },
1216                 .errstr_unpriv = "R2 pointer comparison",
1217                 .result_unpriv = REJECT,
1218                 .result = ACCEPT,
1219         },
1220         {
1221                 "unpriv: obfuscate stack pointer",
1222                 .insns = {
1223                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1224                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1225                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1226                         BPF_MOV64_IMM(BPF_REG_0, 0),
1227                         BPF_EXIT_INSN(),
1228                 },
1229                 .errstr_unpriv = "R2 pointer arithmetic",
1230                 .result_unpriv = REJECT,
1231                 .result = ACCEPT,
1232         },
1233         {
1234                 "raw_stack: no skb_load_bytes",
1235                 .insns = {
1236                         BPF_MOV64_IMM(BPF_REG_2, 4),
1237                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1238                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1239                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1240                         BPF_MOV64_IMM(BPF_REG_4, 8),
1241                         /* Call to skb_load_bytes() omitted. */
1242                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1243                         BPF_EXIT_INSN(),
1244                 },
1245                 .result = REJECT,
1246                 .errstr = "invalid read from stack off -8+0 size 8",
1247                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1248         },
1249         {
1250                 "raw_stack: skb_load_bytes, negative len",
1251                 .insns = {
1252                         BPF_MOV64_IMM(BPF_REG_2, 4),
1253                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1254                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1255                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1256                         BPF_MOV64_IMM(BPF_REG_4, -8),
1257                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1258                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1259                         BPF_EXIT_INSN(),
1260                 },
1261                 .result = REJECT,
1262                 .errstr = "invalid stack type R3",
1263                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1264         },
1265         {
1266                 "raw_stack: skb_load_bytes, negative len 2",
1267                 .insns = {
1268                         BPF_MOV64_IMM(BPF_REG_2, 4),
1269                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1270                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1271                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1272                         BPF_MOV64_IMM(BPF_REG_4, ~0),
1273                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1274                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1275                         BPF_EXIT_INSN(),
1276                 },
1277                 .result = REJECT,
1278                 .errstr = "invalid stack type R3",
1279                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1280         },
1281         {
1282                 "raw_stack: skb_load_bytes, zero len",
1283                 .insns = {
1284                         BPF_MOV64_IMM(BPF_REG_2, 4),
1285                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1286                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1287                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1288                         BPF_MOV64_IMM(BPF_REG_4, 0),
1289                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1290                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1291                         BPF_EXIT_INSN(),
1292                 },
1293                 .result = REJECT,
1294                 .errstr = "invalid stack type R3",
1295                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1296         },
1297         {
1298                 "raw_stack: skb_load_bytes, no init",
1299                 .insns = {
1300                         BPF_MOV64_IMM(BPF_REG_2, 4),
1301                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1302                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1303                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1304                         BPF_MOV64_IMM(BPF_REG_4, 8),
1305                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1306                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1307                         BPF_EXIT_INSN(),
1308                 },
1309                 .result = ACCEPT,
1310                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1311         },
1312         {
1313                 "raw_stack: skb_load_bytes, init",
1314                 .insns = {
1315                         BPF_MOV64_IMM(BPF_REG_2, 4),
1316                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1317                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1318                         BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1319                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1320                         BPF_MOV64_IMM(BPF_REG_4, 8),
1321                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1322                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1323                         BPF_EXIT_INSN(),
1324                 },
1325                 .result = ACCEPT,
1326                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1327         },
1328         {
1329                 "raw_stack: skb_load_bytes, spilled regs around bounds",
1330                 .insns = {
1331                         BPF_MOV64_IMM(BPF_REG_2, 4),
1332                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1333                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1334                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1335                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1336                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1337                         BPF_MOV64_IMM(BPF_REG_4, 8),
1338                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1339                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1340                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1341                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1342                                     offsetof(struct __sk_buff, mark)),
1343                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1344                                     offsetof(struct __sk_buff, priority)),
1345                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1346                         BPF_EXIT_INSN(),
1347                 },
1348                 .result = ACCEPT,
1349                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1350         },
1351         {
1352                 "raw_stack: skb_load_bytes, spilled regs corruption",
1353                 .insns = {
1354                         BPF_MOV64_IMM(BPF_REG_2, 4),
1355                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1356                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1357                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), /* spill ctx from R1 */
1358                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1359                         BPF_MOV64_IMM(BPF_REG_4, 8),
1360                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1361                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), /* fill ctx into R0 */
1362                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1363                                     offsetof(struct __sk_buff, mark)),
1364                         BPF_EXIT_INSN(),
1365                 },
1366                 .result = REJECT,
1367                 .errstr = "R0 invalid mem access 'inv'",
1368                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1369         },
1370         {
1371                 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1372                 .insns = {
1373                         BPF_MOV64_IMM(BPF_REG_2, 4),
1374                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1375                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1376                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1377                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0), /* spill ctx from R1 */
1378                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1379                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1380                         BPF_MOV64_IMM(BPF_REG_4, 8),
1381                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1382                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1383                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1384                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0), /* fill ctx into R3 */
1385                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1386                                     offsetof(struct __sk_buff, mark)),
1387                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1388                                     offsetof(struct __sk_buff, priority)),
1389                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1390                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1391                                     offsetof(struct __sk_buff, pkt_type)),
1392                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1393                         BPF_EXIT_INSN(),
1394                 },
1395                 .result = REJECT,
1396                 .errstr = "R3 invalid mem access 'inv'",
1397                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1398         },
1399         {
1400                 "raw_stack: skb_load_bytes, spilled regs + data",
1401                 .insns = {
1402                         BPF_MOV64_IMM(BPF_REG_2, 4),
1403                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1404                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1405                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1406                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0), /* spill ctx from R1 */
1407                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1408                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1409                         BPF_MOV64_IMM(BPF_REG_4, 8),
1410                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1411                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1412                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1413                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0), /* fill data into R3 */
1414                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1415                                     offsetof(struct __sk_buff, mark)),
1416                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1417                                     offsetof(struct __sk_buff, priority)),
1418                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1419                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1420                         BPF_EXIT_INSN(),
1421                 },
1422                 .result = ACCEPT,
1423                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1424         },
1425         {
1426                 "raw_stack: skb_load_bytes, invalid access 1",
1427                 .insns = {
1428                         BPF_MOV64_IMM(BPF_REG_2, 4),
1429                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1430                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
1431                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1432                         BPF_MOV64_IMM(BPF_REG_4, 8),
1433                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1434                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1435                         BPF_EXIT_INSN(),
1436                 },
1437                 .result = REJECT,
1438                 .errstr = "invalid stack type R3 off=-513 access_size=8",
1439                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1440         },
1441         {
1442                 "raw_stack: skb_load_bytes, invalid access 2",
1443                 .insns = {
1444                         BPF_MOV64_IMM(BPF_REG_2, 4),
1445                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1446                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1447                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1448                         BPF_MOV64_IMM(BPF_REG_4, 8),
1449                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1450                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1451                         BPF_EXIT_INSN(),
1452                 },
1453                 .result = REJECT,
1454                 .errstr = "invalid stack type R3 off=-1 access_size=8",
1455                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1456         },
1457         {
1458                 "raw_stack: skb_load_bytes, invalid access 3",
1459                 .insns = {
1460                         BPF_MOV64_IMM(BPF_REG_2, 4),
1461                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1462                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
1463                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1464                         BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
1465                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 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 = REJECT,
1470                 .errstr = "invalid stack type R3 off=-1 access_size=-1",
1471                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1472         },
1473         {
1474                 "raw_stack: skb_load_bytes, invalid access 4",
1475                 .insns = {
1476                         BPF_MOV64_IMM(BPF_REG_2, 4),
1477                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1478                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1479                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1480                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1481                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1482                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1483                         BPF_EXIT_INSN(),
1484                 },
1485                 .result = REJECT,
1486                 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
1487                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1488         },
1489         {
1490                 "raw_stack: skb_load_bytes, invalid access 5",
1491                 .insns = {
1492                         BPF_MOV64_IMM(BPF_REG_2, 4),
1493                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1494                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1495                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1496                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1497                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1498                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1499                         BPF_EXIT_INSN(),
1500                 },
1501                 .result = REJECT,
1502                 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
1503                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1504         },
1505         {
1506                 "raw_stack: skb_load_bytes, invalid access 6",
1507                 .insns = {
1508                         BPF_MOV64_IMM(BPF_REG_2, 4),
1509                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1510                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1511                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1512                         BPF_MOV64_IMM(BPF_REG_4, 0),
1513                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1514                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1515                         BPF_EXIT_INSN(),
1516                 },
1517                 .result = REJECT,
1518                 .errstr = "invalid stack type R3 off=-512 access_size=0",
1519                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1520         },
1521         {
1522                 "raw_stack: skb_load_bytes, large access",
1523                 .insns = {
1524                         BPF_MOV64_IMM(BPF_REG_2, 4),
1525                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1526                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1527                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1528                         BPF_MOV64_IMM(BPF_REG_4, 512),
1529                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1530                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1531                         BPF_EXIT_INSN(),
1532                 },
1533                 .result = ACCEPT,
1534                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1535         },
1536         {
1537                 "direct packet access: test1",
1538                 .insns = {
1539                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1540                                     offsetof(struct __sk_buff, data)),
1541                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1542                                     offsetof(struct __sk_buff, data_end)),
1543                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1544                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1545                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1546                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1547                         BPF_MOV64_IMM(BPF_REG_0, 0),
1548                         BPF_EXIT_INSN(),
1549                 },
1550                 .result = ACCEPT,
1551                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1552         },
1553         {
1554                 "direct packet access: test2",
1555                 .insns = {
1556                         BPF_MOV64_IMM(BPF_REG_0, 1),
1557                         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
1558                                     offsetof(struct __sk_buff, data_end)),
1559                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1560                                     offsetof(struct __sk_buff, data)),
1561                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
1562                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
1563                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
1564                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
1565                         BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
1566                         BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
1567                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1568                                     offsetof(struct __sk_buff, data)),
1569                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
1570                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
1571                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
1572                         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
1573                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
1574                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
1575                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1576                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1577                                     offsetof(struct __sk_buff, data_end)),
1578                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
1579                         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
1580                         BPF_MOV64_IMM(BPF_REG_0, 0),
1581                         BPF_EXIT_INSN(),
1582                 },
1583                 .result = ACCEPT,
1584                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1585         },
1586         {
1587                 "direct packet access: test3",
1588                 .insns = {
1589                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1590                                     offsetof(struct __sk_buff, data)),
1591                         BPF_MOV64_IMM(BPF_REG_0, 0),
1592                         BPF_EXIT_INSN(),
1593                 },
1594                 .errstr = "invalid bpf_context access off=76",
1595                 .result = REJECT,
1596                 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
1597         },
1598         {
1599                 "direct packet access: test4 (write)",
1600                 .insns = {
1601                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1602                                     offsetof(struct __sk_buff, data)),
1603                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1604                                     offsetof(struct __sk_buff, data_end)),
1605                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1606                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1607                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1608                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1609                         BPF_MOV64_IMM(BPF_REG_0, 0),
1610                         BPF_EXIT_INSN(),
1611                 },
1612                 .result = ACCEPT,
1613                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1614         },
1615         {
1616                 "direct packet access: test5 (pkt_end >= reg, good access)",
1617                 .insns = {
1618                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1619                                     offsetof(struct __sk_buff, data)),
1620                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1621                                     offsetof(struct __sk_buff, data_end)),
1622                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1623                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1624                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1625                         BPF_MOV64_IMM(BPF_REG_0, 1),
1626                         BPF_EXIT_INSN(),
1627                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1628                         BPF_MOV64_IMM(BPF_REG_0, 0),
1629                         BPF_EXIT_INSN(),
1630                 },
1631                 .result = ACCEPT,
1632                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1633         },
1634         {
1635                 "direct packet access: test6 (pkt_end >= reg, bad access)",
1636                 .insns = {
1637                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1638                                     offsetof(struct __sk_buff, data)),
1639                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1640                                     offsetof(struct __sk_buff, data_end)),
1641                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1642                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1643                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1644                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1645                         BPF_MOV64_IMM(BPF_REG_0, 1),
1646                         BPF_EXIT_INSN(),
1647                         BPF_MOV64_IMM(BPF_REG_0, 0),
1648                         BPF_EXIT_INSN(),
1649                 },
1650                 .errstr = "invalid access to packet",
1651                 .result = REJECT,
1652                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1653         },
1654         {
1655                 "direct packet access: test7 (pkt_end >= reg, both accesses)",
1656                 .insns = {
1657                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1658                                     offsetof(struct __sk_buff, data)),
1659                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1660                                     offsetof(struct __sk_buff, data_end)),
1661                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1662                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1663                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1664                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1665                         BPF_MOV64_IMM(BPF_REG_0, 1),
1666                         BPF_EXIT_INSN(),
1667                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1668                         BPF_MOV64_IMM(BPF_REG_0, 0),
1669                         BPF_EXIT_INSN(),
1670                 },
1671                 .errstr = "invalid access to packet",
1672                 .result = REJECT,
1673                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1674         },
1675         {
1676                 "direct packet access: test8 (double test, variant 1)",
1677                 .insns = {
1678                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1679                                     offsetof(struct __sk_buff, data)),
1680                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1681                                     offsetof(struct __sk_buff, data_end)),
1682                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1683                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1684                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
1685                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1686                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1687                         BPF_MOV64_IMM(BPF_REG_0, 1),
1688                         BPF_EXIT_INSN(),
1689                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1690                         BPF_MOV64_IMM(BPF_REG_0, 0),
1691                         BPF_EXIT_INSN(),
1692                 },
1693                 .result = ACCEPT,
1694                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1695         },
1696         {
1697                 "direct packet access: test9 (double test, variant 2)",
1698                 .insns = {
1699                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1700                                     offsetof(struct __sk_buff, data)),
1701                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1702                                     offsetof(struct __sk_buff, data_end)),
1703                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1704                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1705                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1706                         BPF_MOV64_IMM(BPF_REG_0, 1),
1707                         BPF_EXIT_INSN(),
1708                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1709                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1710                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1711                         BPF_MOV64_IMM(BPF_REG_0, 0),
1712                         BPF_EXIT_INSN(),
1713                 },
1714                 .result = ACCEPT,
1715                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1716         },
1717         {
1718                 "direct packet access: test10 (write invalid)",
1719                 .insns = {
1720                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1721                                     offsetof(struct __sk_buff, data)),
1722                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1723                                     offsetof(struct __sk_buff, data_end)),
1724                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1725                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1726                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1727                         BPF_MOV64_IMM(BPF_REG_0, 0),
1728                         BPF_EXIT_INSN(),
1729                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1730                         BPF_MOV64_IMM(BPF_REG_0, 0),
1731                         BPF_EXIT_INSN(),
1732                 },
1733                 .errstr = "invalid access to packet",
1734                 .result = REJECT,
1735                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1736         },
1737         {
1738                 "helper access to packet: test1, valid packet_ptr range",
1739                 .insns = {
1740                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1741                                     offsetof(struct xdp_md, data)),
1742                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1743                                     offsetof(struct xdp_md, data_end)),
1744                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1745                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1746                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1747                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1748                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1749                         BPF_MOV64_IMM(BPF_REG_4, 0),
1750                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1751                         BPF_MOV64_IMM(BPF_REG_0, 0),
1752                         BPF_EXIT_INSN(),
1753                 },
1754                 .fixup = {5},
1755                 .result_unpriv = ACCEPT,
1756                 .result = ACCEPT,
1757                 .prog_type = BPF_PROG_TYPE_XDP,
1758         },
1759         {
1760                 "helper access to packet: test2, unchecked packet_ptr",
1761                 .insns = {
1762                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1763                                     offsetof(struct xdp_md, data)),
1764                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1765                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1766                         BPF_MOV64_IMM(BPF_REG_0, 0),
1767                         BPF_EXIT_INSN(),
1768                 },
1769                 .fixup = {1},
1770                 .result = REJECT,
1771                 .errstr = "invalid access to packet",
1772                 .prog_type = BPF_PROG_TYPE_XDP,
1773         },
1774         {
1775                 "helper access to packet: test3, variable add",
1776                 .insns = {
1777                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1778                                         offsetof(struct xdp_md, data)),
1779                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1780                                         offsetof(struct xdp_md, data_end)),
1781                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1782                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1783                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1784                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1785                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1786                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1787                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1788                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1789                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1790                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1791                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1792                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1793                         BPF_MOV64_IMM(BPF_REG_0, 0),
1794                         BPF_EXIT_INSN(),
1795                 },
1796                 .fixup = {11},
1797                 .result = ACCEPT,
1798                 .prog_type = BPF_PROG_TYPE_XDP,
1799         },
1800         {
1801                 "helper access to packet: test4, packet_ptr with bad range",
1802                 .insns = {
1803                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1804                                     offsetof(struct xdp_md, data)),
1805                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1806                                     offsetof(struct xdp_md, data_end)),
1807                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1808                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1809                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1810                         BPF_MOV64_IMM(BPF_REG_0, 0),
1811                         BPF_EXIT_INSN(),
1812                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1813                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1814                         BPF_MOV64_IMM(BPF_REG_0, 0),
1815                         BPF_EXIT_INSN(),
1816                 },
1817                 .fixup = {7},
1818                 .result = REJECT,
1819                 .errstr = "invalid access to packet",
1820                 .prog_type = BPF_PROG_TYPE_XDP,
1821         },
1822         {
1823                 "helper access to packet: test5, packet_ptr with too short range",
1824                 .insns = {
1825                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1826                                     offsetof(struct xdp_md, data)),
1827                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1828                                     offsetof(struct xdp_md, data_end)),
1829                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1830                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1831                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1832                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1833                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1834                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1835                         BPF_MOV64_IMM(BPF_REG_0, 0),
1836                         BPF_EXIT_INSN(),
1837                 },
1838                 .fixup = {6},
1839                 .result = REJECT,
1840                 .errstr = "invalid access to packet",
1841                 .prog_type = BPF_PROG_TYPE_XDP,
1842         },
1843         {
1844                 "helper access to packet: test6, cls valid packet_ptr range",
1845                 .insns = {
1846                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1847                                     offsetof(struct __sk_buff, data)),
1848                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1849                                     offsetof(struct __sk_buff, data_end)),
1850                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1851                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1852                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1853                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1854                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1855                         BPF_MOV64_IMM(BPF_REG_4, 0),
1856                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1857                         BPF_MOV64_IMM(BPF_REG_0, 0),
1858                         BPF_EXIT_INSN(),
1859                 },
1860                 .fixup = {5},
1861                 .result = ACCEPT,
1862                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1863         },
1864         {
1865                 "helper access to packet: test7, cls unchecked packet_ptr",
1866                 .insns = {
1867                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1868                                     offsetof(struct __sk_buff, data)),
1869                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1870                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1871                         BPF_MOV64_IMM(BPF_REG_0, 0),
1872                         BPF_EXIT_INSN(),
1873                 },
1874                 .fixup = {1},
1875                 .result = REJECT,
1876                 .errstr = "invalid access to packet",
1877                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1878         },
1879         {
1880                 "helper access to packet: test8, cls variable add",
1881                 .insns = {
1882                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1883                                         offsetof(struct __sk_buff, data)),
1884                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1885                                         offsetof(struct __sk_buff, data_end)),
1886                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1887                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1888                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1889                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1890                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1891                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1892                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1893                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1894                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1895                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1896                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1897                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1898                         BPF_MOV64_IMM(BPF_REG_0, 0),
1899                         BPF_EXIT_INSN(),
1900                 },
1901                 .fixup = {11},
1902                 .result = ACCEPT,
1903                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1904         },
1905         {
1906                 "helper access to packet: test9, cls packet_ptr with bad range",
1907                 .insns = {
1908                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1909                                     offsetof(struct __sk_buff, data)),
1910                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1911                                     offsetof(struct __sk_buff, data_end)),
1912                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1913                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1914                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1915                         BPF_MOV64_IMM(BPF_REG_0, 0),
1916                         BPF_EXIT_INSN(),
1917                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1918                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1919                         BPF_MOV64_IMM(BPF_REG_0, 0),
1920                         BPF_EXIT_INSN(),
1921                 },
1922                 .fixup = {7},
1923                 .result = REJECT,
1924                 .errstr = "invalid access to packet",
1925                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1926         },
1927         {
1928                 "helper access to packet: test10, cls packet_ptr with too short range",
1929                 .insns = {
1930                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1931                                     offsetof(struct __sk_buff, data)),
1932                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1933                                     offsetof(struct __sk_buff, data_end)),
1934                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1935                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1936                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1937                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1938                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1939                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1940                         BPF_MOV64_IMM(BPF_REG_0, 0),
1941                         BPF_EXIT_INSN(),
1942                 },
1943                 .fixup = {6},
1944                 .result = REJECT,
1945                 .errstr = "invalid access to packet",
1946                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1947         },
1948         {
1949                 "helper access to packet: test11, cls unsuitable helper 1",
1950                 .insns = {
1951                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1952                                     offsetof(struct __sk_buff, data)),
1953                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1954                                     offsetof(struct __sk_buff, data_end)),
1955                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
1956                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1957                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
1958                         BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
1959                         BPF_MOV64_IMM(BPF_REG_2, 0),
1960                         BPF_MOV64_IMM(BPF_REG_4, 42),
1961                         BPF_MOV64_IMM(BPF_REG_5, 0),
1962                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_store_bytes),
1963                         BPF_MOV64_IMM(BPF_REG_0, 0),
1964                         BPF_EXIT_INSN(),
1965                 },
1966                 .result = REJECT,
1967                 .errstr = "helper access to the packet",
1968                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1969         },
1970         {
1971                 "helper access to packet: test12, cls unsuitable helper 2",
1972                 .insns = {
1973                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1974                                     offsetof(struct __sk_buff, data)),
1975                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1976                                     offsetof(struct __sk_buff, data_end)),
1977                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1978                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
1979                         BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
1980                         BPF_MOV64_IMM(BPF_REG_2, 0),
1981                         BPF_MOV64_IMM(BPF_REG_4, 4),
1982                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1983                         BPF_MOV64_IMM(BPF_REG_0, 0),
1984                         BPF_EXIT_INSN(),
1985                 },
1986                 .result = REJECT,
1987                 .errstr = "helper access to the packet",
1988                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1989         },
1990         {
1991                 "helper access to packet: test13, cls helper ok",
1992                 .insns = {
1993                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1994                                     offsetof(struct __sk_buff, data)),
1995                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1996                                     offsetof(struct __sk_buff, data_end)),
1997                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
1998                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1999                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2000                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2001                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2002                         BPF_MOV64_IMM(BPF_REG_2, 4),
2003                         BPF_MOV64_IMM(BPF_REG_3, 0),
2004                         BPF_MOV64_IMM(BPF_REG_4, 0),
2005                         BPF_MOV64_IMM(BPF_REG_5, 0),
2006                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2007                         BPF_MOV64_IMM(BPF_REG_0, 0),
2008                         BPF_EXIT_INSN(),
2009                 },
2010                 .result = ACCEPT,
2011                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2012         },
2013         {
2014                 "helper access to packet: test14, cls helper fail sub",
2015                 .insns = {
2016                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2017                                     offsetof(struct __sk_buff, data)),
2018                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2019                                     offsetof(struct __sk_buff, data_end)),
2020                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2021                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2022                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2023                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2024                         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2025                         BPF_MOV64_IMM(BPF_REG_2, 4),
2026                         BPF_MOV64_IMM(BPF_REG_3, 0),
2027                         BPF_MOV64_IMM(BPF_REG_4, 0),
2028                         BPF_MOV64_IMM(BPF_REG_5, 0),
2029                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2030                         BPF_MOV64_IMM(BPF_REG_0, 0),
2031                         BPF_EXIT_INSN(),
2032                 },
2033                 .result = REJECT,
2034                 .errstr = "type=inv expected=fp",
2035                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2036         },
2037         {
2038                 "helper access to packet: test15, cls helper fail range 1",
2039                 .insns = {
2040                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2041                                     offsetof(struct __sk_buff, data)),
2042                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2043                                     offsetof(struct __sk_buff, data_end)),
2044                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2045                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2046                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2047                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2048                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2049                         BPF_MOV64_IMM(BPF_REG_2, 8),
2050                         BPF_MOV64_IMM(BPF_REG_3, 0),
2051                         BPF_MOV64_IMM(BPF_REG_4, 0),
2052                         BPF_MOV64_IMM(BPF_REG_5, 0),
2053                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2054                         BPF_MOV64_IMM(BPF_REG_0, 0),
2055                         BPF_EXIT_INSN(),
2056                 },
2057                 .result = REJECT,
2058                 .errstr = "invalid access to packet",
2059                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2060         },
2061         {
2062                 "helper access to packet: test16, cls helper fail range 2",
2063                 .insns = {
2064                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2065                                     offsetof(struct __sk_buff, data)),
2066                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2067                                     offsetof(struct __sk_buff, data_end)),
2068                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2069                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2070                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2071                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2072                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2073                         BPF_MOV64_IMM(BPF_REG_2, -9),
2074                         BPF_MOV64_IMM(BPF_REG_3, 0),
2075                         BPF_MOV64_IMM(BPF_REG_4, 0),
2076                         BPF_MOV64_IMM(BPF_REG_5, 0),
2077                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2078                         BPF_MOV64_IMM(BPF_REG_0, 0),
2079                         BPF_EXIT_INSN(),
2080                 },
2081                 .result = REJECT,
2082                 .errstr = "invalid access to packet",
2083                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2084         },
2085         {
2086                 "helper access to packet: test17, cls helper fail range 3",
2087                 .insns = {
2088                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2089                                     offsetof(struct __sk_buff, data)),
2090                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2091                                     offsetof(struct __sk_buff, data_end)),
2092                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2093                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2094                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2095                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2096                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2097                         BPF_MOV64_IMM(BPF_REG_2, ~0),
2098                         BPF_MOV64_IMM(BPF_REG_3, 0),
2099                         BPF_MOV64_IMM(BPF_REG_4, 0),
2100                         BPF_MOV64_IMM(BPF_REG_5, 0),
2101                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2102                         BPF_MOV64_IMM(BPF_REG_0, 0),
2103                         BPF_EXIT_INSN(),
2104                 },
2105                 .result = REJECT,
2106                 .errstr = "invalid access to packet",
2107                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2108         },
2109         {
2110                 "helper access to packet: test18, cls helper fail range zero",
2111                 .insns = {
2112                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2113                                     offsetof(struct __sk_buff, data)),
2114                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2115                                     offsetof(struct __sk_buff, data_end)),
2116                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2117                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2118                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2119                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2120                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2121                         BPF_MOV64_IMM(BPF_REG_2, 0),
2122                         BPF_MOV64_IMM(BPF_REG_3, 0),
2123                         BPF_MOV64_IMM(BPF_REG_4, 0),
2124                         BPF_MOV64_IMM(BPF_REG_5, 0),
2125                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2126                         BPF_MOV64_IMM(BPF_REG_0, 0),
2127                         BPF_EXIT_INSN(),
2128                 },
2129                 .result = REJECT,
2130                 .errstr = "invalid access to packet",
2131                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2132         },
2133         {
2134                 "helper access to packet: test19, pkt end as input",
2135                 .insns = {
2136                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2137                                     offsetof(struct __sk_buff, data)),
2138                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2139                                     offsetof(struct __sk_buff, data_end)),
2140                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2141                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2142                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2143                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2144                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2145                         BPF_MOV64_IMM(BPF_REG_2, 4),
2146                         BPF_MOV64_IMM(BPF_REG_3, 0),
2147                         BPF_MOV64_IMM(BPF_REG_4, 0),
2148                         BPF_MOV64_IMM(BPF_REG_5, 0),
2149                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2150                         BPF_MOV64_IMM(BPF_REG_0, 0),
2151                         BPF_EXIT_INSN(),
2152                 },
2153                 .result = REJECT,
2154                 .errstr = "R1 type=pkt_end expected=fp",
2155                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2156         },
2157         {
2158                 "helper access to packet: test20, wrong reg",
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_IMM(BPF_REG_2, 4),
2169                         BPF_MOV64_IMM(BPF_REG_3, 0),
2170                         BPF_MOV64_IMM(BPF_REG_4, 0),
2171                         BPF_MOV64_IMM(BPF_REG_5, 0),
2172                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2173                         BPF_MOV64_IMM(BPF_REG_0, 0),
2174                         BPF_EXIT_INSN(),
2175                 },
2176                 .result = REJECT,
2177                 .errstr = "invalid access to packet",
2178                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2179         },
2180         {
2181                 "valid map access into an array with a constant",
2182                 .insns = {
2183                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2184                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2185                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2186                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2187                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2188                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2189                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2190                         BPF_EXIT_INSN(),
2191                 },
2192                 .test_val_map_fixup = {3},
2193                 .errstr_unpriv = "R0 leaks addr",
2194                 .result_unpriv = REJECT,
2195                 .result = ACCEPT,
2196         },
2197         {
2198                 "valid map access into an array with a register",
2199                 .insns = {
2200                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2201                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2202                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2203                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2204                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2205                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2206                         BPF_MOV64_IMM(BPF_REG_1, 4),
2207                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2208                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2209                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2210                         BPF_EXIT_INSN(),
2211                 },
2212                 .test_val_map_fixup = {3},
2213                 .errstr_unpriv = "R0 leaks addr",
2214                 .result_unpriv = REJECT,
2215                 .result = ACCEPT,
2216         },
2217         {
2218                 "valid map access into an array with a variable",
2219                 .insns = {
2220                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2221                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2222                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2223                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2224                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2225                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2226                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2227                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2228                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2229                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2230                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2231                         BPF_EXIT_INSN(),
2232                 },
2233                 .test_val_map_fixup = {3},
2234                 .errstr_unpriv = "R0 leaks addr",
2235                 .result_unpriv = REJECT,
2236                 .result = ACCEPT,
2237         },
2238         {
2239                 "valid map access into an array with a signed variable",
2240                 .insns = {
2241                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2242                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2243                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2244                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2245                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2246                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2247                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2248                         BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2249                         BPF_MOV32_IMM(BPF_REG_1, 0),
2250                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2251                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2252                         BPF_MOV32_IMM(BPF_REG_1, 0),
2253                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2254                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2255                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2256                         BPF_EXIT_INSN(),
2257                 },
2258                 .test_val_map_fixup = {3},
2259                 .errstr_unpriv = "R0 leaks addr",
2260                 .result_unpriv = REJECT,
2261                 .result = ACCEPT,
2262         },
2263         {
2264                 "invalid map access into an array with a constant",
2265                 .insns = {
2266                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2267                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2268                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2269                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2270                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2271                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2272                         BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
2273                                    offsetof(struct test_val, foo)),
2274                         BPF_EXIT_INSN(),
2275                 },
2276                 .test_val_map_fixup = {3},
2277                 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
2278                 .result = REJECT,
2279         },
2280         {
2281                 "invalid map access into an array with a register",
2282                 .insns = {
2283                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2284                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2285                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2286                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2287                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2288                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2289                         BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
2290                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2291                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2292                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2293                         BPF_EXIT_INSN(),
2294                 },
2295                 .test_val_map_fixup = {3},
2296                 .errstr = "R0 min value is outside of the array range",
2297                 .result = REJECT,
2298         },
2299         {
2300                 "invalid map access into an array with a variable",
2301                 .insns = {
2302                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2303                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2304                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2305                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2306                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2307                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2308                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2309                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2310                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2311                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2312                         BPF_EXIT_INSN(),
2313                 },
2314                 .test_val_map_fixup = {3},
2315                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2316                 .result = REJECT,
2317         },
2318         {
2319                 "invalid map access into an array with no floor check",
2320                 .insns = {
2321                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2322                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2323                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2324                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2325                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2326                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2327                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2328                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2329                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2330                         BPF_MOV32_IMM(BPF_REG_1, 0),
2331                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2332                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2333                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2334                         BPF_EXIT_INSN(),
2335                 },
2336                 .test_val_map_fixup = {3},
2337                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2338                 .result = REJECT,
2339         },
2340         {
2341                 "invalid map access into an array with a invalid max check",
2342                 .insns = {
2343                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2344                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2345                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2346                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2347                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2348                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2349                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2350                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
2351                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2352                         BPF_MOV32_IMM(BPF_REG_1, 0),
2353                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2354                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2355                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2356                         BPF_EXIT_INSN(),
2357                 },
2358                 .test_val_map_fixup = {3},
2359                 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
2360                 .result = REJECT,
2361         },
2362         {
2363                 "invalid map access into an array with a invalid max check",
2364                 .insns = {
2365                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2366                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2367                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2368                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2369                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2370                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
2371                         BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
2372                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2373                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2374                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2375                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2376                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2377                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
2378                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
2379                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, offsetof(struct test_val, foo)),
2380                         BPF_EXIT_INSN(),
2381                 },
2382                 .test_val_map_fixup = {3, 11},
2383                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2384                 .result = REJECT,
2385         },
2386 };
2387
2388 static int probe_filter_length(struct bpf_insn *fp)
2389 {
2390         int len = 0;
2391
2392         for (len = MAX_INSNS - 1; len > 0; --len)
2393                 if (fp[len].code != 0 || fp[len].imm != 0)
2394                         break;
2395
2396         return len + 1;
2397 }
2398
2399 static int create_map(size_t val_size, int num)
2400 {
2401         int map_fd;
2402
2403         map_fd = bpf_create_map(BPF_MAP_TYPE_HASH,
2404                                 sizeof(long long), val_size, num, 0);
2405         if (map_fd < 0)
2406                 printf("failed to create map '%s'\n", strerror(errno));
2407
2408         return map_fd;
2409 }
2410
2411 static int create_prog_array(void)
2412 {
2413         int map_fd;
2414
2415         map_fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY,
2416                                 sizeof(int), sizeof(int), 4, 0);
2417         if (map_fd < 0)
2418                 printf("failed to create prog_array '%s'\n", strerror(errno));
2419
2420         return map_fd;
2421 }
2422
2423 static int test(void)
2424 {
2425         int prog_fd, i, pass_cnt = 0, err_cnt = 0;
2426         bool unpriv = geteuid() != 0;
2427
2428         for (i = 0; i < ARRAY_SIZE(tests); i++) {
2429                 struct bpf_insn *prog = tests[i].insns;
2430                 int prog_type = tests[i].prog_type;
2431                 int prog_len = probe_filter_length(prog);
2432                 int *fixup = tests[i].fixup;
2433                 int *prog_array_fixup = tests[i].prog_array_fixup;
2434                 int *test_val_map_fixup = tests[i].test_val_map_fixup;
2435                 int expected_result;
2436                 const char *expected_errstr;
2437                 int map_fd = -1, prog_array_fd = -1, test_val_map_fd = -1;
2438
2439                 if (*fixup) {
2440                         map_fd = create_map(sizeof(long long), 1024);
2441
2442                         do {
2443                                 prog[*fixup].imm = map_fd;
2444                                 fixup++;
2445                         } while (*fixup);
2446                 }
2447                 if (*prog_array_fixup) {
2448                         prog_array_fd = create_prog_array();
2449
2450                         do {
2451                                 prog[*prog_array_fixup].imm = prog_array_fd;
2452                                 prog_array_fixup++;
2453                         } while (*prog_array_fixup);
2454                 }
2455                 if (*test_val_map_fixup) {
2456                         /* Unprivileged can't create a hash map.*/
2457                         if (unpriv)
2458                                 continue;
2459                         test_val_map_fd = create_map(sizeof(struct test_val),
2460                                                      256);
2461                         do {
2462                                 prog[*test_val_map_fixup].imm = test_val_map_fd;
2463                                 test_val_map_fixup++;
2464                         } while (*test_val_map_fixup);
2465                 }
2466
2467                 printf("#%d %s ", i, tests[i].descr);
2468
2469                 prog_fd = bpf_prog_load(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
2470                                         prog, prog_len * sizeof(struct bpf_insn),
2471                                         "GPL", 0);
2472
2473                 if (unpriv && tests[i].result_unpriv != UNDEF)
2474                         expected_result = tests[i].result_unpriv;
2475                 else
2476                         expected_result = tests[i].result;
2477
2478                 if (unpriv && tests[i].errstr_unpriv)
2479                         expected_errstr = tests[i].errstr_unpriv;
2480                 else
2481                         expected_errstr = tests[i].errstr;
2482
2483                 if (expected_result == ACCEPT) {
2484                         if (prog_fd < 0) {
2485                                 printf("FAIL\nfailed to load prog '%s'\n",
2486                                        strerror(errno));
2487                                 printf("%s", bpf_log_buf);
2488                                 err_cnt++;
2489                                 goto fail;
2490                         }
2491                 } else {
2492                         if (prog_fd >= 0) {
2493                                 printf("FAIL\nunexpected success to load\n");
2494                                 printf("%s", bpf_log_buf);
2495                                 err_cnt++;
2496                                 goto fail;
2497                         }
2498                         if (strstr(bpf_log_buf, expected_errstr) == 0) {
2499                                 printf("FAIL\nunexpected error message: %s",
2500                                        bpf_log_buf);
2501                                 err_cnt++;
2502                                 goto fail;
2503                         }
2504                 }
2505
2506                 pass_cnt++;
2507                 printf("OK\n");
2508 fail:
2509                 if (map_fd >= 0)
2510                         close(map_fd);
2511                 if (prog_array_fd >= 0)
2512                         close(prog_array_fd);
2513                 if (test_val_map_fd >= 0)
2514                         close(test_val_map_fd);
2515                 close(prog_fd);
2516
2517         }
2518         printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, err_cnt);
2519
2520         return 0;
2521 }
2522
2523 int main(void)
2524 {
2525         struct rlimit r = {1 << 20, 1 << 20};
2526
2527         setrlimit(RLIMIT_MEMLOCK, &r);
2528         return test();
2529 }