GNU Linux-libre 4.9.304-gnu1
[releases.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                 "stack pointer arithmetic",
1222                 .insns = {
1223                         BPF_MOV64_IMM(BPF_REG_1, 4),
1224                         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1225                         BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1226                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
1227                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
1228                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
1229                         BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
1230                         BPF_ST_MEM(0, BPF_REG_2, 4, 0),
1231                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
1232                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1233                         BPF_ST_MEM(0, BPF_REG_2, 4, 0),
1234                         BPF_MOV64_IMM(BPF_REG_0, 0),
1235                         BPF_EXIT_INSN(),
1236                 },
1237                 .result = ACCEPT,
1238         },
1239         {
1240                 "raw_stack: no skb_load_bytes",
1241                 .insns = {
1242                         BPF_MOV64_IMM(BPF_REG_2, 4),
1243                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1244                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1245                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1246                         BPF_MOV64_IMM(BPF_REG_4, 8),
1247                         /* Call to skb_load_bytes() omitted. */
1248                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1249                         BPF_EXIT_INSN(),
1250                 },
1251                 .result = REJECT,
1252                 .errstr = "invalid read from stack off -8+0 size 8",
1253                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1254         },
1255         {
1256                 "raw_stack: skb_load_bytes, negative len",
1257                 .insns = {
1258                         BPF_MOV64_IMM(BPF_REG_2, 4),
1259                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1260                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1261                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1262                         BPF_MOV64_IMM(BPF_REG_4, -8),
1263                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1264                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1265                         BPF_EXIT_INSN(),
1266                 },
1267                 .result = REJECT,
1268                 .errstr = "invalid stack type R3",
1269                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1270         },
1271         {
1272                 "raw_stack: skb_load_bytes, negative len 2",
1273                 .insns = {
1274                         BPF_MOV64_IMM(BPF_REG_2, 4),
1275                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1276                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1277                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1278                         BPF_MOV64_IMM(BPF_REG_4, ~0),
1279                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1280                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1281                         BPF_EXIT_INSN(),
1282                 },
1283                 .result = REJECT,
1284                 .errstr = "invalid stack type R3",
1285                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1286         },
1287         {
1288                 "raw_stack: skb_load_bytes, zero len",
1289                 .insns = {
1290                         BPF_MOV64_IMM(BPF_REG_2, 4),
1291                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1292                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1293                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1294                         BPF_MOV64_IMM(BPF_REG_4, 0),
1295                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1296                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1297                         BPF_EXIT_INSN(),
1298                 },
1299                 .result = REJECT,
1300                 .errstr = "invalid stack type R3",
1301                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1302         },
1303         {
1304                 "raw_stack: skb_load_bytes, no init",
1305                 .insns = {
1306                         BPF_MOV64_IMM(BPF_REG_2, 4),
1307                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1308                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1309                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1310                         BPF_MOV64_IMM(BPF_REG_4, 8),
1311                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1312                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1313                         BPF_EXIT_INSN(),
1314                 },
1315                 .result = ACCEPT,
1316                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1317         },
1318         {
1319                 "raw_stack: skb_load_bytes, init",
1320                 .insns = {
1321                         BPF_MOV64_IMM(BPF_REG_2, 4),
1322                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1323                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1324                         BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1325                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1326                         BPF_MOV64_IMM(BPF_REG_4, 8),
1327                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1328                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1329                         BPF_EXIT_INSN(),
1330                 },
1331                 .result = ACCEPT,
1332                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1333         },
1334         {
1335                 "raw_stack: skb_load_bytes, spilled regs around bounds",
1336                 .insns = {
1337                         BPF_MOV64_IMM(BPF_REG_2, 4),
1338                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1339                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1340                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1341                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1342                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1343                         BPF_MOV64_IMM(BPF_REG_4, 8),
1344                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1345                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1346                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1347                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1348                                     offsetof(struct __sk_buff, mark)),
1349                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1350                                     offsetof(struct __sk_buff, priority)),
1351                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1352                         BPF_EXIT_INSN(),
1353                 },
1354                 .result = ACCEPT,
1355                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1356         },
1357         {
1358                 "raw_stack: skb_load_bytes, spilled regs corruption",
1359                 .insns = {
1360                         BPF_MOV64_IMM(BPF_REG_2, 4),
1361                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1362                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1363                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), /* spill ctx from R1 */
1364                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1365                         BPF_MOV64_IMM(BPF_REG_4, 8),
1366                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1367                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), /* fill ctx into R0 */
1368                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1369                                     offsetof(struct __sk_buff, mark)),
1370                         BPF_EXIT_INSN(),
1371                 },
1372                 .result = REJECT,
1373                 .errstr = "R0 invalid mem access 'inv'",
1374                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1375         },
1376         {
1377                 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1378                 .insns = {
1379                         BPF_MOV64_IMM(BPF_REG_2, 4),
1380                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1381                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1382                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1383                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0), /* spill ctx from R1 */
1384                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1385                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1386                         BPF_MOV64_IMM(BPF_REG_4, 8),
1387                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1388                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1389                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1390                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0), /* fill ctx into R3 */
1391                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1392                                     offsetof(struct __sk_buff, mark)),
1393                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1394                                     offsetof(struct __sk_buff, priority)),
1395                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1396                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1397                                     offsetof(struct __sk_buff, pkt_type)),
1398                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1399                         BPF_EXIT_INSN(),
1400                 },
1401                 .result = REJECT,
1402                 .errstr = "R3 invalid mem access 'inv'",
1403                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1404         },
1405         {
1406                 "raw_stack: skb_load_bytes, spilled regs + data",
1407                 .insns = {
1408                         BPF_MOV64_IMM(BPF_REG_2, 4),
1409                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1410                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1411                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), /* spill ctx from R1 */
1412                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0), /* spill ctx from R1 */
1413                         BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8), /* spill ctx from R1 */
1414                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1415                         BPF_MOV64_IMM(BPF_REG_4, 8),
1416                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1417                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), /* fill ctx into R0 */
1418                         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8), /* fill ctx into R2 */
1419                         BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0), /* fill data into R3 */
1420                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1421                                     offsetof(struct __sk_buff, mark)),
1422                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1423                                     offsetof(struct __sk_buff, priority)),
1424                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1425                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1426                         BPF_EXIT_INSN(),
1427                 },
1428                 .result = ACCEPT,
1429                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1430         },
1431         {
1432                 "raw_stack: skb_load_bytes, invalid access 1",
1433                 .insns = {
1434                         BPF_MOV64_IMM(BPF_REG_2, 4),
1435                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1436                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
1437                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1438                         BPF_MOV64_IMM(BPF_REG_4, 8),
1439                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1440                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1441                         BPF_EXIT_INSN(),
1442                 },
1443                 .result = REJECT,
1444                 .errstr = "invalid stack type R3 off=-513 access_size=8",
1445                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1446         },
1447         {
1448                 "raw_stack: skb_load_bytes, invalid access 2",
1449                 .insns = {
1450                         BPF_MOV64_IMM(BPF_REG_2, 4),
1451                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1452                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1453                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1454                         BPF_MOV64_IMM(BPF_REG_4, 8),
1455                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1456                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1457                         BPF_EXIT_INSN(),
1458                 },
1459                 .result = REJECT,
1460                 .errstr = "invalid stack type R3 off=-1 access_size=8",
1461                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1462         },
1463         {
1464                 "raw_stack: skb_load_bytes, invalid access 3",
1465                 .insns = {
1466                         BPF_MOV64_IMM(BPF_REG_2, 4),
1467                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1468                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
1469                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1470                         BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
1471                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1472                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1473                         BPF_EXIT_INSN(),
1474                 },
1475                 .result = REJECT,
1476                 .errstr = "invalid stack type R3 off=-1 access_size=-1",
1477                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1478         },
1479         {
1480                 "raw_stack: skb_load_bytes, invalid access 4",
1481                 .insns = {
1482                         BPF_MOV64_IMM(BPF_REG_2, 4),
1483                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1484                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1485                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1486                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1487                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1488                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1489                         BPF_EXIT_INSN(),
1490                 },
1491                 .result = REJECT,
1492                 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
1493                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1494         },
1495         {
1496                 "raw_stack: skb_load_bytes, invalid access 5",
1497                 .insns = {
1498                         BPF_MOV64_IMM(BPF_REG_2, 4),
1499                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1500                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1501                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1502                         BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1503                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1504                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1505                         BPF_EXIT_INSN(),
1506                 },
1507                 .result = REJECT,
1508                 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
1509                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1510         },
1511         {
1512                 "raw_stack: skb_load_bytes, invalid access 6",
1513                 .insns = {
1514                         BPF_MOV64_IMM(BPF_REG_2, 4),
1515                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1516                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1517                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1518                         BPF_MOV64_IMM(BPF_REG_4, 0),
1519                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1520                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1521                         BPF_EXIT_INSN(),
1522                 },
1523                 .result = REJECT,
1524                 .errstr = "invalid stack type R3 off=-512 access_size=0",
1525                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1526         },
1527         {
1528                 "raw_stack: skb_load_bytes, large access",
1529                 .insns = {
1530                         BPF_MOV64_IMM(BPF_REG_2, 4),
1531                         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1532                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1533                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1534                         BPF_MOV64_IMM(BPF_REG_4, 512),
1535                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1536                         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1537                         BPF_EXIT_INSN(),
1538                 },
1539                 .result = ACCEPT,
1540                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1541         },
1542         {
1543                 "direct packet access: test1",
1544                 .insns = {
1545                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1546                                     offsetof(struct __sk_buff, data)),
1547                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1548                                     offsetof(struct __sk_buff, data_end)),
1549                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1550                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1551                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1552                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1553                         BPF_MOV64_IMM(BPF_REG_0, 0),
1554                         BPF_EXIT_INSN(),
1555                 },
1556                 .result = ACCEPT,
1557                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1558         },
1559         {
1560                 "direct packet access: test2",
1561                 .insns = {
1562                         BPF_MOV64_IMM(BPF_REG_0, 1),
1563                         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
1564                                     offsetof(struct __sk_buff, data_end)),
1565                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1566                                     offsetof(struct __sk_buff, data)),
1567                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
1568                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
1569                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
1570                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
1571                         BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
1572                         BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
1573                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1574                                     offsetof(struct __sk_buff, data)),
1575                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
1576                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
1577                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
1578                         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
1579                         BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
1580                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
1581                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1582                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1583                                     offsetof(struct __sk_buff, data_end)),
1584                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
1585                         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
1586                         BPF_MOV64_IMM(BPF_REG_0, 0),
1587                         BPF_EXIT_INSN(),
1588                 },
1589                 .result = ACCEPT,
1590                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1591         },
1592         {
1593                 "direct packet access: test3",
1594                 .insns = {
1595                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1596                                     offsetof(struct __sk_buff, data)),
1597                         BPF_MOV64_IMM(BPF_REG_0, 0),
1598                         BPF_EXIT_INSN(),
1599                 },
1600                 .errstr = "invalid bpf_context access off=76",
1601                 .result = REJECT,
1602                 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
1603         },
1604         {
1605                 "direct packet access: test4 (write)",
1606                 .insns = {
1607                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1608                                     offsetof(struct __sk_buff, data)),
1609                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1610                                     offsetof(struct __sk_buff, data_end)),
1611                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1612                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1613                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1614                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1615                         BPF_MOV64_IMM(BPF_REG_0, 0),
1616                         BPF_EXIT_INSN(),
1617                 },
1618                 .result = ACCEPT,
1619                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1620         },
1621         {
1622                 "direct packet access: test5 (pkt_end >= reg, good access)",
1623                 .insns = {
1624                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1625                                     offsetof(struct __sk_buff, data)),
1626                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1627                                     offsetof(struct __sk_buff, data_end)),
1628                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1629                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1630                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1631                         BPF_MOV64_IMM(BPF_REG_0, 1),
1632                         BPF_EXIT_INSN(),
1633                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1634                         BPF_MOV64_IMM(BPF_REG_0, 0),
1635                         BPF_EXIT_INSN(),
1636                 },
1637                 .result = ACCEPT,
1638                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1639         },
1640         {
1641                 "direct packet access: test6 (pkt_end >= reg, bad access)",
1642                 .insns = {
1643                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1644                                     offsetof(struct __sk_buff, data)),
1645                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1646                                     offsetof(struct __sk_buff, data_end)),
1647                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1648                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1649                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1650                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1651                         BPF_MOV64_IMM(BPF_REG_0, 1),
1652                         BPF_EXIT_INSN(),
1653                         BPF_MOV64_IMM(BPF_REG_0, 0),
1654                         BPF_EXIT_INSN(),
1655                 },
1656                 .errstr = "invalid access to packet",
1657                 .result = REJECT,
1658                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1659         },
1660         {
1661                 "direct packet access: test7 (pkt_end >= reg, both accesses)",
1662                 .insns = {
1663                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1664                                     offsetof(struct __sk_buff, data)),
1665                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1666                                     offsetof(struct __sk_buff, data_end)),
1667                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1668                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1669                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1670                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1671                         BPF_MOV64_IMM(BPF_REG_0, 1),
1672                         BPF_EXIT_INSN(),
1673                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1674                         BPF_MOV64_IMM(BPF_REG_0, 0),
1675                         BPF_EXIT_INSN(),
1676                 },
1677                 .errstr = "invalid access to packet",
1678                 .result = REJECT,
1679                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1680         },
1681         {
1682                 "direct packet access: test8 (double test, variant 1)",
1683                 .insns = {
1684                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1685                                     offsetof(struct __sk_buff, data)),
1686                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1687                                     offsetof(struct __sk_buff, data_end)),
1688                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1689                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1690                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
1691                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1692                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1693                         BPF_MOV64_IMM(BPF_REG_0, 1),
1694                         BPF_EXIT_INSN(),
1695                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1696                         BPF_MOV64_IMM(BPF_REG_0, 0),
1697                         BPF_EXIT_INSN(),
1698                 },
1699                 .result = ACCEPT,
1700                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1701         },
1702         {
1703                 "direct packet access: test9 (double test, variant 2)",
1704                 .insns = {
1705                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1706                                     offsetof(struct __sk_buff, data)),
1707                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1708                                     offsetof(struct __sk_buff, data_end)),
1709                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1710                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1711                         BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1712                         BPF_MOV64_IMM(BPF_REG_0, 1),
1713                         BPF_EXIT_INSN(),
1714                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1715                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1716                         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1717                         BPF_MOV64_IMM(BPF_REG_0, 0),
1718                         BPF_EXIT_INSN(),
1719                 },
1720                 .result = ACCEPT,
1721                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1722         },
1723         {
1724                 "direct packet access: test10 (write invalid)",
1725                 .insns = {
1726                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1727                                     offsetof(struct __sk_buff, data)),
1728                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1729                                     offsetof(struct __sk_buff, data_end)),
1730                         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1731                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1732                         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1733                         BPF_MOV64_IMM(BPF_REG_0, 0),
1734                         BPF_EXIT_INSN(),
1735                         BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1736                         BPF_MOV64_IMM(BPF_REG_0, 0),
1737                         BPF_EXIT_INSN(),
1738                 },
1739                 .errstr = "invalid access to packet",
1740                 .result = REJECT,
1741                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1742         },
1743         {
1744                 "helper access to packet: test1, valid packet_ptr range",
1745                 .insns = {
1746                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1747                                     offsetof(struct xdp_md, data)),
1748                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1749                                     offsetof(struct xdp_md, data_end)),
1750                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1751                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1752                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1753                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1754                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1755                         BPF_MOV64_IMM(BPF_REG_4, 0),
1756                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1757                         BPF_MOV64_IMM(BPF_REG_0, 0),
1758                         BPF_EXIT_INSN(),
1759                 },
1760                 .fixup = {5},
1761                 .result_unpriv = ACCEPT,
1762                 .result = ACCEPT,
1763                 .prog_type = BPF_PROG_TYPE_XDP,
1764         },
1765         {
1766                 "helper access to packet: test2, unchecked packet_ptr",
1767                 .insns = {
1768                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1769                                     offsetof(struct xdp_md, data)),
1770                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1771                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1772                         BPF_MOV64_IMM(BPF_REG_0, 0),
1773                         BPF_EXIT_INSN(),
1774                 },
1775                 .fixup = {1},
1776                 .result = REJECT,
1777                 .errstr = "invalid access to packet",
1778                 .prog_type = BPF_PROG_TYPE_XDP,
1779         },
1780         {
1781                 "helper access to packet: test3, variable add",
1782                 .insns = {
1783                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1784                                         offsetof(struct xdp_md, data)),
1785                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1786                                         offsetof(struct xdp_md, data_end)),
1787                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1788                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1789                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1790                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1791                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1792                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1793                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1794                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1795                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1796                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1797                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1798                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1799                         BPF_MOV64_IMM(BPF_REG_0, 0),
1800                         BPF_EXIT_INSN(),
1801                 },
1802                 .fixup = {11},
1803                 .result = ACCEPT,
1804                 .prog_type = BPF_PROG_TYPE_XDP,
1805         },
1806         {
1807                 "helper access to packet: test4, packet_ptr with bad range",
1808                 .insns = {
1809                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1810                                     offsetof(struct xdp_md, data)),
1811                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1812                                     offsetof(struct xdp_md, data_end)),
1813                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1814                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1815                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1816                         BPF_MOV64_IMM(BPF_REG_0, 0),
1817                         BPF_EXIT_INSN(),
1818                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1819                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1820                         BPF_MOV64_IMM(BPF_REG_0, 0),
1821                         BPF_EXIT_INSN(),
1822                 },
1823                 .fixup = {7},
1824                 .result = REJECT,
1825                 .errstr = "invalid access to packet",
1826                 .prog_type = BPF_PROG_TYPE_XDP,
1827         },
1828         {
1829                 "helper access to packet: test5, packet_ptr with too short range",
1830                 .insns = {
1831                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1832                                     offsetof(struct xdp_md, data)),
1833                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1834                                     offsetof(struct xdp_md, data_end)),
1835                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1836                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1837                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1838                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1839                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1840                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1841                         BPF_MOV64_IMM(BPF_REG_0, 0),
1842                         BPF_EXIT_INSN(),
1843                 },
1844                 .fixup = {6},
1845                 .result = REJECT,
1846                 .errstr = "invalid access to packet",
1847                 .prog_type = BPF_PROG_TYPE_XDP,
1848         },
1849         {
1850                 "helper access to packet: test6, cls valid packet_ptr range",
1851                 .insns = {
1852                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1853                                     offsetof(struct __sk_buff, data)),
1854                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1855                                     offsetof(struct __sk_buff, data_end)),
1856                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1857                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1858                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1859                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1860                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1861                         BPF_MOV64_IMM(BPF_REG_4, 0),
1862                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1863                         BPF_MOV64_IMM(BPF_REG_0, 0),
1864                         BPF_EXIT_INSN(),
1865                 },
1866                 .fixup = {5},
1867                 .result = ACCEPT,
1868                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1869         },
1870         {
1871                 "helper access to packet: test7, cls unchecked packet_ptr",
1872                 .insns = {
1873                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1874                                     offsetof(struct __sk_buff, data)),
1875                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1876                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1877                         BPF_MOV64_IMM(BPF_REG_0, 0),
1878                         BPF_EXIT_INSN(),
1879                 },
1880                 .fixup = {1},
1881                 .result = REJECT,
1882                 .errstr = "invalid access to packet",
1883                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1884         },
1885         {
1886                 "helper access to packet: test8, cls variable add",
1887                 .insns = {
1888                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1889                                         offsetof(struct __sk_buff, data)),
1890                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1891                                         offsetof(struct __sk_buff, data_end)),
1892                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1893                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1894                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1895                         BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1896                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1897                         BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1898                         BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1899                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1900                         BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1901                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1902                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1903                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1904                         BPF_MOV64_IMM(BPF_REG_0, 0),
1905                         BPF_EXIT_INSN(),
1906                 },
1907                 .fixup = {11},
1908                 .result = ACCEPT,
1909                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1910         },
1911         {
1912                 "helper access to packet: test9, cls packet_ptr with bad range",
1913                 .insns = {
1914                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1915                                     offsetof(struct __sk_buff, data)),
1916                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1917                                     offsetof(struct __sk_buff, data_end)),
1918                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1919                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1920                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1921                         BPF_MOV64_IMM(BPF_REG_0, 0),
1922                         BPF_EXIT_INSN(),
1923                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1924                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1925                         BPF_MOV64_IMM(BPF_REG_0, 0),
1926                         BPF_EXIT_INSN(),
1927                 },
1928                 .fixup = {7},
1929                 .result = REJECT,
1930                 .errstr = "invalid access to packet",
1931                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1932         },
1933         {
1934                 "helper access to packet: test10, cls packet_ptr with too short range",
1935                 .insns = {
1936                         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1937                                     offsetof(struct __sk_buff, data)),
1938                         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1939                                     offsetof(struct __sk_buff, data_end)),
1940                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1941                         BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1942                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1943                         BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1944                         BPF_LD_MAP_FD(BPF_REG_1, 0),
1945                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1946                         BPF_MOV64_IMM(BPF_REG_0, 0),
1947                         BPF_EXIT_INSN(),
1948                 },
1949                 .fixup = {6},
1950                 .result = REJECT,
1951                 .errstr = "invalid access to packet",
1952                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1953         },
1954         {
1955                 "helper access to packet: test11, cls unsuitable helper 1",
1956                 .insns = {
1957                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1958                                     offsetof(struct __sk_buff, data)),
1959                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1960                                     offsetof(struct __sk_buff, data_end)),
1961                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
1962                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1963                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
1964                         BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
1965                         BPF_MOV64_IMM(BPF_REG_2, 0),
1966                         BPF_MOV64_IMM(BPF_REG_4, 42),
1967                         BPF_MOV64_IMM(BPF_REG_5, 0),
1968                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_store_bytes),
1969                         BPF_MOV64_IMM(BPF_REG_0, 0),
1970                         BPF_EXIT_INSN(),
1971                 },
1972                 .result = REJECT,
1973                 .errstr = "helper access to the packet",
1974                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1975         },
1976         {
1977                 "helper access to packet: test12, cls unsuitable helper 2",
1978                 .insns = {
1979                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1980                                     offsetof(struct __sk_buff, data)),
1981                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1982                                     offsetof(struct __sk_buff, data_end)),
1983                         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1984                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
1985                         BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
1986                         BPF_MOV64_IMM(BPF_REG_2, 0),
1987                         BPF_MOV64_IMM(BPF_REG_4, 4),
1988                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1989                         BPF_MOV64_IMM(BPF_REG_0, 0),
1990                         BPF_EXIT_INSN(),
1991                 },
1992                 .result = REJECT,
1993                 .errstr = "helper access to the packet",
1994                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1995         },
1996         {
1997                 "helper access to packet: test13, cls helper ok",
1998                 .insns = {
1999                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2000                                     offsetof(struct __sk_buff, data)),
2001                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2002                                     offsetof(struct __sk_buff, data_end)),
2003                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2004                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2005                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2006                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2007                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2008                         BPF_MOV64_IMM(BPF_REG_2, 4),
2009                         BPF_MOV64_IMM(BPF_REG_3, 0),
2010                         BPF_MOV64_IMM(BPF_REG_4, 0),
2011                         BPF_MOV64_IMM(BPF_REG_5, 0),
2012                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2013                         BPF_MOV64_IMM(BPF_REG_0, 0),
2014                         BPF_EXIT_INSN(),
2015                 },
2016                 .result = ACCEPT,
2017                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2018         },
2019         {
2020                 "helper access to packet: test14, cls helper fail sub",
2021                 .insns = {
2022                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2023                                     offsetof(struct __sk_buff, data)),
2024                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2025                                     offsetof(struct __sk_buff, data_end)),
2026                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2027                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2028                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2029                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2030                         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2031                         BPF_MOV64_IMM(BPF_REG_2, 4),
2032                         BPF_MOV64_IMM(BPF_REG_3, 0),
2033                         BPF_MOV64_IMM(BPF_REG_4, 0),
2034                         BPF_MOV64_IMM(BPF_REG_5, 0),
2035                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2036                         BPF_MOV64_IMM(BPF_REG_0, 0),
2037                         BPF_EXIT_INSN(),
2038                 },
2039                 .result = REJECT,
2040                 .errstr = "type=inv expected=fp",
2041                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2042         },
2043         {
2044                 "helper access to packet: test15, cls helper fail range 1",
2045                 .insns = {
2046                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2047                                     offsetof(struct __sk_buff, data)),
2048                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2049                                     offsetof(struct __sk_buff, data_end)),
2050                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2051                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2052                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2053                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2054                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2055                         BPF_MOV64_IMM(BPF_REG_2, 8),
2056                         BPF_MOV64_IMM(BPF_REG_3, 0),
2057                         BPF_MOV64_IMM(BPF_REG_4, 0),
2058                         BPF_MOV64_IMM(BPF_REG_5, 0),
2059                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2060                         BPF_MOV64_IMM(BPF_REG_0, 0),
2061                         BPF_EXIT_INSN(),
2062                 },
2063                 .result = REJECT,
2064                 .errstr = "invalid access to packet",
2065                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2066         },
2067         {
2068                 "helper access to packet: test16, cls helper fail range 2",
2069                 .insns = {
2070                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2071                                     offsetof(struct __sk_buff, data)),
2072                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2073                                     offsetof(struct __sk_buff, data_end)),
2074                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2075                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2076                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2077                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2078                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2079                         BPF_MOV64_IMM(BPF_REG_2, -9),
2080                         BPF_MOV64_IMM(BPF_REG_3, 0),
2081                         BPF_MOV64_IMM(BPF_REG_4, 0),
2082                         BPF_MOV64_IMM(BPF_REG_5, 0),
2083                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2084                         BPF_MOV64_IMM(BPF_REG_0, 0),
2085                         BPF_EXIT_INSN(),
2086                 },
2087                 .result = REJECT,
2088                 .errstr = "invalid access to packet",
2089                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2090         },
2091         {
2092                 "helper access to packet: test17, cls helper fail range 3",
2093                 .insns = {
2094                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2095                                     offsetof(struct __sk_buff, data)),
2096                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2097                                     offsetof(struct __sk_buff, data_end)),
2098                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2099                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2100                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2101                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2102                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2103                         BPF_MOV64_IMM(BPF_REG_2, ~0),
2104                         BPF_MOV64_IMM(BPF_REG_3, 0),
2105                         BPF_MOV64_IMM(BPF_REG_4, 0),
2106                         BPF_MOV64_IMM(BPF_REG_5, 0),
2107                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2108                         BPF_MOV64_IMM(BPF_REG_0, 0),
2109                         BPF_EXIT_INSN(),
2110                 },
2111                 .result = REJECT,
2112                 .errstr = "invalid access to packet",
2113                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2114         },
2115         {
2116                 "helper access to packet: test18, cls helper fail range zero",
2117                 .insns = {
2118                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2119                                     offsetof(struct __sk_buff, data)),
2120                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2121                                     offsetof(struct __sk_buff, data_end)),
2122                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2123                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2124                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2125                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2126                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2127                         BPF_MOV64_IMM(BPF_REG_2, 0),
2128                         BPF_MOV64_IMM(BPF_REG_3, 0),
2129                         BPF_MOV64_IMM(BPF_REG_4, 0),
2130                         BPF_MOV64_IMM(BPF_REG_5, 0),
2131                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2132                         BPF_MOV64_IMM(BPF_REG_0, 0),
2133                         BPF_EXIT_INSN(),
2134                 },
2135                 .result = REJECT,
2136                 .errstr = "invalid access to packet",
2137                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2138         },
2139         {
2140                 "helper access to packet: test19, pkt end as input",
2141                 .insns = {
2142                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2143                                     offsetof(struct __sk_buff, data)),
2144                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2145                                     offsetof(struct __sk_buff, data_end)),
2146                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2147                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2148                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2149                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2150                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2151                         BPF_MOV64_IMM(BPF_REG_2, 4),
2152                         BPF_MOV64_IMM(BPF_REG_3, 0),
2153                         BPF_MOV64_IMM(BPF_REG_4, 0),
2154                         BPF_MOV64_IMM(BPF_REG_5, 0),
2155                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2156                         BPF_MOV64_IMM(BPF_REG_0, 0),
2157                         BPF_EXIT_INSN(),
2158                 },
2159                 .result = REJECT,
2160                 .errstr = "R1 type=pkt_end expected=fp",
2161                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2162         },
2163         {
2164                 "helper access to packet: test20, wrong reg",
2165                 .insns = {
2166                         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2167                                     offsetof(struct __sk_buff, data)),
2168                         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2169                                     offsetof(struct __sk_buff, data_end)),
2170                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2171                         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2172                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2173                         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2174                         BPF_MOV64_IMM(BPF_REG_2, 4),
2175                         BPF_MOV64_IMM(BPF_REG_3, 0),
2176                         BPF_MOV64_IMM(BPF_REG_4, 0),
2177                         BPF_MOV64_IMM(BPF_REG_5, 0),
2178                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2179                         BPF_MOV64_IMM(BPF_REG_0, 0),
2180                         BPF_EXIT_INSN(),
2181                 },
2182                 .result = REJECT,
2183                 .errstr = "invalid access to packet",
2184                 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2185         },
2186         {
2187                 "valid map access into an array with a constant",
2188                 .insns = {
2189                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2190                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2191                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2192                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2193                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2194                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2195                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2196                         BPF_EXIT_INSN(),
2197                 },
2198                 .test_val_map_fixup = {3},
2199                 .errstr_unpriv = "R0 leaks addr",
2200                 .result_unpriv = REJECT,
2201                 .result = ACCEPT,
2202         },
2203         {
2204                 "valid map access into an array with a register",
2205                 .insns = {
2206                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2207                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2208                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2209                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2210                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2211                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2212                         BPF_MOV64_IMM(BPF_REG_1, 4),
2213                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2214                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2215                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2216                         BPF_EXIT_INSN(),
2217                 },
2218                 .test_val_map_fixup = {3},
2219                 .errstr_unpriv = "R0 leaks addr",
2220                 .result_unpriv = REJECT,
2221                 .result = ACCEPT,
2222         },
2223         {
2224                 "valid map access into an array with a variable",
2225                 .insns = {
2226                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2227                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2228                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2229                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2230                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2231                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2232                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2233                         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2234                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2235                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2236                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2237                         BPF_EXIT_INSN(),
2238                 },
2239                 .test_val_map_fixup = {3},
2240                 .errstr_unpriv = "R0 leaks addr",
2241                 .result_unpriv = REJECT,
2242                 .result = ACCEPT,
2243         },
2244         {
2245                 "valid map access into an array with a signed variable",
2246                 .insns = {
2247                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2248                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2249                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2250                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2251                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2252                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2253                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2254                         BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2255                         BPF_MOV32_IMM(BPF_REG_1, 0),
2256                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2257                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2258                         BPF_MOV32_IMM(BPF_REG_1, 0),
2259                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2260                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2261                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2262                         BPF_EXIT_INSN(),
2263                 },
2264                 .test_val_map_fixup = {3},
2265                 .errstr_unpriv = "R0 leaks addr",
2266                 .result_unpriv = REJECT,
2267                 .result = ACCEPT,
2268         },
2269         {
2270                 "invalid map access into an array with a constant",
2271                 .insns = {
2272                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2273                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2274                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2275                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2276                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2277                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2278                         BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
2279                                    offsetof(struct test_val, foo)),
2280                         BPF_EXIT_INSN(),
2281                 },
2282                 .test_val_map_fixup = {3},
2283                 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
2284                 .result = REJECT,
2285         },
2286         {
2287                 "invalid map access into an array with a register",
2288                 .insns = {
2289                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2290                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2291                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2292                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2293                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2294                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2295                         BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
2296                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2297                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2298                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2299                         BPF_EXIT_INSN(),
2300                 },
2301                 .test_val_map_fixup = {3},
2302                 .errstr = "R0 min value is outside of the array range",
2303                 .result = REJECT,
2304         },
2305         {
2306                 "invalid map access into an array with a variable",
2307                 .insns = {
2308                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2309                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2310                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2311                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2312                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2313                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2314                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2315                         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2316                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2317                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2318                         BPF_EXIT_INSN(),
2319                 },
2320                 .test_val_map_fixup = {3},
2321                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2322                 .result = REJECT,
2323         },
2324         {
2325                 "invalid map access into an array with no floor check",
2326                 .insns = {
2327                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2328                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2329                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2330                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2331                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2332                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2333                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2334                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2335                         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2336                         BPF_MOV32_IMM(BPF_REG_1, 0),
2337                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2338                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2339                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2340                         BPF_EXIT_INSN(),
2341                 },
2342                 .test_val_map_fixup = {3},
2343                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2344                 .result = REJECT,
2345         },
2346         {
2347                 "invalid map access into an array with a invalid max check",
2348                 .insns = {
2349                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2350                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2351                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2352                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2353                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2354                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2355                         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2356                         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
2357                         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2358                         BPF_MOV32_IMM(BPF_REG_1, 0),
2359                         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2360                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2361                         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2362                         BPF_EXIT_INSN(),
2363                 },
2364                 .test_val_map_fixup = {3},
2365                 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
2366                 .result = REJECT,
2367         },
2368         {
2369                 "invalid map access into an array with a invalid max check",
2370                 .insns = {
2371                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2372                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2373                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2374                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2375                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2376                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
2377                         BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
2378                         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2379                         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2380                         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2381                         BPF_LD_MAP_FD(BPF_REG_1, 0),
2382                         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2383                         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
2384                         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
2385                         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, offsetof(struct test_val, foo)),
2386                         BPF_EXIT_INSN(),
2387                 },
2388                 .test_val_map_fixup = {3, 11},
2389                 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2390                 .result = REJECT,
2391         },
2392 };
2393
2394 static int probe_filter_length(struct bpf_insn *fp)
2395 {
2396         int len = 0;
2397
2398         for (len = MAX_INSNS - 1; len > 0; --len)
2399                 if (fp[len].code != 0 || fp[len].imm != 0)
2400                         break;
2401
2402         return len + 1;
2403 }
2404
2405 static int create_map(size_t val_size, int num)
2406 {
2407         int map_fd;
2408
2409         map_fd = bpf_create_map(BPF_MAP_TYPE_HASH,
2410                                 sizeof(long long), val_size, num, 0);
2411         if (map_fd < 0)
2412                 printf("failed to create map '%s'\n", strerror(errno));
2413
2414         return map_fd;
2415 }
2416
2417 static int create_prog_array(void)
2418 {
2419         int map_fd;
2420
2421         map_fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY,
2422                                 sizeof(int), sizeof(int), 4, 0);
2423         if (map_fd < 0)
2424                 printf("failed to create prog_array '%s'\n", strerror(errno));
2425
2426         return map_fd;
2427 }
2428
2429 static int test(void)
2430 {
2431         int prog_fd, i, pass_cnt = 0, err_cnt = 0;
2432         bool unpriv = geteuid() != 0;
2433
2434         for (i = 0; i < ARRAY_SIZE(tests); i++) {
2435                 struct bpf_insn *prog = tests[i].insns;
2436                 int prog_type = tests[i].prog_type;
2437                 int prog_len = probe_filter_length(prog);
2438                 int *fixup = tests[i].fixup;
2439                 int *prog_array_fixup = tests[i].prog_array_fixup;
2440                 int *test_val_map_fixup = tests[i].test_val_map_fixup;
2441                 int expected_result;
2442                 const char *expected_errstr;
2443                 int map_fd = -1, prog_array_fd = -1, test_val_map_fd = -1;
2444
2445                 if (*fixup) {
2446                         map_fd = create_map(sizeof(long long), 1024);
2447
2448                         do {
2449                                 prog[*fixup].imm = map_fd;
2450                                 fixup++;
2451                         } while (*fixup);
2452                 }
2453                 if (*prog_array_fixup) {
2454                         prog_array_fd = create_prog_array();
2455
2456                         do {
2457                                 prog[*prog_array_fixup].imm = prog_array_fd;
2458                                 prog_array_fixup++;
2459                         } while (*prog_array_fixup);
2460                 }
2461                 if (*test_val_map_fixup) {
2462                         /* Unprivileged can't create a hash map.*/
2463                         if (unpriv)
2464                                 continue;
2465                         test_val_map_fd = create_map(sizeof(struct test_val),
2466                                                      256);
2467                         do {
2468                                 prog[*test_val_map_fixup].imm = test_val_map_fd;
2469                                 test_val_map_fixup++;
2470                         } while (*test_val_map_fixup);
2471                 }
2472
2473                 printf("#%d %s ", i, tests[i].descr);
2474
2475                 prog_fd = bpf_prog_load(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
2476                                         prog, prog_len * sizeof(struct bpf_insn),
2477                                         "GPL", 0);
2478
2479                 if (unpriv && tests[i].result_unpriv != UNDEF)
2480                         expected_result = tests[i].result_unpriv;
2481                 else
2482                         expected_result = tests[i].result;
2483
2484                 if (unpriv && tests[i].errstr_unpriv)
2485                         expected_errstr = tests[i].errstr_unpriv;
2486                 else
2487                         expected_errstr = tests[i].errstr;
2488
2489                 if (expected_result == ACCEPT) {
2490                         if (prog_fd < 0) {
2491                                 printf("FAIL\nfailed to load prog '%s'\n",
2492                                        strerror(errno));
2493                                 printf("%s", bpf_log_buf);
2494                                 err_cnt++;
2495                                 goto fail;
2496                         }
2497                 } else {
2498                         if (prog_fd >= 0) {
2499                                 printf("FAIL\nunexpected success to load\n");
2500                                 printf("%s", bpf_log_buf);
2501                                 err_cnt++;
2502                                 goto fail;
2503                         }
2504                         if (strstr(bpf_log_buf, expected_errstr) == 0) {
2505                                 printf("FAIL\nunexpected error message: %s",
2506                                        bpf_log_buf);
2507                                 err_cnt++;
2508                                 goto fail;
2509                         }
2510                 }
2511
2512                 pass_cnt++;
2513                 printf("OK\n");
2514 fail:
2515                 if (map_fd >= 0)
2516                         close(map_fd);
2517                 if (prog_array_fd >= 0)
2518                         close(prog_array_fd);
2519                 if (test_val_map_fd >= 0)
2520                         close(test_val_map_fd);
2521                 close(prog_fd);
2522
2523         }
2524         printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, err_cnt);
2525
2526         return 0;
2527 }
2528
2529 int main(void)
2530 {
2531         struct rlimit r = {1 << 20, 1 << 20};
2532
2533         setrlimit(RLIMIT_MEMLOCK, &r);
2534         return test();
2535 }