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 <asm/types.h>
12 #include <linux/types.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <stddef.h>
20 #include <stdbool.h>
21 #include <sched.h>
22 
23 #include <sys/capability.h>
24 #include <sys/resource.h>
25 
26 #include <linux/unistd.h>
27 #include <linux/filter.h>
28 #include <linux/bpf_perf_event.h>
29 #include <linux/bpf.h>
30 
31 #include <bpf/bpf.h>
32 
33 #include "../../../include/linux/filter.h"
34 
35 #ifndef ARRAY_SIZE
36 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
37 #endif
38 
39 #define MAX_INSNS	512
40 #define MAX_FIXUPS	8
41 
42 struct bpf_test {
43 	const char *descr;
44 	struct bpf_insn	insns[MAX_INSNS];
45 	int fixup_map1[MAX_FIXUPS];
46 	int fixup_map2[MAX_FIXUPS];
47 	int fixup_prog[MAX_FIXUPS];
48 	const char *errstr;
49 	const char *errstr_unpriv;
50 	enum {
51 		UNDEF,
52 		ACCEPT,
53 		REJECT
54 	} result, result_unpriv;
55 	enum bpf_prog_type prog_type;
56 };
57 
58 /* Note we want this to be 64 bit aligned so that the end of our array is
59  * actually the end of the structure.
60  */
61 #define MAX_ENTRIES 11
62 
63 struct test_val {
64 	unsigned int index;
65 	int foo[MAX_ENTRIES];
66 };
67 
68 static struct bpf_test tests[] = {
69 	{
70 		"add+sub+mul",
71 		.insns = {
72 			BPF_MOV64_IMM(BPF_REG_1, 1),
73 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
74 			BPF_MOV64_IMM(BPF_REG_2, 3),
75 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
76 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
77 			BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
78 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
79 			BPF_EXIT_INSN(),
80 		},
81 		.result = ACCEPT,
82 	},
83 	{
84 		"unreachable",
85 		.insns = {
86 			BPF_EXIT_INSN(),
87 			BPF_EXIT_INSN(),
88 		},
89 		.errstr = "unreachable",
90 		.result = REJECT,
91 	},
92 	{
93 		"unreachable2",
94 		.insns = {
95 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
96 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
97 			BPF_EXIT_INSN(),
98 		},
99 		.errstr = "unreachable",
100 		.result = REJECT,
101 	},
102 	{
103 		"out of range jump",
104 		.insns = {
105 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
106 			BPF_EXIT_INSN(),
107 		},
108 		.errstr = "jump out of range",
109 		.result = REJECT,
110 	},
111 	{
112 		"out of range jump2",
113 		.insns = {
114 			BPF_JMP_IMM(BPF_JA, 0, 0, -2),
115 			BPF_EXIT_INSN(),
116 		},
117 		.errstr = "jump out of range",
118 		.result = REJECT,
119 	},
120 	{
121 		"test1 ld_imm64",
122 		.insns = {
123 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
124 			BPF_LD_IMM64(BPF_REG_0, 0),
125 			BPF_LD_IMM64(BPF_REG_0, 0),
126 			BPF_LD_IMM64(BPF_REG_0, 1),
127 			BPF_LD_IMM64(BPF_REG_0, 1),
128 			BPF_MOV64_IMM(BPF_REG_0, 2),
129 			BPF_EXIT_INSN(),
130 		},
131 		.errstr = "invalid BPF_LD_IMM insn",
132 		.errstr_unpriv = "R1 pointer comparison",
133 		.result = REJECT,
134 	},
135 	{
136 		"test2 ld_imm64",
137 		.insns = {
138 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
139 			BPF_LD_IMM64(BPF_REG_0, 0),
140 			BPF_LD_IMM64(BPF_REG_0, 0),
141 			BPF_LD_IMM64(BPF_REG_0, 1),
142 			BPF_LD_IMM64(BPF_REG_0, 1),
143 			BPF_EXIT_INSN(),
144 		},
145 		.errstr = "invalid BPF_LD_IMM insn",
146 		.errstr_unpriv = "R1 pointer comparison",
147 		.result = REJECT,
148 	},
149 	{
150 		"test3 ld_imm64",
151 		.insns = {
152 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
153 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
154 			BPF_LD_IMM64(BPF_REG_0, 0),
155 			BPF_LD_IMM64(BPF_REG_0, 0),
156 			BPF_LD_IMM64(BPF_REG_0, 1),
157 			BPF_LD_IMM64(BPF_REG_0, 1),
158 			BPF_EXIT_INSN(),
159 		},
160 		.errstr = "invalid bpf_ld_imm64 insn",
161 		.result = REJECT,
162 	},
163 	{
164 		"test4 ld_imm64",
165 		.insns = {
166 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
167 			BPF_EXIT_INSN(),
168 		},
169 		.errstr = "invalid bpf_ld_imm64 insn",
170 		.result = REJECT,
171 	},
172 	{
173 		"test5 ld_imm64",
174 		.insns = {
175 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
176 		},
177 		.errstr = "invalid bpf_ld_imm64 insn",
178 		.result = REJECT,
179 	},
180 	{
181 		"no bpf_exit",
182 		.insns = {
183 			BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
184 		},
185 		.errstr = "jump out of range",
186 		.result = REJECT,
187 	},
188 	{
189 		"loop (back-edge)",
190 		.insns = {
191 			BPF_JMP_IMM(BPF_JA, 0, 0, -1),
192 			BPF_EXIT_INSN(),
193 		},
194 		.errstr = "back-edge",
195 		.result = REJECT,
196 	},
197 	{
198 		"loop2 (back-edge)",
199 		.insns = {
200 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
201 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
202 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
203 			BPF_JMP_IMM(BPF_JA, 0, 0, -4),
204 			BPF_EXIT_INSN(),
205 		},
206 		.errstr = "back-edge",
207 		.result = REJECT,
208 	},
209 	{
210 		"conditional loop",
211 		.insns = {
212 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
213 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
214 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
215 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
216 			BPF_EXIT_INSN(),
217 		},
218 		.errstr = "back-edge",
219 		.result = REJECT,
220 	},
221 	{
222 		"read uninitialized register",
223 		.insns = {
224 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
225 			BPF_EXIT_INSN(),
226 		},
227 		.errstr = "R2 !read_ok",
228 		.result = REJECT,
229 	},
230 	{
231 		"read invalid register",
232 		.insns = {
233 			BPF_MOV64_REG(BPF_REG_0, -1),
234 			BPF_EXIT_INSN(),
235 		},
236 		.errstr = "R15 is invalid",
237 		.result = REJECT,
238 	},
239 	{
240 		"program doesn't init R0 before exit",
241 		.insns = {
242 			BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
243 			BPF_EXIT_INSN(),
244 		},
245 		.errstr = "R0 !read_ok",
246 		.result = REJECT,
247 	},
248 	{
249 		"program doesn't init R0 before exit in all branches",
250 		.insns = {
251 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
252 			BPF_MOV64_IMM(BPF_REG_0, 1),
253 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
254 			BPF_EXIT_INSN(),
255 		},
256 		.errstr = "R0 !read_ok",
257 		.errstr_unpriv = "R1 pointer comparison",
258 		.result = REJECT,
259 	},
260 	{
261 		"stack out of bounds",
262 		.insns = {
263 			BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
264 			BPF_EXIT_INSN(),
265 		},
266 		.errstr = "invalid stack",
267 		.result = REJECT,
268 	},
269 	{
270 		"invalid call insn1",
271 		.insns = {
272 			BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
273 			BPF_EXIT_INSN(),
274 		},
275 		.errstr = "BPF_CALL uses reserved",
276 		.result = REJECT,
277 	},
278 	{
279 		"invalid call insn2",
280 		.insns = {
281 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
282 			BPF_EXIT_INSN(),
283 		},
284 		.errstr = "BPF_CALL uses reserved",
285 		.result = REJECT,
286 	},
287 	{
288 		"invalid function call",
289 		.insns = {
290 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
291 			BPF_EXIT_INSN(),
292 		},
293 		.errstr = "invalid func unknown#1234567",
294 		.result = REJECT,
295 	},
296 	{
297 		"uninitialized stack1",
298 		.insns = {
299 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
300 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
301 			BPF_LD_MAP_FD(BPF_REG_1, 0),
302 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
303 				     BPF_FUNC_map_lookup_elem),
304 			BPF_EXIT_INSN(),
305 		},
306 		.fixup_map1 = { 2 },
307 		.errstr = "invalid indirect read from stack",
308 		.result = REJECT,
309 	},
310 	{
311 		"uninitialized stack2",
312 		.insns = {
313 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
314 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
315 			BPF_EXIT_INSN(),
316 		},
317 		.errstr = "invalid read from stack",
318 		.result = REJECT,
319 	},
320 	{
321 		"invalid argument register",
322 		.insns = {
323 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
324 				     BPF_FUNC_get_cgroup_classid),
325 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
326 				     BPF_FUNC_get_cgroup_classid),
327 			BPF_EXIT_INSN(),
328 		},
329 		.errstr = "R1 !read_ok",
330 		.result = REJECT,
331 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
332 	},
333 	{
334 		"non-invalid argument register",
335 		.insns = {
336 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
337 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
338 				     BPF_FUNC_get_cgroup_classid),
339 			BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
340 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
341 				     BPF_FUNC_get_cgroup_classid),
342 			BPF_EXIT_INSN(),
343 		},
344 		.result = ACCEPT,
345 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
346 	},
347 	{
348 		"check valid spill/fill",
349 		.insns = {
350 			/* spill R1(ctx) into stack */
351 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
352 			/* fill it back into R2 */
353 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
354 			/* should be able to access R0 = *(R2 + 8) */
355 			/* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
356 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
357 			BPF_EXIT_INSN(),
358 		},
359 		.errstr_unpriv = "R0 leaks addr",
360 		.result = ACCEPT,
361 		.result_unpriv = REJECT,
362 	},
363 	{
364 		"check valid spill/fill, skb mark",
365 		.insns = {
366 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
367 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
368 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
369 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
370 				    offsetof(struct __sk_buff, mark)),
371 			BPF_EXIT_INSN(),
372 		},
373 		.result = ACCEPT,
374 		.result_unpriv = ACCEPT,
375 	},
376 	{
377 		"check corrupted spill/fill",
378 		.insns = {
379 			/* spill R1(ctx) into stack */
380 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
381 			/* mess up with R1 pointer on stack */
382 			BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
383 			/* fill back into R0 should fail */
384 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
385 			BPF_EXIT_INSN(),
386 		},
387 		.errstr_unpriv = "attempt to corrupt spilled",
388 		.errstr = "corrupted spill",
389 		.result = REJECT,
390 	},
391 	{
392 		"invalid src register in STX",
393 		.insns = {
394 			BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
395 			BPF_EXIT_INSN(),
396 		},
397 		.errstr = "R15 is invalid",
398 		.result = REJECT,
399 	},
400 	{
401 		"invalid dst register in STX",
402 		.insns = {
403 			BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
404 			BPF_EXIT_INSN(),
405 		},
406 		.errstr = "R14 is invalid",
407 		.result = REJECT,
408 	},
409 	{
410 		"invalid dst register in ST",
411 		.insns = {
412 			BPF_ST_MEM(BPF_B, 14, -1, -1),
413 			BPF_EXIT_INSN(),
414 		},
415 		.errstr = "R14 is invalid",
416 		.result = REJECT,
417 	},
418 	{
419 		"invalid src register in LDX",
420 		.insns = {
421 			BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
422 			BPF_EXIT_INSN(),
423 		},
424 		.errstr = "R12 is invalid",
425 		.result = REJECT,
426 	},
427 	{
428 		"invalid dst register in LDX",
429 		.insns = {
430 			BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
431 			BPF_EXIT_INSN(),
432 		},
433 		.errstr = "R11 is invalid",
434 		.result = REJECT,
435 	},
436 	{
437 		"junk insn",
438 		.insns = {
439 			BPF_RAW_INSN(0, 0, 0, 0, 0),
440 			BPF_EXIT_INSN(),
441 		},
442 		.errstr = "invalid BPF_LD_IMM",
443 		.result = REJECT,
444 	},
445 	{
446 		"junk insn2",
447 		.insns = {
448 			BPF_RAW_INSN(1, 0, 0, 0, 0),
449 			BPF_EXIT_INSN(),
450 		},
451 		.errstr = "BPF_LDX uses reserved fields",
452 		.result = REJECT,
453 	},
454 	{
455 		"junk insn3",
456 		.insns = {
457 			BPF_RAW_INSN(-1, 0, 0, 0, 0),
458 			BPF_EXIT_INSN(),
459 		},
460 		.errstr = "invalid BPF_ALU opcode f0",
461 		.result = REJECT,
462 	},
463 	{
464 		"junk insn4",
465 		.insns = {
466 			BPF_RAW_INSN(-1, -1, -1, -1, -1),
467 			BPF_EXIT_INSN(),
468 		},
469 		.errstr = "invalid BPF_ALU opcode f0",
470 		.result = REJECT,
471 	},
472 	{
473 		"junk insn5",
474 		.insns = {
475 			BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
476 			BPF_EXIT_INSN(),
477 		},
478 		.errstr = "BPF_ALU uses reserved fields",
479 		.result = REJECT,
480 	},
481 	{
482 		"misaligned read from stack",
483 		.insns = {
484 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
485 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
486 			BPF_EXIT_INSN(),
487 		},
488 		.errstr = "misaligned access",
489 		.result = REJECT,
490 	},
491 	{
492 		"invalid map_fd for function call",
493 		.insns = {
494 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
495 			BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
496 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
497 			BPF_LD_MAP_FD(BPF_REG_1, 0),
498 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
499 				     BPF_FUNC_map_delete_elem),
500 			BPF_EXIT_INSN(),
501 		},
502 		.errstr = "fd 0 is not pointing to valid bpf_map",
503 		.result = REJECT,
504 	},
505 	{
506 		"don't check return value before access",
507 		.insns = {
508 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
509 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
510 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
511 			BPF_LD_MAP_FD(BPF_REG_1, 0),
512 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
513 				     BPF_FUNC_map_lookup_elem),
514 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
515 			BPF_EXIT_INSN(),
516 		},
517 		.fixup_map1 = { 3 },
518 		.errstr = "R0 invalid mem access 'map_value_or_null'",
519 		.result = REJECT,
520 	},
521 	{
522 		"access memory with incorrect alignment",
523 		.insns = {
524 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
525 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
526 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
527 			BPF_LD_MAP_FD(BPF_REG_1, 0),
528 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
529 				     BPF_FUNC_map_lookup_elem),
530 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
531 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
532 			BPF_EXIT_INSN(),
533 		},
534 		.fixup_map1 = { 3 },
535 		.errstr = "misaligned access",
536 		.result = REJECT,
537 	},
538 	{
539 		"sometimes access memory with incorrect alignment",
540 		.insns = {
541 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
542 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
543 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
544 			BPF_LD_MAP_FD(BPF_REG_1, 0),
545 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
546 				     BPF_FUNC_map_lookup_elem),
547 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
548 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
549 			BPF_EXIT_INSN(),
550 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
551 			BPF_EXIT_INSN(),
552 		},
553 		.fixup_map1 = { 3 },
554 		.errstr = "R0 invalid mem access",
555 		.errstr_unpriv = "R0 leaks addr",
556 		.result = REJECT,
557 	},
558 	{
559 		"jump test 1",
560 		.insns = {
561 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
562 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
563 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
564 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
565 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
566 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
567 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
568 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
569 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
570 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
571 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
572 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
573 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
574 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
575 			BPF_MOV64_IMM(BPF_REG_0, 0),
576 			BPF_EXIT_INSN(),
577 		},
578 		.errstr_unpriv = "R1 pointer comparison",
579 		.result_unpriv = REJECT,
580 		.result = ACCEPT,
581 	},
582 	{
583 		"jump test 2",
584 		.insns = {
585 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
586 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
587 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
588 			BPF_JMP_IMM(BPF_JA, 0, 0, 14),
589 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
590 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
591 			BPF_JMP_IMM(BPF_JA, 0, 0, 11),
592 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
593 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
594 			BPF_JMP_IMM(BPF_JA, 0, 0, 8),
595 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
596 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
597 			BPF_JMP_IMM(BPF_JA, 0, 0, 5),
598 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
599 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
600 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
601 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
602 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
603 			BPF_MOV64_IMM(BPF_REG_0, 0),
604 			BPF_EXIT_INSN(),
605 		},
606 		.errstr_unpriv = "R1 pointer comparison",
607 		.result_unpriv = REJECT,
608 		.result = ACCEPT,
609 	},
610 	{
611 		"jump test 3",
612 		.insns = {
613 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
614 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
615 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
616 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
617 			BPF_JMP_IMM(BPF_JA, 0, 0, 19),
618 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
619 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
620 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
621 			BPF_JMP_IMM(BPF_JA, 0, 0, 15),
622 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
623 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
624 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
625 			BPF_JMP_IMM(BPF_JA, 0, 0, 11),
626 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
627 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
628 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
629 			BPF_JMP_IMM(BPF_JA, 0, 0, 7),
630 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
631 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
632 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
633 			BPF_JMP_IMM(BPF_JA, 0, 0, 3),
634 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
635 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
636 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
637 			BPF_LD_MAP_FD(BPF_REG_1, 0),
638 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
639 				     BPF_FUNC_map_delete_elem),
640 			BPF_EXIT_INSN(),
641 		},
642 		.fixup_map1 = { 24 },
643 		.errstr_unpriv = "R1 pointer comparison",
644 		.result_unpriv = REJECT,
645 		.result = ACCEPT,
646 	},
647 	{
648 		"jump test 4",
649 		.insns = {
650 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
651 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
652 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
653 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
654 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
655 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
656 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
657 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
658 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
659 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
660 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
661 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
662 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
663 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
664 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
665 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
666 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
667 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
668 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
669 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
670 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
671 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
672 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
673 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
674 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
675 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
676 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
677 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
678 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
679 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
680 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
681 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
682 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
683 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
684 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
685 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
686 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
687 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
688 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
689 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
690 			BPF_MOV64_IMM(BPF_REG_0, 0),
691 			BPF_EXIT_INSN(),
692 		},
693 		.errstr_unpriv = "R1 pointer comparison",
694 		.result_unpriv = REJECT,
695 		.result = ACCEPT,
696 	},
697 	{
698 		"jump test 5",
699 		.insns = {
700 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
701 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
702 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
703 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
704 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
705 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
706 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
707 			BPF_MOV64_IMM(BPF_REG_0, 0),
708 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
709 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
710 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
711 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
712 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
713 			BPF_MOV64_IMM(BPF_REG_0, 0),
714 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
715 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
716 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
717 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
718 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
719 			BPF_MOV64_IMM(BPF_REG_0, 0),
720 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
721 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
722 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
723 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
724 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
725 			BPF_MOV64_IMM(BPF_REG_0, 0),
726 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
727 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
728 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
729 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
730 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
731 			BPF_MOV64_IMM(BPF_REG_0, 0),
732 			BPF_EXIT_INSN(),
733 		},
734 		.errstr_unpriv = "R1 pointer comparison",
735 		.result_unpriv = REJECT,
736 		.result = ACCEPT,
737 	},
738 	{
739 		"access skb fields ok",
740 		.insns = {
741 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
742 				    offsetof(struct __sk_buff, len)),
743 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
744 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
745 				    offsetof(struct __sk_buff, mark)),
746 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
747 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
748 				    offsetof(struct __sk_buff, pkt_type)),
749 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
750 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
751 				    offsetof(struct __sk_buff, queue_mapping)),
752 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
753 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
754 				    offsetof(struct __sk_buff, protocol)),
755 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
756 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
757 				    offsetof(struct __sk_buff, vlan_present)),
758 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
759 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
760 				    offsetof(struct __sk_buff, vlan_tci)),
761 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
762 			BPF_EXIT_INSN(),
763 		},
764 		.result = ACCEPT,
765 	},
766 	{
767 		"access skb fields bad1",
768 		.insns = {
769 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
770 			BPF_EXIT_INSN(),
771 		},
772 		.errstr = "invalid bpf_context access",
773 		.result = REJECT,
774 	},
775 	{
776 		"access skb fields bad2",
777 		.insns = {
778 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
779 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
780 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
781 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
782 			BPF_LD_MAP_FD(BPF_REG_1, 0),
783 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
784 				     BPF_FUNC_map_lookup_elem),
785 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
786 			BPF_EXIT_INSN(),
787 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
788 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
789 				    offsetof(struct __sk_buff, pkt_type)),
790 			BPF_EXIT_INSN(),
791 		},
792 		.fixup_map1 = { 4 },
793 		.errstr = "different pointers",
794 		.errstr_unpriv = "R1 pointer comparison",
795 		.result = REJECT,
796 	},
797 	{
798 		"access skb fields bad3",
799 		.insns = {
800 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
801 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
802 				    offsetof(struct __sk_buff, pkt_type)),
803 			BPF_EXIT_INSN(),
804 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
805 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
806 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
807 			BPF_LD_MAP_FD(BPF_REG_1, 0),
808 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
809 				     BPF_FUNC_map_lookup_elem),
810 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
811 			BPF_EXIT_INSN(),
812 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
813 			BPF_JMP_IMM(BPF_JA, 0, 0, -12),
814 		},
815 		.fixup_map1 = { 6 },
816 		.errstr = "different pointers",
817 		.errstr_unpriv = "R1 pointer comparison",
818 		.result = REJECT,
819 	},
820 	{
821 		"access skb fields bad4",
822 		.insns = {
823 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
824 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
825 				    offsetof(struct __sk_buff, len)),
826 			BPF_MOV64_IMM(BPF_REG_0, 0),
827 			BPF_EXIT_INSN(),
828 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
829 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
830 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
831 			BPF_LD_MAP_FD(BPF_REG_1, 0),
832 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
833 				     BPF_FUNC_map_lookup_elem),
834 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
835 			BPF_EXIT_INSN(),
836 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
837 			BPF_JMP_IMM(BPF_JA, 0, 0, -13),
838 		},
839 		.fixup_map1 = { 7 },
840 		.errstr = "different pointers",
841 		.errstr_unpriv = "R1 pointer comparison",
842 		.result = REJECT,
843 	},
844 	{
845 		"check skb->mark is not writeable by sockets",
846 		.insns = {
847 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
848 				    offsetof(struct __sk_buff, mark)),
849 			BPF_EXIT_INSN(),
850 		},
851 		.errstr = "invalid bpf_context access",
852 		.errstr_unpriv = "R1 leaks addr",
853 		.result = REJECT,
854 	},
855 	{
856 		"check skb->tc_index is not writeable by sockets",
857 		.insns = {
858 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
859 				    offsetof(struct __sk_buff, tc_index)),
860 			BPF_EXIT_INSN(),
861 		},
862 		.errstr = "invalid bpf_context access",
863 		.errstr_unpriv = "R1 leaks addr",
864 		.result = REJECT,
865 	},
866 	{
867 		"check cb access: byte",
868 		.insns = {
869 			BPF_MOV64_IMM(BPF_REG_0, 0),
870 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
871 				    offsetof(struct __sk_buff, cb[0])),
872 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
873 				    offsetof(struct __sk_buff, cb[0]) + 1),
874 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
875 				    offsetof(struct __sk_buff, cb[0]) + 2),
876 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
877 				    offsetof(struct __sk_buff, cb[0]) + 3),
878 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
879 				    offsetof(struct __sk_buff, cb[1])),
880 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
881 				    offsetof(struct __sk_buff, cb[1]) + 1),
882 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
883 				    offsetof(struct __sk_buff, cb[1]) + 2),
884 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
885 				    offsetof(struct __sk_buff, cb[1]) + 3),
886 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
887 				    offsetof(struct __sk_buff, cb[2])),
888 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
889 				    offsetof(struct __sk_buff, cb[2]) + 1),
890 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
891 				    offsetof(struct __sk_buff, cb[2]) + 2),
892 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
893 				    offsetof(struct __sk_buff, cb[2]) + 3),
894 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
895 				    offsetof(struct __sk_buff, cb[3])),
896 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
897 				    offsetof(struct __sk_buff, cb[3]) + 1),
898 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
899 				    offsetof(struct __sk_buff, cb[3]) + 2),
900 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
901 				    offsetof(struct __sk_buff, cb[3]) + 3),
902 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
903 				    offsetof(struct __sk_buff, cb[4])),
904 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
905 				    offsetof(struct __sk_buff, cb[4]) + 1),
906 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
907 				    offsetof(struct __sk_buff, cb[4]) + 2),
908 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
909 				    offsetof(struct __sk_buff, cb[4]) + 3),
910 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
911 				    offsetof(struct __sk_buff, cb[0])),
912 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
913 				    offsetof(struct __sk_buff, cb[0]) + 1),
914 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
915 				    offsetof(struct __sk_buff, cb[0]) + 2),
916 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
917 				    offsetof(struct __sk_buff, cb[0]) + 3),
918 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
919 				    offsetof(struct __sk_buff, cb[1])),
920 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
921 				    offsetof(struct __sk_buff, cb[1]) + 1),
922 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
923 				    offsetof(struct __sk_buff, cb[1]) + 2),
924 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
925 				    offsetof(struct __sk_buff, cb[1]) + 3),
926 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
927 				    offsetof(struct __sk_buff, cb[2])),
928 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
929 				    offsetof(struct __sk_buff, cb[2]) + 1),
930 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
931 				    offsetof(struct __sk_buff, cb[2]) + 2),
932 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
933 				    offsetof(struct __sk_buff, cb[2]) + 3),
934 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
935 				    offsetof(struct __sk_buff, cb[3])),
936 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
937 				    offsetof(struct __sk_buff, cb[3]) + 1),
938 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
939 				    offsetof(struct __sk_buff, cb[3]) + 2),
940 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
941 				    offsetof(struct __sk_buff, cb[3]) + 3),
942 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
943 				    offsetof(struct __sk_buff, cb[4])),
944 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
945 				    offsetof(struct __sk_buff, cb[4]) + 1),
946 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
947 				    offsetof(struct __sk_buff, cb[4]) + 2),
948 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
949 				    offsetof(struct __sk_buff, cb[4]) + 3),
950 			BPF_EXIT_INSN(),
951 		},
952 		.result = ACCEPT,
953 	},
954 	{
955 		"check cb access: byte, oob 1",
956 		.insns = {
957 			BPF_MOV64_IMM(BPF_REG_0, 0),
958 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
959 				    offsetof(struct __sk_buff, cb[4]) + 4),
960 			BPF_EXIT_INSN(),
961 		},
962 		.errstr = "invalid bpf_context access",
963 		.result = REJECT,
964 	},
965 	{
966 		"check cb access: byte, oob 2",
967 		.insns = {
968 			BPF_MOV64_IMM(BPF_REG_0, 0),
969 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
970 				    offsetof(struct __sk_buff, cb[0]) - 1),
971 			BPF_EXIT_INSN(),
972 		},
973 		.errstr = "invalid bpf_context access",
974 		.result = REJECT,
975 	},
976 	{
977 		"check cb access: byte, oob 3",
978 		.insns = {
979 			BPF_MOV64_IMM(BPF_REG_0, 0),
980 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
981 				    offsetof(struct __sk_buff, cb[4]) + 4),
982 			BPF_EXIT_INSN(),
983 		},
984 		.errstr = "invalid bpf_context access",
985 		.result = REJECT,
986 	},
987 	{
988 		"check cb access: byte, oob 4",
989 		.insns = {
990 			BPF_MOV64_IMM(BPF_REG_0, 0),
991 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
992 				    offsetof(struct __sk_buff, cb[0]) - 1),
993 			BPF_EXIT_INSN(),
994 		},
995 		.errstr = "invalid bpf_context access",
996 		.result = REJECT,
997 	},
998 	{
999 		"check cb access: byte, wrong type",
1000 		.insns = {
1001 			BPF_MOV64_IMM(BPF_REG_0, 0),
1002 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1003 				    offsetof(struct __sk_buff, cb[0])),
1004 			BPF_EXIT_INSN(),
1005 		},
1006 		.errstr = "invalid bpf_context access",
1007 		.result = REJECT,
1008 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1009 	},
1010 	{
1011 		"check cb access: half",
1012 		.insns = {
1013 			BPF_MOV64_IMM(BPF_REG_0, 0),
1014 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1015 				    offsetof(struct __sk_buff, cb[0])),
1016 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1017 				    offsetof(struct __sk_buff, cb[0]) + 2),
1018 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1019 				    offsetof(struct __sk_buff, cb[1])),
1020 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1021 				    offsetof(struct __sk_buff, cb[1]) + 2),
1022 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1023 				    offsetof(struct __sk_buff, cb[2])),
1024 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1025 				    offsetof(struct __sk_buff, cb[2]) + 2),
1026 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1027 				    offsetof(struct __sk_buff, cb[3])),
1028 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1029 				    offsetof(struct __sk_buff, cb[3]) + 2),
1030 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1031 				    offsetof(struct __sk_buff, cb[4])),
1032 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1033 				    offsetof(struct __sk_buff, cb[4]) + 2),
1034 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1035 				    offsetof(struct __sk_buff, cb[0])),
1036 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1037 				    offsetof(struct __sk_buff, cb[0]) + 2),
1038 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1039 				    offsetof(struct __sk_buff, cb[1])),
1040 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1041 				    offsetof(struct __sk_buff, cb[1]) + 2),
1042 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1043 				    offsetof(struct __sk_buff, cb[2])),
1044 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1045 				    offsetof(struct __sk_buff, cb[2]) + 2),
1046 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1047 				    offsetof(struct __sk_buff, cb[3])),
1048 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1049 				    offsetof(struct __sk_buff, cb[3]) + 2),
1050 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1051 				    offsetof(struct __sk_buff, cb[4])),
1052 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1053 				    offsetof(struct __sk_buff, cb[4]) + 2),
1054 			BPF_EXIT_INSN(),
1055 		},
1056 		.result = ACCEPT,
1057 	},
1058 	{
1059 		"check cb access: half, unaligned",
1060 		.insns = {
1061 			BPF_MOV64_IMM(BPF_REG_0, 0),
1062 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1063 				    offsetof(struct __sk_buff, cb[0]) + 1),
1064 			BPF_EXIT_INSN(),
1065 		},
1066 		.errstr = "misaligned access",
1067 		.result = REJECT,
1068 	},
1069 	{
1070 		"check cb access: half, oob 1",
1071 		.insns = {
1072 			BPF_MOV64_IMM(BPF_REG_0, 0),
1073 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1074 				    offsetof(struct __sk_buff, cb[4]) + 4),
1075 			BPF_EXIT_INSN(),
1076 		},
1077 		.errstr = "invalid bpf_context access",
1078 		.result = REJECT,
1079 	},
1080 	{
1081 		"check cb access: half, oob 2",
1082 		.insns = {
1083 			BPF_MOV64_IMM(BPF_REG_0, 0),
1084 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1085 				    offsetof(struct __sk_buff, cb[0]) - 2),
1086 			BPF_EXIT_INSN(),
1087 		},
1088 		.errstr = "invalid bpf_context access",
1089 		.result = REJECT,
1090 	},
1091 	{
1092 		"check cb access: half, oob 3",
1093 		.insns = {
1094 			BPF_MOV64_IMM(BPF_REG_0, 0),
1095 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1096 				    offsetof(struct __sk_buff, cb[4]) + 4),
1097 			BPF_EXIT_INSN(),
1098 		},
1099 		.errstr = "invalid bpf_context access",
1100 		.result = REJECT,
1101 	},
1102 	{
1103 		"check cb access: half, oob 4",
1104 		.insns = {
1105 			BPF_MOV64_IMM(BPF_REG_0, 0),
1106 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1107 				    offsetof(struct __sk_buff, cb[0]) - 2),
1108 			BPF_EXIT_INSN(),
1109 		},
1110 		.errstr = "invalid bpf_context access",
1111 		.result = REJECT,
1112 	},
1113 	{
1114 		"check cb access: half, wrong type",
1115 		.insns = {
1116 			BPF_MOV64_IMM(BPF_REG_0, 0),
1117 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1118 				    offsetof(struct __sk_buff, cb[0])),
1119 			BPF_EXIT_INSN(),
1120 		},
1121 		.errstr = "invalid bpf_context access",
1122 		.result = REJECT,
1123 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1124 	},
1125 	{
1126 		"check cb access: word",
1127 		.insns = {
1128 			BPF_MOV64_IMM(BPF_REG_0, 0),
1129 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1130 				    offsetof(struct __sk_buff, cb[0])),
1131 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1132 				    offsetof(struct __sk_buff, cb[1])),
1133 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1134 				    offsetof(struct __sk_buff, cb[2])),
1135 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1136 				    offsetof(struct __sk_buff, cb[3])),
1137 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1138 				    offsetof(struct __sk_buff, cb[4])),
1139 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1140 				    offsetof(struct __sk_buff, cb[0])),
1141 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1142 				    offsetof(struct __sk_buff, cb[1])),
1143 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1144 				    offsetof(struct __sk_buff, cb[2])),
1145 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1146 				    offsetof(struct __sk_buff, cb[3])),
1147 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1148 				    offsetof(struct __sk_buff, cb[4])),
1149 			BPF_EXIT_INSN(),
1150 		},
1151 		.result = ACCEPT,
1152 	},
1153 	{
1154 		"check cb access: word, unaligned 1",
1155 		.insns = {
1156 			BPF_MOV64_IMM(BPF_REG_0, 0),
1157 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1158 				    offsetof(struct __sk_buff, cb[0]) + 2),
1159 			BPF_EXIT_INSN(),
1160 		},
1161 		.errstr = "misaligned access",
1162 		.result = REJECT,
1163 	},
1164 	{
1165 		"check cb access: word, unaligned 2",
1166 		.insns = {
1167 			BPF_MOV64_IMM(BPF_REG_0, 0),
1168 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1169 				    offsetof(struct __sk_buff, cb[4]) + 1),
1170 			BPF_EXIT_INSN(),
1171 		},
1172 		.errstr = "misaligned access",
1173 		.result = REJECT,
1174 	},
1175 	{
1176 		"check cb access: word, unaligned 3",
1177 		.insns = {
1178 			BPF_MOV64_IMM(BPF_REG_0, 0),
1179 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1180 				    offsetof(struct __sk_buff, cb[4]) + 2),
1181 			BPF_EXIT_INSN(),
1182 		},
1183 		.errstr = "misaligned access",
1184 		.result = REJECT,
1185 	},
1186 	{
1187 		"check cb access: word, unaligned 4",
1188 		.insns = {
1189 			BPF_MOV64_IMM(BPF_REG_0, 0),
1190 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1191 				    offsetof(struct __sk_buff, cb[4]) + 3),
1192 			BPF_EXIT_INSN(),
1193 		},
1194 		.errstr = "misaligned access",
1195 		.result = REJECT,
1196 	},
1197 	{
1198 		"check cb access: double",
1199 		.insns = {
1200 			BPF_MOV64_IMM(BPF_REG_0, 0),
1201 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1202 				    offsetof(struct __sk_buff, cb[0])),
1203 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1204 				    offsetof(struct __sk_buff, cb[2])),
1205 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1206 				    offsetof(struct __sk_buff, cb[0])),
1207 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1208 				    offsetof(struct __sk_buff, cb[2])),
1209 			BPF_EXIT_INSN(),
1210 		},
1211 		.result = ACCEPT,
1212 	},
1213 	{
1214 		"check cb access: double, unaligned 1",
1215 		.insns = {
1216 			BPF_MOV64_IMM(BPF_REG_0, 0),
1217 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1218 				    offsetof(struct __sk_buff, cb[1])),
1219 			BPF_EXIT_INSN(),
1220 		},
1221 		.errstr = "misaligned access",
1222 		.result = REJECT,
1223 	},
1224 	{
1225 		"check cb access: double, unaligned 2",
1226 		.insns = {
1227 			BPF_MOV64_IMM(BPF_REG_0, 0),
1228 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1229 				    offsetof(struct __sk_buff, cb[3])),
1230 			BPF_EXIT_INSN(),
1231 		},
1232 		.errstr = "misaligned access",
1233 		.result = REJECT,
1234 	},
1235 	{
1236 		"check cb access: double, oob 1",
1237 		.insns = {
1238 			BPF_MOV64_IMM(BPF_REG_0, 0),
1239 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1240 				    offsetof(struct __sk_buff, cb[4])),
1241 			BPF_EXIT_INSN(),
1242 		},
1243 		.errstr = "invalid bpf_context access",
1244 		.result = REJECT,
1245 	},
1246 	{
1247 		"check cb access: double, oob 2",
1248 		.insns = {
1249 			BPF_MOV64_IMM(BPF_REG_0, 0),
1250 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1251 				    offsetof(struct __sk_buff, cb[4]) + 8),
1252 			BPF_EXIT_INSN(),
1253 		},
1254 		.errstr = "invalid bpf_context access",
1255 		.result = REJECT,
1256 	},
1257 	{
1258 		"check cb access: double, oob 3",
1259 		.insns = {
1260 			BPF_MOV64_IMM(BPF_REG_0, 0),
1261 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1262 				    offsetof(struct __sk_buff, cb[0]) - 8),
1263 			BPF_EXIT_INSN(),
1264 		},
1265 		.errstr = "invalid bpf_context access",
1266 		.result = REJECT,
1267 	},
1268 	{
1269 		"check cb access: double, oob 4",
1270 		.insns = {
1271 			BPF_MOV64_IMM(BPF_REG_0, 0),
1272 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1273 				    offsetof(struct __sk_buff, cb[4])),
1274 			BPF_EXIT_INSN(),
1275 		},
1276 		.errstr = "invalid bpf_context access",
1277 		.result = REJECT,
1278 	},
1279 	{
1280 		"check cb access: double, oob 5",
1281 		.insns = {
1282 			BPF_MOV64_IMM(BPF_REG_0, 0),
1283 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1284 				    offsetof(struct __sk_buff, cb[4]) + 8),
1285 			BPF_EXIT_INSN(),
1286 		},
1287 		.errstr = "invalid bpf_context access",
1288 		.result = REJECT,
1289 	},
1290 	{
1291 		"check cb access: double, oob 6",
1292 		.insns = {
1293 			BPF_MOV64_IMM(BPF_REG_0, 0),
1294 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1295 				    offsetof(struct __sk_buff, cb[0]) - 8),
1296 			BPF_EXIT_INSN(),
1297 		},
1298 		.errstr = "invalid bpf_context access",
1299 		.result = REJECT,
1300 	},
1301 	{
1302 		"check cb access: double, wrong type",
1303 		.insns = {
1304 			BPF_MOV64_IMM(BPF_REG_0, 0),
1305 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1306 				    offsetof(struct __sk_buff, cb[0])),
1307 			BPF_EXIT_INSN(),
1308 		},
1309 		.errstr = "invalid bpf_context access",
1310 		.result = REJECT,
1311 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1312 	},
1313 	{
1314 		"check out of range skb->cb access",
1315 		.insns = {
1316 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1317 				    offsetof(struct __sk_buff, cb[0]) + 256),
1318 			BPF_EXIT_INSN(),
1319 		},
1320 		.errstr = "invalid bpf_context access",
1321 		.errstr_unpriv = "",
1322 		.result = REJECT,
1323 		.prog_type = BPF_PROG_TYPE_SCHED_ACT,
1324 	},
1325 	{
1326 		"write skb fields from socket prog",
1327 		.insns = {
1328 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1329 				    offsetof(struct __sk_buff, cb[4])),
1330 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1331 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1332 				    offsetof(struct __sk_buff, mark)),
1333 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1334 				    offsetof(struct __sk_buff, tc_index)),
1335 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1336 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1337 				    offsetof(struct __sk_buff, cb[0])),
1338 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1339 				    offsetof(struct __sk_buff, cb[2])),
1340 			BPF_EXIT_INSN(),
1341 		},
1342 		.result = ACCEPT,
1343 		.errstr_unpriv = "R1 leaks addr",
1344 		.result_unpriv = REJECT,
1345 	},
1346 	{
1347 		"write skb fields from tc_cls_act prog",
1348 		.insns = {
1349 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1350 				    offsetof(struct __sk_buff, cb[0])),
1351 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1352 				    offsetof(struct __sk_buff, mark)),
1353 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1354 				    offsetof(struct __sk_buff, tc_index)),
1355 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1356 				    offsetof(struct __sk_buff, tc_index)),
1357 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1358 				    offsetof(struct __sk_buff, cb[3])),
1359 			BPF_EXIT_INSN(),
1360 		},
1361 		.errstr_unpriv = "",
1362 		.result_unpriv = REJECT,
1363 		.result = ACCEPT,
1364 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1365 	},
1366 	{
1367 		"PTR_TO_STACK store/load",
1368 		.insns = {
1369 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1370 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1371 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1372 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1373 			BPF_EXIT_INSN(),
1374 		},
1375 		.result = ACCEPT,
1376 	},
1377 	{
1378 		"PTR_TO_STACK store/load - bad alignment on off",
1379 		.insns = {
1380 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1381 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1382 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1383 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1384 			BPF_EXIT_INSN(),
1385 		},
1386 		.result = REJECT,
1387 		.errstr = "misaligned access off -6 size 8",
1388 	},
1389 	{
1390 		"PTR_TO_STACK store/load - bad alignment on reg",
1391 		.insns = {
1392 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1393 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1394 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1395 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1396 			BPF_EXIT_INSN(),
1397 		},
1398 		.result = REJECT,
1399 		.errstr = "misaligned access off -2 size 8",
1400 	},
1401 	{
1402 		"PTR_TO_STACK store/load - out of bounds low",
1403 		.insns = {
1404 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1405 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1406 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1407 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1408 			BPF_EXIT_INSN(),
1409 		},
1410 		.result = REJECT,
1411 		.errstr = "invalid stack off=-79992 size=8",
1412 	},
1413 	{
1414 		"PTR_TO_STACK store/load - out of bounds high",
1415 		.insns = {
1416 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1417 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1418 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1419 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1420 			BPF_EXIT_INSN(),
1421 		},
1422 		.result = REJECT,
1423 		.errstr = "invalid stack off=0 size=8",
1424 	},
1425 	{
1426 		"unpriv: return pointer",
1427 		.insns = {
1428 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1429 			BPF_EXIT_INSN(),
1430 		},
1431 		.result = ACCEPT,
1432 		.result_unpriv = REJECT,
1433 		.errstr_unpriv = "R0 leaks addr",
1434 	},
1435 	{
1436 		"unpriv: add const to pointer",
1437 		.insns = {
1438 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1439 			BPF_MOV64_IMM(BPF_REG_0, 0),
1440 			BPF_EXIT_INSN(),
1441 		},
1442 		.result = ACCEPT,
1443 		.result_unpriv = REJECT,
1444 		.errstr_unpriv = "R1 pointer arithmetic",
1445 	},
1446 	{
1447 		"unpriv: add pointer to pointer",
1448 		.insns = {
1449 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1450 			BPF_MOV64_IMM(BPF_REG_0, 0),
1451 			BPF_EXIT_INSN(),
1452 		},
1453 		.result = ACCEPT,
1454 		.result_unpriv = REJECT,
1455 		.errstr_unpriv = "R1 pointer arithmetic",
1456 	},
1457 	{
1458 		"unpriv: neg pointer",
1459 		.insns = {
1460 			BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1461 			BPF_MOV64_IMM(BPF_REG_0, 0),
1462 			BPF_EXIT_INSN(),
1463 		},
1464 		.result = ACCEPT,
1465 		.result_unpriv = REJECT,
1466 		.errstr_unpriv = "R1 pointer arithmetic",
1467 	},
1468 	{
1469 		"unpriv: cmp pointer with const",
1470 		.insns = {
1471 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1472 			BPF_MOV64_IMM(BPF_REG_0, 0),
1473 			BPF_EXIT_INSN(),
1474 		},
1475 		.result = ACCEPT,
1476 		.result_unpriv = REJECT,
1477 		.errstr_unpriv = "R1 pointer comparison",
1478 	},
1479 	{
1480 		"unpriv: cmp pointer with pointer",
1481 		.insns = {
1482 			BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1483 			BPF_MOV64_IMM(BPF_REG_0, 0),
1484 			BPF_EXIT_INSN(),
1485 		},
1486 		.result = ACCEPT,
1487 		.result_unpriv = REJECT,
1488 		.errstr_unpriv = "R10 pointer comparison",
1489 	},
1490 	{
1491 		"unpriv: check that printk is disallowed",
1492 		.insns = {
1493 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1494 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1495 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1496 			BPF_MOV64_IMM(BPF_REG_2, 8),
1497 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1498 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1499 				     BPF_FUNC_trace_printk),
1500 			BPF_MOV64_IMM(BPF_REG_0, 0),
1501 			BPF_EXIT_INSN(),
1502 		},
1503 		.errstr_unpriv = "unknown func bpf_trace_printk#6",
1504 		.result_unpriv = REJECT,
1505 		.result = ACCEPT,
1506 	},
1507 	{
1508 		"unpriv: pass pointer to helper function",
1509 		.insns = {
1510 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1511 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1512 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1513 			BPF_LD_MAP_FD(BPF_REG_1, 0),
1514 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1515 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1516 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1517 				     BPF_FUNC_map_update_elem),
1518 			BPF_MOV64_IMM(BPF_REG_0, 0),
1519 			BPF_EXIT_INSN(),
1520 		},
1521 		.fixup_map1 = { 3 },
1522 		.errstr_unpriv = "R4 leaks addr",
1523 		.result_unpriv = REJECT,
1524 		.result = ACCEPT,
1525 	},
1526 	{
1527 		"unpriv: indirectly pass pointer on stack to helper function",
1528 		.insns = {
1529 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1530 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1531 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1532 			BPF_LD_MAP_FD(BPF_REG_1, 0),
1533 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1534 				     BPF_FUNC_map_lookup_elem),
1535 			BPF_MOV64_IMM(BPF_REG_0, 0),
1536 			BPF_EXIT_INSN(),
1537 		},
1538 		.fixup_map1 = { 3 },
1539 		.errstr = "invalid indirect read from stack off -8+0 size 8",
1540 		.result = REJECT,
1541 	},
1542 	{
1543 		"unpriv: mangle pointer on stack 1",
1544 		.insns = {
1545 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1546 			BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1547 			BPF_MOV64_IMM(BPF_REG_0, 0),
1548 			BPF_EXIT_INSN(),
1549 		},
1550 		.errstr_unpriv = "attempt to corrupt spilled",
1551 		.result_unpriv = REJECT,
1552 		.result = ACCEPT,
1553 	},
1554 	{
1555 		"unpriv: mangle pointer on stack 2",
1556 		.insns = {
1557 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1558 			BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1559 			BPF_MOV64_IMM(BPF_REG_0, 0),
1560 			BPF_EXIT_INSN(),
1561 		},
1562 		.errstr_unpriv = "attempt to corrupt spilled",
1563 		.result_unpriv = REJECT,
1564 		.result = ACCEPT,
1565 	},
1566 	{
1567 		"unpriv: read pointer from stack in small chunks",
1568 		.insns = {
1569 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1570 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1571 			BPF_MOV64_IMM(BPF_REG_0, 0),
1572 			BPF_EXIT_INSN(),
1573 		},
1574 		.errstr = "invalid size",
1575 		.result = REJECT,
1576 	},
1577 	{
1578 		"unpriv: write pointer into ctx",
1579 		.insns = {
1580 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1581 			BPF_MOV64_IMM(BPF_REG_0, 0),
1582 			BPF_EXIT_INSN(),
1583 		},
1584 		.errstr_unpriv = "R1 leaks addr",
1585 		.result_unpriv = REJECT,
1586 		.errstr = "invalid bpf_context access",
1587 		.result = REJECT,
1588 	},
1589 	{
1590 		"unpriv: spill/fill of ctx",
1591 		.insns = {
1592 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1593 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1594 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1595 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1596 			BPF_MOV64_IMM(BPF_REG_0, 0),
1597 			BPF_EXIT_INSN(),
1598 		},
1599 		.result = ACCEPT,
1600 	},
1601 	{
1602 		"unpriv: spill/fill of ctx 2",
1603 		.insns = {
1604 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1605 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1606 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1607 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1608 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1609 				     BPF_FUNC_get_hash_recalc),
1610 			BPF_EXIT_INSN(),
1611 		},
1612 		.result = ACCEPT,
1613 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1614 	},
1615 	{
1616 		"unpriv: spill/fill of ctx 3",
1617 		.insns = {
1618 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1619 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1620 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1621 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1622 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1623 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1624 				     BPF_FUNC_get_hash_recalc),
1625 			BPF_EXIT_INSN(),
1626 		},
1627 		.result = REJECT,
1628 		.errstr = "R1 type=fp expected=ctx",
1629 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1630 	},
1631 	{
1632 		"unpriv: spill/fill of ctx 4",
1633 		.insns = {
1634 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1635 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1636 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1637 			BPF_MOV64_IMM(BPF_REG_0, 1),
1638 			BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
1639 				     BPF_REG_0, -8, 0),
1640 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1641 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1642 				     BPF_FUNC_get_hash_recalc),
1643 			BPF_EXIT_INSN(),
1644 		},
1645 		.result = REJECT,
1646 		.errstr = "R1 type=inv expected=ctx",
1647 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1648 	},
1649 	{
1650 		"unpriv: spill/fill of different pointers stx",
1651 		.insns = {
1652 			BPF_MOV64_IMM(BPF_REG_3, 42),
1653 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1654 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1655 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1656 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1657 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1658 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1659 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1660 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1661 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1662 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
1663 				    offsetof(struct __sk_buff, mark)),
1664 			BPF_MOV64_IMM(BPF_REG_0, 0),
1665 			BPF_EXIT_INSN(),
1666 		},
1667 		.result = REJECT,
1668 		.errstr = "same insn cannot be used with different pointers",
1669 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1670 	},
1671 	{
1672 		"unpriv: spill/fill of different pointers ldx",
1673 		.insns = {
1674 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1675 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1676 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1677 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1678 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
1679 				      -(__s32)offsetof(struct bpf_perf_event_data,
1680 						       sample_period) - 8),
1681 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1682 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1683 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1684 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1685 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
1686 				    offsetof(struct bpf_perf_event_data,
1687 					     sample_period)),
1688 			BPF_MOV64_IMM(BPF_REG_0, 0),
1689 			BPF_EXIT_INSN(),
1690 		},
1691 		.result = REJECT,
1692 		.errstr = "same insn cannot be used with different pointers",
1693 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
1694 	},
1695 	{
1696 		"unpriv: write pointer into map elem value",
1697 		.insns = {
1698 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1699 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1700 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1701 			BPF_LD_MAP_FD(BPF_REG_1, 0),
1702 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1703 				     BPF_FUNC_map_lookup_elem),
1704 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1705 			BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1706 			BPF_EXIT_INSN(),
1707 		},
1708 		.fixup_map1 = { 3 },
1709 		.errstr_unpriv = "R0 leaks addr",
1710 		.result_unpriv = REJECT,
1711 		.result = ACCEPT,
1712 	},
1713 	{
1714 		"unpriv: partial copy of pointer",
1715 		.insns = {
1716 			BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1717 			BPF_MOV64_IMM(BPF_REG_0, 0),
1718 			BPF_EXIT_INSN(),
1719 		},
1720 		.errstr_unpriv = "R10 partial copy",
1721 		.result_unpriv = REJECT,
1722 		.result = ACCEPT,
1723 	},
1724 	{
1725 		"unpriv: pass pointer to tail_call",
1726 		.insns = {
1727 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1728 			BPF_LD_MAP_FD(BPF_REG_2, 0),
1729 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1730 				     BPF_FUNC_tail_call),
1731 			BPF_MOV64_IMM(BPF_REG_0, 0),
1732 			BPF_EXIT_INSN(),
1733 		},
1734 		.fixup_prog = { 1 },
1735 		.errstr_unpriv = "R3 leaks addr into helper",
1736 		.result_unpriv = REJECT,
1737 		.result = ACCEPT,
1738 	},
1739 	{
1740 		"unpriv: cmp map pointer with zero",
1741 		.insns = {
1742 			BPF_MOV64_IMM(BPF_REG_1, 0),
1743 			BPF_LD_MAP_FD(BPF_REG_1, 0),
1744 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1745 			BPF_MOV64_IMM(BPF_REG_0, 0),
1746 			BPF_EXIT_INSN(),
1747 		},
1748 		.fixup_map1 = { 1 },
1749 		.errstr_unpriv = "R1 pointer comparison",
1750 		.result_unpriv = REJECT,
1751 		.result = ACCEPT,
1752 	},
1753 	{
1754 		"unpriv: write into frame pointer",
1755 		.insns = {
1756 			BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1757 			BPF_MOV64_IMM(BPF_REG_0, 0),
1758 			BPF_EXIT_INSN(),
1759 		},
1760 		.errstr = "frame pointer is read only",
1761 		.result = REJECT,
1762 	},
1763 	{
1764 		"unpriv: spill/fill frame pointer",
1765 		.insns = {
1766 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1767 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1768 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1769 			BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
1770 			BPF_MOV64_IMM(BPF_REG_0, 0),
1771 			BPF_EXIT_INSN(),
1772 		},
1773 		.errstr = "frame pointer is read only",
1774 		.result = REJECT,
1775 	},
1776 	{
1777 		"unpriv: cmp of frame pointer",
1778 		.insns = {
1779 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1780 			BPF_MOV64_IMM(BPF_REG_0, 0),
1781 			BPF_EXIT_INSN(),
1782 		},
1783 		.errstr_unpriv = "R10 pointer comparison",
1784 		.result_unpriv = REJECT,
1785 		.result = ACCEPT,
1786 	},
1787 	{
1788 		"unpriv: cmp of stack pointer",
1789 		.insns = {
1790 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1791 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1792 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1793 			BPF_MOV64_IMM(BPF_REG_0, 0),
1794 			BPF_EXIT_INSN(),
1795 		},
1796 		.errstr_unpriv = "R2 pointer comparison",
1797 		.result_unpriv = REJECT,
1798 		.result = ACCEPT,
1799 	},
1800 	{
1801 		"unpriv: obfuscate stack pointer",
1802 		.insns = {
1803 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1804 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1805 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1806 			BPF_MOV64_IMM(BPF_REG_0, 0),
1807 			BPF_EXIT_INSN(),
1808 		},
1809 		.errstr_unpriv = "R2 pointer arithmetic",
1810 		.result_unpriv = REJECT,
1811 		.result = ACCEPT,
1812 	},
1813 	{
1814 		"raw_stack: no skb_load_bytes",
1815 		.insns = {
1816 			BPF_MOV64_IMM(BPF_REG_2, 4),
1817 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1818 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1819 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1820 			BPF_MOV64_IMM(BPF_REG_4, 8),
1821 			/* Call to skb_load_bytes() omitted. */
1822 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1823 			BPF_EXIT_INSN(),
1824 		},
1825 		.result = REJECT,
1826 		.errstr = "invalid read from stack off -8+0 size 8",
1827 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1828 	},
1829 	{
1830 		"raw_stack: skb_load_bytes, negative len",
1831 		.insns = {
1832 			BPF_MOV64_IMM(BPF_REG_2, 4),
1833 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1834 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1835 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1836 			BPF_MOV64_IMM(BPF_REG_4, -8),
1837 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1838 				     BPF_FUNC_skb_load_bytes),
1839 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1840 			BPF_EXIT_INSN(),
1841 		},
1842 		.result = REJECT,
1843 		.errstr = "invalid stack type R3",
1844 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1845 	},
1846 	{
1847 		"raw_stack: skb_load_bytes, negative len 2",
1848 		.insns = {
1849 			BPF_MOV64_IMM(BPF_REG_2, 4),
1850 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1851 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1852 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1853 			BPF_MOV64_IMM(BPF_REG_4, ~0),
1854 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1855 				     BPF_FUNC_skb_load_bytes),
1856 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1857 			BPF_EXIT_INSN(),
1858 		},
1859 		.result = REJECT,
1860 		.errstr = "invalid stack type R3",
1861 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1862 	},
1863 	{
1864 		"raw_stack: skb_load_bytes, zero len",
1865 		.insns = {
1866 			BPF_MOV64_IMM(BPF_REG_2, 4),
1867 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1868 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1869 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1870 			BPF_MOV64_IMM(BPF_REG_4, 0),
1871 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1872 				     BPF_FUNC_skb_load_bytes),
1873 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1874 			BPF_EXIT_INSN(),
1875 		},
1876 		.result = REJECT,
1877 		.errstr = "invalid stack type R3",
1878 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1879 	},
1880 	{
1881 		"raw_stack: skb_load_bytes, no init",
1882 		.insns = {
1883 			BPF_MOV64_IMM(BPF_REG_2, 4),
1884 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1885 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1886 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1887 			BPF_MOV64_IMM(BPF_REG_4, 8),
1888 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1889 				     BPF_FUNC_skb_load_bytes),
1890 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1891 			BPF_EXIT_INSN(),
1892 		},
1893 		.result = ACCEPT,
1894 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1895 	},
1896 	{
1897 		"raw_stack: skb_load_bytes, init",
1898 		.insns = {
1899 			BPF_MOV64_IMM(BPF_REG_2, 4),
1900 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1901 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1902 			BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1903 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1904 			BPF_MOV64_IMM(BPF_REG_4, 8),
1905 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1906 				     BPF_FUNC_skb_load_bytes),
1907 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1908 			BPF_EXIT_INSN(),
1909 		},
1910 		.result = ACCEPT,
1911 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1912 	},
1913 	{
1914 		"raw_stack: skb_load_bytes, spilled regs around bounds",
1915 		.insns = {
1916 			BPF_MOV64_IMM(BPF_REG_2, 4),
1917 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1918 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1919 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1920 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1921 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1922 			BPF_MOV64_IMM(BPF_REG_4, 8),
1923 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1924 				     BPF_FUNC_skb_load_bytes),
1925 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1926 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
1927 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1928 				    offsetof(struct __sk_buff, mark)),
1929 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1930 				    offsetof(struct __sk_buff, priority)),
1931 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1932 			BPF_EXIT_INSN(),
1933 		},
1934 		.result = ACCEPT,
1935 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1936 	},
1937 	{
1938 		"raw_stack: skb_load_bytes, spilled regs corruption",
1939 		.insns = {
1940 			BPF_MOV64_IMM(BPF_REG_2, 4),
1941 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1942 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1943 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1944 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1945 			BPF_MOV64_IMM(BPF_REG_4, 8),
1946 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1947 				     BPF_FUNC_skb_load_bytes),
1948 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1949 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1950 				    offsetof(struct __sk_buff, mark)),
1951 			BPF_EXIT_INSN(),
1952 		},
1953 		.result = REJECT,
1954 		.errstr = "R0 invalid mem access 'inv'",
1955 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1956 	},
1957 	{
1958 		"raw_stack: skb_load_bytes, spilled regs corruption 2",
1959 		.insns = {
1960 			BPF_MOV64_IMM(BPF_REG_2, 4),
1961 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1962 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1963 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1964 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
1965 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1966 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1967 			BPF_MOV64_IMM(BPF_REG_4, 8),
1968 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1969 				     BPF_FUNC_skb_load_bytes),
1970 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1971 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
1972 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
1973 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1974 				    offsetof(struct __sk_buff, mark)),
1975 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1976 				    offsetof(struct __sk_buff, priority)),
1977 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1978 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1979 				    offsetof(struct __sk_buff, pkt_type)),
1980 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1981 			BPF_EXIT_INSN(),
1982 		},
1983 		.result = REJECT,
1984 		.errstr = "R3 invalid mem access 'inv'",
1985 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1986 	},
1987 	{
1988 		"raw_stack: skb_load_bytes, spilled regs + data",
1989 		.insns = {
1990 			BPF_MOV64_IMM(BPF_REG_2, 4),
1991 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1992 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1993 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1994 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
1995 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
1996 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1997 			BPF_MOV64_IMM(BPF_REG_4, 8),
1998 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1999 				     BPF_FUNC_skb_load_bytes),
2000 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2001 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
2002 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
2003 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2004 				    offsetof(struct __sk_buff, mark)),
2005 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2006 				    offsetof(struct __sk_buff, priority)),
2007 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2008 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2009 			BPF_EXIT_INSN(),
2010 		},
2011 		.result = ACCEPT,
2012 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2013 	},
2014 	{
2015 		"raw_stack: skb_load_bytes, invalid access 1",
2016 		.insns = {
2017 			BPF_MOV64_IMM(BPF_REG_2, 4),
2018 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2019 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2020 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2021 			BPF_MOV64_IMM(BPF_REG_4, 8),
2022 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2023 				     BPF_FUNC_skb_load_bytes),
2024 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2025 			BPF_EXIT_INSN(),
2026 		},
2027 		.result = REJECT,
2028 		.errstr = "invalid stack type R3 off=-513 access_size=8",
2029 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2030 	},
2031 	{
2032 		"raw_stack: skb_load_bytes, invalid access 2",
2033 		.insns = {
2034 			BPF_MOV64_IMM(BPF_REG_2, 4),
2035 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2036 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2037 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2038 			BPF_MOV64_IMM(BPF_REG_4, 8),
2039 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2040 				     BPF_FUNC_skb_load_bytes),
2041 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2042 			BPF_EXIT_INSN(),
2043 		},
2044 		.result = REJECT,
2045 		.errstr = "invalid stack type R3 off=-1 access_size=8",
2046 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2047 	},
2048 	{
2049 		"raw_stack: skb_load_bytes, invalid access 3",
2050 		.insns = {
2051 			BPF_MOV64_IMM(BPF_REG_2, 4),
2052 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2053 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2054 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2055 			BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
2056 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2057 				     BPF_FUNC_skb_load_bytes),
2058 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2059 			BPF_EXIT_INSN(),
2060 		},
2061 		.result = REJECT,
2062 		.errstr = "invalid stack type R3 off=-1 access_size=-1",
2063 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2064 	},
2065 	{
2066 		"raw_stack: skb_load_bytes, invalid access 4",
2067 		.insns = {
2068 			BPF_MOV64_IMM(BPF_REG_2, 4),
2069 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2070 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2071 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2072 			BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
2073 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2074 				     BPF_FUNC_skb_load_bytes),
2075 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2076 			BPF_EXIT_INSN(),
2077 		},
2078 		.result = REJECT,
2079 		.errstr = "invalid stack type R3 off=-1 access_size=2147483647",
2080 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2081 	},
2082 	{
2083 		"raw_stack: skb_load_bytes, invalid access 5",
2084 		.insns = {
2085 			BPF_MOV64_IMM(BPF_REG_2, 4),
2086 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2087 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2088 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2089 			BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
2090 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2091 				     BPF_FUNC_skb_load_bytes),
2092 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2093 			BPF_EXIT_INSN(),
2094 		},
2095 		.result = REJECT,
2096 		.errstr = "invalid stack type R3 off=-512 access_size=2147483647",
2097 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2098 	},
2099 	{
2100 		"raw_stack: skb_load_bytes, invalid access 6",
2101 		.insns = {
2102 			BPF_MOV64_IMM(BPF_REG_2, 4),
2103 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2104 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2105 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2106 			BPF_MOV64_IMM(BPF_REG_4, 0),
2107 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2108 				     BPF_FUNC_skb_load_bytes),
2109 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2110 			BPF_EXIT_INSN(),
2111 		},
2112 		.result = REJECT,
2113 		.errstr = "invalid stack type R3 off=-512 access_size=0",
2114 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2115 	},
2116 	{
2117 		"raw_stack: skb_load_bytes, large access",
2118 		.insns = {
2119 			BPF_MOV64_IMM(BPF_REG_2, 4),
2120 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2121 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2122 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2123 			BPF_MOV64_IMM(BPF_REG_4, 512),
2124 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2125 				     BPF_FUNC_skb_load_bytes),
2126 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2127 			BPF_EXIT_INSN(),
2128 		},
2129 		.result = ACCEPT,
2130 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2131 	},
2132 	{
2133 		"direct packet access: test1",
2134 		.insns = {
2135 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2136 				    offsetof(struct __sk_buff, data)),
2137 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2138 				    offsetof(struct __sk_buff, data_end)),
2139 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2140 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2141 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2142 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2143 			BPF_MOV64_IMM(BPF_REG_0, 0),
2144 			BPF_EXIT_INSN(),
2145 		},
2146 		.result = ACCEPT,
2147 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2148 	},
2149 	{
2150 		"direct packet access: test2",
2151 		.insns = {
2152 			BPF_MOV64_IMM(BPF_REG_0, 1),
2153 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2154 				    offsetof(struct __sk_buff, data_end)),
2155 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2156 				    offsetof(struct __sk_buff, data)),
2157 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2158 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2159 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2160 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2161 			BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2162 			BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2163 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2164 				    offsetof(struct __sk_buff, data)),
2165 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
2166 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
2167 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
2168 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
2169 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2170 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2171 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2172 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2173 				    offsetof(struct __sk_buff, data_end)),
2174 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2175 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2176 			BPF_MOV64_IMM(BPF_REG_0, 0),
2177 			BPF_EXIT_INSN(),
2178 		},
2179 		.result = ACCEPT,
2180 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2181 	},
2182 	{
2183 		"direct packet access: test3",
2184 		.insns = {
2185 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2186 				    offsetof(struct __sk_buff, data)),
2187 			BPF_MOV64_IMM(BPF_REG_0, 0),
2188 			BPF_EXIT_INSN(),
2189 		},
2190 		.errstr = "invalid bpf_context access off=76",
2191 		.result = REJECT,
2192 		.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2193 	},
2194 	{
2195 		"direct packet access: test4 (write)",
2196 		.insns = {
2197 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2198 				    offsetof(struct __sk_buff, data)),
2199 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2200 				    offsetof(struct __sk_buff, data_end)),
2201 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2202 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2203 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2204 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2205 			BPF_MOV64_IMM(BPF_REG_0, 0),
2206 			BPF_EXIT_INSN(),
2207 		},
2208 		.result = ACCEPT,
2209 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2210 	},
2211 	{
2212 		"direct packet access: test5 (pkt_end >= reg, good access)",
2213 		.insns = {
2214 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2215 				    offsetof(struct __sk_buff, data)),
2216 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2217 				    offsetof(struct __sk_buff, data_end)),
2218 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2219 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2220 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2221 			BPF_MOV64_IMM(BPF_REG_0, 1),
2222 			BPF_EXIT_INSN(),
2223 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2224 			BPF_MOV64_IMM(BPF_REG_0, 0),
2225 			BPF_EXIT_INSN(),
2226 		},
2227 		.result = ACCEPT,
2228 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2229 	},
2230 	{
2231 		"direct packet access: test6 (pkt_end >= reg, bad access)",
2232 		.insns = {
2233 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2234 				    offsetof(struct __sk_buff, data)),
2235 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2236 				    offsetof(struct __sk_buff, data_end)),
2237 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2238 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2239 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2240 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2241 			BPF_MOV64_IMM(BPF_REG_0, 1),
2242 			BPF_EXIT_INSN(),
2243 			BPF_MOV64_IMM(BPF_REG_0, 0),
2244 			BPF_EXIT_INSN(),
2245 		},
2246 		.errstr = "invalid access to packet",
2247 		.result = REJECT,
2248 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2249 	},
2250 	{
2251 		"direct packet access: test7 (pkt_end >= reg, both accesses)",
2252 		.insns = {
2253 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2254 				    offsetof(struct __sk_buff, data)),
2255 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2256 				    offsetof(struct __sk_buff, data_end)),
2257 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2258 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2259 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2260 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2261 			BPF_MOV64_IMM(BPF_REG_0, 1),
2262 			BPF_EXIT_INSN(),
2263 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2264 			BPF_MOV64_IMM(BPF_REG_0, 0),
2265 			BPF_EXIT_INSN(),
2266 		},
2267 		.errstr = "invalid access to packet",
2268 		.result = REJECT,
2269 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2270 	},
2271 	{
2272 		"direct packet access: test8 (double test, variant 1)",
2273 		.insns = {
2274 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2275 				    offsetof(struct __sk_buff, data)),
2276 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2277 				    offsetof(struct __sk_buff, data_end)),
2278 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2279 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2280 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2281 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2282 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2283 			BPF_MOV64_IMM(BPF_REG_0, 1),
2284 			BPF_EXIT_INSN(),
2285 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2286 			BPF_MOV64_IMM(BPF_REG_0, 0),
2287 			BPF_EXIT_INSN(),
2288 		},
2289 		.result = ACCEPT,
2290 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2291 	},
2292 	{
2293 		"direct packet access: test9 (double test, variant 2)",
2294 		.insns = {
2295 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2296 				    offsetof(struct __sk_buff, data)),
2297 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2298 				    offsetof(struct __sk_buff, data_end)),
2299 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2300 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2301 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2302 			BPF_MOV64_IMM(BPF_REG_0, 1),
2303 			BPF_EXIT_INSN(),
2304 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2305 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2306 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2307 			BPF_MOV64_IMM(BPF_REG_0, 0),
2308 			BPF_EXIT_INSN(),
2309 		},
2310 		.result = ACCEPT,
2311 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2312 	},
2313 	{
2314 		"direct packet access: test10 (write invalid)",
2315 		.insns = {
2316 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2317 				    offsetof(struct __sk_buff, data)),
2318 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2319 				    offsetof(struct __sk_buff, data_end)),
2320 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2321 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2322 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2323 			BPF_MOV64_IMM(BPF_REG_0, 0),
2324 			BPF_EXIT_INSN(),
2325 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2326 			BPF_MOV64_IMM(BPF_REG_0, 0),
2327 			BPF_EXIT_INSN(),
2328 		},
2329 		.errstr = "invalid access to packet",
2330 		.result = REJECT,
2331 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2332 	},
2333 	{
2334 		"direct packet access: test11 (shift, good access)",
2335 		.insns = {
2336 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2337 				    offsetof(struct __sk_buff, data)),
2338 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2339 				    offsetof(struct __sk_buff, data_end)),
2340 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2341 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2342 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2343 			BPF_MOV64_IMM(BPF_REG_3, 144),
2344 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2345 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2346 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2347 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2348 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2349 			BPF_MOV64_IMM(BPF_REG_0, 1),
2350 			BPF_EXIT_INSN(),
2351 			BPF_MOV64_IMM(BPF_REG_0, 0),
2352 			BPF_EXIT_INSN(),
2353 		},
2354 		.result = ACCEPT,
2355 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2356 	},
2357 	{
2358 		"direct packet access: test12 (and, good access)",
2359 		.insns = {
2360 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2361 				    offsetof(struct __sk_buff, data)),
2362 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2363 				    offsetof(struct __sk_buff, data_end)),
2364 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2365 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2366 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2367 			BPF_MOV64_IMM(BPF_REG_3, 144),
2368 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2369 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2370 			BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2371 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2372 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2373 			BPF_MOV64_IMM(BPF_REG_0, 1),
2374 			BPF_EXIT_INSN(),
2375 			BPF_MOV64_IMM(BPF_REG_0, 0),
2376 			BPF_EXIT_INSN(),
2377 		},
2378 		.result = ACCEPT,
2379 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2380 	},
2381 	{
2382 		"direct packet access: test13 (branches, good access)",
2383 		.insns = {
2384 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2385 				    offsetof(struct __sk_buff, data)),
2386 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2387 				    offsetof(struct __sk_buff, data_end)),
2388 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2389 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2390 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2391 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2392 				    offsetof(struct __sk_buff, mark)),
2393 			BPF_MOV64_IMM(BPF_REG_4, 1),
2394 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2395 			BPF_MOV64_IMM(BPF_REG_3, 14),
2396 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2397 			BPF_MOV64_IMM(BPF_REG_3, 24),
2398 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2399 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2400 			BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2401 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2402 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2403 			BPF_MOV64_IMM(BPF_REG_0, 1),
2404 			BPF_EXIT_INSN(),
2405 			BPF_MOV64_IMM(BPF_REG_0, 0),
2406 			BPF_EXIT_INSN(),
2407 		},
2408 		.result = ACCEPT,
2409 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2410 	},
2411 	{
2412 		"direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2413 		.insns = {
2414 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2415 				    offsetof(struct __sk_buff, data)),
2416 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2417 				    offsetof(struct __sk_buff, data_end)),
2418 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2419 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2420 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2421 			BPF_MOV64_IMM(BPF_REG_5, 12),
2422 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2423 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2424 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2425 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2426 			BPF_MOV64_IMM(BPF_REG_0, 1),
2427 			BPF_EXIT_INSN(),
2428 			BPF_MOV64_IMM(BPF_REG_0, 0),
2429 			BPF_EXIT_INSN(),
2430 		},
2431 		.result = ACCEPT,
2432 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2433 	},
2434 	{
2435 		"helper access to packet: test1, valid packet_ptr range",
2436 		.insns = {
2437 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2438 				    offsetof(struct xdp_md, data)),
2439 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2440 				    offsetof(struct xdp_md, data_end)),
2441 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2442 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2443 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2444 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2445 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2446 			BPF_MOV64_IMM(BPF_REG_4, 0),
2447 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2448 				     BPF_FUNC_map_update_elem),
2449 			BPF_MOV64_IMM(BPF_REG_0, 0),
2450 			BPF_EXIT_INSN(),
2451 		},
2452 		.fixup_map1 = { 5 },
2453 		.result_unpriv = ACCEPT,
2454 		.result = ACCEPT,
2455 		.prog_type = BPF_PROG_TYPE_XDP,
2456 	},
2457 	{
2458 		"helper access to packet: test2, unchecked packet_ptr",
2459 		.insns = {
2460 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2461 				    offsetof(struct xdp_md, data)),
2462 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2463 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2464 				     BPF_FUNC_map_lookup_elem),
2465 			BPF_MOV64_IMM(BPF_REG_0, 0),
2466 			BPF_EXIT_INSN(),
2467 		},
2468 		.fixup_map1 = { 1 },
2469 		.result = REJECT,
2470 		.errstr = "invalid access to packet",
2471 		.prog_type = BPF_PROG_TYPE_XDP,
2472 	},
2473 	{
2474 		"helper access to packet: test3, variable add",
2475 		.insns = {
2476 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2477 					offsetof(struct xdp_md, data)),
2478 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2479 					offsetof(struct xdp_md, data_end)),
2480 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2481 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2482 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2483 			BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2484 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2485 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2486 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2487 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2488 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2489 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2490 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
2491 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2492 				     BPF_FUNC_map_lookup_elem),
2493 			BPF_MOV64_IMM(BPF_REG_0, 0),
2494 			BPF_EXIT_INSN(),
2495 		},
2496 		.fixup_map1 = { 11 },
2497 		.result = ACCEPT,
2498 		.prog_type = BPF_PROG_TYPE_XDP,
2499 	},
2500 	{
2501 		"helper access to packet: test4, packet_ptr with bad range",
2502 		.insns = {
2503 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2504 				    offsetof(struct xdp_md, data)),
2505 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2506 				    offsetof(struct xdp_md, data_end)),
2507 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2508 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2509 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2510 			BPF_MOV64_IMM(BPF_REG_0, 0),
2511 			BPF_EXIT_INSN(),
2512 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2513 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2514 				     BPF_FUNC_map_lookup_elem),
2515 			BPF_MOV64_IMM(BPF_REG_0, 0),
2516 			BPF_EXIT_INSN(),
2517 		},
2518 		.fixup_map1 = { 7 },
2519 		.result = REJECT,
2520 		.errstr = "invalid access to packet",
2521 		.prog_type = BPF_PROG_TYPE_XDP,
2522 	},
2523 	{
2524 		"helper access to packet: test5, packet_ptr with too short range",
2525 		.insns = {
2526 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2527 				    offsetof(struct xdp_md, data)),
2528 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2529 				    offsetof(struct xdp_md, data_end)),
2530 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2531 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2532 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2533 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2534 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2535 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2536 				     BPF_FUNC_map_lookup_elem),
2537 			BPF_MOV64_IMM(BPF_REG_0, 0),
2538 			BPF_EXIT_INSN(),
2539 		},
2540 		.fixup_map1 = { 6 },
2541 		.result = REJECT,
2542 		.errstr = "invalid access to packet",
2543 		.prog_type = BPF_PROG_TYPE_XDP,
2544 	},
2545 	{
2546 		"helper access to packet: test6, cls valid packet_ptr range",
2547 		.insns = {
2548 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2549 				    offsetof(struct __sk_buff, data)),
2550 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2551 				    offsetof(struct __sk_buff, data_end)),
2552 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2553 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2554 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2555 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2556 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2557 			BPF_MOV64_IMM(BPF_REG_4, 0),
2558 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2559 				     BPF_FUNC_map_update_elem),
2560 			BPF_MOV64_IMM(BPF_REG_0, 0),
2561 			BPF_EXIT_INSN(),
2562 		},
2563 		.fixup_map1 = { 5 },
2564 		.result = ACCEPT,
2565 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2566 	},
2567 	{
2568 		"helper access to packet: test7, cls unchecked packet_ptr",
2569 		.insns = {
2570 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2571 				    offsetof(struct __sk_buff, data)),
2572 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2573 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2574 				     BPF_FUNC_map_lookup_elem),
2575 			BPF_MOV64_IMM(BPF_REG_0, 0),
2576 			BPF_EXIT_INSN(),
2577 		},
2578 		.fixup_map1 = { 1 },
2579 		.result = REJECT,
2580 		.errstr = "invalid access to packet",
2581 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2582 	},
2583 	{
2584 		"helper access to packet: test8, cls variable add",
2585 		.insns = {
2586 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2587 					offsetof(struct __sk_buff, data)),
2588 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2589 					offsetof(struct __sk_buff, data_end)),
2590 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2591 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2592 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2593 			BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2594 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2595 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2596 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2597 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2598 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2599 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2600 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
2601 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2602 				     BPF_FUNC_map_lookup_elem),
2603 			BPF_MOV64_IMM(BPF_REG_0, 0),
2604 			BPF_EXIT_INSN(),
2605 		},
2606 		.fixup_map1 = { 11 },
2607 		.result = ACCEPT,
2608 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2609 	},
2610 	{
2611 		"helper access to packet: test9, cls packet_ptr with bad range",
2612 		.insns = {
2613 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2614 				    offsetof(struct __sk_buff, data)),
2615 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2616 				    offsetof(struct __sk_buff, data_end)),
2617 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2618 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2619 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2620 			BPF_MOV64_IMM(BPF_REG_0, 0),
2621 			BPF_EXIT_INSN(),
2622 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2623 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2624 				     BPF_FUNC_map_lookup_elem),
2625 			BPF_MOV64_IMM(BPF_REG_0, 0),
2626 			BPF_EXIT_INSN(),
2627 		},
2628 		.fixup_map1 = { 7 },
2629 		.result = REJECT,
2630 		.errstr = "invalid access to packet",
2631 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2632 	},
2633 	{
2634 		"helper access to packet: test10, cls packet_ptr with too short range",
2635 		.insns = {
2636 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2637 				    offsetof(struct __sk_buff, data)),
2638 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2639 				    offsetof(struct __sk_buff, data_end)),
2640 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2641 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2642 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2643 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2644 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2645 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2646 				     BPF_FUNC_map_lookup_elem),
2647 			BPF_MOV64_IMM(BPF_REG_0, 0),
2648 			BPF_EXIT_INSN(),
2649 		},
2650 		.fixup_map1 = { 6 },
2651 		.result = REJECT,
2652 		.errstr = "invalid access to packet",
2653 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2654 	},
2655 	{
2656 		"helper access to packet: test11, cls unsuitable helper 1",
2657 		.insns = {
2658 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2659 				    offsetof(struct __sk_buff, data)),
2660 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2661 				    offsetof(struct __sk_buff, data_end)),
2662 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2663 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2664 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
2665 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
2666 			BPF_MOV64_IMM(BPF_REG_2, 0),
2667 			BPF_MOV64_IMM(BPF_REG_4, 42),
2668 			BPF_MOV64_IMM(BPF_REG_5, 0),
2669 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2670 				     BPF_FUNC_skb_store_bytes),
2671 			BPF_MOV64_IMM(BPF_REG_0, 0),
2672 			BPF_EXIT_INSN(),
2673 		},
2674 		.result = REJECT,
2675 		.errstr = "helper access to the packet",
2676 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2677 	},
2678 	{
2679 		"helper access to packet: test12, cls unsuitable helper 2",
2680 		.insns = {
2681 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2682 				    offsetof(struct __sk_buff, data)),
2683 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2684 				    offsetof(struct __sk_buff, data_end)),
2685 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2686 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
2687 			BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
2688 			BPF_MOV64_IMM(BPF_REG_2, 0),
2689 			BPF_MOV64_IMM(BPF_REG_4, 4),
2690 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2691 				     BPF_FUNC_skb_load_bytes),
2692 			BPF_MOV64_IMM(BPF_REG_0, 0),
2693 			BPF_EXIT_INSN(),
2694 		},
2695 		.result = REJECT,
2696 		.errstr = "helper access to the packet",
2697 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2698 	},
2699 	{
2700 		"helper access to packet: test13, cls helper ok",
2701 		.insns = {
2702 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2703 				    offsetof(struct __sk_buff, data)),
2704 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2705 				    offsetof(struct __sk_buff, data_end)),
2706 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2707 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2708 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2709 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2710 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2711 			BPF_MOV64_IMM(BPF_REG_2, 4),
2712 			BPF_MOV64_IMM(BPF_REG_3, 0),
2713 			BPF_MOV64_IMM(BPF_REG_4, 0),
2714 			BPF_MOV64_IMM(BPF_REG_5, 0),
2715 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2716 				     BPF_FUNC_csum_diff),
2717 			BPF_MOV64_IMM(BPF_REG_0, 0),
2718 			BPF_EXIT_INSN(),
2719 		},
2720 		.result = ACCEPT,
2721 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2722 	},
2723 	{
2724 		"helper access to packet: test14, cls helper fail sub",
2725 		.insns = {
2726 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2727 				    offsetof(struct __sk_buff, data)),
2728 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2729 				    offsetof(struct __sk_buff, data_end)),
2730 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2731 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2732 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2733 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2734 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2735 			BPF_MOV64_IMM(BPF_REG_2, 4),
2736 			BPF_MOV64_IMM(BPF_REG_3, 0),
2737 			BPF_MOV64_IMM(BPF_REG_4, 0),
2738 			BPF_MOV64_IMM(BPF_REG_5, 0),
2739 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2740 				     BPF_FUNC_csum_diff),
2741 			BPF_MOV64_IMM(BPF_REG_0, 0),
2742 			BPF_EXIT_INSN(),
2743 		},
2744 		.result = REJECT,
2745 		.errstr = "type=inv expected=fp",
2746 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2747 	},
2748 	{
2749 		"helper access to packet: test15, cls helper fail range 1",
2750 		.insns = {
2751 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2752 				    offsetof(struct __sk_buff, data)),
2753 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2754 				    offsetof(struct __sk_buff, data_end)),
2755 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2756 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2757 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2758 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2759 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2760 			BPF_MOV64_IMM(BPF_REG_2, 8),
2761 			BPF_MOV64_IMM(BPF_REG_3, 0),
2762 			BPF_MOV64_IMM(BPF_REG_4, 0),
2763 			BPF_MOV64_IMM(BPF_REG_5, 0),
2764 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2765 				     BPF_FUNC_csum_diff),
2766 			BPF_MOV64_IMM(BPF_REG_0, 0),
2767 			BPF_EXIT_INSN(),
2768 		},
2769 		.result = REJECT,
2770 		.errstr = "invalid access to packet",
2771 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2772 	},
2773 	{
2774 		"helper access to packet: test16, cls helper fail range 2",
2775 		.insns = {
2776 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2777 				    offsetof(struct __sk_buff, data)),
2778 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2779 				    offsetof(struct __sk_buff, data_end)),
2780 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2781 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2782 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2783 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2784 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2785 			BPF_MOV64_IMM(BPF_REG_2, -9),
2786 			BPF_MOV64_IMM(BPF_REG_3, 0),
2787 			BPF_MOV64_IMM(BPF_REG_4, 0),
2788 			BPF_MOV64_IMM(BPF_REG_5, 0),
2789 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2790 				     BPF_FUNC_csum_diff),
2791 			BPF_MOV64_IMM(BPF_REG_0, 0),
2792 			BPF_EXIT_INSN(),
2793 		},
2794 		.result = REJECT,
2795 		.errstr = "invalid access to packet",
2796 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2797 	},
2798 	{
2799 		"helper access to packet: test17, cls helper fail range 3",
2800 		.insns = {
2801 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2802 				    offsetof(struct __sk_buff, data)),
2803 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2804 				    offsetof(struct __sk_buff, data_end)),
2805 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2806 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2807 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2808 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2809 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2810 			BPF_MOV64_IMM(BPF_REG_2, ~0),
2811 			BPF_MOV64_IMM(BPF_REG_3, 0),
2812 			BPF_MOV64_IMM(BPF_REG_4, 0),
2813 			BPF_MOV64_IMM(BPF_REG_5, 0),
2814 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2815 				     BPF_FUNC_csum_diff),
2816 			BPF_MOV64_IMM(BPF_REG_0, 0),
2817 			BPF_EXIT_INSN(),
2818 		},
2819 		.result = REJECT,
2820 		.errstr = "invalid access to packet",
2821 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2822 	},
2823 	{
2824 		"helper access to packet: test18, cls helper fail range zero",
2825 		.insns = {
2826 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2827 				    offsetof(struct __sk_buff, data)),
2828 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2829 				    offsetof(struct __sk_buff, data_end)),
2830 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2831 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2832 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2833 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2834 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2835 			BPF_MOV64_IMM(BPF_REG_2, 0),
2836 			BPF_MOV64_IMM(BPF_REG_3, 0),
2837 			BPF_MOV64_IMM(BPF_REG_4, 0),
2838 			BPF_MOV64_IMM(BPF_REG_5, 0),
2839 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2840 				     BPF_FUNC_csum_diff),
2841 			BPF_MOV64_IMM(BPF_REG_0, 0),
2842 			BPF_EXIT_INSN(),
2843 		},
2844 		.result = REJECT,
2845 		.errstr = "invalid access to packet",
2846 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2847 	},
2848 	{
2849 		"helper access to packet: test19, pkt end as input",
2850 		.insns = {
2851 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2852 				    offsetof(struct __sk_buff, data)),
2853 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2854 				    offsetof(struct __sk_buff, data_end)),
2855 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2856 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2857 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2858 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2859 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2860 			BPF_MOV64_IMM(BPF_REG_2, 4),
2861 			BPF_MOV64_IMM(BPF_REG_3, 0),
2862 			BPF_MOV64_IMM(BPF_REG_4, 0),
2863 			BPF_MOV64_IMM(BPF_REG_5, 0),
2864 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2865 				     BPF_FUNC_csum_diff),
2866 			BPF_MOV64_IMM(BPF_REG_0, 0),
2867 			BPF_EXIT_INSN(),
2868 		},
2869 		.result = REJECT,
2870 		.errstr = "R1 type=pkt_end expected=fp",
2871 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2872 	},
2873 	{
2874 		"helper access to packet: test20, wrong reg",
2875 		.insns = {
2876 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2877 				    offsetof(struct __sk_buff, data)),
2878 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2879 				    offsetof(struct __sk_buff, data_end)),
2880 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2881 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2882 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2883 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2884 			BPF_MOV64_IMM(BPF_REG_2, 4),
2885 			BPF_MOV64_IMM(BPF_REG_3, 0),
2886 			BPF_MOV64_IMM(BPF_REG_4, 0),
2887 			BPF_MOV64_IMM(BPF_REG_5, 0),
2888 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2889 				     BPF_FUNC_csum_diff),
2890 			BPF_MOV64_IMM(BPF_REG_0, 0),
2891 			BPF_EXIT_INSN(),
2892 		},
2893 		.result = REJECT,
2894 		.errstr = "invalid access to packet",
2895 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2896 	},
2897 	{
2898 		"valid map access into an array with a constant",
2899 		.insns = {
2900 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2901 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2902 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2903 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2904 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2905 				     BPF_FUNC_map_lookup_elem),
2906 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2907 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2908 				   offsetof(struct test_val, foo)),
2909 			BPF_EXIT_INSN(),
2910 		},
2911 		.fixup_map2 = { 3 },
2912 		.errstr_unpriv = "R0 leaks addr",
2913 		.result_unpriv = REJECT,
2914 		.result = ACCEPT,
2915 	},
2916 	{
2917 		"valid map access into an array with a register",
2918 		.insns = {
2919 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2920 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2921 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2922 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2923 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2924 				     BPF_FUNC_map_lookup_elem),
2925 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2926 			BPF_MOV64_IMM(BPF_REG_1, 4),
2927 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2928 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2929 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2930 				   offsetof(struct test_val, foo)),
2931 			BPF_EXIT_INSN(),
2932 		},
2933 		.fixup_map2 = { 3 },
2934 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
2935 		.result_unpriv = REJECT,
2936 		.result = ACCEPT,
2937 	},
2938 	{
2939 		"valid map access into an array with a variable",
2940 		.insns = {
2941 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2942 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2943 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2944 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2945 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2946 				     BPF_FUNC_map_lookup_elem),
2947 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2948 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2949 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2950 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2951 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2952 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2953 				   offsetof(struct test_val, foo)),
2954 			BPF_EXIT_INSN(),
2955 		},
2956 		.fixup_map2 = { 3 },
2957 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
2958 		.result_unpriv = REJECT,
2959 		.result = ACCEPT,
2960 	},
2961 	{
2962 		"valid map access into an array with a signed variable",
2963 		.insns = {
2964 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2965 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2966 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2967 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2968 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2969 				     BPF_FUNC_map_lookup_elem),
2970 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2971 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2972 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2973 			BPF_MOV32_IMM(BPF_REG_1, 0),
2974 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2975 			BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2976 			BPF_MOV32_IMM(BPF_REG_1, 0),
2977 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2978 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2979 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2980 				   offsetof(struct test_val, foo)),
2981 			BPF_EXIT_INSN(),
2982 		},
2983 		.fixup_map2 = { 3 },
2984 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
2985 		.result_unpriv = REJECT,
2986 		.result = ACCEPT,
2987 	},
2988 	{
2989 		"invalid map access into an array with a constant",
2990 		.insns = {
2991 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2992 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2993 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2994 			BPF_LD_MAP_FD(BPF_REG_1, 0),
2995 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2996 				     BPF_FUNC_map_lookup_elem),
2997 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2998 			BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
2999 				   offsetof(struct test_val, foo)),
3000 			BPF_EXIT_INSN(),
3001 		},
3002 		.fixup_map2 = { 3 },
3003 		.errstr = "invalid access to map value, value_size=48 off=48 size=8",
3004 		.result = REJECT,
3005 	},
3006 	{
3007 		"invalid map access into an array with a register",
3008 		.insns = {
3009 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3010 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3011 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3012 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3013 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3014 				     BPF_FUNC_map_lookup_elem),
3015 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3016 			BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3017 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3018 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3019 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3020 				   offsetof(struct test_val, foo)),
3021 			BPF_EXIT_INSN(),
3022 		},
3023 		.fixup_map2 = { 3 },
3024 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3025 		.errstr = "R0 min value is outside of the array range",
3026 		.result_unpriv = REJECT,
3027 		.result = REJECT,
3028 	},
3029 	{
3030 		"invalid map access into an array with a variable",
3031 		.insns = {
3032 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3033 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3034 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3035 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3036 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3037 				     BPF_FUNC_map_lookup_elem),
3038 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3039 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3040 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3041 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3042 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3043 				   offsetof(struct test_val, foo)),
3044 			BPF_EXIT_INSN(),
3045 		},
3046 		.fixup_map2 = { 3 },
3047 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3048 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3049 		.result_unpriv = REJECT,
3050 		.result = REJECT,
3051 	},
3052 	{
3053 		"invalid map access into an array with no floor check",
3054 		.insns = {
3055 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3056 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3057 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3058 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3059 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3060 				     BPF_FUNC_map_lookup_elem),
3061 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3062 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3063 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3064 			BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3065 			BPF_MOV32_IMM(BPF_REG_1, 0),
3066 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3067 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3068 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3069 				   offsetof(struct test_val, foo)),
3070 			BPF_EXIT_INSN(),
3071 		},
3072 		.fixup_map2 = { 3 },
3073 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3074 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3075 		.result_unpriv = REJECT,
3076 		.result = REJECT,
3077 	},
3078 	{
3079 		"invalid map access into an array with a invalid max check",
3080 		.insns = {
3081 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3082 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3083 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3084 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3085 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3086 				     BPF_FUNC_map_lookup_elem),
3087 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3088 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3089 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3090 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3091 			BPF_MOV32_IMM(BPF_REG_1, 0),
3092 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3093 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3094 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3095 				   offsetof(struct test_val, foo)),
3096 			BPF_EXIT_INSN(),
3097 		},
3098 		.fixup_map2 = { 3 },
3099 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3100 		.errstr = "invalid access to map value, value_size=48 off=44 size=8",
3101 		.result_unpriv = REJECT,
3102 		.result = REJECT,
3103 	},
3104 	{
3105 		"invalid map access into an array with a invalid max check",
3106 		.insns = {
3107 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3108 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3109 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3110 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3111 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3112 				     BPF_FUNC_map_lookup_elem),
3113 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3114 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3115 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3116 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3117 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3118 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3119 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3120 				     BPF_FUNC_map_lookup_elem),
3121 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3122 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
3123 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3124 				    offsetof(struct test_val, foo)),
3125 			BPF_EXIT_INSN(),
3126 		},
3127 		.fixup_map2 = { 3, 11 },
3128 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3129 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3130 		.result_unpriv = REJECT,
3131 		.result = REJECT,
3132 	},
3133 	{
3134 		"multiple registers share map_lookup_elem result",
3135 		.insns = {
3136 			BPF_MOV64_IMM(BPF_REG_1, 10),
3137 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3138 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3139 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3140 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3141 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3142 				     BPF_FUNC_map_lookup_elem),
3143 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3144 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3145 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3146 			BPF_EXIT_INSN(),
3147 		},
3148 		.fixup_map1 = { 4 },
3149 		.result = ACCEPT,
3150 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
3151 	},
3152 	{
3153 		"invalid memory access with multiple map_lookup_elem calls",
3154 		.insns = {
3155 			BPF_MOV64_IMM(BPF_REG_1, 10),
3156 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3157 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3158 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3159 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3160 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3161 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3162 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3163 				     BPF_FUNC_map_lookup_elem),
3164 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3165 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3166 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3167 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3168 				     BPF_FUNC_map_lookup_elem),
3169 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3170 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3171 			BPF_EXIT_INSN(),
3172 		},
3173 		.fixup_map1 = { 4 },
3174 		.result = REJECT,
3175 		.errstr = "R4 !read_ok",
3176 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
3177 	},
3178 	{
3179 		"valid indirect map_lookup_elem access with 2nd lookup in branch",
3180 		.insns = {
3181 			BPF_MOV64_IMM(BPF_REG_1, 10),
3182 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3183 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3184 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3185 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3186 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3187 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3188 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3189 				     BPF_FUNC_map_lookup_elem),
3190 			BPF_MOV64_IMM(BPF_REG_2, 10),
3191 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
3192 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3193 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3194 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3195 				     BPF_FUNC_map_lookup_elem),
3196 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3197 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3198 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3199 			BPF_EXIT_INSN(),
3200 		},
3201 		.fixup_map1 = { 4 },
3202 		.result = ACCEPT,
3203 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
3204 	},
3205 	{
3206 		"multiple registers share map_lookup_elem bad reg type",
3207 		.insns = {
3208 			BPF_MOV64_IMM(BPF_REG_1, 10),
3209 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3210 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3211 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3212 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3213 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3214 				     BPF_FUNC_map_lookup_elem),
3215 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
3216 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
3217 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3218 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3219 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3220 			BPF_MOV64_IMM(BPF_REG_1, 1),
3221 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3222 			BPF_MOV64_IMM(BPF_REG_1, 2),
3223 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1),
3224 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 0),
3225 			BPF_MOV64_IMM(BPF_REG_1, 3),
3226 			BPF_EXIT_INSN(),
3227 		},
3228 		.fixup_map1 = { 4 },
3229 		.result = REJECT,
3230 		.errstr = "R3 invalid mem access 'inv'",
3231 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
3232 	},
3233 	{
3234 		"invalid map access from else condition",
3235 		.insns = {
3236 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3237 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3238 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3239 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3240 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
3241 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3242 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3243 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
3244 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
3245 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3246 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3247 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
3248 			BPF_EXIT_INSN(),
3249 		},
3250 		.fixup_map2 = { 3 },
3251 		.errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
3252 		.result = REJECT,
3253 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3254 		.result_unpriv = REJECT,
3255 	},
3256 	{
3257 		"constant register |= constant should keep constant type",
3258 		.insns = {
3259 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3260 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3261 			BPF_MOV64_IMM(BPF_REG_2, 34),
3262 			BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
3263 			BPF_MOV64_IMM(BPF_REG_3, 0),
3264 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3265 			BPF_EXIT_INSN(),
3266 		},
3267 		.result = ACCEPT,
3268 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3269 	},
3270 	{
3271 		"constant register |= constant should not bypass stack boundary checks",
3272 		.insns = {
3273 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3274 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3275 			BPF_MOV64_IMM(BPF_REG_2, 34),
3276 			BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
3277 			BPF_MOV64_IMM(BPF_REG_3, 0),
3278 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3279 			BPF_EXIT_INSN(),
3280 		},
3281 		.errstr = "invalid stack type R1 off=-48 access_size=58",
3282 		.result = REJECT,
3283 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3284 	},
3285 	{
3286 		"constant register |= constant register should keep constant type",
3287 		.insns = {
3288 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3289 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3290 			BPF_MOV64_IMM(BPF_REG_2, 34),
3291 			BPF_MOV64_IMM(BPF_REG_4, 13),
3292 			BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3293 			BPF_MOV64_IMM(BPF_REG_3, 0),
3294 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3295 			BPF_EXIT_INSN(),
3296 		},
3297 		.result = ACCEPT,
3298 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3299 	},
3300 	{
3301 		"constant register |= constant register should not bypass stack boundary checks",
3302 		.insns = {
3303 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3304 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3305 			BPF_MOV64_IMM(BPF_REG_2, 34),
3306 			BPF_MOV64_IMM(BPF_REG_4, 24),
3307 			BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3308 			BPF_MOV64_IMM(BPF_REG_3, 0),
3309 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3310 			BPF_EXIT_INSN(),
3311 		},
3312 		.errstr = "invalid stack type R1 off=-48 access_size=58",
3313 		.result = REJECT,
3314 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3315 	},
3316 	{
3317 		"invalid direct packet write for LWT_IN",
3318 		.insns = {
3319 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3320 				    offsetof(struct __sk_buff, data)),
3321 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3322 				    offsetof(struct __sk_buff, data_end)),
3323 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3324 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3325 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3326 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3327 			BPF_MOV64_IMM(BPF_REG_0, 0),
3328 			BPF_EXIT_INSN(),
3329 		},
3330 		.errstr = "cannot write into packet",
3331 		.result = REJECT,
3332 		.prog_type = BPF_PROG_TYPE_LWT_IN,
3333 	},
3334 	{
3335 		"invalid direct packet write for LWT_OUT",
3336 		.insns = {
3337 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3338 				    offsetof(struct __sk_buff, data)),
3339 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3340 				    offsetof(struct __sk_buff, data_end)),
3341 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3342 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3343 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3344 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3345 			BPF_MOV64_IMM(BPF_REG_0, 0),
3346 			BPF_EXIT_INSN(),
3347 		},
3348 		.errstr = "cannot write into packet",
3349 		.result = REJECT,
3350 		.prog_type = BPF_PROG_TYPE_LWT_OUT,
3351 	},
3352 	{
3353 		"direct packet write for LWT_XMIT",
3354 		.insns = {
3355 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3356 				    offsetof(struct __sk_buff, data)),
3357 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3358 				    offsetof(struct __sk_buff, data_end)),
3359 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3360 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3361 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3362 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3363 			BPF_MOV64_IMM(BPF_REG_0, 0),
3364 			BPF_EXIT_INSN(),
3365 		},
3366 		.result = ACCEPT,
3367 		.prog_type = BPF_PROG_TYPE_LWT_XMIT,
3368 	},
3369 	{
3370 		"direct packet read for LWT_IN",
3371 		.insns = {
3372 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3373 				    offsetof(struct __sk_buff, data)),
3374 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3375 				    offsetof(struct __sk_buff, data_end)),
3376 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3377 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3378 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3379 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3380 			BPF_MOV64_IMM(BPF_REG_0, 0),
3381 			BPF_EXIT_INSN(),
3382 		},
3383 		.result = ACCEPT,
3384 		.prog_type = BPF_PROG_TYPE_LWT_IN,
3385 	},
3386 	{
3387 		"direct packet read for LWT_OUT",
3388 		.insns = {
3389 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3390 				    offsetof(struct __sk_buff, data)),
3391 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3392 				    offsetof(struct __sk_buff, data_end)),
3393 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3394 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3395 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3396 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3397 			BPF_MOV64_IMM(BPF_REG_0, 0),
3398 			BPF_EXIT_INSN(),
3399 		},
3400 		.result = ACCEPT,
3401 		.prog_type = BPF_PROG_TYPE_LWT_OUT,
3402 	},
3403 	{
3404 		"direct packet read for LWT_XMIT",
3405 		.insns = {
3406 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3407 				    offsetof(struct __sk_buff, data)),
3408 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3409 				    offsetof(struct __sk_buff, data_end)),
3410 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3411 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3412 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3413 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3414 			BPF_MOV64_IMM(BPF_REG_0, 0),
3415 			BPF_EXIT_INSN(),
3416 		},
3417 		.result = ACCEPT,
3418 		.prog_type = BPF_PROG_TYPE_LWT_XMIT,
3419 	},
3420 	{
3421 		"invalid access of tc_classid for LWT_IN",
3422 		.insns = {
3423 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3424 				    offsetof(struct __sk_buff, tc_classid)),
3425 			BPF_EXIT_INSN(),
3426 		},
3427 		.result = REJECT,
3428 		.errstr = "invalid bpf_context access",
3429 	},
3430 	{
3431 		"invalid access of tc_classid for LWT_OUT",
3432 		.insns = {
3433 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3434 				    offsetof(struct __sk_buff, tc_classid)),
3435 			BPF_EXIT_INSN(),
3436 		},
3437 		.result = REJECT,
3438 		.errstr = "invalid bpf_context access",
3439 	},
3440 	{
3441 		"invalid access of tc_classid for LWT_XMIT",
3442 		.insns = {
3443 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3444 				    offsetof(struct __sk_buff, tc_classid)),
3445 			BPF_EXIT_INSN(),
3446 		},
3447 		.result = REJECT,
3448 		.errstr = "invalid bpf_context access",
3449 	},
3450 	{
3451 		"helper access to map: full range",
3452 		.insns = {
3453 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3454 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3455 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3456 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3457 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3458 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3459 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3460 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
3461 			BPF_MOV64_IMM(BPF_REG_3, 0),
3462 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3463 			BPF_EXIT_INSN(),
3464 		},
3465 		.fixup_map2 = { 3 },
3466 		.result = ACCEPT,
3467 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3468 	},
3469 	{
3470 		"helper access to map: partial range",
3471 		.insns = {
3472 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3473 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3474 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3475 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3476 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3477 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3478 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3479 			BPF_MOV64_IMM(BPF_REG_2, 8),
3480 			BPF_MOV64_IMM(BPF_REG_3, 0),
3481 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3482 			BPF_EXIT_INSN(),
3483 		},
3484 		.fixup_map2 = { 3 },
3485 		.result = ACCEPT,
3486 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3487 	},
3488 	{
3489 		"helper access to map: empty range",
3490 		.insns = {
3491 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3492 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3493 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3494 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3495 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3496 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3497 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3498 			BPF_MOV64_IMM(BPF_REG_2, 0),
3499 			BPF_MOV64_IMM(BPF_REG_3, 0),
3500 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3501 			BPF_EXIT_INSN(),
3502 		},
3503 		.fixup_map2 = { 3 },
3504 		.errstr = "invalid access to map value, value_size=48 off=0 size=0",
3505 		.result = REJECT,
3506 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3507 	},
3508 	{
3509 		"helper access to map: out-of-bound range",
3510 		.insns = {
3511 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3512 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3513 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3514 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3515 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3516 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3517 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3518 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
3519 			BPF_MOV64_IMM(BPF_REG_3, 0),
3520 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3521 			BPF_EXIT_INSN(),
3522 		},
3523 		.fixup_map2 = { 3 },
3524 		.errstr = "invalid access to map value, value_size=48 off=0 size=56",
3525 		.result = REJECT,
3526 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3527 	},
3528 	{
3529 		"helper access to map: negative range",
3530 		.insns = {
3531 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3532 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3533 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3534 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3535 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3536 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3537 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3538 			BPF_MOV64_IMM(BPF_REG_2, -8),
3539 			BPF_MOV64_IMM(BPF_REG_3, 0),
3540 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3541 			BPF_EXIT_INSN(),
3542 		},
3543 		.fixup_map2 = { 3 },
3544 		.errstr = "invalid access to map value, value_size=48 off=0 size=-8",
3545 		.result = REJECT,
3546 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3547 	},
3548 	{
3549 		"helper access to adjusted map (via const imm): full range",
3550 		.insns = {
3551 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3552 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3553 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3554 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3555 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3556 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3557 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3558 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3559 				offsetof(struct test_val, foo)),
3560 			BPF_MOV64_IMM(BPF_REG_2,
3561 				sizeof(struct test_val) -
3562 				offsetof(struct test_val, foo)),
3563 			BPF_MOV64_IMM(BPF_REG_3, 0),
3564 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3565 			BPF_EXIT_INSN(),
3566 		},
3567 		.fixup_map2 = { 3 },
3568 		.result = ACCEPT,
3569 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3570 	},
3571 	{
3572 		"helper access to adjusted map (via const imm): partial range",
3573 		.insns = {
3574 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3575 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3576 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3577 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3578 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3579 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3580 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3581 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3582 				offsetof(struct test_val, foo)),
3583 			BPF_MOV64_IMM(BPF_REG_2, 8),
3584 			BPF_MOV64_IMM(BPF_REG_3, 0),
3585 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3586 			BPF_EXIT_INSN(),
3587 		},
3588 		.fixup_map2 = { 3 },
3589 		.result = ACCEPT,
3590 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3591 	},
3592 	{
3593 		"helper access to adjusted map (via const imm): empty range",
3594 		.insns = {
3595 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3596 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3597 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3598 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3599 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3600 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3601 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3602 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3603 				offsetof(struct test_val, foo)),
3604 			BPF_MOV64_IMM(BPF_REG_2, 0),
3605 			BPF_MOV64_IMM(BPF_REG_3, 0),
3606 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3607 			BPF_EXIT_INSN(),
3608 		},
3609 		.fixup_map2 = { 3 },
3610 		.errstr = "R1 min value is outside of the array range",
3611 		.result = REJECT,
3612 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3613 	},
3614 	{
3615 		"helper access to adjusted map (via const imm): out-of-bound range",
3616 		.insns = {
3617 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3618 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3619 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3620 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3621 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3622 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3623 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3624 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3625 				offsetof(struct test_val, foo)),
3626 			BPF_MOV64_IMM(BPF_REG_2,
3627 				sizeof(struct test_val) -
3628 				offsetof(struct test_val, foo) + 8),
3629 			BPF_MOV64_IMM(BPF_REG_3, 0),
3630 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3631 			BPF_EXIT_INSN(),
3632 		},
3633 		.fixup_map2 = { 3 },
3634 		.errstr = "invalid access to map value, value_size=48 off=4 size=52",
3635 		.result = REJECT,
3636 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3637 	},
3638 	{
3639 		"helper access to adjusted map (via const imm): negative range (> adjustment)",
3640 		.insns = {
3641 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3642 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3643 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3644 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3645 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3646 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3647 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3648 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3649 				offsetof(struct test_val, foo)),
3650 			BPF_MOV64_IMM(BPF_REG_2, -8),
3651 			BPF_MOV64_IMM(BPF_REG_3, 0),
3652 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3653 			BPF_EXIT_INSN(),
3654 		},
3655 		.fixup_map2 = { 3 },
3656 		.errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3657 		.result = REJECT,
3658 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3659 	},
3660 	{
3661 		"helper access to adjusted map (via const imm): negative range (< adjustment)",
3662 		.insns = {
3663 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3664 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3665 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3666 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3667 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3668 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3669 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3670 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3671 				offsetof(struct test_val, foo)),
3672 			BPF_MOV64_IMM(BPF_REG_2, -1),
3673 			BPF_MOV64_IMM(BPF_REG_3, 0),
3674 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3675 			BPF_EXIT_INSN(),
3676 		},
3677 		.fixup_map2 = { 3 },
3678 		.errstr = "R1 min value is outside of the array range",
3679 		.result = REJECT,
3680 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3681 	},
3682 	{
3683 		"helper access to adjusted map (via const reg): full range",
3684 		.insns = {
3685 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3686 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3687 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3688 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3689 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3690 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3691 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3692 			BPF_MOV64_IMM(BPF_REG_3,
3693 				offsetof(struct test_val, foo)),
3694 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3695 			BPF_MOV64_IMM(BPF_REG_2,
3696 				sizeof(struct test_val) -
3697 				offsetof(struct test_val, foo)),
3698 			BPF_MOV64_IMM(BPF_REG_3, 0),
3699 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3700 			BPF_EXIT_INSN(),
3701 		},
3702 		.fixup_map2 = { 3 },
3703 		.result = ACCEPT,
3704 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3705 	},
3706 	{
3707 		"helper access to adjusted map (via const reg): partial range",
3708 		.insns = {
3709 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3710 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3711 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3712 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3713 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3714 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3715 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3716 			BPF_MOV64_IMM(BPF_REG_3,
3717 				offsetof(struct test_val, foo)),
3718 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3719 			BPF_MOV64_IMM(BPF_REG_2, 8),
3720 			BPF_MOV64_IMM(BPF_REG_3, 0),
3721 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3722 			BPF_EXIT_INSN(),
3723 		},
3724 		.fixup_map2 = { 3 },
3725 		.result = ACCEPT,
3726 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3727 	},
3728 	{
3729 		"helper access to adjusted map (via const reg): empty range",
3730 		.insns = {
3731 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3732 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3733 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3734 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3735 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3736 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3737 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3738 			BPF_MOV64_IMM(BPF_REG_3, 0),
3739 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3740 			BPF_MOV64_IMM(BPF_REG_2, 0),
3741 			BPF_MOV64_IMM(BPF_REG_3, 0),
3742 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3743 			BPF_EXIT_INSN(),
3744 		},
3745 		.fixup_map2 = { 3 },
3746 		.errstr = "R1 min value is outside of the array range",
3747 		.result = REJECT,
3748 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3749 	},
3750 	{
3751 		"helper access to adjusted map (via const reg): out-of-bound range",
3752 		.insns = {
3753 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3754 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3755 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3756 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3757 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3758 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3759 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3760 			BPF_MOV64_IMM(BPF_REG_3,
3761 				offsetof(struct test_val, foo)),
3762 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3763 			BPF_MOV64_IMM(BPF_REG_2,
3764 				sizeof(struct test_val) -
3765 				offsetof(struct test_val, foo) + 8),
3766 			BPF_MOV64_IMM(BPF_REG_3, 0),
3767 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3768 			BPF_EXIT_INSN(),
3769 		},
3770 		.fixup_map2 = { 3 },
3771 		.errstr = "invalid access to map value, value_size=48 off=4 size=52",
3772 		.result = REJECT,
3773 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3774 	},
3775 	{
3776 		"helper access to adjusted map (via const reg): negative range (> adjustment)",
3777 		.insns = {
3778 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3779 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3780 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3781 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3782 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3783 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3784 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3785 			BPF_MOV64_IMM(BPF_REG_3,
3786 				offsetof(struct test_val, foo)),
3787 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3788 			BPF_MOV64_IMM(BPF_REG_2, -8),
3789 			BPF_MOV64_IMM(BPF_REG_3, 0),
3790 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3791 			BPF_EXIT_INSN(),
3792 		},
3793 		.fixup_map2 = { 3 },
3794 		.errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3795 		.result = REJECT,
3796 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3797 	},
3798 	{
3799 		"helper access to adjusted map (via const reg): negative range (< adjustment)",
3800 		.insns = {
3801 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3802 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3803 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3804 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3805 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3806 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3807 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3808 			BPF_MOV64_IMM(BPF_REG_3,
3809 				offsetof(struct test_val, foo)),
3810 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3811 			BPF_MOV64_IMM(BPF_REG_2, -1),
3812 			BPF_MOV64_IMM(BPF_REG_3, 0),
3813 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3814 			BPF_EXIT_INSN(),
3815 		},
3816 		.fixup_map2 = { 3 },
3817 		.errstr = "R1 min value is outside of the array range",
3818 		.result = REJECT,
3819 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3820 	},
3821 	{
3822 		"helper access to adjusted map (via variable): full range",
3823 		.insns = {
3824 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3825 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3826 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3827 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3828 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3829 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3830 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3831 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3832 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3833 				offsetof(struct test_val, foo), 4),
3834 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3835 			BPF_MOV64_IMM(BPF_REG_2,
3836 				sizeof(struct test_val) -
3837 				offsetof(struct test_val, foo)),
3838 			BPF_MOV64_IMM(BPF_REG_3, 0),
3839 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3840 			BPF_EXIT_INSN(),
3841 		},
3842 		.fixup_map2 = { 3 },
3843 		.result = ACCEPT,
3844 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3845 	},
3846 	{
3847 		"helper access to adjusted map (via variable): partial range",
3848 		.insns = {
3849 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3850 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3851 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3852 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3853 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3854 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3855 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3856 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3857 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3858 				offsetof(struct test_val, foo), 4),
3859 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3860 			BPF_MOV64_IMM(BPF_REG_2, 8),
3861 			BPF_MOV64_IMM(BPF_REG_3, 0),
3862 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3863 			BPF_EXIT_INSN(),
3864 		},
3865 		.fixup_map2 = { 3 },
3866 		.result = ACCEPT,
3867 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3868 	},
3869 	{
3870 		"helper access to adjusted map (via variable): empty range",
3871 		.insns = {
3872 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3873 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3874 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3875 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3876 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3877 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3878 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3879 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3880 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3881 				offsetof(struct test_val, foo), 4),
3882 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3883 			BPF_MOV64_IMM(BPF_REG_2, 0),
3884 			BPF_MOV64_IMM(BPF_REG_3, 0),
3885 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3886 			BPF_EXIT_INSN(),
3887 		},
3888 		.fixup_map2 = { 3 },
3889 		.errstr = "R1 min value is outside of the array range",
3890 		.result = REJECT,
3891 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3892 	},
3893 	{
3894 		"helper access to adjusted map (via variable): no max check",
3895 		.insns = {
3896 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3897 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3898 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3899 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3900 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3901 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3902 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3903 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3904 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3905 			BPF_MOV64_IMM(BPF_REG_2, 0),
3906 			BPF_MOV64_IMM(BPF_REG_3, 0),
3907 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3908 			BPF_EXIT_INSN(),
3909 		},
3910 		.fixup_map2 = { 3 },
3911 		.errstr = "R1 min value is negative, either use unsigned index or do a if (index >=0) check",
3912 		.result = REJECT,
3913 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3914 	},
3915 	{
3916 		"helper access to adjusted map (via variable): wrong max check",
3917 		.insns = {
3918 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3919 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3920 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3921 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3922 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3923 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3924 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3925 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3926 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3927 				offsetof(struct test_val, foo), 4),
3928 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3929 			BPF_MOV64_IMM(BPF_REG_2,
3930 				sizeof(struct test_val) -
3931 				offsetof(struct test_val, foo) + 1),
3932 			BPF_MOV64_IMM(BPF_REG_3, 0),
3933 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
3934 			BPF_EXIT_INSN(),
3935 		},
3936 		.fixup_map2 = { 3 },
3937 		.errstr = "invalid access to map value, value_size=48 off=4 size=45",
3938 		.result = REJECT,
3939 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
3940 	},
3941 	{
3942 		"map element value is preserved across register spilling",
3943 		.insns = {
3944 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3945 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3946 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3947 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3948 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3949 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3950 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3951 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3952 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3953 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3954 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3955 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3956 			BPF_EXIT_INSN(),
3957 		},
3958 		.fixup_map2 = { 3 },
3959 		.errstr_unpriv = "R0 leaks addr",
3960 		.result = ACCEPT,
3961 		.result_unpriv = REJECT,
3962 	},
3963 	{
3964 		"map element value (adjusted) is preserved across register spilling",
3965 		.insns = {
3966 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3967 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3968 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3969 			BPF_LD_MAP_FD(BPF_REG_1, 0),
3970 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3971 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3972 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
3973 				offsetof(struct test_val, foo)),
3974 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3975 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3976 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3977 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3978 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3979 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3980 			BPF_EXIT_INSN(),
3981 		},
3982 		.fixup_map2 = { 3 },
3983 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
3984 		.result = ACCEPT,
3985 		.result_unpriv = REJECT,
3986 	},
3987 	{
3988 		"helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
3989 		.insns = {
3990 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3991 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
3992 			BPF_MOV64_IMM(BPF_REG_0, 0),
3993 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
3994 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
3995 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
3996 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
3997 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
3998 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
3999 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4000 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4001 			BPF_MOV64_IMM(BPF_REG_2, 16),
4002 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4003 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4004 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4005 			BPF_MOV64_IMM(BPF_REG_4, 0),
4006 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4007 			BPF_MOV64_IMM(BPF_REG_3, 0),
4008 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4009 			BPF_MOV64_IMM(BPF_REG_0, 0),
4010 			BPF_EXIT_INSN(),
4011 		},
4012 		.result = ACCEPT,
4013 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4014 	},
4015 	{
4016 		"helper access to variable memory: stack, bitwise AND, zero included",
4017 		.insns = {
4018 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4019 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4020 			BPF_MOV64_IMM(BPF_REG_2, 16),
4021 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4022 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4023 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4024 			BPF_MOV64_IMM(BPF_REG_3, 0),
4025 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4026 			BPF_EXIT_INSN(),
4027 		},
4028 		.errstr = "invalid stack type R1 off=-64 access_size=0",
4029 		.result = REJECT,
4030 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4031 	},
4032 	{
4033 		"helper access to variable memory: stack, bitwise AND + JMP, wrong max",
4034 		.insns = {
4035 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4036 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4037 			BPF_MOV64_IMM(BPF_REG_2, 16),
4038 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4039 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4040 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
4041 			BPF_MOV64_IMM(BPF_REG_4, 0),
4042 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4043 			BPF_MOV64_IMM(BPF_REG_3, 0),
4044 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4045 			BPF_MOV64_IMM(BPF_REG_0, 0),
4046 			BPF_EXIT_INSN(),
4047 		},
4048 		.errstr = "invalid stack type R1 off=-64 access_size=65",
4049 		.result = REJECT,
4050 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4051 	},
4052 	{
4053 		"helper access to variable memory: stack, JMP, correct bounds",
4054 		.insns = {
4055 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4056 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4057 			BPF_MOV64_IMM(BPF_REG_0, 0),
4058 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4059 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4060 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4061 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4062 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4063 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4064 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4065 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4066 			BPF_MOV64_IMM(BPF_REG_2, 16),
4067 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4068 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4069 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
4070 			BPF_MOV64_IMM(BPF_REG_4, 0),
4071 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4072 			BPF_MOV64_IMM(BPF_REG_3, 0),
4073 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4074 			BPF_MOV64_IMM(BPF_REG_0, 0),
4075 			BPF_EXIT_INSN(),
4076 		},
4077 		.result = ACCEPT,
4078 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4079 	},
4080 	{
4081 		"helper access to variable memory: stack, JMP (signed), correct bounds",
4082 		.insns = {
4083 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4084 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4085 			BPF_MOV64_IMM(BPF_REG_0, 0),
4086 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4087 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4088 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4089 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4090 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4091 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4092 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4093 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4094 			BPF_MOV64_IMM(BPF_REG_2, 16),
4095 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4096 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4097 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
4098 			BPF_MOV64_IMM(BPF_REG_4, 0),
4099 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
4100 			BPF_MOV64_IMM(BPF_REG_3, 0),
4101 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4102 			BPF_MOV64_IMM(BPF_REG_0, 0),
4103 			BPF_EXIT_INSN(),
4104 		},
4105 		.result = ACCEPT,
4106 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4107 	},
4108 	{
4109 		"helper access to variable memory: stack, JMP, bounds + offset",
4110 		.insns = {
4111 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4112 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4113 			BPF_MOV64_IMM(BPF_REG_2, 16),
4114 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4115 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4116 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
4117 			BPF_MOV64_IMM(BPF_REG_4, 0),
4118 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
4119 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4120 			BPF_MOV64_IMM(BPF_REG_3, 0),
4121 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4122 			BPF_MOV64_IMM(BPF_REG_0, 0),
4123 			BPF_EXIT_INSN(),
4124 		},
4125 		.errstr = "invalid stack type R1 off=-64 access_size=65",
4126 		.result = REJECT,
4127 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4128 	},
4129 	{
4130 		"helper access to variable memory: stack, JMP, wrong max",
4131 		.insns = {
4132 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4133 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4134 			BPF_MOV64_IMM(BPF_REG_2, 16),
4135 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4136 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4137 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
4138 			BPF_MOV64_IMM(BPF_REG_4, 0),
4139 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4140 			BPF_MOV64_IMM(BPF_REG_3, 0),
4141 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4142 			BPF_MOV64_IMM(BPF_REG_0, 0),
4143 			BPF_EXIT_INSN(),
4144 		},
4145 		.errstr = "invalid stack type R1 off=-64 access_size=65",
4146 		.result = REJECT,
4147 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4148 	},
4149 	{
4150 		"helper access to variable memory: stack, JMP, no max check",
4151 		.insns = {
4152 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4153 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4154 			BPF_MOV64_IMM(BPF_REG_2, 16),
4155 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4156 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4157 			BPF_MOV64_IMM(BPF_REG_4, 0),
4158 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4159 			BPF_MOV64_IMM(BPF_REG_3, 0),
4160 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4161 			BPF_MOV64_IMM(BPF_REG_0, 0),
4162 			BPF_EXIT_INSN(),
4163 		},
4164 		.errstr = "R2 unbounded memory access",
4165 		.result = REJECT,
4166 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4167 	},
4168 	{
4169 		"helper access to variable memory: stack, JMP, no min check",
4170 		.insns = {
4171 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4172 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4173 			BPF_MOV64_IMM(BPF_REG_2, 16),
4174 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4175 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4176 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
4177 			BPF_MOV64_IMM(BPF_REG_3, 0),
4178 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4179 			BPF_MOV64_IMM(BPF_REG_0, 0),
4180 			BPF_EXIT_INSN(),
4181 		},
4182 		.errstr = "invalid stack type R1 off=-64 access_size=0",
4183 		.result = REJECT,
4184 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4185 	},
4186 	{
4187 		"helper access to variable memory: stack, JMP (signed), no min check",
4188 		.insns = {
4189 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4190 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4191 			BPF_MOV64_IMM(BPF_REG_2, 16),
4192 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4193 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4194 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
4195 			BPF_MOV64_IMM(BPF_REG_3, 0),
4196 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4197 			BPF_MOV64_IMM(BPF_REG_0, 0),
4198 			BPF_EXIT_INSN(),
4199 		},
4200 		.errstr = "R2 min value is negative",
4201 		.result = REJECT,
4202 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4203 	},
4204 	{
4205 		"helper access to variable memory: map, JMP, correct bounds",
4206 		.insns = {
4207 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4208 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4209 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4210 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4211 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4212 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4213 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4214 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4215 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4216 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4217 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4218 				sizeof(struct test_val), 4),
4219 			BPF_MOV64_IMM(BPF_REG_4, 0),
4220 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4221 			BPF_MOV64_IMM(BPF_REG_3, 0),
4222 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4223 			BPF_MOV64_IMM(BPF_REG_0, 0),
4224 			BPF_EXIT_INSN(),
4225 		},
4226 		.fixup_map2 = { 3 },
4227 		.result = ACCEPT,
4228 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4229 	},
4230 	{
4231 		"helper access to variable memory: map, JMP, wrong max",
4232 		.insns = {
4233 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4234 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4235 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4236 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4237 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4238 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4239 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4240 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4241 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4242 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4243 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4244 				sizeof(struct test_val) + 1, 4),
4245 			BPF_MOV64_IMM(BPF_REG_4, 0),
4246 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4247 			BPF_MOV64_IMM(BPF_REG_3, 0),
4248 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4249 			BPF_MOV64_IMM(BPF_REG_0, 0),
4250 			BPF_EXIT_INSN(),
4251 		},
4252 		.fixup_map2 = { 3 },
4253 		.errstr = "invalid access to map value, value_size=48 off=0 size=49",
4254 		.result = REJECT,
4255 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4256 	},
4257 	{
4258 		"helper access to variable memory: map adjusted, JMP, correct bounds",
4259 		.insns = {
4260 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4261 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4262 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4263 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4264 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4265 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4266 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4267 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4268 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4269 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4270 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4271 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4272 				sizeof(struct test_val) - 20, 4),
4273 			BPF_MOV64_IMM(BPF_REG_4, 0),
4274 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4275 			BPF_MOV64_IMM(BPF_REG_3, 0),
4276 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4277 			BPF_MOV64_IMM(BPF_REG_0, 0),
4278 			BPF_EXIT_INSN(),
4279 		},
4280 		.fixup_map2 = { 3 },
4281 		.result = ACCEPT,
4282 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4283 	},
4284 	{
4285 		"helper access to variable memory: map adjusted, JMP, wrong max",
4286 		.insns = {
4287 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4288 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4289 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4290 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4291 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4292 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4293 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4294 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4295 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4296 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4297 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4298 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4299 				sizeof(struct test_val) - 19, 4),
4300 			BPF_MOV64_IMM(BPF_REG_4, 0),
4301 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4302 			BPF_MOV64_IMM(BPF_REG_3, 0),
4303 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4304 			BPF_MOV64_IMM(BPF_REG_0, 0),
4305 			BPF_EXIT_INSN(),
4306 		},
4307 		.fixup_map2 = { 3 },
4308 		.errstr = "R1 min value is outside of the array range",
4309 		.result = REJECT,
4310 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4311 	},
4312 	{
4313 		"helper access to variable memory: size > 0 not allowed on NULL",
4314 		.insns = {
4315 			BPF_MOV64_IMM(BPF_REG_1, 0),
4316 			BPF_MOV64_IMM(BPF_REG_2, 0),
4317 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4318 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4319 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4320 			BPF_MOV64_IMM(BPF_REG_3, 0),
4321 			BPF_MOV64_IMM(BPF_REG_4, 0),
4322 			BPF_MOV64_IMM(BPF_REG_5, 0),
4323 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4324 			BPF_EXIT_INSN(),
4325 		},
4326 		.errstr = "R1 type=imm expected=fp",
4327 		.result = REJECT,
4328 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
4329 	},
4330 	{
4331 		"helper access to variable memory: size = 0 not allowed on != NULL",
4332 		.insns = {
4333 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4334 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
4335 			BPF_MOV64_IMM(BPF_REG_2, 0),
4336 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
4337 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
4338 			BPF_MOV64_IMM(BPF_REG_3, 0),
4339 			BPF_MOV64_IMM(BPF_REG_4, 0),
4340 			BPF_MOV64_IMM(BPF_REG_5, 0),
4341 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4342 			BPF_EXIT_INSN(),
4343 		},
4344 		.errstr = "invalid stack type R1 off=-8 access_size=0",
4345 		.result = REJECT,
4346 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
4347 	},
4348 	{
4349 		"helper access to variable memory: 8 bytes leak",
4350 		.insns = {
4351 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4352 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4353 			BPF_MOV64_IMM(BPF_REG_0, 0),
4354 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4355 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4356 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4357 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4358 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4359 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4360 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4361 			BPF_MOV64_IMM(BPF_REG_2, 0),
4362 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4363 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4364 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
4365 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4366 			BPF_MOV64_IMM(BPF_REG_3, 0),
4367 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4368 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4369 			BPF_EXIT_INSN(),
4370 		},
4371 		.errstr = "invalid indirect read from stack off -64+32 size 64",
4372 		.result = REJECT,
4373 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4374 	},
4375 	{
4376 		"helper access to variable memory: 8 bytes no leak (init memory)",
4377 		.insns = {
4378 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4379 			BPF_MOV64_IMM(BPF_REG_0, 0),
4380 			BPF_MOV64_IMM(BPF_REG_0, 0),
4381 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4382 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4383 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4384 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4385 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4386 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4387 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4388 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4389 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4390 			BPF_MOV64_IMM(BPF_REG_2, 0),
4391 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
4392 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
4393 			BPF_MOV64_IMM(BPF_REG_3, 0),
4394 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
4395 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4396 			BPF_EXIT_INSN(),
4397 		},
4398 		.result = ACCEPT,
4399 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
4400 	},
4401 	{
4402 		"invalid and of negative number",
4403 		.insns = {
4404 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4405 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4406 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4407 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4408 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4409 				     BPF_FUNC_map_lookup_elem),
4410 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4411 			BPF_MOV64_IMM(BPF_REG_1, 6),
4412 			BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
4413 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4414 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4415 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4416 				   offsetof(struct test_val, foo)),
4417 			BPF_EXIT_INSN(),
4418 		},
4419 		.fixup_map2 = { 3 },
4420 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
4421 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4422 		.result = REJECT,
4423 		.result_unpriv = REJECT,
4424 	},
4425 	{
4426 		"invalid range check",
4427 		.insns = {
4428 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4429 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4430 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4431 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4432 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4433 				     BPF_FUNC_map_lookup_elem),
4434 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
4435 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4436 			BPF_MOV64_IMM(BPF_REG_9, 1),
4437 			BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
4438 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
4439 			BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
4440 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
4441 			BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
4442 			BPF_MOV32_IMM(BPF_REG_3, 1),
4443 			BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
4444 			BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
4445 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
4446 			BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
4447 			BPF_MOV64_REG(BPF_REG_0, 0),
4448 			BPF_EXIT_INSN(),
4449 		},
4450 		.fixup_map2 = { 3 },
4451 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
4452 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4453 		.result = REJECT,
4454 		.result_unpriv = REJECT,
4455 	}
4456 };
4457 
4458 static int probe_filter_length(const struct bpf_insn *fp)
4459 {
4460 	int len;
4461 
4462 	for (len = MAX_INSNS - 1; len > 0; --len)
4463 		if (fp[len].code != 0 || fp[len].imm != 0)
4464 			break;
4465 	return len + 1;
4466 }
4467 
4468 static int create_map(uint32_t size_value, uint32_t max_elem)
4469 {
4470 	int fd;
4471 
4472 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
4473 			    size_value, max_elem, BPF_F_NO_PREALLOC);
4474 	if (fd < 0)
4475 		printf("Failed to create hash map '%s'!\n", strerror(errno));
4476 
4477 	return fd;
4478 }
4479 
4480 static int create_prog_array(void)
4481 {
4482 	int fd;
4483 
4484 	fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
4485 			    sizeof(int), 4, 0);
4486 	if (fd < 0)
4487 		printf("Failed to create prog array '%s'!\n", strerror(errno));
4488 
4489 	return fd;
4490 }
4491 
4492 static char bpf_vlog[32768];
4493 
4494 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
4495 			  int *fd_f1, int *fd_f2, int *fd_f3)
4496 {
4497 	int *fixup_map1 = test->fixup_map1;
4498 	int *fixup_map2 = test->fixup_map2;
4499 	int *fixup_prog = test->fixup_prog;
4500 
4501 	/* Allocating HTs with 1 elem is fine here, since we only test
4502 	 * for verifier and not do a runtime lookup, so the only thing
4503 	 * that really matters is value size in this case.
4504 	 */
4505 	if (*fixup_map1) {
4506 		*fd_f1 = create_map(sizeof(long long), 1);
4507 		do {
4508 			prog[*fixup_map1].imm = *fd_f1;
4509 			fixup_map1++;
4510 		} while (*fixup_map1);
4511 	}
4512 
4513 	if (*fixup_map2) {
4514 		*fd_f2 = create_map(sizeof(struct test_val), 1);
4515 		do {
4516 			prog[*fixup_map2].imm = *fd_f2;
4517 			fixup_map2++;
4518 		} while (*fixup_map2);
4519 	}
4520 
4521 	if (*fixup_prog) {
4522 		*fd_f3 = create_prog_array();
4523 		do {
4524 			prog[*fixup_prog].imm = *fd_f3;
4525 			fixup_prog++;
4526 		} while (*fixup_prog);
4527 	}
4528 }
4529 
4530 static void do_test_single(struct bpf_test *test, bool unpriv,
4531 			   int *passes, int *errors)
4532 {
4533 	struct bpf_insn *prog = test->insns;
4534 	int prog_len = probe_filter_length(prog);
4535 	int prog_type = test->prog_type;
4536 	int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1;
4537 	int fd_prog, expected_ret;
4538 	const char *expected_err;
4539 
4540 	do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3);
4541 
4542 	fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
4543 				   prog, prog_len, "GPL", 0, bpf_vlog,
4544 				   sizeof(bpf_vlog));
4545 
4546 	expected_ret = unpriv && test->result_unpriv != UNDEF ?
4547 		       test->result_unpriv : test->result;
4548 	expected_err = unpriv && test->errstr_unpriv ?
4549 		       test->errstr_unpriv : test->errstr;
4550 	if (expected_ret == ACCEPT) {
4551 		if (fd_prog < 0) {
4552 			printf("FAIL\nFailed to load prog '%s'!\n",
4553 			       strerror(errno));
4554 			goto fail_log;
4555 		}
4556 	} else {
4557 		if (fd_prog >= 0) {
4558 			printf("FAIL\nUnexpected success to load!\n");
4559 			goto fail_log;
4560 		}
4561 		if (!strstr(bpf_vlog, expected_err)) {
4562 			printf("FAIL\nUnexpected error message!\n");
4563 			goto fail_log;
4564 		}
4565 	}
4566 
4567 	(*passes)++;
4568 	printf("OK\n");
4569 close_fds:
4570 	close(fd_prog);
4571 	close(fd_f1);
4572 	close(fd_f2);
4573 	close(fd_f3);
4574 	sched_yield();
4575 	return;
4576 fail_log:
4577 	(*errors)++;
4578 	printf("%s", bpf_vlog);
4579 	goto close_fds;
4580 }
4581 
4582 static bool is_admin(void)
4583 {
4584 	cap_t caps;
4585 	cap_flag_value_t sysadmin = CAP_CLEAR;
4586 	const cap_value_t cap_val = CAP_SYS_ADMIN;
4587 
4588 #ifdef CAP_IS_SUPPORTED
4589 	if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
4590 		perror("cap_get_flag");
4591 		return false;
4592 	}
4593 #endif
4594 	caps = cap_get_proc();
4595 	if (!caps) {
4596 		perror("cap_get_proc");
4597 		return false;
4598 	}
4599 	if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
4600 		perror("cap_get_flag");
4601 	if (cap_free(caps))
4602 		perror("cap_free");
4603 	return (sysadmin == CAP_SET);
4604 }
4605 
4606 static int set_admin(bool admin)
4607 {
4608 	cap_t caps;
4609 	const cap_value_t cap_val = CAP_SYS_ADMIN;
4610 	int ret = -1;
4611 
4612 	caps = cap_get_proc();
4613 	if (!caps) {
4614 		perror("cap_get_proc");
4615 		return -1;
4616 	}
4617 	if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
4618 				admin ? CAP_SET : CAP_CLEAR)) {
4619 		perror("cap_set_flag");
4620 		goto out;
4621 	}
4622 	if (cap_set_proc(caps)) {
4623 		perror("cap_set_proc");
4624 		goto out;
4625 	}
4626 	ret = 0;
4627 out:
4628 	if (cap_free(caps))
4629 		perror("cap_free");
4630 	return ret;
4631 }
4632 
4633 static int do_test(bool unpriv, unsigned int from, unsigned int to)
4634 {
4635 	int i, passes = 0, errors = 0;
4636 
4637 	for (i = from; i < to; i++) {
4638 		struct bpf_test *test = &tests[i];
4639 
4640 		/* Program types that are not supported by non-root we
4641 		 * skip right away.
4642 		 */
4643 		if (!test->prog_type) {
4644 			if (!unpriv)
4645 				set_admin(false);
4646 			printf("#%d/u %s ", i, test->descr);
4647 			do_test_single(test, true, &passes, &errors);
4648 			if (!unpriv)
4649 				set_admin(true);
4650 		}
4651 
4652 		if (!unpriv) {
4653 			printf("#%d/p %s ", i, test->descr);
4654 			do_test_single(test, false, &passes, &errors);
4655 		}
4656 	}
4657 
4658 	printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
4659 	return errors ? -errors : 0;
4660 }
4661 
4662 int main(int argc, char **argv)
4663 {
4664 	struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
4665 	struct rlimit rlim = { 1 << 20, 1 << 20 };
4666 	unsigned int from = 0, to = ARRAY_SIZE(tests);
4667 	bool unpriv = !is_admin();
4668 
4669 	if (argc == 3) {
4670 		unsigned int l = atoi(argv[argc - 2]);
4671 		unsigned int u = atoi(argv[argc - 1]);
4672 
4673 		if (l < to && u < to) {
4674 			from = l;
4675 			to   = u + 1;
4676 		}
4677 	} else if (argc == 2) {
4678 		unsigned int t = atoi(argv[argc - 1]);
4679 
4680 		if (t < to) {
4681 			from = t;
4682 			to   = t + 1;
4683 		}
4684 	}
4685 
4686 	setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
4687 	return do_test(unpriv, from, to);
4688 }
4689