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