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