]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/testing/selftests/bpf/test_verifier.c
960179882a1c51edf95bf4095d1d2d1f9769e614
[mirror_ubuntu-jammy-kernel.git] / tools / testing / selftests / bpf / test_verifier.c
1 /*
2 * Testsuite for eBPF verifier
3 *
4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5 * Copyright (c) 2017 Facebook
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General Public
9 * License as published by the Free Software Foundation.
10 */
11
12 #include <endian.h>
13 #include <asm/types.h>
14 #include <linux/types.h>
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stddef.h>
22 #include <stdbool.h>
23 #include <sched.h>
24
25 #include <sys/capability.h>
26 #include <sys/resource.h>
27
28 #include <linux/unistd.h>
29 #include <linux/filter.h>
30 #include <linux/bpf_perf_event.h>
31 #include <linux/bpf.h>
32
33 #include <bpf/bpf.h>
34
35 #ifdef HAVE_GENHDR
36 # include "autoconf.h"
37 #else
38 # if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
39 # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
40 # endif
41 #endif
42
43 #include "../../../include/linux/filter.h"
44
45 #ifndef ARRAY_SIZE
46 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
47 #endif
48
49 #define MAX_INSNS 512
50 #define MAX_FIXUPS 8
51 #define MAX_NR_MAPS 4
52
53 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
54 #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
55
56 struct bpf_test {
57 const char *descr;
58 struct bpf_insn insns[MAX_INSNS];
59 int fixup_map1[MAX_FIXUPS];
60 int fixup_map2[MAX_FIXUPS];
61 int fixup_prog[MAX_FIXUPS];
62 int fixup_map_in_map[MAX_FIXUPS];
63 const char *errstr;
64 const char *errstr_unpriv;
65 enum {
66 UNDEF,
67 ACCEPT,
68 REJECT
69 } result, result_unpriv;
70 enum bpf_prog_type prog_type;
71 uint8_t flags;
72 };
73
74 /* Note we want this to be 64 bit aligned so that the end of our array is
75 * actually the end of the structure.
76 */
77 #define MAX_ENTRIES 11
78
79 struct test_val {
80 unsigned int index;
81 int foo[MAX_ENTRIES];
82 };
83
84 static struct bpf_test tests[] = {
85 {
86 "add+sub+mul",
87 .insns = {
88 BPF_MOV64_IMM(BPF_REG_1, 1),
89 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
90 BPF_MOV64_IMM(BPF_REG_2, 3),
91 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
92 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
93 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
94 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
95 BPF_EXIT_INSN(),
96 },
97 .result = ACCEPT,
98 },
99 {
100 "unreachable",
101 .insns = {
102 BPF_EXIT_INSN(),
103 BPF_EXIT_INSN(),
104 },
105 .errstr = "unreachable",
106 .result = REJECT,
107 },
108 {
109 "unreachable2",
110 .insns = {
111 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
112 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
113 BPF_EXIT_INSN(),
114 },
115 .errstr = "unreachable",
116 .result = REJECT,
117 },
118 {
119 "out of range jump",
120 .insns = {
121 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
122 BPF_EXIT_INSN(),
123 },
124 .errstr = "jump out of range",
125 .result = REJECT,
126 },
127 {
128 "out of range jump2",
129 .insns = {
130 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
131 BPF_EXIT_INSN(),
132 },
133 .errstr = "jump out of range",
134 .result = REJECT,
135 },
136 {
137 "test1 ld_imm64",
138 .insns = {
139 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
140 BPF_LD_IMM64(BPF_REG_0, 0),
141 BPF_LD_IMM64(BPF_REG_0, 0),
142 BPF_LD_IMM64(BPF_REG_0, 1),
143 BPF_LD_IMM64(BPF_REG_0, 1),
144 BPF_MOV64_IMM(BPF_REG_0, 2),
145 BPF_EXIT_INSN(),
146 },
147 .errstr = "invalid BPF_LD_IMM insn",
148 .errstr_unpriv = "R1 pointer comparison",
149 .result = REJECT,
150 },
151 {
152 "test2 ld_imm64",
153 .insns = {
154 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
155 BPF_LD_IMM64(BPF_REG_0, 0),
156 BPF_LD_IMM64(BPF_REG_0, 0),
157 BPF_LD_IMM64(BPF_REG_0, 1),
158 BPF_LD_IMM64(BPF_REG_0, 1),
159 BPF_EXIT_INSN(),
160 },
161 .errstr = "invalid BPF_LD_IMM insn",
162 .errstr_unpriv = "R1 pointer comparison",
163 .result = REJECT,
164 },
165 {
166 "test3 ld_imm64",
167 .insns = {
168 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
169 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
170 BPF_LD_IMM64(BPF_REG_0, 0),
171 BPF_LD_IMM64(BPF_REG_0, 0),
172 BPF_LD_IMM64(BPF_REG_0, 1),
173 BPF_LD_IMM64(BPF_REG_0, 1),
174 BPF_EXIT_INSN(),
175 },
176 .errstr = "invalid bpf_ld_imm64 insn",
177 .result = REJECT,
178 },
179 {
180 "test4 ld_imm64",
181 .insns = {
182 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
183 BPF_EXIT_INSN(),
184 },
185 .errstr = "invalid bpf_ld_imm64 insn",
186 .result = REJECT,
187 },
188 {
189 "test5 ld_imm64",
190 .insns = {
191 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
192 },
193 .errstr = "invalid bpf_ld_imm64 insn",
194 .result = REJECT,
195 },
196 {
197 "test6 ld_imm64",
198 .insns = {
199 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
200 BPF_RAW_INSN(0, 0, 0, 0, 0),
201 BPF_EXIT_INSN(),
202 },
203 .result = ACCEPT,
204 },
205 {
206 "test7 ld_imm64",
207 .insns = {
208 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
209 BPF_RAW_INSN(0, 0, 0, 0, 1),
210 BPF_EXIT_INSN(),
211 },
212 .result = ACCEPT,
213 },
214 {
215 "test8 ld_imm64",
216 .insns = {
217 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
218 BPF_RAW_INSN(0, 0, 0, 0, 1),
219 BPF_EXIT_INSN(),
220 },
221 .errstr = "uses reserved fields",
222 .result = REJECT,
223 },
224 {
225 "test9 ld_imm64",
226 .insns = {
227 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
228 BPF_RAW_INSN(0, 0, 0, 1, 1),
229 BPF_EXIT_INSN(),
230 },
231 .errstr = "invalid bpf_ld_imm64 insn",
232 .result = REJECT,
233 },
234 {
235 "test10 ld_imm64",
236 .insns = {
237 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
238 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
239 BPF_EXIT_INSN(),
240 },
241 .errstr = "invalid bpf_ld_imm64 insn",
242 .result = REJECT,
243 },
244 {
245 "test11 ld_imm64",
246 .insns = {
247 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
248 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
249 BPF_EXIT_INSN(),
250 },
251 .errstr = "invalid bpf_ld_imm64 insn",
252 .result = REJECT,
253 },
254 {
255 "test12 ld_imm64",
256 .insns = {
257 BPF_MOV64_IMM(BPF_REG_1, 0),
258 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
259 BPF_RAW_INSN(0, 0, 0, 0, 1),
260 BPF_EXIT_INSN(),
261 },
262 .errstr = "not pointing to valid bpf_map",
263 .result = REJECT,
264 },
265 {
266 "test13 ld_imm64",
267 .insns = {
268 BPF_MOV64_IMM(BPF_REG_1, 0),
269 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
270 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
271 BPF_EXIT_INSN(),
272 },
273 .errstr = "invalid bpf_ld_imm64 insn",
274 .result = REJECT,
275 },
276 {
277 "arsh32 on imm",
278 .insns = {
279 BPF_MOV64_IMM(BPF_REG_0, 1),
280 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
281 BPF_EXIT_INSN(),
282 },
283 .result = REJECT,
284 .errstr = "BPF_ARSH not supported for 32 bit ALU",
285 },
286 {
287 "arsh32 on reg",
288 .insns = {
289 BPF_MOV64_IMM(BPF_REG_0, 1),
290 BPF_MOV64_IMM(BPF_REG_1, 5),
291 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
292 BPF_EXIT_INSN(),
293 },
294 .result = REJECT,
295 .errstr = "BPF_ARSH not supported for 32 bit ALU",
296 },
297 {
298 "arsh64 on imm",
299 .insns = {
300 BPF_MOV64_IMM(BPF_REG_0, 1),
301 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
302 BPF_EXIT_INSN(),
303 },
304 .result = ACCEPT,
305 },
306 {
307 "arsh64 on reg",
308 .insns = {
309 BPF_MOV64_IMM(BPF_REG_0, 1),
310 BPF_MOV64_IMM(BPF_REG_1, 5),
311 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
312 BPF_EXIT_INSN(),
313 },
314 .result = ACCEPT,
315 },
316 {
317 "no bpf_exit",
318 .insns = {
319 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
320 },
321 .errstr = "not an exit",
322 .result = REJECT,
323 },
324 {
325 "loop (back-edge)",
326 .insns = {
327 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
328 BPF_EXIT_INSN(),
329 },
330 .errstr = "back-edge",
331 .result = REJECT,
332 },
333 {
334 "loop2 (back-edge)",
335 .insns = {
336 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
337 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
338 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
339 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
340 BPF_EXIT_INSN(),
341 },
342 .errstr = "back-edge",
343 .result = REJECT,
344 },
345 {
346 "conditional loop",
347 .insns = {
348 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
349 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
350 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
351 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
352 BPF_EXIT_INSN(),
353 },
354 .errstr = "back-edge",
355 .result = REJECT,
356 },
357 {
358 "read uninitialized register",
359 .insns = {
360 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
361 BPF_EXIT_INSN(),
362 },
363 .errstr = "R2 !read_ok",
364 .result = REJECT,
365 },
366 {
367 "read invalid register",
368 .insns = {
369 BPF_MOV64_REG(BPF_REG_0, -1),
370 BPF_EXIT_INSN(),
371 },
372 .errstr = "R15 is invalid",
373 .result = REJECT,
374 },
375 {
376 "program doesn't init R0 before exit",
377 .insns = {
378 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
379 BPF_EXIT_INSN(),
380 },
381 .errstr = "R0 !read_ok",
382 .result = REJECT,
383 },
384 {
385 "program doesn't init R0 before exit in all branches",
386 .insns = {
387 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
388 BPF_MOV64_IMM(BPF_REG_0, 1),
389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
390 BPF_EXIT_INSN(),
391 },
392 .errstr = "R0 !read_ok",
393 .errstr_unpriv = "R1 pointer comparison",
394 .result = REJECT,
395 },
396 {
397 "stack out of bounds",
398 .insns = {
399 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
400 BPF_EXIT_INSN(),
401 },
402 .errstr = "invalid stack",
403 .result = REJECT,
404 },
405 {
406 "invalid call insn1",
407 .insns = {
408 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
409 BPF_EXIT_INSN(),
410 },
411 .errstr = "BPF_CALL uses reserved",
412 .result = REJECT,
413 },
414 {
415 "invalid call insn2",
416 .insns = {
417 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
418 BPF_EXIT_INSN(),
419 },
420 .errstr = "BPF_CALL uses reserved",
421 .result = REJECT,
422 },
423 {
424 "invalid function call",
425 .insns = {
426 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
427 BPF_EXIT_INSN(),
428 },
429 .errstr = "invalid func unknown#1234567",
430 .result = REJECT,
431 },
432 {
433 "uninitialized stack1",
434 .insns = {
435 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
437 BPF_LD_MAP_FD(BPF_REG_1, 0),
438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
439 BPF_FUNC_map_lookup_elem),
440 BPF_EXIT_INSN(),
441 },
442 .fixup_map1 = { 2 },
443 .errstr = "invalid indirect read from stack",
444 .result = REJECT,
445 },
446 {
447 "uninitialized stack2",
448 .insns = {
449 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
450 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
451 BPF_EXIT_INSN(),
452 },
453 .errstr = "invalid read from stack",
454 .result = REJECT,
455 },
456 {
457 "invalid fp arithmetic",
458 /* If this gets ever changed, make sure JITs can deal with it. */
459 .insns = {
460 BPF_MOV64_IMM(BPF_REG_0, 0),
461 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
462 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
463 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
464 BPF_EXIT_INSN(),
465 },
466 .errstr = "R1 subtraction from stack pointer",
467 .result = REJECT,
468 },
469 {
470 "non-invalid fp arithmetic",
471 .insns = {
472 BPF_MOV64_IMM(BPF_REG_0, 0),
473 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
474 BPF_EXIT_INSN(),
475 },
476 .result = ACCEPT,
477 },
478 {
479 "invalid argument register",
480 .insns = {
481 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
482 BPF_FUNC_get_cgroup_classid),
483 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
484 BPF_FUNC_get_cgroup_classid),
485 BPF_EXIT_INSN(),
486 },
487 .errstr = "R1 !read_ok",
488 .result = REJECT,
489 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
490 },
491 {
492 "non-invalid argument register",
493 .insns = {
494 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
495 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
496 BPF_FUNC_get_cgroup_classid),
497 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
498 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
499 BPF_FUNC_get_cgroup_classid),
500 BPF_EXIT_INSN(),
501 },
502 .result = ACCEPT,
503 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
504 },
505 {
506 "check valid spill/fill",
507 .insns = {
508 /* spill R1(ctx) into stack */
509 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
510 /* fill it back into R2 */
511 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
512 /* should be able to access R0 = *(R2 + 8) */
513 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
514 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
515 BPF_EXIT_INSN(),
516 },
517 .errstr_unpriv = "R0 leaks addr",
518 .result = ACCEPT,
519 .result_unpriv = REJECT,
520 },
521 {
522 "check valid spill/fill, skb mark",
523 .insns = {
524 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
525 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
526 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
527 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
528 offsetof(struct __sk_buff, mark)),
529 BPF_EXIT_INSN(),
530 },
531 .result = ACCEPT,
532 .result_unpriv = ACCEPT,
533 },
534 {
535 "check corrupted spill/fill",
536 .insns = {
537 /* spill R1(ctx) into stack */
538 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
539 /* mess up with R1 pointer on stack */
540 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
541 /* fill back into R0 should fail */
542 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
543 BPF_EXIT_INSN(),
544 },
545 .errstr_unpriv = "attempt to corrupt spilled",
546 .errstr = "corrupted spill",
547 .result = REJECT,
548 },
549 {
550 "invalid src register in STX",
551 .insns = {
552 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
553 BPF_EXIT_INSN(),
554 },
555 .errstr = "R15 is invalid",
556 .result = REJECT,
557 },
558 {
559 "invalid dst register in STX",
560 .insns = {
561 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
562 BPF_EXIT_INSN(),
563 },
564 .errstr = "R14 is invalid",
565 .result = REJECT,
566 },
567 {
568 "invalid dst register in ST",
569 .insns = {
570 BPF_ST_MEM(BPF_B, 14, -1, -1),
571 BPF_EXIT_INSN(),
572 },
573 .errstr = "R14 is invalid",
574 .result = REJECT,
575 },
576 {
577 "invalid src register in LDX",
578 .insns = {
579 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
580 BPF_EXIT_INSN(),
581 },
582 .errstr = "R12 is invalid",
583 .result = REJECT,
584 },
585 {
586 "invalid dst register in LDX",
587 .insns = {
588 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
589 BPF_EXIT_INSN(),
590 },
591 .errstr = "R11 is invalid",
592 .result = REJECT,
593 },
594 {
595 "junk insn",
596 .insns = {
597 BPF_RAW_INSN(0, 0, 0, 0, 0),
598 BPF_EXIT_INSN(),
599 },
600 .errstr = "invalid BPF_LD_IMM",
601 .result = REJECT,
602 },
603 {
604 "junk insn2",
605 .insns = {
606 BPF_RAW_INSN(1, 0, 0, 0, 0),
607 BPF_EXIT_INSN(),
608 },
609 .errstr = "BPF_LDX uses reserved fields",
610 .result = REJECT,
611 },
612 {
613 "junk insn3",
614 .insns = {
615 BPF_RAW_INSN(-1, 0, 0, 0, 0),
616 BPF_EXIT_INSN(),
617 },
618 .errstr = "invalid BPF_ALU opcode f0",
619 .result = REJECT,
620 },
621 {
622 "junk insn4",
623 .insns = {
624 BPF_RAW_INSN(-1, -1, -1, -1, -1),
625 BPF_EXIT_INSN(),
626 },
627 .errstr = "invalid BPF_ALU opcode f0",
628 .result = REJECT,
629 },
630 {
631 "junk insn5",
632 .insns = {
633 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
634 BPF_EXIT_INSN(),
635 },
636 .errstr = "BPF_ALU uses reserved fields",
637 .result = REJECT,
638 },
639 {
640 "misaligned read from stack",
641 .insns = {
642 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
643 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
644 BPF_EXIT_INSN(),
645 },
646 .errstr = "misaligned stack access",
647 .result = REJECT,
648 },
649 {
650 "invalid map_fd for function call",
651 .insns = {
652 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
653 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
655 BPF_LD_MAP_FD(BPF_REG_1, 0),
656 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
657 BPF_FUNC_map_delete_elem),
658 BPF_EXIT_INSN(),
659 },
660 .errstr = "fd 0 is not pointing to valid bpf_map",
661 .result = REJECT,
662 },
663 {
664 "don't check return value before access",
665 .insns = {
666 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
667 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
668 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
669 BPF_LD_MAP_FD(BPF_REG_1, 0),
670 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
671 BPF_FUNC_map_lookup_elem),
672 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
673 BPF_EXIT_INSN(),
674 },
675 .fixup_map1 = { 3 },
676 .errstr = "R0 invalid mem access 'map_value_or_null'",
677 .result = REJECT,
678 },
679 {
680 "access memory with incorrect alignment",
681 .insns = {
682 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
683 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
684 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
685 BPF_LD_MAP_FD(BPF_REG_1, 0),
686 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
687 BPF_FUNC_map_lookup_elem),
688 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
689 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
690 BPF_EXIT_INSN(),
691 },
692 .fixup_map1 = { 3 },
693 .errstr = "misaligned value access",
694 .result = REJECT,
695 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
696 },
697 {
698 "sometimes access memory with incorrect alignment",
699 .insns = {
700 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
701 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
703 BPF_LD_MAP_FD(BPF_REG_1, 0),
704 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
705 BPF_FUNC_map_lookup_elem),
706 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
707 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
708 BPF_EXIT_INSN(),
709 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
710 BPF_EXIT_INSN(),
711 },
712 .fixup_map1 = { 3 },
713 .errstr = "R0 invalid mem access",
714 .errstr_unpriv = "R0 leaks addr",
715 .result = REJECT,
716 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
717 },
718 {
719 "jump test 1",
720 .insns = {
721 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
722 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
723 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
724 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
725 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
726 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
727 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
728 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
729 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
730 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
731 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
732 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
733 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
734 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
735 BPF_MOV64_IMM(BPF_REG_0, 0),
736 BPF_EXIT_INSN(),
737 },
738 .errstr_unpriv = "R1 pointer comparison",
739 .result_unpriv = REJECT,
740 .result = ACCEPT,
741 },
742 {
743 "jump test 2",
744 .insns = {
745 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
746 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
747 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
748 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
749 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
750 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
751 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
752 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
753 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
754 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
756 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
757 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
758 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
759 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
760 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
761 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
762 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
763 BPF_MOV64_IMM(BPF_REG_0, 0),
764 BPF_EXIT_INSN(),
765 },
766 .errstr_unpriv = "R1 pointer comparison",
767 .result_unpriv = REJECT,
768 .result = ACCEPT,
769 },
770 {
771 "jump test 3",
772 .insns = {
773 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
774 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
775 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
776 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
777 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
778 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
779 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
780 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
781 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
782 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
783 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
784 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
785 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
786 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
787 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
789 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
790 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
791 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
792 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
793 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
794 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
795 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
796 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
797 BPF_LD_MAP_FD(BPF_REG_1, 0),
798 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
799 BPF_FUNC_map_delete_elem),
800 BPF_EXIT_INSN(),
801 },
802 .fixup_map1 = { 24 },
803 .errstr_unpriv = "R1 pointer comparison",
804 .result_unpriv = REJECT,
805 .result = ACCEPT,
806 },
807 {
808 "jump test 4",
809 .insns = {
810 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
811 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
812 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
813 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
814 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
815 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
816 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
817 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
818 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
820 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
821 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
822 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
823 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
824 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
825 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
828 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
829 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
830 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
831 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
832 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
833 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
834 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
835 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
836 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
837 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
838 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
839 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
840 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
841 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
842 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
843 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
844 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
845 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
847 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
848 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
849 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
850 BPF_MOV64_IMM(BPF_REG_0, 0),
851 BPF_EXIT_INSN(),
852 },
853 .errstr_unpriv = "R1 pointer comparison",
854 .result_unpriv = REJECT,
855 .result = ACCEPT,
856 },
857 {
858 "jump test 5",
859 .insns = {
860 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
861 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
862 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
863 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
864 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
865 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
866 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
867 BPF_MOV64_IMM(BPF_REG_0, 0),
868 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
869 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
870 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
871 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
872 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
873 BPF_MOV64_IMM(BPF_REG_0, 0),
874 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
875 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
876 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
877 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
878 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
879 BPF_MOV64_IMM(BPF_REG_0, 0),
880 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
881 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
882 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
883 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
884 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
885 BPF_MOV64_IMM(BPF_REG_0, 0),
886 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
887 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
888 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
889 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
890 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
891 BPF_MOV64_IMM(BPF_REG_0, 0),
892 BPF_EXIT_INSN(),
893 },
894 .errstr_unpriv = "R1 pointer comparison",
895 .result_unpriv = REJECT,
896 .result = ACCEPT,
897 },
898 {
899 "access skb fields ok",
900 .insns = {
901 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
902 offsetof(struct __sk_buff, len)),
903 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
904 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
905 offsetof(struct __sk_buff, mark)),
906 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
907 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
908 offsetof(struct __sk_buff, pkt_type)),
909 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
910 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
911 offsetof(struct __sk_buff, queue_mapping)),
912 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
913 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
914 offsetof(struct __sk_buff, protocol)),
915 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
916 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
917 offsetof(struct __sk_buff, vlan_present)),
918 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
919 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
920 offsetof(struct __sk_buff, vlan_tci)),
921 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
922 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
923 offsetof(struct __sk_buff, napi_id)),
924 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
925 BPF_EXIT_INSN(),
926 },
927 .result = ACCEPT,
928 },
929 {
930 "access skb fields bad1",
931 .insns = {
932 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
933 BPF_EXIT_INSN(),
934 },
935 .errstr = "invalid bpf_context access",
936 .result = REJECT,
937 },
938 {
939 "access skb fields bad2",
940 .insns = {
941 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
942 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
943 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
944 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
945 BPF_LD_MAP_FD(BPF_REG_1, 0),
946 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
947 BPF_FUNC_map_lookup_elem),
948 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
949 BPF_EXIT_INSN(),
950 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
951 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
952 offsetof(struct __sk_buff, pkt_type)),
953 BPF_EXIT_INSN(),
954 },
955 .fixup_map1 = { 4 },
956 .errstr = "different pointers",
957 .errstr_unpriv = "R1 pointer comparison",
958 .result = REJECT,
959 },
960 {
961 "access skb fields bad3",
962 .insns = {
963 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
964 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
965 offsetof(struct __sk_buff, pkt_type)),
966 BPF_EXIT_INSN(),
967 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
968 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
970 BPF_LD_MAP_FD(BPF_REG_1, 0),
971 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
972 BPF_FUNC_map_lookup_elem),
973 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
974 BPF_EXIT_INSN(),
975 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
976 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
977 },
978 .fixup_map1 = { 6 },
979 .errstr = "different pointers",
980 .errstr_unpriv = "R1 pointer comparison",
981 .result = REJECT,
982 },
983 {
984 "access skb fields bad4",
985 .insns = {
986 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
987 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
988 offsetof(struct __sk_buff, len)),
989 BPF_MOV64_IMM(BPF_REG_0, 0),
990 BPF_EXIT_INSN(),
991 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
992 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
993 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
994 BPF_LD_MAP_FD(BPF_REG_1, 0),
995 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
996 BPF_FUNC_map_lookup_elem),
997 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
998 BPF_EXIT_INSN(),
999 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1000 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1001 },
1002 .fixup_map1 = { 7 },
1003 .errstr = "different pointers",
1004 .errstr_unpriv = "R1 pointer comparison",
1005 .result = REJECT,
1006 },
1007 {
1008 "invalid access __sk_buff family",
1009 .insns = {
1010 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1011 offsetof(struct __sk_buff, family)),
1012 BPF_EXIT_INSN(),
1013 },
1014 .errstr = "invalid bpf_context access",
1015 .result = REJECT,
1016 },
1017 {
1018 "invalid access __sk_buff remote_ip4",
1019 .insns = {
1020 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1021 offsetof(struct __sk_buff, remote_ip4)),
1022 BPF_EXIT_INSN(),
1023 },
1024 .errstr = "invalid bpf_context access",
1025 .result = REJECT,
1026 },
1027 {
1028 "invalid access __sk_buff local_ip4",
1029 .insns = {
1030 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1031 offsetof(struct __sk_buff, local_ip4)),
1032 BPF_EXIT_INSN(),
1033 },
1034 .errstr = "invalid bpf_context access",
1035 .result = REJECT,
1036 },
1037 {
1038 "invalid access __sk_buff remote_ip6",
1039 .insns = {
1040 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1041 offsetof(struct __sk_buff, remote_ip6)),
1042 BPF_EXIT_INSN(),
1043 },
1044 .errstr = "invalid bpf_context access",
1045 .result = REJECT,
1046 },
1047 {
1048 "invalid access __sk_buff local_ip6",
1049 .insns = {
1050 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1051 offsetof(struct __sk_buff, local_ip6)),
1052 BPF_EXIT_INSN(),
1053 },
1054 .errstr = "invalid bpf_context access",
1055 .result = REJECT,
1056 },
1057 {
1058 "invalid access __sk_buff remote_port",
1059 .insns = {
1060 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1061 offsetof(struct __sk_buff, remote_port)),
1062 BPF_EXIT_INSN(),
1063 },
1064 .errstr = "invalid bpf_context access",
1065 .result = REJECT,
1066 },
1067 {
1068 "invalid access __sk_buff remote_port",
1069 .insns = {
1070 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1071 offsetof(struct __sk_buff, local_port)),
1072 BPF_EXIT_INSN(),
1073 },
1074 .errstr = "invalid bpf_context access",
1075 .result = REJECT,
1076 },
1077 {
1078 "valid access __sk_buff family",
1079 .insns = {
1080 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1081 offsetof(struct __sk_buff, family)),
1082 BPF_EXIT_INSN(),
1083 },
1084 .result = ACCEPT,
1085 .prog_type = BPF_PROG_TYPE_SK_SKB,
1086 },
1087 {
1088 "valid access __sk_buff remote_ip4",
1089 .insns = {
1090 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1091 offsetof(struct __sk_buff, remote_ip4)),
1092 BPF_EXIT_INSN(),
1093 },
1094 .result = ACCEPT,
1095 .prog_type = BPF_PROG_TYPE_SK_SKB,
1096 },
1097 {
1098 "valid access __sk_buff local_ip4",
1099 .insns = {
1100 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1101 offsetof(struct __sk_buff, local_ip4)),
1102 BPF_EXIT_INSN(),
1103 },
1104 .result = ACCEPT,
1105 .prog_type = BPF_PROG_TYPE_SK_SKB,
1106 },
1107 {
1108 "valid access __sk_buff remote_ip6",
1109 .insns = {
1110 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1111 offsetof(struct __sk_buff, remote_ip6[0])),
1112 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1113 offsetof(struct __sk_buff, remote_ip6[1])),
1114 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1115 offsetof(struct __sk_buff, remote_ip6[2])),
1116 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1117 offsetof(struct __sk_buff, remote_ip6[3])),
1118 BPF_EXIT_INSN(),
1119 },
1120 .result = ACCEPT,
1121 .prog_type = BPF_PROG_TYPE_SK_SKB,
1122 },
1123 {
1124 "valid access __sk_buff local_ip6",
1125 .insns = {
1126 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1127 offsetof(struct __sk_buff, local_ip6[0])),
1128 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1129 offsetof(struct __sk_buff, local_ip6[1])),
1130 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1131 offsetof(struct __sk_buff, local_ip6[2])),
1132 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1133 offsetof(struct __sk_buff, local_ip6[3])),
1134 BPF_EXIT_INSN(),
1135 },
1136 .result = ACCEPT,
1137 .prog_type = BPF_PROG_TYPE_SK_SKB,
1138 },
1139 {
1140 "valid access __sk_buff remote_port",
1141 .insns = {
1142 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1143 offsetof(struct __sk_buff, remote_port)),
1144 BPF_EXIT_INSN(),
1145 },
1146 .result = ACCEPT,
1147 .prog_type = BPF_PROG_TYPE_SK_SKB,
1148 },
1149 {
1150 "valid access __sk_buff remote_port",
1151 .insns = {
1152 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1153 offsetof(struct __sk_buff, local_port)),
1154 BPF_EXIT_INSN(),
1155 },
1156 .result = ACCEPT,
1157 .prog_type = BPF_PROG_TYPE_SK_SKB,
1158 },
1159 {
1160 "invalid access of tc_classid for SK_SKB",
1161 .insns = {
1162 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1163 offsetof(struct __sk_buff, tc_classid)),
1164 BPF_EXIT_INSN(),
1165 },
1166 .result = REJECT,
1167 .prog_type = BPF_PROG_TYPE_SK_SKB,
1168 .errstr = "invalid bpf_context access",
1169 },
1170 {
1171 "invalid access of skb->mark for SK_SKB",
1172 .insns = {
1173 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1174 offsetof(struct __sk_buff, mark)),
1175 BPF_EXIT_INSN(),
1176 },
1177 .result = REJECT,
1178 .prog_type = BPF_PROG_TYPE_SK_SKB,
1179 .errstr = "invalid bpf_context access",
1180 },
1181 {
1182 "check skb->mark is not writeable by SK_SKB",
1183 .insns = {
1184 BPF_MOV64_IMM(BPF_REG_0, 0),
1185 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1186 offsetof(struct __sk_buff, mark)),
1187 BPF_EXIT_INSN(),
1188 },
1189 .result = REJECT,
1190 .prog_type = BPF_PROG_TYPE_SK_SKB,
1191 .errstr = "invalid bpf_context access",
1192 },
1193 {
1194 "check skb->tc_index is writeable by SK_SKB",
1195 .insns = {
1196 BPF_MOV64_IMM(BPF_REG_0, 0),
1197 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1198 offsetof(struct __sk_buff, tc_index)),
1199 BPF_EXIT_INSN(),
1200 },
1201 .result = ACCEPT,
1202 .prog_type = BPF_PROG_TYPE_SK_SKB,
1203 },
1204 {
1205 "check skb->priority is writeable by SK_SKB",
1206 .insns = {
1207 BPF_MOV64_IMM(BPF_REG_0, 0),
1208 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1209 offsetof(struct __sk_buff, priority)),
1210 BPF_EXIT_INSN(),
1211 },
1212 .result = ACCEPT,
1213 .prog_type = BPF_PROG_TYPE_SK_SKB,
1214 },
1215 {
1216 "direct packet read for SK_SKB",
1217 .insns = {
1218 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1219 offsetof(struct __sk_buff, data)),
1220 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1221 offsetof(struct __sk_buff, data_end)),
1222 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1223 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1224 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1225 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1226 BPF_MOV64_IMM(BPF_REG_0, 0),
1227 BPF_EXIT_INSN(),
1228 },
1229 .result = ACCEPT,
1230 .prog_type = BPF_PROG_TYPE_SK_SKB,
1231 },
1232 {
1233 "direct packet write for SK_SKB",
1234 .insns = {
1235 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1236 offsetof(struct __sk_buff, data)),
1237 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1238 offsetof(struct __sk_buff, data_end)),
1239 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1240 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1241 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1242 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1243 BPF_MOV64_IMM(BPF_REG_0, 0),
1244 BPF_EXIT_INSN(),
1245 },
1246 .result = ACCEPT,
1247 .prog_type = BPF_PROG_TYPE_SK_SKB,
1248 },
1249 {
1250 "overlapping checks for direct packet access SK_SKB",
1251 .insns = {
1252 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1253 offsetof(struct __sk_buff, data)),
1254 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1255 offsetof(struct __sk_buff, data_end)),
1256 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1257 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1258 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1259 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1261 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1262 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1263 BPF_MOV64_IMM(BPF_REG_0, 0),
1264 BPF_EXIT_INSN(),
1265 },
1266 .result = ACCEPT,
1267 .prog_type = BPF_PROG_TYPE_SK_SKB,
1268 },
1269 {
1270 "check skb->mark is not writeable by sockets",
1271 .insns = {
1272 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1273 offsetof(struct __sk_buff, mark)),
1274 BPF_EXIT_INSN(),
1275 },
1276 .errstr = "invalid bpf_context access",
1277 .errstr_unpriv = "R1 leaks addr",
1278 .result = REJECT,
1279 },
1280 {
1281 "check skb->tc_index is not writeable by sockets",
1282 .insns = {
1283 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1284 offsetof(struct __sk_buff, tc_index)),
1285 BPF_EXIT_INSN(),
1286 },
1287 .errstr = "invalid bpf_context access",
1288 .errstr_unpriv = "R1 leaks addr",
1289 .result = REJECT,
1290 },
1291 {
1292 "check cb access: byte",
1293 .insns = {
1294 BPF_MOV64_IMM(BPF_REG_0, 0),
1295 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1296 offsetof(struct __sk_buff, cb[0])),
1297 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1298 offsetof(struct __sk_buff, cb[0]) + 1),
1299 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1300 offsetof(struct __sk_buff, cb[0]) + 2),
1301 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1302 offsetof(struct __sk_buff, cb[0]) + 3),
1303 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1304 offsetof(struct __sk_buff, cb[1])),
1305 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1306 offsetof(struct __sk_buff, cb[1]) + 1),
1307 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1308 offsetof(struct __sk_buff, cb[1]) + 2),
1309 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1310 offsetof(struct __sk_buff, cb[1]) + 3),
1311 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1312 offsetof(struct __sk_buff, cb[2])),
1313 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1314 offsetof(struct __sk_buff, cb[2]) + 1),
1315 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1316 offsetof(struct __sk_buff, cb[2]) + 2),
1317 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1318 offsetof(struct __sk_buff, cb[2]) + 3),
1319 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1320 offsetof(struct __sk_buff, cb[3])),
1321 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1322 offsetof(struct __sk_buff, cb[3]) + 1),
1323 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1324 offsetof(struct __sk_buff, cb[3]) + 2),
1325 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1326 offsetof(struct __sk_buff, cb[3]) + 3),
1327 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1328 offsetof(struct __sk_buff, cb[4])),
1329 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1330 offsetof(struct __sk_buff, cb[4]) + 1),
1331 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1332 offsetof(struct __sk_buff, cb[4]) + 2),
1333 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1334 offsetof(struct __sk_buff, cb[4]) + 3),
1335 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1336 offsetof(struct __sk_buff, cb[0])),
1337 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1338 offsetof(struct __sk_buff, cb[0]) + 1),
1339 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1340 offsetof(struct __sk_buff, cb[0]) + 2),
1341 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1342 offsetof(struct __sk_buff, cb[0]) + 3),
1343 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1344 offsetof(struct __sk_buff, cb[1])),
1345 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1346 offsetof(struct __sk_buff, cb[1]) + 1),
1347 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1348 offsetof(struct __sk_buff, cb[1]) + 2),
1349 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1350 offsetof(struct __sk_buff, cb[1]) + 3),
1351 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1352 offsetof(struct __sk_buff, cb[2])),
1353 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1354 offsetof(struct __sk_buff, cb[2]) + 1),
1355 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1356 offsetof(struct __sk_buff, cb[2]) + 2),
1357 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1358 offsetof(struct __sk_buff, cb[2]) + 3),
1359 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1360 offsetof(struct __sk_buff, cb[3])),
1361 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1362 offsetof(struct __sk_buff, cb[3]) + 1),
1363 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1364 offsetof(struct __sk_buff, cb[3]) + 2),
1365 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1366 offsetof(struct __sk_buff, cb[3]) + 3),
1367 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1368 offsetof(struct __sk_buff, cb[4])),
1369 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1370 offsetof(struct __sk_buff, cb[4]) + 1),
1371 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1372 offsetof(struct __sk_buff, cb[4]) + 2),
1373 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1374 offsetof(struct __sk_buff, cb[4]) + 3),
1375 BPF_EXIT_INSN(),
1376 },
1377 .result = ACCEPT,
1378 },
1379 {
1380 "__sk_buff->hash, offset 0, byte store not permitted",
1381 .insns = {
1382 BPF_MOV64_IMM(BPF_REG_0, 0),
1383 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1384 offsetof(struct __sk_buff, hash)),
1385 BPF_EXIT_INSN(),
1386 },
1387 .errstr = "invalid bpf_context access",
1388 .result = REJECT,
1389 },
1390 {
1391 "__sk_buff->tc_index, offset 3, byte store not permitted",
1392 .insns = {
1393 BPF_MOV64_IMM(BPF_REG_0, 0),
1394 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1395 offsetof(struct __sk_buff, tc_index) + 3),
1396 BPF_EXIT_INSN(),
1397 },
1398 .errstr = "invalid bpf_context access",
1399 .result = REJECT,
1400 },
1401 {
1402 "check skb->hash byte load permitted",
1403 .insns = {
1404 BPF_MOV64_IMM(BPF_REG_0, 0),
1405 #if __BYTE_ORDER == __LITTLE_ENDIAN
1406 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1407 offsetof(struct __sk_buff, hash)),
1408 #else
1409 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1410 offsetof(struct __sk_buff, hash) + 3),
1411 #endif
1412 BPF_EXIT_INSN(),
1413 },
1414 .result = ACCEPT,
1415 },
1416 {
1417 "check skb->hash byte load not permitted 1",
1418 .insns = {
1419 BPF_MOV64_IMM(BPF_REG_0, 0),
1420 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1421 offsetof(struct __sk_buff, hash) + 1),
1422 BPF_EXIT_INSN(),
1423 },
1424 .errstr = "invalid bpf_context access",
1425 .result = REJECT,
1426 },
1427 {
1428 "check skb->hash byte load not permitted 2",
1429 .insns = {
1430 BPF_MOV64_IMM(BPF_REG_0, 0),
1431 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1432 offsetof(struct __sk_buff, hash) + 2),
1433 BPF_EXIT_INSN(),
1434 },
1435 .errstr = "invalid bpf_context access",
1436 .result = REJECT,
1437 },
1438 {
1439 "check skb->hash byte load not permitted 3",
1440 .insns = {
1441 BPF_MOV64_IMM(BPF_REG_0, 0),
1442 #if __BYTE_ORDER == __LITTLE_ENDIAN
1443 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1444 offsetof(struct __sk_buff, hash) + 3),
1445 #else
1446 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1447 offsetof(struct __sk_buff, hash)),
1448 #endif
1449 BPF_EXIT_INSN(),
1450 },
1451 .errstr = "invalid bpf_context access",
1452 .result = REJECT,
1453 },
1454 {
1455 "check cb access: byte, wrong type",
1456 .insns = {
1457 BPF_MOV64_IMM(BPF_REG_0, 0),
1458 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1459 offsetof(struct __sk_buff, cb[0])),
1460 BPF_EXIT_INSN(),
1461 },
1462 .errstr = "invalid bpf_context access",
1463 .result = REJECT,
1464 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1465 },
1466 {
1467 "check cb access: half",
1468 .insns = {
1469 BPF_MOV64_IMM(BPF_REG_0, 0),
1470 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1471 offsetof(struct __sk_buff, cb[0])),
1472 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1473 offsetof(struct __sk_buff, cb[0]) + 2),
1474 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1475 offsetof(struct __sk_buff, cb[1])),
1476 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1477 offsetof(struct __sk_buff, cb[1]) + 2),
1478 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1479 offsetof(struct __sk_buff, cb[2])),
1480 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1481 offsetof(struct __sk_buff, cb[2]) + 2),
1482 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1483 offsetof(struct __sk_buff, cb[3])),
1484 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1485 offsetof(struct __sk_buff, cb[3]) + 2),
1486 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1487 offsetof(struct __sk_buff, cb[4])),
1488 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1489 offsetof(struct __sk_buff, cb[4]) + 2),
1490 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1491 offsetof(struct __sk_buff, cb[0])),
1492 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1493 offsetof(struct __sk_buff, cb[0]) + 2),
1494 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1495 offsetof(struct __sk_buff, cb[1])),
1496 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1497 offsetof(struct __sk_buff, cb[1]) + 2),
1498 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1499 offsetof(struct __sk_buff, cb[2])),
1500 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1501 offsetof(struct __sk_buff, cb[2]) + 2),
1502 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1503 offsetof(struct __sk_buff, cb[3])),
1504 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1505 offsetof(struct __sk_buff, cb[3]) + 2),
1506 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1507 offsetof(struct __sk_buff, cb[4])),
1508 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1509 offsetof(struct __sk_buff, cb[4]) + 2),
1510 BPF_EXIT_INSN(),
1511 },
1512 .result = ACCEPT,
1513 },
1514 {
1515 "check cb access: half, unaligned",
1516 .insns = {
1517 BPF_MOV64_IMM(BPF_REG_0, 0),
1518 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1519 offsetof(struct __sk_buff, cb[0]) + 1),
1520 BPF_EXIT_INSN(),
1521 },
1522 .errstr = "misaligned context access",
1523 .result = REJECT,
1524 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1525 },
1526 {
1527 "check __sk_buff->hash, offset 0, half store not permitted",
1528 .insns = {
1529 BPF_MOV64_IMM(BPF_REG_0, 0),
1530 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1531 offsetof(struct __sk_buff, hash)),
1532 BPF_EXIT_INSN(),
1533 },
1534 .errstr = "invalid bpf_context access",
1535 .result = REJECT,
1536 },
1537 {
1538 "check __sk_buff->tc_index, offset 2, half store not permitted",
1539 .insns = {
1540 BPF_MOV64_IMM(BPF_REG_0, 0),
1541 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1542 offsetof(struct __sk_buff, tc_index) + 2),
1543 BPF_EXIT_INSN(),
1544 },
1545 .errstr = "invalid bpf_context access",
1546 .result = REJECT,
1547 },
1548 {
1549 "check skb->hash half load permitted",
1550 .insns = {
1551 BPF_MOV64_IMM(BPF_REG_0, 0),
1552 #if __BYTE_ORDER == __LITTLE_ENDIAN
1553 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1554 offsetof(struct __sk_buff, hash)),
1555 #else
1556 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1557 offsetof(struct __sk_buff, hash) + 2),
1558 #endif
1559 BPF_EXIT_INSN(),
1560 },
1561 .result = ACCEPT,
1562 },
1563 {
1564 "check skb->hash half load not permitted",
1565 .insns = {
1566 BPF_MOV64_IMM(BPF_REG_0, 0),
1567 #if __BYTE_ORDER == __LITTLE_ENDIAN
1568 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1569 offsetof(struct __sk_buff, hash) + 2),
1570 #else
1571 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1572 offsetof(struct __sk_buff, hash)),
1573 #endif
1574 BPF_EXIT_INSN(),
1575 },
1576 .errstr = "invalid bpf_context access",
1577 .result = REJECT,
1578 },
1579 {
1580 "check cb access: half, wrong type",
1581 .insns = {
1582 BPF_MOV64_IMM(BPF_REG_0, 0),
1583 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1584 offsetof(struct __sk_buff, cb[0])),
1585 BPF_EXIT_INSN(),
1586 },
1587 .errstr = "invalid bpf_context access",
1588 .result = REJECT,
1589 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1590 },
1591 {
1592 "check cb access: word",
1593 .insns = {
1594 BPF_MOV64_IMM(BPF_REG_0, 0),
1595 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1596 offsetof(struct __sk_buff, cb[0])),
1597 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1598 offsetof(struct __sk_buff, cb[1])),
1599 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1600 offsetof(struct __sk_buff, cb[2])),
1601 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1602 offsetof(struct __sk_buff, cb[3])),
1603 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1604 offsetof(struct __sk_buff, cb[4])),
1605 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1606 offsetof(struct __sk_buff, cb[0])),
1607 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1608 offsetof(struct __sk_buff, cb[1])),
1609 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1610 offsetof(struct __sk_buff, cb[2])),
1611 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1612 offsetof(struct __sk_buff, cb[3])),
1613 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1614 offsetof(struct __sk_buff, cb[4])),
1615 BPF_EXIT_INSN(),
1616 },
1617 .result = ACCEPT,
1618 },
1619 {
1620 "check cb access: word, unaligned 1",
1621 .insns = {
1622 BPF_MOV64_IMM(BPF_REG_0, 0),
1623 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1624 offsetof(struct __sk_buff, cb[0]) + 2),
1625 BPF_EXIT_INSN(),
1626 },
1627 .errstr = "misaligned context access",
1628 .result = REJECT,
1629 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1630 },
1631 {
1632 "check cb access: word, unaligned 2",
1633 .insns = {
1634 BPF_MOV64_IMM(BPF_REG_0, 0),
1635 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1636 offsetof(struct __sk_buff, cb[4]) + 1),
1637 BPF_EXIT_INSN(),
1638 },
1639 .errstr = "misaligned context access",
1640 .result = REJECT,
1641 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1642 },
1643 {
1644 "check cb access: word, unaligned 3",
1645 .insns = {
1646 BPF_MOV64_IMM(BPF_REG_0, 0),
1647 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1648 offsetof(struct __sk_buff, cb[4]) + 2),
1649 BPF_EXIT_INSN(),
1650 },
1651 .errstr = "misaligned context access",
1652 .result = REJECT,
1653 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1654 },
1655 {
1656 "check cb access: word, unaligned 4",
1657 .insns = {
1658 BPF_MOV64_IMM(BPF_REG_0, 0),
1659 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1660 offsetof(struct __sk_buff, cb[4]) + 3),
1661 BPF_EXIT_INSN(),
1662 },
1663 .errstr = "misaligned context access",
1664 .result = REJECT,
1665 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1666 },
1667 {
1668 "check cb access: double",
1669 .insns = {
1670 BPF_MOV64_IMM(BPF_REG_0, 0),
1671 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1672 offsetof(struct __sk_buff, cb[0])),
1673 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1674 offsetof(struct __sk_buff, cb[2])),
1675 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1676 offsetof(struct __sk_buff, cb[0])),
1677 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1678 offsetof(struct __sk_buff, cb[2])),
1679 BPF_EXIT_INSN(),
1680 },
1681 .result = ACCEPT,
1682 },
1683 {
1684 "check cb access: double, unaligned 1",
1685 .insns = {
1686 BPF_MOV64_IMM(BPF_REG_0, 0),
1687 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1688 offsetof(struct __sk_buff, cb[1])),
1689 BPF_EXIT_INSN(),
1690 },
1691 .errstr = "misaligned context access",
1692 .result = REJECT,
1693 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1694 },
1695 {
1696 "check cb access: double, unaligned 2",
1697 .insns = {
1698 BPF_MOV64_IMM(BPF_REG_0, 0),
1699 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1700 offsetof(struct __sk_buff, cb[3])),
1701 BPF_EXIT_INSN(),
1702 },
1703 .errstr = "misaligned context access",
1704 .result = REJECT,
1705 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1706 },
1707 {
1708 "check cb access: double, oob 1",
1709 .insns = {
1710 BPF_MOV64_IMM(BPF_REG_0, 0),
1711 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1712 offsetof(struct __sk_buff, cb[4])),
1713 BPF_EXIT_INSN(),
1714 },
1715 .errstr = "invalid bpf_context access",
1716 .result = REJECT,
1717 },
1718 {
1719 "check cb access: double, oob 2",
1720 .insns = {
1721 BPF_MOV64_IMM(BPF_REG_0, 0),
1722 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1723 offsetof(struct __sk_buff, cb[4])),
1724 BPF_EXIT_INSN(),
1725 },
1726 .errstr = "invalid bpf_context access",
1727 .result = REJECT,
1728 },
1729 {
1730 "check __sk_buff->ifindex dw store not permitted",
1731 .insns = {
1732 BPF_MOV64_IMM(BPF_REG_0, 0),
1733 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1734 offsetof(struct __sk_buff, ifindex)),
1735 BPF_EXIT_INSN(),
1736 },
1737 .errstr = "invalid bpf_context access",
1738 .result = REJECT,
1739 },
1740 {
1741 "check __sk_buff->ifindex dw load not permitted",
1742 .insns = {
1743 BPF_MOV64_IMM(BPF_REG_0, 0),
1744 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1745 offsetof(struct __sk_buff, ifindex)),
1746 BPF_EXIT_INSN(),
1747 },
1748 .errstr = "invalid bpf_context access",
1749 .result = REJECT,
1750 },
1751 {
1752 "check cb access: double, wrong type",
1753 .insns = {
1754 BPF_MOV64_IMM(BPF_REG_0, 0),
1755 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1756 offsetof(struct __sk_buff, cb[0])),
1757 BPF_EXIT_INSN(),
1758 },
1759 .errstr = "invalid bpf_context access",
1760 .result = REJECT,
1761 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1762 },
1763 {
1764 "check out of range skb->cb access",
1765 .insns = {
1766 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1767 offsetof(struct __sk_buff, cb[0]) + 256),
1768 BPF_EXIT_INSN(),
1769 },
1770 .errstr = "invalid bpf_context access",
1771 .errstr_unpriv = "",
1772 .result = REJECT,
1773 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
1774 },
1775 {
1776 "write skb fields from socket prog",
1777 .insns = {
1778 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1779 offsetof(struct __sk_buff, cb[4])),
1780 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1781 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1782 offsetof(struct __sk_buff, mark)),
1783 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1784 offsetof(struct __sk_buff, tc_index)),
1785 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1786 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1787 offsetof(struct __sk_buff, cb[0])),
1788 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1789 offsetof(struct __sk_buff, cb[2])),
1790 BPF_EXIT_INSN(),
1791 },
1792 .result = ACCEPT,
1793 .errstr_unpriv = "R1 leaks addr",
1794 .result_unpriv = REJECT,
1795 },
1796 {
1797 "write skb fields from tc_cls_act prog",
1798 .insns = {
1799 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1800 offsetof(struct __sk_buff, cb[0])),
1801 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1802 offsetof(struct __sk_buff, mark)),
1803 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1804 offsetof(struct __sk_buff, tc_index)),
1805 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1806 offsetof(struct __sk_buff, tc_index)),
1807 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1808 offsetof(struct __sk_buff, cb[3])),
1809 BPF_EXIT_INSN(),
1810 },
1811 .errstr_unpriv = "",
1812 .result_unpriv = REJECT,
1813 .result = ACCEPT,
1814 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1815 },
1816 {
1817 "PTR_TO_STACK store/load",
1818 .insns = {
1819 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1821 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1822 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1823 BPF_EXIT_INSN(),
1824 },
1825 .result = ACCEPT,
1826 },
1827 {
1828 "PTR_TO_STACK store/load - bad alignment on off",
1829 .insns = {
1830 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1831 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1832 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1833 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1834 BPF_EXIT_INSN(),
1835 },
1836 .result = REJECT,
1837 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
1838 },
1839 {
1840 "PTR_TO_STACK store/load - bad alignment on reg",
1841 .insns = {
1842 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1843 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1844 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1845 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1846 BPF_EXIT_INSN(),
1847 },
1848 .result = REJECT,
1849 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
1850 },
1851 {
1852 "PTR_TO_STACK store/load - out of bounds low",
1853 .insns = {
1854 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1855 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1856 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1857 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1858 BPF_EXIT_INSN(),
1859 },
1860 .result = REJECT,
1861 .errstr = "invalid stack off=-79992 size=8",
1862 },
1863 {
1864 "PTR_TO_STACK store/load - out of bounds high",
1865 .insns = {
1866 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1867 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1868 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1869 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1870 BPF_EXIT_INSN(),
1871 },
1872 .result = REJECT,
1873 .errstr = "invalid stack off=0 size=8",
1874 },
1875 {
1876 "unpriv: return pointer",
1877 .insns = {
1878 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1879 BPF_EXIT_INSN(),
1880 },
1881 .result = ACCEPT,
1882 .result_unpriv = REJECT,
1883 .errstr_unpriv = "R0 leaks addr",
1884 },
1885 {
1886 "unpriv: add const to pointer",
1887 .insns = {
1888 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1889 BPF_MOV64_IMM(BPF_REG_0, 0),
1890 BPF_EXIT_INSN(),
1891 },
1892 .result = ACCEPT,
1893 },
1894 {
1895 "unpriv: add pointer to pointer",
1896 .insns = {
1897 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1898 BPF_MOV64_IMM(BPF_REG_0, 0),
1899 BPF_EXIT_INSN(),
1900 },
1901 .result = REJECT,
1902 .errstr = "R1 pointer += pointer",
1903 },
1904 {
1905 "unpriv: neg pointer",
1906 .insns = {
1907 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1908 BPF_MOV64_IMM(BPF_REG_0, 0),
1909 BPF_EXIT_INSN(),
1910 },
1911 .result = ACCEPT,
1912 .result_unpriv = REJECT,
1913 .errstr_unpriv = "R1 pointer arithmetic",
1914 },
1915 {
1916 "unpriv: cmp pointer with const",
1917 .insns = {
1918 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1919 BPF_MOV64_IMM(BPF_REG_0, 0),
1920 BPF_EXIT_INSN(),
1921 },
1922 .result = ACCEPT,
1923 .result_unpriv = REJECT,
1924 .errstr_unpriv = "R1 pointer comparison",
1925 },
1926 {
1927 "unpriv: cmp pointer with pointer",
1928 .insns = {
1929 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1930 BPF_MOV64_IMM(BPF_REG_0, 0),
1931 BPF_EXIT_INSN(),
1932 },
1933 .result = ACCEPT,
1934 .result_unpriv = REJECT,
1935 .errstr_unpriv = "R10 pointer comparison",
1936 },
1937 {
1938 "unpriv: check that printk is disallowed",
1939 .insns = {
1940 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1941 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1943 BPF_MOV64_IMM(BPF_REG_2, 8),
1944 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1945 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1946 BPF_FUNC_trace_printk),
1947 BPF_MOV64_IMM(BPF_REG_0, 0),
1948 BPF_EXIT_INSN(),
1949 },
1950 .errstr_unpriv = "unknown func bpf_trace_printk#6",
1951 .result_unpriv = REJECT,
1952 .result = ACCEPT,
1953 },
1954 {
1955 "unpriv: pass pointer to helper function",
1956 .insns = {
1957 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1958 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1960 BPF_LD_MAP_FD(BPF_REG_1, 0),
1961 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1962 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1963 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1964 BPF_FUNC_map_update_elem),
1965 BPF_MOV64_IMM(BPF_REG_0, 0),
1966 BPF_EXIT_INSN(),
1967 },
1968 .fixup_map1 = { 3 },
1969 .errstr_unpriv = "R4 leaks addr",
1970 .result_unpriv = REJECT,
1971 .result = ACCEPT,
1972 },
1973 {
1974 "unpriv: indirectly pass pointer on stack to helper function",
1975 .insns = {
1976 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1977 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1978 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1979 BPF_LD_MAP_FD(BPF_REG_1, 0),
1980 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1981 BPF_FUNC_map_lookup_elem),
1982 BPF_MOV64_IMM(BPF_REG_0, 0),
1983 BPF_EXIT_INSN(),
1984 },
1985 .fixup_map1 = { 3 },
1986 .errstr = "invalid indirect read from stack off -8+0 size 8",
1987 .result = REJECT,
1988 },
1989 {
1990 "unpriv: mangle pointer on stack 1",
1991 .insns = {
1992 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1993 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1994 BPF_MOV64_IMM(BPF_REG_0, 0),
1995 BPF_EXIT_INSN(),
1996 },
1997 .errstr_unpriv = "attempt to corrupt spilled",
1998 .result_unpriv = REJECT,
1999 .result = ACCEPT,
2000 },
2001 {
2002 "unpriv: mangle pointer on stack 2",
2003 .insns = {
2004 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2005 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2006 BPF_MOV64_IMM(BPF_REG_0, 0),
2007 BPF_EXIT_INSN(),
2008 },
2009 .errstr_unpriv = "attempt to corrupt spilled",
2010 .result_unpriv = REJECT,
2011 .result = ACCEPT,
2012 },
2013 {
2014 "unpriv: read pointer from stack in small chunks",
2015 .insns = {
2016 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2017 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2018 BPF_MOV64_IMM(BPF_REG_0, 0),
2019 BPF_EXIT_INSN(),
2020 },
2021 .errstr = "invalid size",
2022 .result = REJECT,
2023 },
2024 {
2025 "unpriv: write pointer into ctx",
2026 .insns = {
2027 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2028 BPF_MOV64_IMM(BPF_REG_0, 0),
2029 BPF_EXIT_INSN(),
2030 },
2031 .errstr_unpriv = "R1 leaks addr",
2032 .result_unpriv = REJECT,
2033 .errstr = "invalid bpf_context access",
2034 .result = REJECT,
2035 },
2036 {
2037 "unpriv: spill/fill of ctx",
2038 .insns = {
2039 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2040 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2041 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2042 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2043 BPF_MOV64_IMM(BPF_REG_0, 0),
2044 BPF_EXIT_INSN(),
2045 },
2046 .result = ACCEPT,
2047 },
2048 {
2049 "unpriv: spill/fill of ctx 2",
2050 .insns = {
2051 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2053 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2054 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2055 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2056 BPF_FUNC_get_hash_recalc),
2057 BPF_EXIT_INSN(),
2058 },
2059 .result = ACCEPT,
2060 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2061 },
2062 {
2063 "unpriv: spill/fill of ctx 3",
2064 .insns = {
2065 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2067 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2068 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2069 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2070 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2071 BPF_FUNC_get_hash_recalc),
2072 BPF_EXIT_INSN(),
2073 },
2074 .result = REJECT,
2075 .errstr = "R1 type=fp expected=ctx",
2076 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2077 },
2078 {
2079 "unpriv: spill/fill of ctx 4",
2080 .insns = {
2081 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2083 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2084 BPF_MOV64_IMM(BPF_REG_0, 1),
2085 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2086 BPF_REG_0, -8, 0),
2087 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2088 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2089 BPF_FUNC_get_hash_recalc),
2090 BPF_EXIT_INSN(),
2091 },
2092 .result = REJECT,
2093 .errstr = "R1 type=inv expected=ctx",
2094 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2095 },
2096 {
2097 "unpriv: spill/fill of different pointers stx",
2098 .insns = {
2099 BPF_MOV64_IMM(BPF_REG_3, 42),
2100 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2101 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2102 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2105 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2106 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2107 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2108 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2109 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2110 offsetof(struct __sk_buff, mark)),
2111 BPF_MOV64_IMM(BPF_REG_0, 0),
2112 BPF_EXIT_INSN(),
2113 },
2114 .result = REJECT,
2115 .errstr = "same insn cannot be used with different pointers",
2116 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2117 },
2118 {
2119 "unpriv: spill/fill of different pointers ldx",
2120 .insns = {
2121 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2123 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2124 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2125 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2126 -(__s32)offsetof(struct bpf_perf_event_data,
2127 sample_period) - 8),
2128 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2129 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2130 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2131 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2132 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2133 offsetof(struct bpf_perf_event_data,
2134 sample_period)),
2135 BPF_MOV64_IMM(BPF_REG_0, 0),
2136 BPF_EXIT_INSN(),
2137 },
2138 .result = REJECT,
2139 .errstr = "same insn cannot be used with different pointers",
2140 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2141 },
2142 {
2143 "unpriv: write pointer into map elem value",
2144 .insns = {
2145 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2146 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2147 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2148 BPF_LD_MAP_FD(BPF_REG_1, 0),
2149 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2150 BPF_FUNC_map_lookup_elem),
2151 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2152 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2153 BPF_EXIT_INSN(),
2154 },
2155 .fixup_map1 = { 3 },
2156 .errstr_unpriv = "R0 leaks addr",
2157 .result_unpriv = REJECT,
2158 .result = ACCEPT,
2159 },
2160 {
2161 "unpriv: partial copy of pointer",
2162 .insns = {
2163 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2164 BPF_MOV64_IMM(BPF_REG_0, 0),
2165 BPF_EXIT_INSN(),
2166 },
2167 .errstr_unpriv = "R10 partial copy",
2168 .result_unpriv = REJECT,
2169 .result = ACCEPT,
2170 },
2171 {
2172 "unpriv: pass pointer to tail_call",
2173 .insns = {
2174 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2175 BPF_LD_MAP_FD(BPF_REG_2, 0),
2176 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2177 BPF_FUNC_tail_call),
2178 BPF_MOV64_IMM(BPF_REG_0, 0),
2179 BPF_EXIT_INSN(),
2180 },
2181 .fixup_prog = { 1 },
2182 .errstr_unpriv = "R3 leaks addr into helper",
2183 .result_unpriv = REJECT,
2184 .result = ACCEPT,
2185 },
2186 {
2187 "unpriv: cmp map pointer with zero",
2188 .insns = {
2189 BPF_MOV64_IMM(BPF_REG_1, 0),
2190 BPF_LD_MAP_FD(BPF_REG_1, 0),
2191 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2192 BPF_MOV64_IMM(BPF_REG_0, 0),
2193 BPF_EXIT_INSN(),
2194 },
2195 .fixup_map1 = { 1 },
2196 .errstr_unpriv = "R1 pointer comparison",
2197 .result_unpriv = REJECT,
2198 .result = ACCEPT,
2199 },
2200 {
2201 "unpriv: write into frame pointer",
2202 .insns = {
2203 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2204 BPF_MOV64_IMM(BPF_REG_0, 0),
2205 BPF_EXIT_INSN(),
2206 },
2207 .errstr = "frame pointer is read only",
2208 .result = REJECT,
2209 },
2210 {
2211 "unpriv: spill/fill frame pointer",
2212 .insns = {
2213 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2215 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2216 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2217 BPF_MOV64_IMM(BPF_REG_0, 0),
2218 BPF_EXIT_INSN(),
2219 },
2220 .errstr = "frame pointer is read only",
2221 .result = REJECT,
2222 },
2223 {
2224 "unpriv: cmp of frame pointer",
2225 .insns = {
2226 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2227 BPF_MOV64_IMM(BPF_REG_0, 0),
2228 BPF_EXIT_INSN(),
2229 },
2230 .errstr_unpriv = "R10 pointer comparison",
2231 .result_unpriv = REJECT,
2232 .result = ACCEPT,
2233 },
2234 {
2235 "unpriv: adding of fp",
2236 .insns = {
2237 BPF_MOV64_IMM(BPF_REG_0, 0),
2238 BPF_MOV64_IMM(BPF_REG_1, 0),
2239 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2240 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2241 BPF_EXIT_INSN(),
2242 },
2243 .result = ACCEPT,
2244 },
2245 {
2246 "unpriv: cmp of stack pointer",
2247 .insns = {
2248 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2249 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2251 BPF_MOV64_IMM(BPF_REG_0, 0),
2252 BPF_EXIT_INSN(),
2253 },
2254 .errstr_unpriv = "R2 pointer comparison",
2255 .result_unpriv = REJECT,
2256 .result = ACCEPT,
2257 },
2258 {
2259 "stack pointer arithmetic",
2260 .insns = {
2261 BPF_MOV64_IMM(BPF_REG_1, 4),
2262 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2263 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2264 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2266 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2267 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2268 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2269 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2271 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2272 BPF_MOV64_IMM(BPF_REG_0, 0),
2273 BPF_EXIT_INSN(),
2274 },
2275 .result = ACCEPT,
2276 },
2277 {
2278 "raw_stack: no skb_load_bytes",
2279 .insns = {
2280 BPF_MOV64_IMM(BPF_REG_2, 4),
2281 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2283 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2284 BPF_MOV64_IMM(BPF_REG_4, 8),
2285 /* Call to skb_load_bytes() omitted. */
2286 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2287 BPF_EXIT_INSN(),
2288 },
2289 .result = REJECT,
2290 .errstr = "invalid read from stack off -8+0 size 8",
2291 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2292 },
2293 {
2294 "raw_stack: skb_load_bytes, negative len",
2295 .insns = {
2296 BPF_MOV64_IMM(BPF_REG_2, 4),
2297 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2298 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2299 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2300 BPF_MOV64_IMM(BPF_REG_4, -8),
2301 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2302 BPF_FUNC_skb_load_bytes),
2303 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2304 BPF_EXIT_INSN(),
2305 },
2306 .result = REJECT,
2307 .errstr = "R4 min value is negative",
2308 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2309 },
2310 {
2311 "raw_stack: skb_load_bytes, negative len 2",
2312 .insns = {
2313 BPF_MOV64_IMM(BPF_REG_2, 4),
2314 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2316 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2317 BPF_MOV64_IMM(BPF_REG_4, ~0),
2318 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2319 BPF_FUNC_skb_load_bytes),
2320 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2321 BPF_EXIT_INSN(),
2322 },
2323 .result = REJECT,
2324 .errstr = "R4 min value is negative",
2325 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2326 },
2327 {
2328 "raw_stack: skb_load_bytes, zero len",
2329 .insns = {
2330 BPF_MOV64_IMM(BPF_REG_2, 4),
2331 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2332 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2333 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2334 BPF_MOV64_IMM(BPF_REG_4, 0),
2335 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2336 BPF_FUNC_skb_load_bytes),
2337 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2338 BPF_EXIT_INSN(),
2339 },
2340 .result = REJECT,
2341 .errstr = "invalid stack type R3",
2342 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2343 },
2344 {
2345 "raw_stack: skb_load_bytes, no init",
2346 .insns = {
2347 BPF_MOV64_IMM(BPF_REG_2, 4),
2348 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2349 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2350 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2351 BPF_MOV64_IMM(BPF_REG_4, 8),
2352 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2353 BPF_FUNC_skb_load_bytes),
2354 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2355 BPF_EXIT_INSN(),
2356 },
2357 .result = ACCEPT,
2358 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2359 },
2360 {
2361 "raw_stack: skb_load_bytes, init",
2362 .insns = {
2363 BPF_MOV64_IMM(BPF_REG_2, 4),
2364 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2366 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
2367 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2368 BPF_MOV64_IMM(BPF_REG_4, 8),
2369 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2370 BPF_FUNC_skb_load_bytes),
2371 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2372 BPF_EXIT_INSN(),
2373 },
2374 .result = ACCEPT,
2375 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2376 },
2377 {
2378 "raw_stack: skb_load_bytes, spilled regs around bounds",
2379 .insns = {
2380 BPF_MOV64_IMM(BPF_REG_2, 4),
2381 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2382 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
2383 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2384 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
2385 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2386 BPF_MOV64_IMM(BPF_REG_4, 8),
2387 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2388 BPF_FUNC_skb_load_bytes),
2389 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2390 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2391 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2392 offsetof(struct __sk_buff, mark)),
2393 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2394 offsetof(struct __sk_buff, priority)),
2395 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2396 BPF_EXIT_INSN(),
2397 },
2398 .result = ACCEPT,
2399 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2400 },
2401 {
2402 "raw_stack: skb_load_bytes, spilled regs corruption",
2403 .insns = {
2404 BPF_MOV64_IMM(BPF_REG_2, 4),
2405 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2406 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2407 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2408 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2409 BPF_MOV64_IMM(BPF_REG_4, 8),
2410 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2411 BPF_FUNC_skb_load_bytes),
2412 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2413 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2414 offsetof(struct __sk_buff, mark)),
2415 BPF_EXIT_INSN(),
2416 },
2417 .result = REJECT,
2418 .errstr = "R0 invalid mem access 'inv'",
2419 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2420 },
2421 {
2422 "raw_stack: skb_load_bytes, spilled regs corruption 2",
2423 .insns = {
2424 BPF_MOV64_IMM(BPF_REG_2, 4),
2425 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2426 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
2427 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2428 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2429 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
2430 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2431 BPF_MOV64_IMM(BPF_REG_4, 8),
2432 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2433 BPF_FUNC_skb_load_bytes),
2434 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2435 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2436 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
2437 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2438 offsetof(struct __sk_buff, mark)),
2439 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2440 offsetof(struct __sk_buff, priority)),
2441 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2442 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
2443 offsetof(struct __sk_buff, pkt_type)),
2444 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2445 BPF_EXIT_INSN(),
2446 },
2447 .result = REJECT,
2448 .errstr = "R3 invalid mem access 'inv'",
2449 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2450 },
2451 {
2452 "raw_stack: skb_load_bytes, spilled regs + data",
2453 .insns = {
2454 BPF_MOV64_IMM(BPF_REG_2, 4),
2455 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
2457 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2458 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2459 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
2460 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2461 BPF_MOV64_IMM(BPF_REG_4, 8),
2462 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2463 BPF_FUNC_skb_load_bytes),
2464 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2465 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2466 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
2467 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2468 offsetof(struct __sk_buff, mark)),
2469 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2470 offsetof(struct __sk_buff, priority)),
2471 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2472 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2473 BPF_EXIT_INSN(),
2474 },
2475 .result = ACCEPT,
2476 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2477 },
2478 {
2479 "raw_stack: skb_load_bytes, invalid access 1",
2480 .insns = {
2481 BPF_MOV64_IMM(BPF_REG_2, 4),
2482 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2483 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2484 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2485 BPF_MOV64_IMM(BPF_REG_4, 8),
2486 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2487 BPF_FUNC_skb_load_bytes),
2488 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2489 BPF_EXIT_INSN(),
2490 },
2491 .result = REJECT,
2492 .errstr = "invalid stack type R3 off=-513 access_size=8",
2493 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2494 },
2495 {
2496 "raw_stack: skb_load_bytes, invalid access 2",
2497 .insns = {
2498 BPF_MOV64_IMM(BPF_REG_2, 4),
2499 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2500 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2501 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2502 BPF_MOV64_IMM(BPF_REG_4, 8),
2503 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2504 BPF_FUNC_skb_load_bytes),
2505 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2506 BPF_EXIT_INSN(),
2507 },
2508 .result = REJECT,
2509 .errstr = "invalid stack type R3 off=-1 access_size=8",
2510 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2511 },
2512 {
2513 "raw_stack: skb_load_bytes, invalid access 3",
2514 .insns = {
2515 BPF_MOV64_IMM(BPF_REG_2, 4),
2516 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2517 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2518 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2519 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
2520 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2521 BPF_FUNC_skb_load_bytes),
2522 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2523 BPF_EXIT_INSN(),
2524 },
2525 .result = REJECT,
2526 .errstr = "R4 min value is negative",
2527 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2528 },
2529 {
2530 "raw_stack: skb_load_bytes, invalid access 4",
2531 .insns = {
2532 BPF_MOV64_IMM(BPF_REG_2, 4),
2533 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2535 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2536 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
2537 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2538 BPF_FUNC_skb_load_bytes),
2539 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2540 BPF_EXIT_INSN(),
2541 },
2542 .result = REJECT,
2543 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
2544 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2545 },
2546 {
2547 "raw_stack: skb_load_bytes, invalid access 5",
2548 .insns = {
2549 BPF_MOV64_IMM(BPF_REG_2, 4),
2550 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2552 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2553 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
2554 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2555 BPF_FUNC_skb_load_bytes),
2556 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2557 BPF_EXIT_INSN(),
2558 },
2559 .result = REJECT,
2560 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
2561 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2562 },
2563 {
2564 "raw_stack: skb_load_bytes, invalid access 6",
2565 .insns = {
2566 BPF_MOV64_IMM(BPF_REG_2, 4),
2567 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2568 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2569 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2570 BPF_MOV64_IMM(BPF_REG_4, 0),
2571 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2572 BPF_FUNC_skb_load_bytes),
2573 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2574 BPF_EXIT_INSN(),
2575 },
2576 .result = REJECT,
2577 .errstr = "invalid stack type R3 off=-512 access_size=0",
2578 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2579 },
2580 {
2581 "raw_stack: skb_load_bytes, large access",
2582 .insns = {
2583 BPF_MOV64_IMM(BPF_REG_2, 4),
2584 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2585 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2586 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2587 BPF_MOV64_IMM(BPF_REG_4, 512),
2588 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2589 BPF_FUNC_skb_load_bytes),
2590 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2591 BPF_EXIT_INSN(),
2592 },
2593 .result = ACCEPT,
2594 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2595 },
2596 {
2597 "direct packet access: test1",
2598 .insns = {
2599 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2600 offsetof(struct __sk_buff, data)),
2601 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2602 offsetof(struct __sk_buff, data_end)),
2603 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2605 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2606 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2607 BPF_MOV64_IMM(BPF_REG_0, 0),
2608 BPF_EXIT_INSN(),
2609 },
2610 .result = ACCEPT,
2611 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2612 },
2613 {
2614 "direct packet access: test2",
2615 .insns = {
2616 BPF_MOV64_IMM(BPF_REG_0, 1),
2617 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2618 offsetof(struct __sk_buff, data_end)),
2619 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2620 offsetof(struct __sk_buff, data)),
2621 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2622 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2623 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2624 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2625 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2626 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2627 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2628 offsetof(struct __sk_buff, data)),
2629 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
2630 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2631 offsetof(struct __sk_buff, len)),
2632 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
2633 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
2634 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2635 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2636 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2637 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2638 offsetof(struct __sk_buff, data_end)),
2639 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2640 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2641 BPF_MOV64_IMM(BPF_REG_0, 0),
2642 BPF_EXIT_INSN(),
2643 },
2644 .result = ACCEPT,
2645 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2646 },
2647 {
2648 "direct packet access: test3",
2649 .insns = {
2650 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2651 offsetof(struct __sk_buff, data)),
2652 BPF_MOV64_IMM(BPF_REG_0, 0),
2653 BPF_EXIT_INSN(),
2654 },
2655 .errstr = "invalid bpf_context access off=76",
2656 .result = REJECT,
2657 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2658 },
2659 {
2660 "direct packet access: test4 (write)",
2661 .insns = {
2662 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2663 offsetof(struct __sk_buff, data)),
2664 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2665 offsetof(struct __sk_buff, data_end)),
2666 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2667 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2668 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2669 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2670 BPF_MOV64_IMM(BPF_REG_0, 0),
2671 BPF_EXIT_INSN(),
2672 },
2673 .result = ACCEPT,
2674 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2675 },
2676 {
2677 "direct packet access: test5 (pkt_end >= reg, good access)",
2678 .insns = {
2679 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2680 offsetof(struct __sk_buff, data)),
2681 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2682 offsetof(struct __sk_buff, data_end)),
2683 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2684 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2685 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2686 BPF_MOV64_IMM(BPF_REG_0, 1),
2687 BPF_EXIT_INSN(),
2688 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2689 BPF_MOV64_IMM(BPF_REG_0, 0),
2690 BPF_EXIT_INSN(),
2691 },
2692 .result = ACCEPT,
2693 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2694 },
2695 {
2696 "direct packet access: test6 (pkt_end >= reg, bad access)",
2697 .insns = {
2698 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2699 offsetof(struct __sk_buff, data)),
2700 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2701 offsetof(struct __sk_buff, data_end)),
2702 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2703 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2704 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2705 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2706 BPF_MOV64_IMM(BPF_REG_0, 1),
2707 BPF_EXIT_INSN(),
2708 BPF_MOV64_IMM(BPF_REG_0, 0),
2709 BPF_EXIT_INSN(),
2710 },
2711 .errstr = "invalid access to packet",
2712 .result = REJECT,
2713 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2714 },
2715 {
2716 "direct packet access: test7 (pkt_end >= reg, both accesses)",
2717 .insns = {
2718 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2719 offsetof(struct __sk_buff, data)),
2720 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2721 offsetof(struct __sk_buff, data_end)),
2722 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2723 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2724 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2725 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2726 BPF_MOV64_IMM(BPF_REG_0, 1),
2727 BPF_EXIT_INSN(),
2728 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2729 BPF_MOV64_IMM(BPF_REG_0, 0),
2730 BPF_EXIT_INSN(),
2731 },
2732 .errstr = "invalid access to packet",
2733 .result = REJECT,
2734 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2735 },
2736 {
2737 "direct packet access: test8 (double test, variant 1)",
2738 .insns = {
2739 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2740 offsetof(struct __sk_buff, data)),
2741 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2742 offsetof(struct __sk_buff, data_end)),
2743 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2745 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2746 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2747 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2748 BPF_MOV64_IMM(BPF_REG_0, 1),
2749 BPF_EXIT_INSN(),
2750 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2751 BPF_MOV64_IMM(BPF_REG_0, 0),
2752 BPF_EXIT_INSN(),
2753 },
2754 .result = ACCEPT,
2755 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2756 },
2757 {
2758 "direct packet access: test9 (double test, variant 2)",
2759 .insns = {
2760 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2761 offsetof(struct __sk_buff, data)),
2762 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2763 offsetof(struct __sk_buff, data_end)),
2764 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2765 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2766 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2767 BPF_MOV64_IMM(BPF_REG_0, 1),
2768 BPF_EXIT_INSN(),
2769 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2770 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2771 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2772 BPF_MOV64_IMM(BPF_REG_0, 0),
2773 BPF_EXIT_INSN(),
2774 },
2775 .result = ACCEPT,
2776 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2777 },
2778 {
2779 "direct packet access: test10 (write invalid)",
2780 .insns = {
2781 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2782 offsetof(struct __sk_buff, data)),
2783 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2784 offsetof(struct __sk_buff, data_end)),
2785 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2786 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2787 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2788 BPF_MOV64_IMM(BPF_REG_0, 0),
2789 BPF_EXIT_INSN(),
2790 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2791 BPF_MOV64_IMM(BPF_REG_0, 0),
2792 BPF_EXIT_INSN(),
2793 },
2794 .errstr = "invalid access to packet",
2795 .result = REJECT,
2796 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2797 },
2798 {
2799 "direct packet access: test11 (shift, good access)",
2800 .insns = {
2801 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2802 offsetof(struct __sk_buff, data)),
2803 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2804 offsetof(struct __sk_buff, data_end)),
2805 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2807 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2808 BPF_MOV64_IMM(BPF_REG_3, 144),
2809 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2810 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2811 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2812 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2813 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2814 BPF_MOV64_IMM(BPF_REG_0, 1),
2815 BPF_EXIT_INSN(),
2816 BPF_MOV64_IMM(BPF_REG_0, 0),
2817 BPF_EXIT_INSN(),
2818 },
2819 .result = ACCEPT,
2820 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2821 },
2822 {
2823 "direct packet access: test12 (and, good access)",
2824 .insns = {
2825 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2826 offsetof(struct __sk_buff, data)),
2827 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2828 offsetof(struct __sk_buff, data_end)),
2829 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2830 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2831 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2832 BPF_MOV64_IMM(BPF_REG_3, 144),
2833 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2834 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2835 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2836 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2837 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2838 BPF_MOV64_IMM(BPF_REG_0, 1),
2839 BPF_EXIT_INSN(),
2840 BPF_MOV64_IMM(BPF_REG_0, 0),
2841 BPF_EXIT_INSN(),
2842 },
2843 .result = ACCEPT,
2844 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2845 },
2846 {
2847 "direct packet access: test13 (branches, good access)",
2848 .insns = {
2849 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2850 offsetof(struct __sk_buff, data)),
2851 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2852 offsetof(struct __sk_buff, data_end)),
2853 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2854 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2855 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2857 offsetof(struct __sk_buff, mark)),
2858 BPF_MOV64_IMM(BPF_REG_4, 1),
2859 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2860 BPF_MOV64_IMM(BPF_REG_3, 14),
2861 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2862 BPF_MOV64_IMM(BPF_REG_3, 24),
2863 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2864 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2865 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2866 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2867 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2868 BPF_MOV64_IMM(BPF_REG_0, 1),
2869 BPF_EXIT_INSN(),
2870 BPF_MOV64_IMM(BPF_REG_0, 0),
2871 BPF_EXIT_INSN(),
2872 },
2873 .result = ACCEPT,
2874 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2875 },
2876 {
2877 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2878 .insns = {
2879 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2880 offsetof(struct __sk_buff, data)),
2881 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2882 offsetof(struct __sk_buff, data_end)),
2883 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2885 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2886 BPF_MOV64_IMM(BPF_REG_5, 12),
2887 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2888 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2889 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2890 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2891 BPF_MOV64_IMM(BPF_REG_0, 1),
2892 BPF_EXIT_INSN(),
2893 BPF_MOV64_IMM(BPF_REG_0, 0),
2894 BPF_EXIT_INSN(),
2895 },
2896 .result = ACCEPT,
2897 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2898 },
2899 {
2900 "direct packet access: test15 (spill with xadd)",
2901 .insns = {
2902 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2903 offsetof(struct __sk_buff, data)),
2904 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2905 offsetof(struct __sk_buff, data_end)),
2906 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2907 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2908 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2909 BPF_MOV64_IMM(BPF_REG_5, 4096),
2910 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2911 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2912 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2913 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
2914 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
2915 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
2916 BPF_MOV64_IMM(BPF_REG_0, 0),
2917 BPF_EXIT_INSN(),
2918 },
2919 .errstr = "R2 invalid mem access 'inv'",
2920 .result = REJECT,
2921 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2922 },
2923 {
2924 "direct packet access: test16 (arith on data_end)",
2925 .insns = {
2926 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2927 offsetof(struct __sk_buff, data)),
2928 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2929 offsetof(struct __sk_buff, data_end)),
2930 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2931 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2932 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
2933 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2934 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2935 BPF_MOV64_IMM(BPF_REG_0, 0),
2936 BPF_EXIT_INSN(),
2937 },
2938 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
2939 .result = REJECT,
2940 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2941 },
2942 {
2943 "direct packet access: test17 (pruning, alignment)",
2944 .insns = {
2945 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2946 offsetof(struct __sk_buff, data)),
2947 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2948 offsetof(struct __sk_buff, data_end)),
2949 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2950 offsetof(struct __sk_buff, mark)),
2951 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2952 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
2953 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
2954 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2955 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
2956 BPF_MOV64_IMM(BPF_REG_0, 0),
2957 BPF_EXIT_INSN(),
2958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
2959 BPF_JMP_A(-6),
2960 },
2961 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
2962 .result = REJECT,
2963 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2964 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2965 },
2966 {
2967 "direct packet access: test18 (imm += pkt_ptr, 1)",
2968 .insns = {
2969 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2970 offsetof(struct __sk_buff, data)),
2971 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2972 offsetof(struct __sk_buff, data_end)),
2973 BPF_MOV64_IMM(BPF_REG_0, 8),
2974 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2975 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2976 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2977 BPF_MOV64_IMM(BPF_REG_0, 0),
2978 BPF_EXIT_INSN(),
2979 },
2980 .result = ACCEPT,
2981 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2982 },
2983 {
2984 "direct packet access: test19 (imm += pkt_ptr, 2)",
2985 .insns = {
2986 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2987 offsetof(struct __sk_buff, data)),
2988 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2989 offsetof(struct __sk_buff, data_end)),
2990 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2992 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2993 BPF_MOV64_IMM(BPF_REG_4, 4),
2994 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
2995 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
2996 BPF_MOV64_IMM(BPF_REG_0, 0),
2997 BPF_EXIT_INSN(),
2998 },
2999 .result = ACCEPT,
3000 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3001 },
3002 {
3003 "direct packet access: test20 (x += pkt_ptr, 1)",
3004 .insns = {
3005 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3006 offsetof(struct __sk_buff, data)),
3007 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3008 offsetof(struct __sk_buff, data_end)),
3009 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3010 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3011 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3012 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
3013 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3014 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3015 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3016 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3017 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3018 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3019 BPF_MOV64_IMM(BPF_REG_0, 0),
3020 BPF_EXIT_INSN(),
3021 },
3022 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3023 .result = ACCEPT,
3024 },
3025 {
3026 "direct packet access: test21 (x += pkt_ptr, 2)",
3027 .insns = {
3028 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3029 offsetof(struct __sk_buff, data)),
3030 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3031 offsetof(struct __sk_buff, data_end)),
3032 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3033 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3034 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3035 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3036 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3037 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3038 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
3039 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3040 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3042 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3043 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3044 BPF_MOV64_IMM(BPF_REG_0, 0),
3045 BPF_EXIT_INSN(),
3046 },
3047 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3048 .result = ACCEPT,
3049 },
3050 {
3051 "direct packet access: test22 (x += pkt_ptr, 3)",
3052 .insns = {
3053 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3054 offsetof(struct __sk_buff, data)),
3055 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3056 offsetof(struct __sk_buff, data_end)),
3057 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3059 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3060 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3061 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3062 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3063 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3064 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3065 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3066 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3067 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
3068 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3069 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3071 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3072 BPF_MOV64_IMM(BPF_REG_2, 1),
3073 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3074 BPF_MOV64_IMM(BPF_REG_0, 0),
3075 BPF_EXIT_INSN(),
3076 },
3077 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3078 .result = ACCEPT,
3079 },
3080 {
3081 "direct packet access: test23 (x += pkt_ptr, 4)",
3082 .insns = {
3083 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3084 offsetof(struct __sk_buff, data)),
3085 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3086 offsetof(struct __sk_buff, data_end)),
3087 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3088 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3089 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3090 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3091 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3092 BPF_MOV64_IMM(BPF_REG_0, 31),
3093 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3094 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3095 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3096 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3097 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3098 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3099 BPF_MOV64_IMM(BPF_REG_0, 0),
3100 BPF_EXIT_INSN(),
3101 },
3102 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3103 .result = REJECT,
3104 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
3105 },
3106 {
3107 "direct packet access: test24 (x += pkt_ptr, 5)",
3108 .insns = {
3109 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3110 offsetof(struct __sk_buff, data)),
3111 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3112 offsetof(struct __sk_buff, data_end)),
3113 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3114 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3115 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3116 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3117 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3118 BPF_MOV64_IMM(BPF_REG_0, 64),
3119 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3120 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3121 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
3123 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3124 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3125 BPF_MOV64_IMM(BPF_REG_0, 0),
3126 BPF_EXIT_INSN(),
3127 },
3128 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3129 .result = ACCEPT,
3130 },
3131 {
3132 "direct packet access: test25 (marking on <, good access)",
3133 .insns = {
3134 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3135 offsetof(struct __sk_buff, data)),
3136 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3137 offsetof(struct __sk_buff, data_end)),
3138 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3139 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3140 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
3141 BPF_MOV64_IMM(BPF_REG_0, 0),
3142 BPF_EXIT_INSN(),
3143 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3144 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3145 },
3146 .result = ACCEPT,
3147 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3148 },
3149 {
3150 "direct packet access: test26 (marking on <, bad access)",
3151 .insns = {
3152 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3153 offsetof(struct __sk_buff, data)),
3154 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3155 offsetof(struct __sk_buff, data_end)),
3156 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3157 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3158 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
3159 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3160 BPF_MOV64_IMM(BPF_REG_0, 0),
3161 BPF_EXIT_INSN(),
3162 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
3163 },
3164 .result = REJECT,
3165 .errstr = "invalid access to packet",
3166 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3167 },
3168 {
3169 "direct packet access: test27 (marking on <=, good access)",
3170 .insns = {
3171 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3172 offsetof(struct __sk_buff, data)),
3173 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3174 offsetof(struct __sk_buff, data_end)),
3175 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3176 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3177 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
3178 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3179 BPF_MOV64_IMM(BPF_REG_0, 1),
3180 BPF_EXIT_INSN(),
3181 },
3182 .result = ACCEPT,
3183 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3184 },
3185 {
3186 "direct packet access: test28 (marking on <=, bad access)",
3187 .insns = {
3188 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3189 offsetof(struct __sk_buff, data)),
3190 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3191 offsetof(struct __sk_buff, data_end)),
3192 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3193 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3194 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
3195 BPF_MOV64_IMM(BPF_REG_0, 1),
3196 BPF_EXIT_INSN(),
3197 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3198 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3199 },
3200 .result = REJECT,
3201 .errstr = "invalid access to packet",
3202 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3203 },
3204 {
3205 "helper access to packet: test1, valid packet_ptr range",
3206 .insns = {
3207 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3208 offsetof(struct xdp_md, data)),
3209 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3210 offsetof(struct xdp_md, data_end)),
3211 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3213 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3214 BPF_LD_MAP_FD(BPF_REG_1, 0),
3215 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3216 BPF_MOV64_IMM(BPF_REG_4, 0),
3217 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3218 BPF_FUNC_map_update_elem),
3219 BPF_MOV64_IMM(BPF_REG_0, 0),
3220 BPF_EXIT_INSN(),
3221 },
3222 .fixup_map1 = { 5 },
3223 .result_unpriv = ACCEPT,
3224 .result = ACCEPT,
3225 .prog_type = BPF_PROG_TYPE_XDP,
3226 },
3227 {
3228 "helper access to packet: test2, unchecked packet_ptr",
3229 .insns = {
3230 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3231 offsetof(struct xdp_md, data)),
3232 BPF_LD_MAP_FD(BPF_REG_1, 0),
3233 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3234 BPF_FUNC_map_lookup_elem),
3235 BPF_MOV64_IMM(BPF_REG_0, 0),
3236 BPF_EXIT_INSN(),
3237 },
3238 .fixup_map1 = { 1 },
3239 .result = REJECT,
3240 .errstr = "invalid access to packet",
3241 .prog_type = BPF_PROG_TYPE_XDP,
3242 },
3243 {
3244 "helper access to packet: test3, variable add",
3245 .insns = {
3246 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3247 offsetof(struct xdp_md, data)),
3248 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3249 offsetof(struct xdp_md, data_end)),
3250 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3251 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3252 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3253 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3254 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3255 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3256 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3257 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3258 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3259 BPF_LD_MAP_FD(BPF_REG_1, 0),
3260 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
3261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3262 BPF_FUNC_map_lookup_elem),
3263 BPF_MOV64_IMM(BPF_REG_0, 0),
3264 BPF_EXIT_INSN(),
3265 },
3266 .fixup_map1 = { 11 },
3267 .result = ACCEPT,
3268 .prog_type = BPF_PROG_TYPE_XDP,
3269 },
3270 {
3271 "helper access to packet: test4, packet_ptr with bad range",
3272 .insns = {
3273 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3274 offsetof(struct xdp_md, data)),
3275 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3276 offsetof(struct xdp_md, data_end)),
3277 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3279 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3280 BPF_MOV64_IMM(BPF_REG_0, 0),
3281 BPF_EXIT_INSN(),
3282 BPF_LD_MAP_FD(BPF_REG_1, 0),
3283 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3284 BPF_FUNC_map_lookup_elem),
3285 BPF_MOV64_IMM(BPF_REG_0, 0),
3286 BPF_EXIT_INSN(),
3287 },
3288 .fixup_map1 = { 7 },
3289 .result = REJECT,
3290 .errstr = "invalid access to packet",
3291 .prog_type = BPF_PROG_TYPE_XDP,
3292 },
3293 {
3294 "helper access to packet: test5, packet_ptr with too short range",
3295 .insns = {
3296 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3297 offsetof(struct xdp_md, data)),
3298 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3299 offsetof(struct xdp_md, data_end)),
3300 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3301 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
3303 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
3304 BPF_LD_MAP_FD(BPF_REG_1, 0),
3305 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3306 BPF_FUNC_map_lookup_elem),
3307 BPF_MOV64_IMM(BPF_REG_0, 0),
3308 BPF_EXIT_INSN(),
3309 },
3310 .fixup_map1 = { 6 },
3311 .result = REJECT,
3312 .errstr = "invalid access to packet",
3313 .prog_type = BPF_PROG_TYPE_XDP,
3314 },
3315 {
3316 "helper access to packet: test6, cls valid packet_ptr range",
3317 .insns = {
3318 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3319 offsetof(struct __sk_buff, data)),
3320 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3321 offsetof(struct __sk_buff, data_end)),
3322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3324 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3325 BPF_LD_MAP_FD(BPF_REG_1, 0),
3326 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3327 BPF_MOV64_IMM(BPF_REG_4, 0),
3328 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3329 BPF_FUNC_map_update_elem),
3330 BPF_MOV64_IMM(BPF_REG_0, 0),
3331 BPF_EXIT_INSN(),
3332 },
3333 .fixup_map1 = { 5 },
3334 .result = ACCEPT,
3335 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3336 },
3337 {
3338 "helper access to packet: test7, cls unchecked packet_ptr",
3339 .insns = {
3340 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3341 offsetof(struct __sk_buff, data)),
3342 BPF_LD_MAP_FD(BPF_REG_1, 0),
3343 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3344 BPF_FUNC_map_lookup_elem),
3345 BPF_MOV64_IMM(BPF_REG_0, 0),
3346 BPF_EXIT_INSN(),
3347 },
3348 .fixup_map1 = { 1 },
3349 .result = REJECT,
3350 .errstr = "invalid access to packet",
3351 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3352 },
3353 {
3354 "helper access to packet: test8, cls variable add",
3355 .insns = {
3356 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3357 offsetof(struct __sk_buff, data)),
3358 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3359 offsetof(struct __sk_buff, data_end)),
3360 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3362 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3363 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3364 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3365 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3366 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3368 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3369 BPF_LD_MAP_FD(BPF_REG_1, 0),
3370 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
3371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3372 BPF_FUNC_map_lookup_elem),
3373 BPF_MOV64_IMM(BPF_REG_0, 0),
3374 BPF_EXIT_INSN(),
3375 },
3376 .fixup_map1 = { 11 },
3377 .result = ACCEPT,
3378 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3379 },
3380 {
3381 "helper access to packet: test9, cls packet_ptr with bad range",
3382 .insns = {
3383 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3384 offsetof(struct __sk_buff, data)),
3385 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3386 offsetof(struct __sk_buff, data_end)),
3387 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3388 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3389 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3390 BPF_MOV64_IMM(BPF_REG_0, 0),
3391 BPF_EXIT_INSN(),
3392 BPF_LD_MAP_FD(BPF_REG_1, 0),
3393 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3394 BPF_FUNC_map_lookup_elem),
3395 BPF_MOV64_IMM(BPF_REG_0, 0),
3396 BPF_EXIT_INSN(),
3397 },
3398 .fixup_map1 = { 7 },
3399 .result = REJECT,
3400 .errstr = "invalid access to packet",
3401 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3402 },
3403 {
3404 "helper access to packet: test10, cls packet_ptr with too short range",
3405 .insns = {
3406 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3407 offsetof(struct __sk_buff, data)),
3408 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3409 offsetof(struct __sk_buff, data_end)),
3410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3411 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
3413 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
3414 BPF_LD_MAP_FD(BPF_REG_1, 0),
3415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3416 BPF_FUNC_map_lookup_elem),
3417 BPF_MOV64_IMM(BPF_REG_0, 0),
3418 BPF_EXIT_INSN(),
3419 },
3420 .fixup_map1 = { 6 },
3421 .result = REJECT,
3422 .errstr = "invalid access to packet",
3423 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3424 },
3425 {
3426 "helper access to packet: test11, cls unsuitable helper 1",
3427 .insns = {
3428 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3429 offsetof(struct __sk_buff, data)),
3430 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3431 offsetof(struct __sk_buff, data_end)),
3432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3433 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
3435 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
3436 BPF_MOV64_IMM(BPF_REG_2, 0),
3437 BPF_MOV64_IMM(BPF_REG_4, 42),
3438 BPF_MOV64_IMM(BPF_REG_5, 0),
3439 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3440 BPF_FUNC_skb_store_bytes),
3441 BPF_MOV64_IMM(BPF_REG_0, 0),
3442 BPF_EXIT_INSN(),
3443 },
3444 .result = REJECT,
3445 .errstr = "helper access to the packet",
3446 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3447 },
3448 {
3449 "helper access to packet: test12, cls unsuitable helper 2",
3450 .insns = {
3451 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3452 offsetof(struct __sk_buff, data)),
3453 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3454 offsetof(struct __sk_buff, data_end)),
3455 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
3457 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
3458 BPF_MOV64_IMM(BPF_REG_2, 0),
3459 BPF_MOV64_IMM(BPF_REG_4, 4),
3460 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3461 BPF_FUNC_skb_load_bytes),
3462 BPF_MOV64_IMM(BPF_REG_0, 0),
3463 BPF_EXIT_INSN(),
3464 },
3465 .result = REJECT,
3466 .errstr = "helper access to the packet",
3467 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3468 },
3469 {
3470 "helper access to packet: test13, cls helper ok",
3471 .insns = {
3472 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3473 offsetof(struct __sk_buff, data)),
3474 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3475 offsetof(struct __sk_buff, data_end)),
3476 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3477 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3479 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3480 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3481 BPF_MOV64_IMM(BPF_REG_2, 4),
3482 BPF_MOV64_IMM(BPF_REG_3, 0),
3483 BPF_MOV64_IMM(BPF_REG_4, 0),
3484 BPF_MOV64_IMM(BPF_REG_5, 0),
3485 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3486 BPF_FUNC_csum_diff),
3487 BPF_MOV64_IMM(BPF_REG_0, 0),
3488 BPF_EXIT_INSN(),
3489 },
3490 .result = ACCEPT,
3491 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3492 },
3493 {
3494 "helper access to packet: test14, cls helper ok sub",
3495 .insns = {
3496 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3497 offsetof(struct __sk_buff, data)),
3498 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3499 offsetof(struct __sk_buff, data_end)),
3500 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3501 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3502 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3503 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3504 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
3505 BPF_MOV64_IMM(BPF_REG_2, 4),
3506 BPF_MOV64_IMM(BPF_REG_3, 0),
3507 BPF_MOV64_IMM(BPF_REG_4, 0),
3508 BPF_MOV64_IMM(BPF_REG_5, 0),
3509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3510 BPF_FUNC_csum_diff),
3511 BPF_MOV64_IMM(BPF_REG_0, 0),
3512 BPF_EXIT_INSN(),
3513 },
3514 .result = ACCEPT,
3515 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3516 },
3517 {
3518 "helper access to packet: test15, cls helper fail sub",
3519 .insns = {
3520 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3521 offsetof(struct __sk_buff, data)),
3522 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3523 offsetof(struct __sk_buff, data_end)),
3524 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3525 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3526 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3527 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3528 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
3529 BPF_MOV64_IMM(BPF_REG_2, 4),
3530 BPF_MOV64_IMM(BPF_REG_3, 0),
3531 BPF_MOV64_IMM(BPF_REG_4, 0),
3532 BPF_MOV64_IMM(BPF_REG_5, 0),
3533 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3534 BPF_FUNC_csum_diff),
3535 BPF_MOV64_IMM(BPF_REG_0, 0),
3536 BPF_EXIT_INSN(),
3537 },
3538 .result = REJECT,
3539 .errstr = "invalid access to packet",
3540 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3541 },
3542 {
3543 "helper access to packet: test16, cls helper fail range 1",
3544 .insns = {
3545 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3546 offsetof(struct __sk_buff, data)),
3547 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3548 offsetof(struct __sk_buff, data_end)),
3549 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3550 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3552 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3553 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3554 BPF_MOV64_IMM(BPF_REG_2, 8),
3555 BPF_MOV64_IMM(BPF_REG_3, 0),
3556 BPF_MOV64_IMM(BPF_REG_4, 0),
3557 BPF_MOV64_IMM(BPF_REG_5, 0),
3558 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3559 BPF_FUNC_csum_diff),
3560 BPF_MOV64_IMM(BPF_REG_0, 0),
3561 BPF_EXIT_INSN(),
3562 },
3563 .result = REJECT,
3564 .errstr = "invalid access to packet",
3565 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3566 },
3567 {
3568 "helper access to packet: test17, cls helper fail range 2",
3569 .insns = {
3570 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3571 offsetof(struct __sk_buff, data)),
3572 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3573 offsetof(struct __sk_buff, data_end)),
3574 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3575 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3576 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3577 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3578 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3579 BPF_MOV64_IMM(BPF_REG_2, -9),
3580 BPF_MOV64_IMM(BPF_REG_3, 0),
3581 BPF_MOV64_IMM(BPF_REG_4, 0),
3582 BPF_MOV64_IMM(BPF_REG_5, 0),
3583 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3584 BPF_FUNC_csum_diff),
3585 BPF_MOV64_IMM(BPF_REG_0, 0),
3586 BPF_EXIT_INSN(),
3587 },
3588 .result = REJECT,
3589 .errstr = "R2 min value is negative",
3590 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3591 },
3592 {
3593 "helper access to packet: test18, cls helper fail range 3",
3594 .insns = {
3595 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3596 offsetof(struct __sk_buff, data)),
3597 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3598 offsetof(struct __sk_buff, data_end)),
3599 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3600 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3601 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3602 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3603 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3604 BPF_MOV64_IMM(BPF_REG_2, ~0),
3605 BPF_MOV64_IMM(BPF_REG_3, 0),
3606 BPF_MOV64_IMM(BPF_REG_4, 0),
3607 BPF_MOV64_IMM(BPF_REG_5, 0),
3608 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3609 BPF_FUNC_csum_diff),
3610 BPF_MOV64_IMM(BPF_REG_0, 0),
3611 BPF_EXIT_INSN(),
3612 },
3613 .result = REJECT,
3614 .errstr = "R2 min value is negative",
3615 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3616 },
3617 {
3618 "helper access to packet: test19, cls helper range zero",
3619 .insns = {
3620 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3621 offsetof(struct __sk_buff, data)),
3622 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3623 offsetof(struct __sk_buff, data_end)),
3624 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3625 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3627 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3628 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3629 BPF_MOV64_IMM(BPF_REG_2, 0),
3630 BPF_MOV64_IMM(BPF_REG_3, 0),
3631 BPF_MOV64_IMM(BPF_REG_4, 0),
3632 BPF_MOV64_IMM(BPF_REG_5, 0),
3633 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3634 BPF_FUNC_csum_diff),
3635 BPF_MOV64_IMM(BPF_REG_0, 0),
3636 BPF_EXIT_INSN(),
3637 },
3638 .result = ACCEPT,
3639 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3640 },
3641 {
3642 "helper access to packet: test20, pkt end as input",
3643 .insns = {
3644 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3645 offsetof(struct __sk_buff, data)),
3646 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3647 offsetof(struct __sk_buff, data_end)),
3648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3649 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3651 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3652 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
3653 BPF_MOV64_IMM(BPF_REG_2, 4),
3654 BPF_MOV64_IMM(BPF_REG_3, 0),
3655 BPF_MOV64_IMM(BPF_REG_4, 0),
3656 BPF_MOV64_IMM(BPF_REG_5, 0),
3657 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3658 BPF_FUNC_csum_diff),
3659 BPF_MOV64_IMM(BPF_REG_0, 0),
3660 BPF_EXIT_INSN(),
3661 },
3662 .result = REJECT,
3663 .errstr = "R1 type=pkt_end expected=fp",
3664 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3665 },
3666 {
3667 "helper access to packet: test21, wrong reg",
3668 .insns = {
3669 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3670 offsetof(struct __sk_buff, data)),
3671 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3672 offsetof(struct __sk_buff, data_end)),
3673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3674 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3675 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3676 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3677 BPF_MOV64_IMM(BPF_REG_2, 4),
3678 BPF_MOV64_IMM(BPF_REG_3, 0),
3679 BPF_MOV64_IMM(BPF_REG_4, 0),
3680 BPF_MOV64_IMM(BPF_REG_5, 0),
3681 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3682 BPF_FUNC_csum_diff),
3683 BPF_MOV64_IMM(BPF_REG_0, 0),
3684 BPF_EXIT_INSN(),
3685 },
3686 .result = REJECT,
3687 .errstr = "invalid access to packet",
3688 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3689 },
3690 {
3691 "valid map access into an array with a constant",
3692 .insns = {
3693 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3694 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3696 BPF_LD_MAP_FD(BPF_REG_1, 0),
3697 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3698 BPF_FUNC_map_lookup_elem),
3699 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3700 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3701 offsetof(struct test_val, foo)),
3702 BPF_EXIT_INSN(),
3703 },
3704 .fixup_map2 = { 3 },
3705 .errstr_unpriv = "R0 leaks addr",
3706 .result_unpriv = REJECT,
3707 .result = ACCEPT,
3708 },
3709 {
3710 "valid map access into an array with a register",
3711 .insns = {
3712 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3713 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3714 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3715 BPF_LD_MAP_FD(BPF_REG_1, 0),
3716 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3717 BPF_FUNC_map_lookup_elem),
3718 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3719 BPF_MOV64_IMM(BPF_REG_1, 4),
3720 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3721 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3722 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3723 offsetof(struct test_val, foo)),
3724 BPF_EXIT_INSN(),
3725 },
3726 .fixup_map2 = { 3 },
3727 .errstr_unpriv = "R0 leaks addr",
3728 .result_unpriv = REJECT,
3729 .result = ACCEPT,
3730 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3731 },
3732 {
3733 "valid map access into an array with a variable",
3734 .insns = {
3735 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3736 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3738 BPF_LD_MAP_FD(BPF_REG_1, 0),
3739 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3740 BPF_FUNC_map_lookup_elem),
3741 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3742 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3743 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
3744 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3745 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3746 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3747 offsetof(struct test_val, foo)),
3748 BPF_EXIT_INSN(),
3749 },
3750 .fixup_map2 = { 3 },
3751 .errstr_unpriv = "R0 leaks addr",
3752 .result_unpriv = REJECT,
3753 .result = ACCEPT,
3754 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3755 },
3756 {
3757 "valid map access into an array with a signed variable",
3758 .insns = {
3759 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3760 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3762 BPF_LD_MAP_FD(BPF_REG_1, 0),
3763 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3764 BPF_FUNC_map_lookup_elem),
3765 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
3766 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3767 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
3768 BPF_MOV32_IMM(BPF_REG_1, 0),
3769 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3770 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3771 BPF_MOV32_IMM(BPF_REG_1, 0),
3772 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3773 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3774 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3775 offsetof(struct test_val, foo)),
3776 BPF_EXIT_INSN(),
3777 },
3778 .fixup_map2 = { 3 },
3779 .errstr_unpriv = "R0 leaks addr",
3780 .result_unpriv = REJECT,
3781 .result = ACCEPT,
3782 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3783 },
3784 {
3785 "invalid map access into an array with a constant",
3786 .insns = {
3787 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3788 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3789 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3790 BPF_LD_MAP_FD(BPF_REG_1, 0),
3791 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3792 BPF_FUNC_map_lookup_elem),
3793 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3794 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
3795 offsetof(struct test_val, foo)),
3796 BPF_EXIT_INSN(),
3797 },
3798 .fixup_map2 = { 3 },
3799 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
3800 .result = REJECT,
3801 },
3802 {
3803 "invalid map access into an array with a register",
3804 .insns = {
3805 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3806 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3808 BPF_LD_MAP_FD(BPF_REG_1, 0),
3809 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3810 BPF_FUNC_map_lookup_elem),
3811 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3812 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3813 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3814 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3815 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3816 offsetof(struct test_val, foo)),
3817 BPF_EXIT_INSN(),
3818 },
3819 .fixup_map2 = { 3 },
3820 .errstr = "R0 min value is outside of the array range",
3821 .result = REJECT,
3822 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3823 },
3824 {
3825 "invalid map access into an array with a variable",
3826 .insns = {
3827 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3828 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3830 BPF_LD_MAP_FD(BPF_REG_1, 0),
3831 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3832 BPF_FUNC_map_lookup_elem),
3833 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3834 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3835 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3836 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3837 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3838 offsetof(struct test_val, foo)),
3839 BPF_EXIT_INSN(),
3840 },
3841 .fixup_map2 = { 3 },
3842 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
3843 .result = REJECT,
3844 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3845 },
3846 {
3847 "invalid map access into an array with no floor check",
3848 .insns = {
3849 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3850 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3851 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3852 BPF_LD_MAP_FD(BPF_REG_1, 0),
3853 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3854 BPF_FUNC_map_lookup_elem),
3855 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3856 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3857 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3858 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3859 BPF_MOV32_IMM(BPF_REG_1, 0),
3860 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3861 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3862 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3863 offsetof(struct test_val, foo)),
3864 BPF_EXIT_INSN(),
3865 },
3866 .fixup_map2 = { 3 },
3867 .errstr_unpriv = "R0 leaks addr",
3868 .errstr = "R0 unbounded memory access",
3869 .result_unpriv = REJECT,
3870 .result = REJECT,
3871 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3872 },
3873 {
3874 "invalid map access into an array with a invalid max check",
3875 .insns = {
3876 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3877 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3879 BPF_LD_MAP_FD(BPF_REG_1, 0),
3880 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3881 BPF_FUNC_map_lookup_elem),
3882 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3883 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3884 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3885 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3886 BPF_MOV32_IMM(BPF_REG_1, 0),
3887 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3888 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3889 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3890 offsetof(struct test_val, foo)),
3891 BPF_EXIT_INSN(),
3892 },
3893 .fixup_map2 = { 3 },
3894 .errstr_unpriv = "R0 leaks addr",
3895 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
3896 .result_unpriv = REJECT,
3897 .result = REJECT,
3898 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3899 },
3900 {
3901 "invalid map access into an array with a invalid max check",
3902 .insns = {
3903 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3904 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3906 BPF_LD_MAP_FD(BPF_REG_1, 0),
3907 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3908 BPF_FUNC_map_lookup_elem),
3909 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3910 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3911 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3912 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3913 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3914 BPF_LD_MAP_FD(BPF_REG_1, 0),
3915 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3916 BPF_FUNC_map_lookup_elem),
3917 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3918 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
3919 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3920 offsetof(struct test_val, foo)),
3921 BPF_EXIT_INSN(),
3922 },
3923 .fixup_map2 = { 3, 11 },
3924 .errstr = "R0 pointer += pointer",
3925 .result = REJECT,
3926 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3927 },
3928 {
3929 "multiple registers share map_lookup_elem result",
3930 .insns = {
3931 BPF_MOV64_IMM(BPF_REG_1, 10),
3932 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3933 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3934 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3935 BPF_LD_MAP_FD(BPF_REG_1, 0),
3936 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3937 BPF_FUNC_map_lookup_elem),
3938 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3939 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3940 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3941 BPF_EXIT_INSN(),
3942 },
3943 .fixup_map1 = { 4 },
3944 .result = ACCEPT,
3945 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3946 },
3947 {
3948 "alu ops on ptr_to_map_value_or_null, 1",
3949 .insns = {
3950 BPF_MOV64_IMM(BPF_REG_1, 10),
3951 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3952 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3953 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3954 BPF_LD_MAP_FD(BPF_REG_1, 0),
3955 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3956 BPF_FUNC_map_lookup_elem),
3957 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
3959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
3960 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3961 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3962 BPF_EXIT_INSN(),
3963 },
3964 .fixup_map1 = { 4 },
3965 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
3966 .result = REJECT,
3967 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3968 },
3969 {
3970 "alu ops on ptr_to_map_value_or_null, 2",
3971 .insns = {
3972 BPF_MOV64_IMM(BPF_REG_1, 10),
3973 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3974 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3975 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3976 BPF_LD_MAP_FD(BPF_REG_1, 0),
3977 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3978 BPF_FUNC_map_lookup_elem),
3979 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3980 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
3981 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3982 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3983 BPF_EXIT_INSN(),
3984 },
3985 .fixup_map1 = { 4 },
3986 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
3987 .result = REJECT,
3988 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3989 },
3990 {
3991 "alu ops on ptr_to_map_value_or_null, 3",
3992 .insns = {
3993 BPF_MOV64_IMM(BPF_REG_1, 10),
3994 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3995 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3996 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3997 BPF_LD_MAP_FD(BPF_REG_1, 0),
3998 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3999 BPF_FUNC_map_lookup_elem),
4000 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4001 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4002 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4003 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4004 BPF_EXIT_INSN(),
4005 },
4006 .fixup_map1 = { 4 },
4007 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4008 .result = REJECT,
4009 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4010 },
4011 {
4012 "invalid memory access with multiple map_lookup_elem calls",
4013 .insns = {
4014 BPF_MOV64_IMM(BPF_REG_1, 10),
4015 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4016 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4017 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4018 BPF_LD_MAP_FD(BPF_REG_1, 0),
4019 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4020 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4022 BPF_FUNC_map_lookup_elem),
4023 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4024 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4025 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4026 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4027 BPF_FUNC_map_lookup_elem),
4028 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4029 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4030 BPF_EXIT_INSN(),
4031 },
4032 .fixup_map1 = { 4 },
4033 .result = REJECT,
4034 .errstr = "R4 !read_ok",
4035 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4036 },
4037 {
4038 "valid indirect map_lookup_elem access with 2nd lookup in branch",
4039 .insns = {
4040 BPF_MOV64_IMM(BPF_REG_1, 10),
4041 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4042 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4044 BPF_LD_MAP_FD(BPF_REG_1, 0),
4045 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4046 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4047 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4048 BPF_FUNC_map_lookup_elem),
4049 BPF_MOV64_IMM(BPF_REG_2, 10),
4050 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
4051 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4052 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4053 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4054 BPF_FUNC_map_lookup_elem),
4055 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4057 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4058 BPF_EXIT_INSN(),
4059 },
4060 .fixup_map1 = { 4 },
4061 .result = ACCEPT,
4062 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4063 },
4064 {
4065 "invalid map access from else condition",
4066 .insns = {
4067 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4068 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4069 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4070 BPF_LD_MAP_FD(BPF_REG_1, 0),
4071 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
4072 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4073 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4074 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
4075 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4076 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4077 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4078 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
4079 BPF_EXIT_INSN(),
4080 },
4081 .fixup_map2 = { 3 },
4082 .errstr = "R0 unbounded memory access",
4083 .result = REJECT,
4084 .errstr_unpriv = "R0 leaks addr",
4085 .result_unpriv = REJECT,
4086 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4087 },
4088 {
4089 "constant register |= constant should keep constant type",
4090 .insns = {
4091 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4093 BPF_MOV64_IMM(BPF_REG_2, 34),
4094 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
4095 BPF_MOV64_IMM(BPF_REG_3, 0),
4096 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4097 BPF_EXIT_INSN(),
4098 },
4099 .result = ACCEPT,
4100 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4101 },
4102 {
4103 "constant register |= constant should not bypass stack boundary checks",
4104 .insns = {
4105 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4106 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4107 BPF_MOV64_IMM(BPF_REG_2, 34),
4108 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
4109 BPF_MOV64_IMM(BPF_REG_3, 0),
4110 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4111 BPF_EXIT_INSN(),
4112 },
4113 .errstr = "invalid stack type R1 off=-48 access_size=58",
4114 .result = REJECT,
4115 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4116 },
4117 {
4118 "constant register |= constant register should keep constant type",
4119 .insns = {
4120 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4122 BPF_MOV64_IMM(BPF_REG_2, 34),
4123 BPF_MOV64_IMM(BPF_REG_4, 13),
4124 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4125 BPF_MOV64_IMM(BPF_REG_3, 0),
4126 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4127 BPF_EXIT_INSN(),
4128 },
4129 .result = ACCEPT,
4130 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4131 },
4132 {
4133 "constant register |= constant register should not bypass stack boundary checks",
4134 .insns = {
4135 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4136 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4137 BPF_MOV64_IMM(BPF_REG_2, 34),
4138 BPF_MOV64_IMM(BPF_REG_4, 24),
4139 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4140 BPF_MOV64_IMM(BPF_REG_3, 0),
4141 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4142 BPF_EXIT_INSN(),
4143 },
4144 .errstr = "invalid stack type R1 off=-48 access_size=58",
4145 .result = REJECT,
4146 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4147 },
4148 {
4149 "invalid direct packet write for LWT_IN",
4150 .insns = {
4151 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4152 offsetof(struct __sk_buff, data)),
4153 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4154 offsetof(struct __sk_buff, data_end)),
4155 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4157 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4158 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4159 BPF_MOV64_IMM(BPF_REG_0, 0),
4160 BPF_EXIT_INSN(),
4161 },
4162 .errstr = "cannot write into packet",
4163 .result = REJECT,
4164 .prog_type = BPF_PROG_TYPE_LWT_IN,
4165 },
4166 {
4167 "invalid direct packet write for LWT_OUT",
4168 .insns = {
4169 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4170 offsetof(struct __sk_buff, data)),
4171 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4172 offsetof(struct __sk_buff, data_end)),
4173 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4175 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4176 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4177 BPF_MOV64_IMM(BPF_REG_0, 0),
4178 BPF_EXIT_INSN(),
4179 },
4180 .errstr = "cannot write into packet",
4181 .result = REJECT,
4182 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4183 },
4184 {
4185 "direct packet write for LWT_XMIT",
4186 .insns = {
4187 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4188 offsetof(struct __sk_buff, data)),
4189 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4190 offsetof(struct __sk_buff, data_end)),
4191 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4193 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4194 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4195 BPF_MOV64_IMM(BPF_REG_0, 0),
4196 BPF_EXIT_INSN(),
4197 },
4198 .result = ACCEPT,
4199 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4200 },
4201 {
4202 "direct packet read for LWT_IN",
4203 .insns = {
4204 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4205 offsetof(struct __sk_buff, data)),
4206 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4207 offsetof(struct __sk_buff, data_end)),
4208 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4209 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4210 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4211 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4212 BPF_MOV64_IMM(BPF_REG_0, 0),
4213 BPF_EXIT_INSN(),
4214 },
4215 .result = ACCEPT,
4216 .prog_type = BPF_PROG_TYPE_LWT_IN,
4217 },
4218 {
4219 "direct packet read for LWT_OUT",
4220 .insns = {
4221 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4222 offsetof(struct __sk_buff, data)),
4223 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4224 offsetof(struct __sk_buff, data_end)),
4225 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4226 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4227 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4228 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4229 BPF_MOV64_IMM(BPF_REG_0, 0),
4230 BPF_EXIT_INSN(),
4231 },
4232 .result = ACCEPT,
4233 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4234 },
4235 {
4236 "direct packet read for LWT_XMIT",
4237 .insns = {
4238 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4239 offsetof(struct __sk_buff, data)),
4240 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4241 offsetof(struct __sk_buff, data_end)),
4242 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4243 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4244 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4245 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4246 BPF_MOV64_IMM(BPF_REG_0, 0),
4247 BPF_EXIT_INSN(),
4248 },
4249 .result = ACCEPT,
4250 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4251 },
4252 {
4253 "overlapping checks for direct packet access",
4254 .insns = {
4255 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4256 offsetof(struct __sk_buff, data)),
4257 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4258 offsetof(struct __sk_buff, data_end)),
4259 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4261 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
4262 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
4264 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
4265 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
4266 BPF_MOV64_IMM(BPF_REG_0, 0),
4267 BPF_EXIT_INSN(),
4268 },
4269 .result = ACCEPT,
4270 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4271 },
4272 {
4273 "invalid access of tc_classid for LWT_IN",
4274 .insns = {
4275 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4276 offsetof(struct __sk_buff, tc_classid)),
4277 BPF_EXIT_INSN(),
4278 },
4279 .result = REJECT,
4280 .errstr = "invalid bpf_context access",
4281 },
4282 {
4283 "invalid access of tc_classid for LWT_OUT",
4284 .insns = {
4285 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4286 offsetof(struct __sk_buff, tc_classid)),
4287 BPF_EXIT_INSN(),
4288 },
4289 .result = REJECT,
4290 .errstr = "invalid bpf_context access",
4291 },
4292 {
4293 "invalid access of tc_classid for LWT_XMIT",
4294 .insns = {
4295 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4296 offsetof(struct __sk_buff, tc_classid)),
4297 BPF_EXIT_INSN(),
4298 },
4299 .result = REJECT,
4300 .errstr = "invalid bpf_context access",
4301 },
4302 {
4303 "leak pointer into ctx 1",
4304 .insns = {
4305 BPF_MOV64_IMM(BPF_REG_0, 0),
4306 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
4307 offsetof(struct __sk_buff, cb[0])),
4308 BPF_LD_MAP_FD(BPF_REG_2, 0),
4309 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
4310 offsetof(struct __sk_buff, cb[0])),
4311 BPF_EXIT_INSN(),
4312 },
4313 .fixup_map1 = { 2 },
4314 .errstr_unpriv = "R2 leaks addr into mem",
4315 .result_unpriv = REJECT,
4316 .result = ACCEPT,
4317 },
4318 {
4319 "leak pointer into ctx 2",
4320 .insns = {
4321 BPF_MOV64_IMM(BPF_REG_0, 0),
4322 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
4323 offsetof(struct __sk_buff, cb[0])),
4324 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
4325 offsetof(struct __sk_buff, cb[0])),
4326 BPF_EXIT_INSN(),
4327 },
4328 .errstr_unpriv = "R10 leaks addr into mem",
4329 .result_unpriv = REJECT,
4330 .result = ACCEPT,
4331 },
4332 {
4333 "leak pointer into ctx 3",
4334 .insns = {
4335 BPF_MOV64_IMM(BPF_REG_0, 0),
4336 BPF_LD_MAP_FD(BPF_REG_2, 0),
4337 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
4338 offsetof(struct __sk_buff, cb[0])),
4339 BPF_EXIT_INSN(),
4340 },
4341 .fixup_map1 = { 1 },
4342 .errstr_unpriv = "R2 leaks addr into ctx",
4343 .result_unpriv = REJECT,
4344 .result = ACCEPT,
4345 },
4346 {
4347 "leak pointer into map val",
4348 .insns = {
4349 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
4350 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4351 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4352 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4353 BPF_LD_MAP_FD(BPF_REG_1, 0),
4354 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4355 BPF_FUNC_map_lookup_elem),
4356 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
4357 BPF_MOV64_IMM(BPF_REG_3, 0),
4358 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
4359 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
4360 BPF_MOV64_IMM(BPF_REG_0, 0),
4361 BPF_EXIT_INSN(),
4362 },
4363 .fixup_map1 = { 4 },
4364 .errstr_unpriv = "R6 leaks addr into mem",
4365 .result_unpriv = REJECT,
4366 .result = ACCEPT,
4367 },
4368 {
4369 "helper access to map: full range",
4370 .insns = {
4371 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4372 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4373 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4374 BPF_LD_MAP_FD(BPF_REG_1, 0),
4375 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4376 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4377 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4378 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4379 BPF_MOV64_IMM(BPF_REG_3, 0),
4380 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4381 BPF_EXIT_INSN(),
4382 },
4383 .fixup_map2 = { 3 },
4384 .result = ACCEPT,
4385 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4386 },
4387 {
4388 "helper access to map: partial range",
4389 .insns = {
4390 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4392 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4393 BPF_LD_MAP_FD(BPF_REG_1, 0),
4394 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4395 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4396 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4397 BPF_MOV64_IMM(BPF_REG_2, 8),
4398 BPF_MOV64_IMM(BPF_REG_3, 0),
4399 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4400 BPF_EXIT_INSN(),
4401 },
4402 .fixup_map2 = { 3 },
4403 .result = ACCEPT,
4404 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4405 },
4406 {
4407 "helper access to map: empty range",
4408 .insns = {
4409 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4411 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4412 BPF_LD_MAP_FD(BPF_REG_1, 0),
4413 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4414 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
4415 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4416 BPF_MOV64_IMM(BPF_REG_2, 0),
4417 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
4418 BPF_EXIT_INSN(),
4419 },
4420 .fixup_map2 = { 3 },
4421 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
4422 .result = REJECT,
4423 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4424 },
4425 {
4426 "helper access to map: out-of-bound range",
4427 .insns = {
4428 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4429 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4430 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4431 BPF_LD_MAP_FD(BPF_REG_1, 0),
4432 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4433 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4434 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4435 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
4436 BPF_MOV64_IMM(BPF_REG_3, 0),
4437 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4438 BPF_EXIT_INSN(),
4439 },
4440 .fixup_map2 = { 3 },
4441 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
4442 .result = REJECT,
4443 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4444 },
4445 {
4446 "helper access to map: negative range",
4447 .insns = {
4448 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4450 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4451 BPF_LD_MAP_FD(BPF_REG_1, 0),
4452 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4453 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4454 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4455 BPF_MOV64_IMM(BPF_REG_2, -8),
4456 BPF_MOV64_IMM(BPF_REG_3, 0),
4457 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4458 BPF_EXIT_INSN(),
4459 },
4460 .fixup_map2 = { 3 },
4461 .errstr = "R2 min value is negative",
4462 .result = REJECT,
4463 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4464 },
4465 {
4466 "helper access to adjusted map (via const imm): full range",
4467 .insns = {
4468 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4469 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4470 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4471 BPF_LD_MAP_FD(BPF_REG_1, 0),
4472 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4473 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4474 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4476 offsetof(struct test_val, foo)),
4477 BPF_MOV64_IMM(BPF_REG_2,
4478 sizeof(struct test_val) -
4479 offsetof(struct test_val, foo)),
4480 BPF_MOV64_IMM(BPF_REG_3, 0),
4481 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4482 BPF_EXIT_INSN(),
4483 },
4484 .fixup_map2 = { 3 },
4485 .result = ACCEPT,
4486 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4487 },
4488 {
4489 "helper access to adjusted map (via const imm): partial range",
4490 .insns = {
4491 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4493 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4494 BPF_LD_MAP_FD(BPF_REG_1, 0),
4495 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4496 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4497 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4499 offsetof(struct test_val, foo)),
4500 BPF_MOV64_IMM(BPF_REG_2, 8),
4501 BPF_MOV64_IMM(BPF_REG_3, 0),
4502 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4503 BPF_EXIT_INSN(),
4504 },
4505 .fixup_map2 = { 3 },
4506 .result = ACCEPT,
4507 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4508 },
4509 {
4510 "helper access to adjusted map (via const imm): empty range",
4511 .insns = {
4512 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4513 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4514 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4515 BPF_LD_MAP_FD(BPF_REG_1, 0),
4516 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4517 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4518 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4519 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4520 offsetof(struct test_val, foo)),
4521 BPF_MOV64_IMM(BPF_REG_2, 0),
4522 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
4523 BPF_EXIT_INSN(),
4524 },
4525 .fixup_map2 = { 3 },
4526 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
4527 .result = REJECT,
4528 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4529 },
4530 {
4531 "helper access to adjusted map (via const imm): out-of-bound range",
4532 .insns = {
4533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4535 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4536 BPF_LD_MAP_FD(BPF_REG_1, 0),
4537 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4538 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4539 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4540 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4541 offsetof(struct test_val, foo)),
4542 BPF_MOV64_IMM(BPF_REG_2,
4543 sizeof(struct test_val) -
4544 offsetof(struct test_val, foo) + 8),
4545 BPF_MOV64_IMM(BPF_REG_3, 0),
4546 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4547 BPF_EXIT_INSN(),
4548 },
4549 .fixup_map2 = { 3 },
4550 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4551 .result = REJECT,
4552 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4553 },
4554 {
4555 "helper access to adjusted map (via const imm): negative range (> adjustment)",
4556 .insns = {
4557 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4559 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4560 BPF_LD_MAP_FD(BPF_REG_1, 0),
4561 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4562 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4563 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4565 offsetof(struct test_val, foo)),
4566 BPF_MOV64_IMM(BPF_REG_2, -8),
4567 BPF_MOV64_IMM(BPF_REG_3, 0),
4568 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4569 BPF_EXIT_INSN(),
4570 },
4571 .fixup_map2 = { 3 },
4572 .errstr = "R2 min value is negative",
4573 .result = REJECT,
4574 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4575 },
4576 {
4577 "helper access to adjusted map (via const imm): negative range (< adjustment)",
4578 .insns = {
4579 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4581 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4582 BPF_LD_MAP_FD(BPF_REG_1, 0),
4583 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4585 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4587 offsetof(struct test_val, foo)),
4588 BPF_MOV64_IMM(BPF_REG_2, -1),
4589 BPF_MOV64_IMM(BPF_REG_3, 0),
4590 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4591 BPF_EXIT_INSN(),
4592 },
4593 .fixup_map2 = { 3 },
4594 .errstr = "R2 min value is negative",
4595 .result = REJECT,
4596 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4597 },
4598 {
4599 "helper access to adjusted map (via const reg): full range",
4600 .insns = {
4601 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4603 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4604 BPF_LD_MAP_FD(BPF_REG_1, 0),
4605 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4606 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4607 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4608 BPF_MOV64_IMM(BPF_REG_3,
4609 offsetof(struct test_val, foo)),
4610 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4611 BPF_MOV64_IMM(BPF_REG_2,
4612 sizeof(struct test_val) -
4613 offsetof(struct test_val, foo)),
4614 BPF_MOV64_IMM(BPF_REG_3, 0),
4615 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4616 BPF_EXIT_INSN(),
4617 },
4618 .fixup_map2 = { 3 },
4619 .result = ACCEPT,
4620 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4621 },
4622 {
4623 "helper access to adjusted map (via const reg): partial range",
4624 .insns = {
4625 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4627 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4628 BPF_LD_MAP_FD(BPF_REG_1, 0),
4629 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4630 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4631 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4632 BPF_MOV64_IMM(BPF_REG_3,
4633 offsetof(struct test_val, foo)),
4634 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4635 BPF_MOV64_IMM(BPF_REG_2, 8),
4636 BPF_MOV64_IMM(BPF_REG_3, 0),
4637 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4638 BPF_EXIT_INSN(),
4639 },
4640 .fixup_map2 = { 3 },
4641 .result = ACCEPT,
4642 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4643 },
4644 {
4645 "helper access to adjusted map (via const reg): empty range",
4646 .insns = {
4647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4649 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4650 BPF_LD_MAP_FD(BPF_REG_1, 0),
4651 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4653 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4654 BPF_MOV64_IMM(BPF_REG_3, 0),
4655 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4656 BPF_MOV64_IMM(BPF_REG_2, 0),
4657 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
4658 BPF_EXIT_INSN(),
4659 },
4660 .fixup_map2 = { 3 },
4661 .errstr = "R1 min value is outside of the array range",
4662 .result = REJECT,
4663 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4664 },
4665 {
4666 "helper access to adjusted map (via const reg): out-of-bound range",
4667 .insns = {
4668 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4669 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4670 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4671 BPF_LD_MAP_FD(BPF_REG_1, 0),
4672 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4673 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4674 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4675 BPF_MOV64_IMM(BPF_REG_3,
4676 offsetof(struct test_val, foo)),
4677 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4678 BPF_MOV64_IMM(BPF_REG_2,
4679 sizeof(struct test_val) -
4680 offsetof(struct test_val, foo) + 8),
4681 BPF_MOV64_IMM(BPF_REG_3, 0),
4682 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4683 BPF_EXIT_INSN(),
4684 },
4685 .fixup_map2 = { 3 },
4686 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4687 .result = REJECT,
4688 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4689 },
4690 {
4691 "helper access to adjusted map (via const reg): negative range (> adjustment)",
4692 .insns = {
4693 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4695 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4696 BPF_LD_MAP_FD(BPF_REG_1, 0),
4697 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4698 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4699 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4700 BPF_MOV64_IMM(BPF_REG_3,
4701 offsetof(struct test_val, foo)),
4702 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4703 BPF_MOV64_IMM(BPF_REG_2, -8),
4704 BPF_MOV64_IMM(BPF_REG_3, 0),
4705 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4706 BPF_EXIT_INSN(),
4707 },
4708 .fixup_map2 = { 3 },
4709 .errstr = "R2 min value is negative",
4710 .result = REJECT,
4711 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4712 },
4713 {
4714 "helper access to adjusted map (via const reg): negative range (< adjustment)",
4715 .insns = {
4716 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4718 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4719 BPF_LD_MAP_FD(BPF_REG_1, 0),
4720 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4721 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4722 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4723 BPF_MOV64_IMM(BPF_REG_3,
4724 offsetof(struct test_val, foo)),
4725 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4726 BPF_MOV64_IMM(BPF_REG_2, -1),
4727 BPF_MOV64_IMM(BPF_REG_3, 0),
4728 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4729 BPF_EXIT_INSN(),
4730 },
4731 .fixup_map2 = { 3 },
4732 .errstr = "R2 min value is negative",
4733 .result = REJECT,
4734 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4735 },
4736 {
4737 "helper access to adjusted map (via variable): full range",
4738 .insns = {
4739 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4740 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4741 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4742 BPF_LD_MAP_FD(BPF_REG_1, 0),
4743 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4744 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4745 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4746 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4747 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4748 offsetof(struct test_val, foo), 4),
4749 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4750 BPF_MOV64_IMM(BPF_REG_2,
4751 sizeof(struct test_val) -
4752 offsetof(struct test_val, foo)),
4753 BPF_MOV64_IMM(BPF_REG_3, 0),
4754 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4755 BPF_EXIT_INSN(),
4756 },
4757 .fixup_map2 = { 3 },
4758 .result = ACCEPT,
4759 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4760 },
4761 {
4762 "helper access to adjusted map (via variable): partial range",
4763 .insns = {
4764 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4765 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4766 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4767 BPF_LD_MAP_FD(BPF_REG_1, 0),
4768 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4769 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4770 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4771 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4772 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4773 offsetof(struct test_val, foo), 4),
4774 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4775 BPF_MOV64_IMM(BPF_REG_2, 8),
4776 BPF_MOV64_IMM(BPF_REG_3, 0),
4777 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4778 BPF_EXIT_INSN(),
4779 },
4780 .fixup_map2 = { 3 },
4781 .result = ACCEPT,
4782 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4783 },
4784 {
4785 "helper access to adjusted map (via variable): empty range",
4786 .insns = {
4787 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4789 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4790 BPF_LD_MAP_FD(BPF_REG_1, 0),
4791 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4792 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4793 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4794 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4795 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4796 offsetof(struct test_val, foo), 3),
4797 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4798 BPF_MOV64_IMM(BPF_REG_2, 0),
4799 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
4800 BPF_EXIT_INSN(),
4801 },
4802 .fixup_map2 = { 3 },
4803 .errstr = "R1 min value is outside of the array range",
4804 .result = REJECT,
4805 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4806 },
4807 {
4808 "helper access to adjusted map (via variable): no max check",
4809 .insns = {
4810 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4812 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4813 BPF_LD_MAP_FD(BPF_REG_1, 0),
4814 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4815 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4816 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4817 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4818 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4819 BPF_MOV64_IMM(BPF_REG_2, 1),
4820 BPF_MOV64_IMM(BPF_REG_3, 0),
4821 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4822 BPF_EXIT_INSN(),
4823 },
4824 .fixup_map2 = { 3 },
4825 .errstr = "R1 unbounded memory access",
4826 .result = REJECT,
4827 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4828 },
4829 {
4830 "helper access to adjusted map (via variable): wrong max check",
4831 .insns = {
4832 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4833 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4834 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4835 BPF_LD_MAP_FD(BPF_REG_1, 0),
4836 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4837 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4838 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4839 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4840 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4841 offsetof(struct test_val, foo), 4),
4842 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4843 BPF_MOV64_IMM(BPF_REG_2,
4844 sizeof(struct test_val) -
4845 offsetof(struct test_val, foo) + 1),
4846 BPF_MOV64_IMM(BPF_REG_3, 0),
4847 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4848 BPF_EXIT_INSN(),
4849 },
4850 .fixup_map2 = { 3 },
4851 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
4852 .result = REJECT,
4853 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4854 },
4855 {
4856 "helper access to map: bounds check using <, good access",
4857 .insns = {
4858 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4860 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4861 BPF_LD_MAP_FD(BPF_REG_1, 0),
4862 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4863 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4864 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4865 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4866 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
4867 BPF_MOV64_IMM(BPF_REG_0, 0),
4868 BPF_EXIT_INSN(),
4869 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4870 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4871 BPF_MOV64_IMM(BPF_REG_0, 0),
4872 BPF_EXIT_INSN(),
4873 },
4874 .fixup_map2 = { 3 },
4875 .result = ACCEPT,
4876 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4877 },
4878 {
4879 "helper access to map: bounds check using <, bad access",
4880 .insns = {
4881 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4883 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4884 BPF_LD_MAP_FD(BPF_REG_1, 0),
4885 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4886 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4887 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4888 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4889 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
4890 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4891 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4892 BPF_MOV64_IMM(BPF_REG_0, 0),
4893 BPF_EXIT_INSN(),
4894 BPF_MOV64_IMM(BPF_REG_0, 0),
4895 BPF_EXIT_INSN(),
4896 },
4897 .fixup_map2 = { 3 },
4898 .result = REJECT,
4899 .errstr = "R1 unbounded memory access",
4900 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4901 },
4902 {
4903 "helper access to map: bounds check using <=, good access",
4904 .insns = {
4905 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4906 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4907 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4908 BPF_LD_MAP_FD(BPF_REG_1, 0),
4909 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4910 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4911 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4912 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4913 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
4914 BPF_MOV64_IMM(BPF_REG_0, 0),
4915 BPF_EXIT_INSN(),
4916 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4917 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4918 BPF_MOV64_IMM(BPF_REG_0, 0),
4919 BPF_EXIT_INSN(),
4920 },
4921 .fixup_map2 = { 3 },
4922 .result = ACCEPT,
4923 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4924 },
4925 {
4926 "helper access to map: bounds check using <=, bad access",
4927 .insns = {
4928 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4930 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4931 BPF_LD_MAP_FD(BPF_REG_1, 0),
4932 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4933 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4934 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4935 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4936 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
4937 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4938 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4939 BPF_MOV64_IMM(BPF_REG_0, 0),
4940 BPF_EXIT_INSN(),
4941 BPF_MOV64_IMM(BPF_REG_0, 0),
4942 BPF_EXIT_INSN(),
4943 },
4944 .fixup_map2 = { 3 },
4945 .result = REJECT,
4946 .errstr = "R1 unbounded memory access",
4947 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4948 },
4949 {
4950 "helper access to map: bounds check using s<, good access",
4951 .insns = {
4952 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4953 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4954 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4955 BPF_LD_MAP_FD(BPF_REG_1, 0),
4956 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4957 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4958 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4959 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4960 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
4961 BPF_MOV64_IMM(BPF_REG_0, 0),
4962 BPF_EXIT_INSN(),
4963 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
4964 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4965 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4966 BPF_MOV64_IMM(BPF_REG_0, 0),
4967 BPF_EXIT_INSN(),
4968 },
4969 .fixup_map2 = { 3 },
4970 .result = ACCEPT,
4971 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4972 },
4973 {
4974 "helper access to map: bounds check using s<, good access 2",
4975 .insns = {
4976 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4977 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4978 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4979 BPF_LD_MAP_FD(BPF_REG_1, 0),
4980 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4981 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4982 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4983 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4984 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
4985 BPF_MOV64_IMM(BPF_REG_0, 0),
4986 BPF_EXIT_INSN(),
4987 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
4988 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4989 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4990 BPF_MOV64_IMM(BPF_REG_0, 0),
4991 BPF_EXIT_INSN(),
4992 },
4993 .fixup_map2 = { 3 },
4994 .result = ACCEPT,
4995 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4996 },
4997 {
4998 "helper access to map: bounds check using s<, bad access",
4999 .insns = {
5000 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5001 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5002 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5003 BPF_LD_MAP_FD(BPF_REG_1, 0),
5004 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5005 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5006 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5007 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5008 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5009 BPF_MOV64_IMM(BPF_REG_0, 0),
5010 BPF_EXIT_INSN(),
5011 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5012 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5013 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5014 BPF_MOV64_IMM(BPF_REG_0, 0),
5015 BPF_EXIT_INSN(),
5016 },
5017 .fixup_map2 = { 3 },
5018 .result = REJECT,
5019 .errstr = "R1 min value is negative",
5020 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5021 },
5022 {
5023 "helper access to map: bounds check using s<=, good access",
5024 .insns = {
5025 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5027 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5028 BPF_LD_MAP_FD(BPF_REG_1, 0),
5029 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5030 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5031 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5032 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5033 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5034 BPF_MOV64_IMM(BPF_REG_0, 0),
5035 BPF_EXIT_INSN(),
5036 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
5037 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5038 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5039 BPF_MOV64_IMM(BPF_REG_0, 0),
5040 BPF_EXIT_INSN(),
5041 },
5042 .fixup_map2 = { 3 },
5043 .result = ACCEPT,
5044 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5045 },
5046 {
5047 "helper access to map: bounds check using s<=, good access 2",
5048 .insns = {
5049 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5050 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5051 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5052 BPF_LD_MAP_FD(BPF_REG_1, 0),
5053 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5054 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5055 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5056 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5057 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5058 BPF_MOV64_IMM(BPF_REG_0, 0),
5059 BPF_EXIT_INSN(),
5060 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5061 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5062 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5063 BPF_MOV64_IMM(BPF_REG_0, 0),
5064 BPF_EXIT_INSN(),
5065 },
5066 .fixup_map2 = { 3 },
5067 .result = ACCEPT,
5068 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5069 },
5070 {
5071 "helper access to map: bounds check using s<=, bad access",
5072 .insns = {
5073 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5074 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5075 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5076 BPF_LD_MAP_FD(BPF_REG_1, 0),
5077 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5078 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5079 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5080 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5081 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5082 BPF_MOV64_IMM(BPF_REG_0, 0),
5083 BPF_EXIT_INSN(),
5084 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5085 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5086 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5087 BPF_MOV64_IMM(BPF_REG_0, 0),
5088 BPF_EXIT_INSN(),
5089 },
5090 .fixup_map2 = { 3 },
5091 .result = REJECT,
5092 .errstr = "R1 min value is negative",
5093 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5094 },
5095 {
5096 "map element value is preserved across register spilling",
5097 .insns = {
5098 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5099 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5100 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5101 BPF_LD_MAP_FD(BPF_REG_1, 0),
5102 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5103 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5104 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5105 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5106 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
5107 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5108 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5109 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5110 BPF_EXIT_INSN(),
5111 },
5112 .fixup_map2 = { 3 },
5113 .errstr_unpriv = "R0 leaks addr",
5114 .result = ACCEPT,
5115 .result_unpriv = REJECT,
5116 },
5117 {
5118 "map element value or null is marked on register spilling",
5119 .insns = {
5120 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5122 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5123 BPF_LD_MAP_FD(BPF_REG_1, 0),
5124 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5125 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5126 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
5127 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5128 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5129 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5130 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5131 BPF_EXIT_INSN(),
5132 },
5133 .fixup_map2 = { 3 },
5134 .errstr_unpriv = "R0 leaks addr",
5135 .result = ACCEPT,
5136 .result_unpriv = REJECT,
5137 },
5138 {
5139 "map element value store of cleared call register",
5140 .insns = {
5141 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5142 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5143 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5144 BPF_LD_MAP_FD(BPF_REG_1, 0),
5145 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5146 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5147 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
5148 BPF_EXIT_INSN(),
5149 },
5150 .fixup_map2 = { 3 },
5151 .errstr_unpriv = "R1 !read_ok",
5152 .errstr = "R1 !read_ok",
5153 .result = REJECT,
5154 .result_unpriv = REJECT,
5155 },
5156 {
5157 "map element value with unaligned store",
5158 .insns = {
5159 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5161 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5162 BPF_LD_MAP_FD(BPF_REG_1, 0),
5163 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5164 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
5165 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
5166 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5167 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
5168 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
5169 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
5170 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
5171 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
5172 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
5173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
5174 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
5175 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
5176 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
5177 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
5178 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
5179 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
5180 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
5181 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
5182 BPF_EXIT_INSN(),
5183 },
5184 .fixup_map2 = { 3 },
5185 .errstr_unpriv = "R0 leaks addr",
5186 .result = ACCEPT,
5187 .result_unpriv = REJECT,
5188 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5189 },
5190 {
5191 "map element value with unaligned load",
5192 .insns = {
5193 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5195 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5196 BPF_LD_MAP_FD(BPF_REG_1, 0),
5197 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5198 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5199 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5200 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
5201 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
5202 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
5203 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
5204 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
5205 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
5206 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
5207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
5208 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
5209 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
5210 BPF_EXIT_INSN(),
5211 },
5212 .fixup_map2 = { 3 },
5213 .errstr_unpriv = "R0 leaks addr",
5214 .result = ACCEPT,
5215 .result_unpriv = REJECT,
5216 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5217 },
5218 {
5219 "map element value illegal alu op, 1",
5220 .insns = {
5221 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5223 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5224 BPF_LD_MAP_FD(BPF_REG_1, 0),
5225 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5226 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5227 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
5228 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5229 BPF_EXIT_INSN(),
5230 },
5231 .fixup_map2 = { 3 },
5232 .errstr = "R0 bitwise operator &= on pointer",
5233 .result = REJECT,
5234 },
5235 {
5236 "map element value illegal alu op, 2",
5237 .insns = {
5238 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5239 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5240 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5241 BPF_LD_MAP_FD(BPF_REG_1, 0),
5242 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5244 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
5245 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5246 BPF_EXIT_INSN(),
5247 },
5248 .fixup_map2 = { 3 },
5249 .errstr = "R0 32-bit pointer arithmetic prohibited",
5250 .result = REJECT,
5251 },
5252 {
5253 "map element value illegal alu op, 3",
5254 .insns = {
5255 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5256 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5257 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5258 BPF_LD_MAP_FD(BPF_REG_1, 0),
5259 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5260 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5261 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
5262 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5263 BPF_EXIT_INSN(),
5264 },
5265 .fixup_map2 = { 3 },
5266 .errstr = "R0 pointer arithmetic with /= operator",
5267 .result = REJECT,
5268 },
5269 {
5270 "map element value illegal alu op, 4",
5271 .insns = {
5272 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5273 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5274 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5275 BPF_LD_MAP_FD(BPF_REG_1, 0),
5276 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5277 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5278 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
5279 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5280 BPF_EXIT_INSN(),
5281 },
5282 .fixup_map2 = { 3 },
5283 .errstr_unpriv = "R0 pointer arithmetic prohibited",
5284 .errstr = "invalid mem access 'inv'",
5285 .result = REJECT,
5286 .result_unpriv = REJECT,
5287 },
5288 {
5289 "map element value illegal alu op, 5",
5290 .insns = {
5291 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5292 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5293 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5294 BPF_LD_MAP_FD(BPF_REG_1, 0),
5295 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5296 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5297 BPF_MOV64_IMM(BPF_REG_3, 4096),
5298 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5299 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5300 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5301 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
5302 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
5303 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5304 BPF_EXIT_INSN(),
5305 },
5306 .fixup_map2 = { 3 },
5307 .errstr = "R0 invalid mem access 'inv'",
5308 .result = REJECT,
5309 },
5310 {
5311 "map element value is preserved across register spilling",
5312 .insns = {
5313 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5314 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5315 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5316 BPF_LD_MAP_FD(BPF_REG_1, 0),
5317 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5318 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5319 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
5320 offsetof(struct test_val, foo)),
5321 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
5324 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5325 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5326 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5327 BPF_EXIT_INSN(),
5328 },
5329 .fixup_map2 = { 3 },
5330 .errstr_unpriv = "R0 leaks addr",
5331 .result = ACCEPT,
5332 .result_unpriv = REJECT,
5333 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5334 },
5335 {
5336 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
5337 .insns = {
5338 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5339 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5340 BPF_MOV64_IMM(BPF_REG_0, 0),
5341 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5342 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5343 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5344 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5345 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5346 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5347 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5348 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5349 BPF_MOV64_IMM(BPF_REG_2, 16),
5350 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5351 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5352 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5353 BPF_MOV64_IMM(BPF_REG_4, 0),
5354 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5355 BPF_MOV64_IMM(BPF_REG_3, 0),
5356 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5357 BPF_MOV64_IMM(BPF_REG_0, 0),
5358 BPF_EXIT_INSN(),
5359 },
5360 .result = ACCEPT,
5361 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5362 },
5363 {
5364 "helper access to variable memory: stack, bitwise AND, zero included",
5365 .insns = {
5366 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5368 BPF_MOV64_IMM(BPF_REG_2, 16),
5369 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5370 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5371 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5372 BPF_MOV64_IMM(BPF_REG_3, 0),
5373 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5374 BPF_EXIT_INSN(),
5375 },
5376 .errstr = "invalid indirect read from stack off -64+0 size 64",
5377 .result = REJECT,
5378 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5379 },
5380 {
5381 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
5382 .insns = {
5383 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5384 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5385 BPF_MOV64_IMM(BPF_REG_2, 16),
5386 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5387 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5388 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
5389 BPF_MOV64_IMM(BPF_REG_4, 0),
5390 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5391 BPF_MOV64_IMM(BPF_REG_3, 0),
5392 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5393 BPF_MOV64_IMM(BPF_REG_0, 0),
5394 BPF_EXIT_INSN(),
5395 },
5396 .errstr = "invalid stack type R1 off=-64 access_size=65",
5397 .result = REJECT,
5398 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5399 },
5400 {
5401 "helper access to variable memory: stack, JMP, correct bounds",
5402 .insns = {
5403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5405 BPF_MOV64_IMM(BPF_REG_0, 0),
5406 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5407 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5408 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5409 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5410 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5411 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5412 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5413 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5414 BPF_MOV64_IMM(BPF_REG_2, 16),
5415 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5416 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5417 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
5418 BPF_MOV64_IMM(BPF_REG_4, 0),
5419 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5420 BPF_MOV64_IMM(BPF_REG_3, 0),
5421 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5422 BPF_MOV64_IMM(BPF_REG_0, 0),
5423 BPF_EXIT_INSN(),
5424 },
5425 .result = ACCEPT,
5426 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5427 },
5428 {
5429 "helper access to variable memory: stack, JMP (signed), correct bounds",
5430 .insns = {
5431 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5433 BPF_MOV64_IMM(BPF_REG_0, 0),
5434 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5435 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5436 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5437 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5438 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5439 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5440 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5441 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5442 BPF_MOV64_IMM(BPF_REG_2, 16),
5443 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5444 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5445 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
5446 BPF_MOV64_IMM(BPF_REG_4, 0),
5447 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5448 BPF_MOV64_IMM(BPF_REG_3, 0),
5449 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5450 BPF_MOV64_IMM(BPF_REG_0, 0),
5451 BPF_EXIT_INSN(),
5452 },
5453 .result = ACCEPT,
5454 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5455 },
5456 {
5457 "helper access to variable memory: stack, JMP, bounds + offset",
5458 .insns = {
5459 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5461 BPF_MOV64_IMM(BPF_REG_2, 16),
5462 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5463 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5464 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
5465 BPF_MOV64_IMM(BPF_REG_4, 0),
5466 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
5467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5468 BPF_MOV64_IMM(BPF_REG_3, 0),
5469 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5470 BPF_MOV64_IMM(BPF_REG_0, 0),
5471 BPF_EXIT_INSN(),
5472 },
5473 .errstr = "invalid stack type R1 off=-64 access_size=65",
5474 .result = REJECT,
5475 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5476 },
5477 {
5478 "helper access to variable memory: stack, JMP, wrong max",
5479 .insns = {
5480 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5481 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5482 BPF_MOV64_IMM(BPF_REG_2, 16),
5483 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5484 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5485 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
5486 BPF_MOV64_IMM(BPF_REG_4, 0),
5487 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5488 BPF_MOV64_IMM(BPF_REG_3, 0),
5489 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5490 BPF_MOV64_IMM(BPF_REG_0, 0),
5491 BPF_EXIT_INSN(),
5492 },
5493 .errstr = "invalid stack type R1 off=-64 access_size=65",
5494 .result = REJECT,
5495 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5496 },
5497 {
5498 "helper access to variable memory: stack, JMP, no max check",
5499 .insns = {
5500 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5501 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5502 BPF_MOV64_IMM(BPF_REG_2, 16),
5503 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5504 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5505 BPF_MOV64_IMM(BPF_REG_4, 0),
5506 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5507 BPF_MOV64_IMM(BPF_REG_3, 0),
5508 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5509 BPF_MOV64_IMM(BPF_REG_0, 0),
5510 BPF_EXIT_INSN(),
5511 },
5512 /* because max wasn't checked, signed min is negative */
5513 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
5514 .result = REJECT,
5515 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5516 },
5517 {
5518 "helper access to variable memory: stack, JMP, no min check",
5519 .insns = {
5520 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5522 BPF_MOV64_IMM(BPF_REG_2, 16),
5523 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5524 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5525 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
5526 BPF_MOV64_IMM(BPF_REG_3, 0),
5527 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5528 BPF_MOV64_IMM(BPF_REG_0, 0),
5529 BPF_EXIT_INSN(),
5530 },
5531 .errstr = "invalid indirect read from stack off -64+0 size 64",
5532 .result = REJECT,
5533 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5534 },
5535 {
5536 "helper access to variable memory: stack, JMP (signed), no min check",
5537 .insns = {
5538 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5539 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5540 BPF_MOV64_IMM(BPF_REG_2, 16),
5541 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5542 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5543 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
5544 BPF_MOV64_IMM(BPF_REG_3, 0),
5545 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5546 BPF_MOV64_IMM(BPF_REG_0, 0),
5547 BPF_EXIT_INSN(),
5548 },
5549 .errstr = "R2 min value is negative",
5550 .result = REJECT,
5551 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5552 },
5553 {
5554 "helper access to variable memory: map, JMP, correct bounds",
5555 .insns = {
5556 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5557 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5558 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5559 BPF_LD_MAP_FD(BPF_REG_1, 0),
5560 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5561 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
5562 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5563 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5564 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5565 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5566 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5567 sizeof(struct test_val), 4),
5568 BPF_MOV64_IMM(BPF_REG_4, 0),
5569 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5570 BPF_MOV64_IMM(BPF_REG_3, 0),
5571 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5572 BPF_MOV64_IMM(BPF_REG_0, 0),
5573 BPF_EXIT_INSN(),
5574 },
5575 .fixup_map2 = { 3 },
5576 .result = ACCEPT,
5577 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5578 },
5579 {
5580 "helper access to variable memory: map, JMP, wrong max",
5581 .insns = {
5582 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5584 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5585 BPF_LD_MAP_FD(BPF_REG_1, 0),
5586 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5587 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
5588 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5589 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5590 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5591 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5592 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5593 sizeof(struct test_val) + 1, 4),
5594 BPF_MOV64_IMM(BPF_REG_4, 0),
5595 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5596 BPF_MOV64_IMM(BPF_REG_3, 0),
5597 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5598 BPF_MOV64_IMM(BPF_REG_0, 0),
5599 BPF_EXIT_INSN(),
5600 },
5601 .fixup_map2 = { 3 },
5602 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
5603 .result = REJECT,
5604 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5605 },
5606 {
5607 "helper access to variable memory: map adjusted, JMP, correct bounds",
5608 .insns = {
5609 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5610 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5611 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5612 BPF_LD_MAP_FD(BPF_REG_1, 0),
5613 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5614 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5615 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5616 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5617 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5618 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5619 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5620 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5621 sizeof(struct test_val) - 20, 4),
5622 BPF_MOV64_IMM(BPF_REG_4, 0),
5623 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5624 BPF_MOV64_IMM(BPF_REG_3, 0),
5625 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5626 BPF_MOV64_IMM(BPF_REG_0, 0),
5627 BPF_EXIT_INSN(),
5628 },
5629 .fixup_map2 = { 3 },
5630 .result = ACCEPT,
5631 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5632 },
5633 {
5634 "helper access to variable memory: map adjusted, JMP, wrong max",
5635 .insns = {
5636 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5638 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5639 BPF_LD_MAP_FD(BPF_REG_1, 0),
5640 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5641 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5642 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5643 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5644 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5645 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5646 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5647 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5648 sizeof(struct test_val) - 19, 4),
5649 BPF_MOV64_IMM(BPF_REG_4, 0),
5650 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5651 BPF_MOV64_IMM(BPF_REG_3, 0),
5652 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5653 BPF_MOV64_IMM(BPF_REG_0, 0),
5654 BPF_EXIT_INSN(),
5655 },
5656 .fixup_map2 = { 3 },
5657 .errstr = "R1 min value is outside of the array range",
5658 .result = REJECT,
5659 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5660 },
5661 {
5662 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
5663 .insns = {
5664 BPF_MOV64_IMM(BPF_REG_1, 0),
5665 BPF_MOV64_IMM(BPF_REG_2, 0),
5666 BPF_MOV64_IMM(BPF_REG_3, 0),
5667 BPF_MOV64_IMM(BPF_REG_4, 0),
5668 BPF_MOV64_IMM(BPF_REG_5, 0),
5669 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5670 BPF_EXIT_INSN(),
5671 },
5672 .result = ACCEPT,
5673 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5674 },
5675 {
5676 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
5677 .insns = {
5678 BPF_MOV64_IMM(BPF_REG_1, 0),
5679 BPF_MOV64_IMM(BPF_REG_2, 1),
5680 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5681 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5682 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5683 BPF_MOV64_IMM(BPF_REG_3, 0),
5684 BPF_MOV64_IMM(BPF_REG_4, 0),
5685 BPF_MOV64_IMM(BPF_REG_5, 0),
5686 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5687 BPF_EXIT_INSN(),
5688 },
5689 .errstr = "R1 type=inv expected=fp",
5690 .result = REJECT,
5691 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5692 },
5693 {
5694 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
5695 .insns = {
5696 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5697 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5698 BPF_MOV64_IMM(BPF_REG_2, 0),
5699 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
5700 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
5701 BPF_MOV64_IMM(BPF_REG_3, 0),
5702 BPF_MOV64_IMM(BPF_REG_4, 0),
5703 BPF_MOV64_IMM(BPF_REG_5, 0),
5704 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5705 BPF_EXIT_INSN(),
5706 },
5707 .result = ACCEPT,
5708 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5709 },
5710 {
5711 "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
5712 .insns = {
5713 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5716 BPF_LD_MAP_FD(BPF_REG_1, 0),
5717 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5718 BPF_FUNC_map_lookup_elem),
5719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5720 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5721 BPF_MOV64_IMM(BPF_REG_2, 0),
5722 BPF_MOV64_IMM(BPF_REG_3, 0),
5723 BPF_MOV64_IMM(BPF_REG_4, 0),
5724 BPF_MOV64_IMM(BPF_REG_5, 0),
5725 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5726 BPF_EXIT_INSN(),
5727 },
5728 .fixup_map1 = { 3 },
5729 .result = ACCEPT,
5730 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5731 },
5732 {
5733 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
5734 .insns = {
5735 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5736 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5738 BPF_LD_MAP_FD(BPF_REG_1, 0),
5739 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5740 BPF_FUNC_map_lookup_elem),
5741 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5742 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5743 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
5744 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5746 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
5747 BPF_MOV64_IMM(BPF_REG_3, 0),
5748 BPF_MOV64_IMM(BPF_REG_4, 0),
5749 BPF_MOV64_IMM(BPF_REG_5, 0),
5750 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5751 BPF_EXIT_INSN(),
5752 },
5753 .fixup_map1 = { 3 },
5754 .result = ACCEPT,
5755 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5756 },
5757 {
5758 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
5759 .insns = {
5760 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5761 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5762 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5763 BPF_LD_MAP_FD(BPF_REG_1, 0),
5764 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5765 BPF_FUNC_map_lookup_elem),
5766 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5767 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5768 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5769 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5770 BPF_MOV64_IMM(BPF_REG_3, 0),
5771 BPF_MOV64_IMM(BPF_REG_4, 0),
5772 BPF_MOV64_IMM(BPF_REG_5, 0),
5773 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5774 BPF_EXIT_INSN(),
5775 },
5776 .fixup_map1 = { 3 },
5777 .result = ACCEPT,
5778 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5779 },
5780 {
5781 "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
5782 .insns = {
5783 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
5784 offsetof(struct __sk_buff, data)),
5785 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5786 offsetof(struct __sk_buff, data_end)),
5787 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
5788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5789 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
5790 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
5791 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
5792 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5793 BPF_MOV64_IMM(BPF_REG_3, 0),
5794 BPF_MOV64_IMM(BPF_REG_4, 0),
5795 BPF_MOV64_IMM(BPF_REG_5, 0),
5796 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5797 BPF_EXIT_INSN(),
5798 },
5799 .result = ACCEPT,
5800 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5801 },
5802 {
5803 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
5804 .insns = {
5805 BPF_MOV64_IMM(BPF_REG_1, 0),
5806 BPF_MOV64_IMM(BPF_REG_2, 0),
5807 BPF_MOV64_IMM(BPF_REG_3, 0),
5808 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5809 BPF_EXIT_INSN(),
5810 },
5811 .errstr = "R1 type=inv expected=fp",
5812 .result = REJECT,
5813 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5814 },
5815 {
5816 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
5817 .insns = {
5818 BPF_MOV64_IMM(BPF_REG_1, 0),
5819 BPF_MOV64_IMM(BPF_REG_2, 1),
5820 BPF_MOV64_IMM(BPF_REG_3, 0),
5821 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5822 BPF_EXIT_INSN(),
5823 },
5824 .errstr = "R1 type=inv expected=fp",
5825 .result = REJECT,
5826 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5827 },
5828 {
5829 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5830 .insns = {
5831 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5832 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5833 BPF_MOV64_IMM(BPF_REG_2, 0),
5834 BPF_MOV64_IMM(BPF_REG_3, 0),
5835 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5836 BPF_EXIT_INSN(),
5837 },
5838 .result = ACCEPT,
5839 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5840 },
5841 {
5842 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5843 .insns = {
5844 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5845 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5846 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5847 BPF_LD_MAP_FD(BPF_REG_1, 0),
5848 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5849 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5850 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5851 BPF_MOV64_IMM(BPF_REG_2, 0),
5852 BPF_MOV64_IMM(BPF_REG_3, 0),
5853 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5854 BPF_EXIT_INSN(),
5855 },
5856 .fixup_map1 = { 3 },
5857 .result = ACCEPT,
5858 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5859 },
5860 {
5861 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5862 .insns = {
5863 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5864 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5865 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5866 BPF_LD_MAP_FD(BPF_REG_1, 0),
5867 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5868 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5869 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5870 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5871 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5872 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5873 BPF_MOV64_IMM(BPF_REG_3, 0),
5874 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5875 BPF_EXIT_INSN(),
5876 },
5877 .fixup_map1 = { 3 },
5878 .result = ACCEPT,
5879 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5880 },
5881 {
5882 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5883 .insns = {
5884 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5885 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5886 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5887 BPF_LD_MAP_FD(BPF_REG_1, 0),
5888 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5889 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5890 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5891 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5892 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
5893 BPF_MOV64_IMM(BPF_REG_3, 0),
5894 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5895 BPF_EXIT_INSN(),
5896 },
5897 .fixup_map1 = { 3 },
5898 .result = ACCEPT,
5899 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5900 },
5901 {
5902 "helper access to variable memory: 8 bytes leak",
5903 .insns = {
5904 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5906 BPF_MOV64_IMM(BPF_REG_0, 0),
5907 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5908 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5909 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5910 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5911 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5912 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5913 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5914 BPF_MOV64_IMM(BPF_REG_2, 1),
5915 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5916 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5917 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
5918 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5919 BPF_MOV64_IMM(BPF_REG_3, 0),
5920 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5921 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5922 BPF_EXIT_INSN(),
5923 },
5924 .errstr = "invalid indirect read from stack off -64+32 size 64",
5925 .result = REJECT,
5926 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5927 },
5928 {
5929 "helper access to variable memory: 8 bytes no leak (init memory)",
5930 .insns = {
5931 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5932 BPF_MOV64_IMM(BPF_REG_0, 0),
5933 BPF_MOV64_IMM(BPF_REG_0, 0),
5934 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5935 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5936 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5937 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5938 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5939 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5940 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5941 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5943 BPF_MOV64_IMM(BPF_REG_2, 0),
5944 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
5945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
5946 BPF_MOV64_IMM(BPF_REG_3, 0),
5947 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5948 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5949 BPF_EXIT_INSN(),
5950 },
5951 .result = ACCEPT,
5952 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5953 },
5954 {
5955 "invalid and of negative number",
5956 .insns = {
5957 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5958 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5960 BPF_LD_MAP_FD(BPF_REG_1, 0),
5961 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5962 BPF_FUNC_map_lookup_elem),
5963 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5964 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
5965 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
5966 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
5967 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5968 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
5969 offsetof(struct test_val, foo)),
5970 BPF_EXIT_INSN(),
5971 },
5972 .fixup_map2 = { 3 },
5973 .errstr = "R0 max value is outside of the array range",
5974 .result = REJECT,
5975 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5976 },
5977 {
5978 "invalid range check",
5979 .insns = {
5980 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5981 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5982 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5983 BPF_LD_MAP_FD(BPF_REG_1, 0),
5984 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5985 BPF_FUNC_map_lookup_elem),
5986 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
5987 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5988 BPF_MOV64_IMM(BPF_REG_9, 1),
5989 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
5990 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
5991 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
5992 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
5993 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
5994 BPF_MOV32_IMM(BPF_REG_3, 1),
5995 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
5996 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
5997 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
5998 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
5999 BPF_MOV64_REG(BPF_REG_0, 0),
6000 BPF_EXIT_INSN(),
6001 },
6002 .fixup_map2 = { 3 },
6003 .errstr = "R0 max value is outside of the array range",
6004 .result = REJECT,
6005 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6006 },
6007 {
6008 "map in map access",
6009 .insns = {
6010 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6011 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6012 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6013 BPF_LD_MAP_FD(BPF_REG_1, 0),
6014 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6015 BPF_FUNC_map_lookup_elem),
6016 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6017 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6018 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6019 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6020 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6022 BPF_FUNC_map_lookup_elem),
6023 BPF_MOV64_REG(BPF_REG_0, 0),
6024 BPF_EXIT_INSN(),
6025 },
6026 .fixup_map_in_map = { 3 },
6027 .result = ACCEPT,
6028 },
6029 {
6030 "invalid inner map pointer",
6031 .insns = {
6032 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6033 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6034 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6035 BPF_LD_MAP_FD(BPF_REG_1, 0),
6036 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6037 BPF_FUNC_map_lookup_elem),
6038 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6039 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6040 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6042 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6044 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6045 BPF_FUNC_map_lookup_elem),
6046 BPF_MOV64_REG(BPF_REG_0, 0),
6047 BPF_EXIT_INSN(),
6048 },
6049 .fixup_map_in_map = { 3 },
6050 .errstr = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
6051 .result = REJECT,
6052 },
6053 {
6054 "forgot null checking on the inner map pointer",
6055 .insns = {
6056 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6057 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6059 BPF_LD_MAP_FD(BPF_REG_1, 0),
6060 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6061 BPF_FUNC_map_lookup_elem),
6062 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6063 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6064 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6065 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6066 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6067 BPF_FUNC_map_lookup_elem),
6068 BPF_MOV64_REG(BPF_REG_0, 0),
6069 BPF_EXIT_INSN(),
6070 },
6071 .fixup_map_in_map = { 3 },
6072 .errstr = "R1 type=map_value_or_null expected=map_ptr",
6073 .result = REJECT,
6074 },
6075 {
6076 "ld_abs: check calling conv, r1",
6077 .insns = {
6078 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6079 BPF_MOV64_IMM(BPF_REG_1, 0),
6080 BPF_LD_ABS(BPF_W, -0x200000),
6081 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6082 BPF_EXIT_INSN(),
6083 },
6084 .errstr = "R1 !read_ok",
6085 .result = REJECT,
6086 },
6087 {
6088 "ld_abs: check calling conv, r2",
6089 .insns = {
6090 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6091 BPF_MOV64_IMM(BPF_REG_2, 0),
6092 BPF_LD_ABS(BPF_W, -0x200000),
6093 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
6094 BPF_EXIT_INSN(),
6095 },
6096 .errstr = "R2 !read_ok",
6097 .result = REJECT,
6098 },
6099 {
6100 "ld_abs: check calling conv, r3",
6101 .insns = {
6102 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6103 BPF_MOV64_IMM(BPF_REG_3, 0),
6104 BPF_LD_ABS(BPF_W, -0x200000),
6105 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
6106 BPF_EXIT_INSN(),
6107 },
6108 .errstr = "R3 !read_ok",
6109 .result = REJECT,
6110 },
6111 {
6112 "ld_abs: check calling conv, r4",
6113 .insns = {
6114 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6115 BPF_MOV64_IMM(BPF_REG_4, 0),
6116 BPF_LD_ABS(BPF_W, -0x200000),
6117 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
6118 BPF_EXIT_INSN(),
6119 },
6120 .errstr = "R4 !read_ok",
6121 .result = REJECT,
6122 },
6123 {
6124 "ld_abs: check calling conv, r5",
6125 .insns = {
6126 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6127 BPF_MOV64_IMM(BPF_REG_5, 0),
6128 BPF_LD_ABS(BPF_W, -0x200000),
6129 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
6130 BPF_EXIT_INSN(),
6131 },
6132 .errstr = "R5 !read_ok",
6133 .result = REJECT,
6134 },
6135 {
6136 "ld_abs: check calling conv, r7",
6137 .insns = {
6138 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6139 BPF_MOV64_IMM(BPF_REG_7, 0),
6140 BPF_LD_ABS(BPF_W, -0x200000),
6141 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
6142 BPF_EXIT_INSN(),
6143 },
6144 .result = ACCEPT,
6145 },
6146 {
6147 "ld_abs: tests on r6 and skb data reload helper",
6148 .insns = {
6149 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6150 BPF_LD_ABS(BPF_B, 0),
6151 BPF_LD_ABS(BPF_H, 0),
6152 BPF_LD_ABS(BPF_W, 0),
6153 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
6154 BPF_MOV64_IMM(BPF_REG_6, 0),
6155 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
6156 BPF_MOV64_IMM(BPF_REG_2, 1),
6157 BPF_MOV64_IMM(BPF_REG_3, 2),
6158 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6159 BPF_FUNC_skb_vlan_push),
6160 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
6161 BPF_LD_ABS(BPF_B, 0),
6162 BPF_LD_ABS(BPF_H, 0),
6163 BPF_LD_ABS(BPF_W, 0),
6164 BPF_MOV64_IMM(BPF_REG_0, 42),
6165 BPF_EXIT_INSN(),
6166 },
6167 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6168 .result = ACCEPT,
6169 },
6170 {
6171 "ld_ind: check calling conv, r1",
6172 .insns = {
6173 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6174 BPF_MOV64_IMM(BPF_REG_1, 1),
6175 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
6176 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6177 BPF_EXIT_INSN(),
6178 },
6179 .errstr = "R1 !read_ok",
6180 .result = REJECT,
6181 },
6182 {
6183 "ld_ind: check calling conv, r2",
6184 .insns = {
6185 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6186 BPF_MOV64_IMM(BPF_REG_2, 1),
6187 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
6188 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
6189 BPF_EXIT_INSN(),
6190 },
6191 .errstr = "R2 !read_ok",
6192 .result = REJECT,
6193 },
6194 {
6195 "ld_ind: check calling conv, r3",
6196 .insns = {
6197 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6198 BPF_MOV64_IMM(BPF_REG_3, 1),
6199 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
6200 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
6201 BPF_EXIT_INSN(),
6202 },
6203 .errstr = "R3 !read_ok",
6204 .result = REJECT,
6205 },
6206 {
6207 "ld_ind: check calling conv, r4",
6208 .insns = {
6209 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6210 BPF_MOV64_IMM(BPF_REG_4, 1),
6211 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
6212 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
6213 BPF_EXIT_INSN(),
6214 },
6215 .errstr = "R4 !read_ok",
6216 .result = REJECT,
6217 },
6218 {
6219 "ld_ind: check calling conv, r5",
6220 .insns = {
6221 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6222 BPF_MOV64_IMM(BPF_REG_5, 1),
6223 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
6224 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
6225 BPF_EXIT_INSN(),
6226 },
6227 .errstr = "R5 !read_ok",
6228 .result = REJECT,
6229 },
6230 {
6231 "ld_ind: check calling conv, r7",
6232 .insns = {
6233 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6234 BPF_MOV64_IMM(BPF_REG_7, 1),
6235 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
6236 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
6237 BPF_EXIT_INSN(),
6238 },
6239 .result = ACCEPT,
6240 },
6241 {
6242 "check bpf_perf_event_data->sample_period byte load permitted",
6243 .insns = {
6244 BPF_MOV64_IMM(BPF_REG_0, 0),
6245 #if __BYTE_ORDER == __LITTLE_ENDIAN
6246 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
6247 offsetof(struct bpf_perf_event_data, sample_period)),
6248 #else
6249 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
6250 offsetof(struct bpf_perf_event_data, sample_period) + 7),
6251 #endif
6252 BPF_EXIT_INSN(),
6253 },
6254 .result = ACCEPT,
6255 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6256 },
6257 {
6258 "check bpf_perf_event_data->sample_period half load permitted",
6259 .insns = {
6260 BPF_MOV64_IMM(BPF_REG_0, 0),
6261 #if __BYTE_ORDER == __LITTLE_ENDIAN
6262 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6263 offsetof(struct bpf_perf_event_data, sample_period)),
6264 #else
6265 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6266 offsetof(struct bpf_perf_event_data, sample_period) + 6),
6267 #endif
6268 BPF_EXIT_INSN(),
6269 },
6270 .result = ACCEPT,
6271 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6272 },
6273 {
6274 "check bpf_perf_event_data->sample_period word load permitted",
6275 .insns = {
6276 BPF_MOV64_IMM(BPF_REG_0, 0),
6277 #if __BYTE_ORDER == __LITTLE_ENDIAN
6278 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6279 offsetof(struct bpf_perf_event_data, sample_period)),
6280 #else
6281 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6282 offsetof(struct bpf_perf_event_data, sample_period) + 4),
6283 #endif
6284 BPF_EXIT_INSN(),
6285 },
6286 .result = ACCEPT,
6287 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6288 },
6289 {
6290 "check bpf_perf_event_data->sample_period dword load permitted",
6291 .insns = {
6292 BPF_MOV64_IMM(BPF_REG_0, 0),
6293 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
6294 offsetof(struct bpf_perf_event_data, sample_period)),
6295 BPF_EXIT_INSN(),
6296 },
6297 .result = ACCEPT,
6298 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6299 },
6300 {
6301 "check skb->data half load not permitted",
6302 .insns = {
6303 BPF_MOV64_IMM(BPF_REG_0, 0),
6304 #if __BYTE_ORDER == __LITTLE_ENDIAN
6305 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6306 offsetof(struct __sk_buff, data)),
6307 #else
6308 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6309 offsetof(struct __sk_buff, data) + 2),
6310 #endif
6311 BPF_EXIT_INSN(),
6312 },
6313 .result = REJECT,
6314 .errstr = "invalid bpf_context access",
6315 },
6316 {
6317 "check skb->tc_classid half load not permitted for lwt prog",
6318 .insns = {
6319 BPF_MOV64_IMM(BPF_REG_0, 0),
6320 #if __BYTE_ORDER == __LITTLE_ENDIAN
6321 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6322 offsetof(struct __sk_buff, tc_classid)),
6323 #else
6324 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6325 offsetof(struct __sk_buff, tc_classid) + 2),
6326 #endif
6327 BPF_EXIT_INSN(),
6328 },
6329 .result = REJECT,
6330 .errstr = "invalid bpf_context access",
6331 .prog_type = BPF_PROG_TYPE_LWT_IN,
6332 },
6333 {
6334 "bounds checks mixing signed and unsigned, positive bounds",
6335 .insns = {
6336 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6337 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6339 BPF_LD_MAP_FD(BPF_REG_1, 0),
6340 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6341 BPF_FUNC_map_lookup_elem),
6342 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6343 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6344 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6345 BPF_MOV64_IMM(BPF_REG_2, 2),
6346 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
6347 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
6348 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6349 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6350 BPF_MOV64_IMM(BPF_REG_0, 0),
6351 BPF_EXIT_INSN(),
6352 },
6353 .fixup_map1 = { 3 },
6354 .errstr = "unbounded min value",
6355 .result = REJECT,
6356 },
6357 {
6358 "bounds checks mixing signed and unsigned",
6359 .insns = {
6360 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6361 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6362 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6363 BPF_LD_MAP_FD(BPF_REG_1, 0),
6364 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6365 BPF_FUNC_map_lookup_elem),
6366 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6367 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6368 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6369 BPF_MOV64_IMM(BPF_REG_2, -1),
6370 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
6371 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6372 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6373 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6374 BPF_MOV64_IMM(BPF_REG_0, 0),
6375 BPF_EXIT_INSN(),
6376 },
6377 .fixup_map1 = { 3 },
6378 .errstr = "unbounded min value",
6379 .result = REJECT,
6380 },
6381 {
6382 "bounds checks mixing signed and unsigned, variant 2",
6383 .insns = {
6384 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6385 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6387 BPF_LD_MAP_FD(BPF_REG_1, 0),
6388 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6389 BPF_FUNC_map_lookup_elem),
6390 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6391 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6392 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6393 BPF_MOV64_IMM(BPF_REG_2, -1),
6394 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
6395 BPF_MOV64_IMM(BPF_REG_8, 0),
6396 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
6397 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
6398 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
6399 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
6400 BPF_MOV64_IMM(BPF_REG_0, 0),
6401 BPF_EXIT_INSN(),
6402 },
6403 .fixup_map1 = { 3 },
6404 .errstr = "unbounded min value",
6405 .result = REJECT,
6406 },
6407 {
6408 "bounds checks mixing signed and unsigned, variant 3",
6409 .insns = {
6410 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6411 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6413 BPF_LD_MAP_FD(BPF_REG_1, 0),
6414 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6415 BPF_FUNC_map_lookup_elem),
6416 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6417 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6418 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6419 BPF_MOV64_IMM(BPF_REG_2, -1),
6420 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
6421 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
6422 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
6423 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
6424 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
6425 BPF_MOV64_IMM(BPF_REG_0, 0),
6426 BPF_EXIT_INSN(),
6427 },
6428 .fixup_map1 = { 3 },
6429 .errstr = "unbounded min value",
6430 .result = REJECT,
6431 },
6432 {
6433 "bounds checks mixing signed and unsigned, variant 4",
6434 .insns = {
6435 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6436 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6437 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6438 BPF_LD_MAP_FD(BPF_REG_1, 0),
6439 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6440 BPF_FUNC_map_lookup_elem),
6441 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6442 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6443 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6444 BPF_MOV64_IMM(BPF_REG_2, 1),
6445 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
6446 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6447 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6448 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6449 BPF_MOV64_IMM(BPF_REG_0, 0),
6450 BPF_EXIT_INSN(),
6451 },
6452 .fixup_map1 = { 3 },
6453 .result = ACCEPT,
6454 },
6455 {
6456 "bounds checks mixing signed and unsigned, variant 5",
6457 .insns = {
6458 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6459 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6461 BPF_LD_MAP_FD(BPF_REG_1, 0),
6462 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6463 BPF_FUNC_map_lookup_elem),
6464 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6465 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6466 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6467 BPF_MOV64_IMM(BPF_REG_2, -1),
6468 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
6469 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
6470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
6471 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
6472 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6473 BPF_MOV64_IMM(BPF_REG_0, 0),
6474 BPF_EXIT_INSN(),
6475 },
6476 .fixup_map1 = { 3 },
6477 .errstr = "unbounded min value",
6478 .result = REJECT,
6479 },
6480 {
6481 "bounds checks mixing signed and unsigned, variant 6",
6482 .insns = {
6483 BPF_MOV64_IMM(BPF_REG_2, 0),
6484 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
6485 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
6486 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6487 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
6488 BPF_MOV64_IMM(BPF_REG_6, -1),
6489 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
6490 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
6491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
6492 BPF_MOV64_IMM(BPF_REG_5, 0),
6493 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
6494 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6495 BPF_FUNC_skb_load_bytes),
6496 BPF_MOV64_IMM(BPF_REG_0, 0),
6497 BPF_EXIT_INSN(),
6498 },
6499 .errstr = "R4 min value is negative, either use unsigned",
6500 .result = REJECT,
6501 },
6502 {
6503 "bounds checks mixing signed and unsigned, variant 7",
6504 .insns = {
6505 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6506 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6507 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6508 BPF_LD_MAP_FD(BPF_REG_1, 0),
6509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6510 BPF_FUNC_map_lookup_elem),
6511 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6512 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6513 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6514 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
6515 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
6516 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6517 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6518 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6519 BPF_MOV64_IMM(BPF_REG_0, 0),
6520 BPF_EXIT_INSN(),
6521 },
6522 .fixup_map1 = { 3 },
6523 .result = ACCEPT,
6524 },
6525 {
6526 "bounds checks mixing signed and unsigned, variant 8",
6527 .insns = {
6528 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6529 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6530 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6531 BPF_LD_MAP_FD(BPF_REG_1, 0),
6532 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6533 BPF_FUNC_map_lookup_elem),
6534 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6535 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6536 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6537 BPF_MOV64_IMM(BPF_REG_2, -1),
6538 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6539 BPF_MOV64_IMM(BPF_REG_0, 0),
6540 BPF_EXIT_INSN(),
6541 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6542 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6543 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6544 BPF_MOV64_IMM(BPF_REG_0, 0),
6545 BPF_EXIT_INSN(),
6546 },
6547 .fixup_map1 = { 3 },
6548 .errstr = "unbounded min value",
6549 .result = REJECT,
6550 },
6551 {
6552 "bounds checks mixing signed and unsigned, variant 9",
6553 .insns = {
6554 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6555 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6557 BPF_LD_MAP_FD(BPF_REG_1, 0),
6558 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6559 BPF_FUNC_map_lookup_elem),
6560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6561 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6562 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6563 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
6564 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6565 BPF_MOV64_IMM(BPF_REG_0, 0),
6566 BPF_EXIT_INSN(),
6567 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6568 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6569 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6570 BPF_MOV64_IMM(BPF_REG_0, 0),
6571 BPF_EXIT_INSN(),
6572 },
6573 .fixup_map1 = { 3 },
6574 .result = ACCEPT,
6575 },
6576 {
6577 "bounds checks mixing signed and unsigned, variant 10",
6578 .insns = {
6579 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6582 BPF_LD_MAP_FD(BPF_REG_1, 0),
6583 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6584 BPF_FUNC_map_lookup_elem),
6585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6586 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6587 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6588 BPF_MOV64_IMM(BPF_REG_2, 0),
6589 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6590 BPF_MOV64_IMM(BPF_REG_0, 0),
6591 BPF_EXIT_INSN(),
6592 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6593 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6594 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6595 BPF_MOV64_IMM(BPF_REG_0, 0),
6596 BPF_EXIT_INSN(),
6597 },
6598 .fixup_map1 = { 3 },
6599 .errstr = "unbounded min value",
6600 .result = REJECT,
6601 },
6602 {
6603 "bounds checks mixing signed and unsigned, variant 11",
6604 .insns = {
6605 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6606 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6608 BPF_LD_MAP_FD(BPF_REG_1, 0),
6609 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6610 BPF_FUNC_map_lookup_elem),
6611 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6612 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6613 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6614 BPF_MOV64_IMM(BPF_REG_2, -1),
6615 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6616 /* Dead branch. */
6617 BPF_MOV64_IMM(BPF_REG_0, 0),
6618 BPF_EXIT_INSN(),
6619 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6620 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6621 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6622 BPF_MOV64_IMM(BPF_REG_0, 0),
6623 BPF_EXIT_INSN(),
6624 },
6625 .fixup_map1 = { 3 },
6626 .errstr = "unbounded min value",
6627 .result = REJECT,
6628 },
6629 {
6630 "bounds checks mixing signed and unsigned, variant 12",
6631 .insns = {
6632 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6633 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6635 BPF_LD_MAP_FD(BPF_REG_1, 0),
6636 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6637 BPF_FUNC_map_lookup_elem),
6638 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6639 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6640 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6641 BPF_MOV64_IMM(BPF_REG_2, -6),
6642 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6643 BPF_MOV64_IMM(BPF_REG_0, 0),
6644 BPF_EXIT_INSN(),
6645 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6646 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6647 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6648 BPF_MOV64_IMM(BPF_REG_0, 0),
6649 BPF_EXIT_INSN(),
6650 },
6651 .fixup_map1 = { 3 },
6652 .errstr = "unbounded min value",
6653 .result = REJECT,
6654 },
6655 {
6656 "bounds checks mixing signed and unsigned, variant 13",
6657 .insns = {
6658 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6659 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6660 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6661 BPF_LD_MAP_FD(BPF_REG_1, 0),
6662 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6663 BPF_FUNC_map_lookup_elem),
6664 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6665 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6666 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6667 BPF_MOV64_IMM(BPF_REG_2, 2),
6668 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6669 BPF_MOV64_IMM(BPF_REG_7, 1),
6670 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
6671 BPF_MOV64_IMM(BPF_REG_0, 0),
6672 BPF_EXIT_INSN(),
6673 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
6674 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
6675 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
6676 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6677 BPF_MOV64_IMM(BPF_REG_0, 0),
6678 BPF_EXIT_INSN(),
6679 },
6680 .fixup_map1 = { 3 },
6681 .errstr = "unbounded min value",
6682 .result = REJECT,
6683 },
6684 {
6685 "bounds checks mixing signed and unsigned, variant 14",
6686 .insns = {
6687 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
6688 offsetof(struct __sk_buff, mark)),
6689 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6690 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6691 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6692 BPF_LD_MAP_FD(BPF_REG_1, 0),
6693 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6694 BPF_FUNC_map_lookup_elem),
6695 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6696 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6697 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6698 BPF_MOV64_IMM(BPF_REG_2, -1),
6699 BPF_MOV64_IMM(BPF_REG_8, 2),
6700 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
6701 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
6702 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6703 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6704 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6705 BPF_MOV64_IMM(BPF_REG_0, 0),
6706 BPF_EXIT_INSN(),
6707 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
6708 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
6709 },
6710 .fixup_map1 = { 4 },
6711 .errstr = "unbounded min value",
6712 .result = REJECT,
6713 },
6714 {
6715 "bounds checks mixing signed and unsigned, variant 15",
6716 .insns = {
6717 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6718 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6719 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6720 BPF_LD_MAP_FD(BPF_REG_1, 0),
6721 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6722 BPF_FUNC_map_lookup_elem),
6723 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6724 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6725 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6726 BPF_MOV64_IMM(BPF_REG_2, -6),
6727 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6728 BPF_MOV64_IMM(BPF_REG_0, 0),
6729 BPF_EXIT_INSN(),
6730 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6731 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
6732 BPF_MOV64_IMM(BPF_REG_0, 0),
6733 BPF_EXIT_INSN(),
6734 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6735 BPF_MOV64_IMM(BPF_REG_0, 0),
6736 BPF_EXIT_INSN(),
6737 },
6738 .fixup_map1 = { 3 },
6739 .errstr = "unbounded min value",
6740 .result = REJECT,
6741 .result_unpriv = REJECT,
6742 },
6743 {
6744 "subtraction bounds (map value) variant 1",
6745 .insns = {
6746 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6747 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6748 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6749 BPF_LD_MAP_FD(BPF_REG_1, 0),
6750 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6751 BPF_FUNC_map_lookup_elem),
6752 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6753 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6754 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
6755 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
6756 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
6757 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
6758 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
6759 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6760 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6761 BPF_EXIT_INSN(),
6762 BPF_MOV64_IMM(BPF_REG_0, 0),
6763 BPF_EXIT_INSN(),
6764 },
6765 .fixup_map1 = { 3 },
6766 .errstr = "R0 max value is outside of the array range",
6767 .result = REJECT,
6768 },
6769 {
6770 "subtraction bounds (map value) variant 2",
6771 .insns = {
6772 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6773 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6775 BPF_LD_MAP_FD(BPF_REG_1, 0),
6776 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6777 BPF_FUNC_map_lookup_elem),
6778 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6779 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6780 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
6781 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
6782 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
6783 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
6784 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6785 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6786 BPF_EXIT_INSN(),
6787 BPF_MOV64_IMM(BPF_REG_0, 0),
6788 BPF_EXIT_INSN(),
6789 },
6790 .fixup_map1 = { 3 },
6791 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
6792 .result = REJECT,
6793 },
6794 {
6795 "bounds check based on zero-extended MOV",
6796 .insns = {
6797 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6798 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6799 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6800 BPF_LD_MAP_FD(BPF_REG_1, 0),
6801 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6802 BPF_FUNC_map_lookup_elem),
6803 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6804 /* r2 = 0x0000'0000'ffff'ffff */
6805 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
6806 /* r2 = 0 */
6807 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
6808 /* no-op */
6809 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6810 /* access at offset 0 */
6811 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6812 /* exit */
6813 BPF_MOV64_IMM(BPF_REG_0, 0),
6814 BPF_EXIT_INSN(),
6815 },
6816 .fixup_map1 = { 3 },
6817 .result = ACCEPT
6818 },
6819 {
6820 "bounds check based on sign-extended MOV. test1",
6821 .insns = {
6822 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6823 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6825 BPF_LD_MAP_FD(BPF_REG_1, 0),
6826 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6827 BPF_FUNC_map_lookup_elem),
6828 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6829 /* r2 = 0xffff'ffff'ffff'ffff */
6830 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
6831 /* r2 = 0xffff'ffff */
6832 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
6833 /* r0 = <oob pointer> */
6834 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6835 /* access to OOB pointer */
6836 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6837 /* exit */
6838 BPF_MOV64_IMM(BPF_REG_0, 0),
6839 BPF_EXIT_INSN(),
6840 },
6841 .fixup_map1 = { 3 },
6842 .errstr = "map_value pointer and 4294967295",
6843 .result = REJECT
6844 },
6845 {
6846 "bounds check based on sign-extended MOV. test2",
6847 .insns = {
6848 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6849 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6851 BPF_LD_MAP_FD(BPF_REG_1, 0),
6852 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6853 BPF_FUNC_map_lookup_elem),
6854 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6855 /* r2 = 0xffff'ffff'ffff'ffff */
6856 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
6857 /* r2 = 0xfff'ffff */
6858 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
6859 /* r0 = <oob pointer> */
6860 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6861 /* access to OOB pointer */
6862 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6863 /* exit */
6864 BPF_MOV64_IMM(BPF_REG_0, 0),
6865 BPF_EXIT_INSN(),
6866 },
6867 .fixup_map1 = { 3 },
6868 .errstr = "R0 min value is outside of the array range",
6869 .result = REJECT
6870 },
6871 {
6872 "bounds check based on reg_off + var_off + insn_off. test1",
6873 .insns = {
6874 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6875 offsetof(struct __sk_buff, mark)),
6876 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6877 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6879 BPF_LD_MAP_FD(BPF_REG_1, 0),
6880 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6881 BPF_FUNC_map_lookup_elem),
6882 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6883 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
6884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
6885 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
6886 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
6887 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
6888 BPF_MOV64_IMM(BPF_REG_0, 0),
6889 BPF_EXIT_INSN(),
6890 },
6891 .fixup_map1 = { 4 },
6892 .errstr = "value_size=8 off=1073741825",
6893 .result = REJECT,
6894 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6895 },
6896 {
6897 "bounds check based on reg_off + var_off + insn_off. test2",
6898 .insns = {
6899 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6900 offsetof(struct __sk_buff, mark)),
6901 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6902 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6903 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6904 BPF_LD_MAP_FD(BPF_REG_1, 0),
6905 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6906 BPF_FUNC_map_lookup_elem),
6907 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6908 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
6909 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
6910 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
6911 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
6912 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
6913 BPF_MOV64_IMM(BPF_REG_0, 0),
6914 BPF_EXIT_INSN(),
6915 },
6916 .fixup_map1 = { 4 },
6917 .errstr = "value 1073741823",
6918 .result = REJECT,
6919 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6920 },
6921 {
6922 "bounds check after truncation of non-boundary-crossing range",
6923 .insns = {
6924 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6925 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6926 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6927 BPF_LD_MAP_FD(BPF_REG_1, 0),
6928 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6929 BPF_FUNC_map_lookup_elem),
6930 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6931 /* r1 = [0x00, 0xff] */
6932 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6933 BPF_MOV64_IMM(BPF_REG_2, 1),
6934 /* r2 = 0x10'0000'0000 */
6935 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
6936 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
6937 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
6938 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
6939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
6940 /* r1 = [0x00, 0xff] */
6941 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
6942 /* r1 = 0 */
6943 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
6944 /* no-op */
6945 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6946 /* access at offset 0 */
6947 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6948 /* exit */
6949 BPF_MOV64_IMM(BPF_REG_0, 0),
6950 BPF_EXIT_INSN(),
6951 },
6952 .fixup_map1 = { 3 },
6953 .result = ACCEPT
6954 },
6955 {
6956 "bounds check after truncation of boundary-crossing range (1)",
6957 .insns = {
6958 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6959 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6960 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6961 BPF_LD_MAP_FD(BPF_REG_1, 0),
6962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6963 BPF_FUNC_map_lookup_elem),
6964 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6965 /* r1 = [0x00, 0xff] */
6966 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
6968 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
6969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
6970 /* r1 = [0xffff'ff80, 0xffff'ffff] or
6971 * [0x0000'0000, 0x0000'007f]
6972 */
6973 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
6974 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
6975 /* r1 = [0x00, 0xff] or
6976 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
6977 */
6978 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
6979 /* r1 = 0 or
6980 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
6981 */
6982 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
6983 /* no-op or OOB pointer computation */
6984 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6985 /* potentially OOB access */
6986 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6987 /* exit */
6988 BPF_MOV64_IMM(BPF_REG_0, 0),
6989 BPF_EXIT_INSN(),
6990 },
6991 .fixup_map1 = { 3 },
6992 /* not actually fully unbounded, but the bound is very high */
6993 .errstr = "R0 unbounded memory access",
6994 .result = REJECT
6995 },
6996 {
6997 "bounds check after truncation of boundary-crossing range (2)",
6998 .insns = {
6999 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7000 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7001 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7002 BPF_LD_MAP_FD(BPF_REG_1, 0),
7003 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7004 BPF_FUNC_map_lookup_elem),
7005 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7006 /* r1 = [0x00, 0xff] */
7007 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7008 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7009 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7010 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7011 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7012 * [0x0000'0000, 0x0000'007f]
7013 * difference to previous test: truncation via MOV32
7014 * instead of ALU32.
7015 */
7016 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
7017 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7018 /* r1 = [0x00, 0xff] or
7019 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7020 */
7021 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7022 /* r1 = 0 or
7023 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7024 */
7025 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7026 /* no-op or OOB pointer computation */
7027 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7028 /* potentially OOB access */
7029 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7030 /* exit */
7031 BPF_MOV64_IMM(BPF_REG_0, 0),
7032 BPF_EXIT_INSN(),
7033 },
7034 .fixup_map1 = { 3 },
7035 /* not actually fully unbounded, but the bound is very high */
7036 .errstr = "R0 unbounded memory access",
7037 .result = REJECT
7038 },
7039 {
7040 "bounds check after wrapping 32-bit addition",
7041 .insns = {
7042 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7043 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7045 BPF_LD_MAP_FD(BPF_REG_1, 0),
7046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7047 BPF_FUNC_map_lookup_elem),
7048 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7049 /* r1 = 0x7fff'ffff */
7050 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
7051 /* r1 = 0xffff'fffe */
7052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7053 /* r1 = 0 */
7054 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
7055 /* no-op */
7056 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7057 /* access at offset 0 */
7058 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7059 /* exit */
7060 BPF_MOV64_IMM(BPF_REG_0, 0),
7061 BPF_EXIT_INSN(),
7062 },
7063 .fixup_map1 = { 3 },
7064 .result = ACCEPT
7065 },
7066 {
7067 "bounds check after shift with oversized count operand",
7068 .insns = {
7069 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7070 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7072 BPF_LD_MAP_FD(BPF_REG_1, 0),
7073 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7074 BPF_FUNC_map_lookup_elem),
7075 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7076 BPF_MOV64_IMM(BPF_REG_2, 32),
7077 BPF_MOV64_IMM(BPF_REG_1, 1),
7078 /* r1 = (u32)1 << (u32)32 = ? */
7079 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
7080 /* r1 = [0x0000, 0xffff] */
7081 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
7082 /* computes unknown pointer, potentially OOB */
7083 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7084 /* potentially OOB access */
7085 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7086 /* exit */
7087 BPF_MOV64_IMM(BPF_REG_0, 0),
7088 BPF_EXIT_INSN(),
7089 },
7090 .fixup_map1 = { 3 },
7091 .errstr = "R0 max value is outside of the array range",
7092 .result = REJECT
7093 },
7094 {
7095 "bounds check after right shift of maybe-negative number",
7096 .insns = {
7097 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7098 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7099 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7100 BPF_LD_MAP_FD(BPF_REG_1, 0),
7101 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7102 BPF_FUNC_map_lookup_elem),
7103 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7104 /* r1 = [0x00, 0xff] */
7105 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7106 /* r1 = [-0x01, 0xfe] */
7107 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
7108 /* r1 = 0 or 0xff'ffff'ffff'ffff */
7109 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7110 /* r1 = 0 or 0xffff'ffff'ffff */
7111 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7112 /* computes unknown pointer, potentially OOB */
7113 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7114 /* potentially OOB access */
7115 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7116 /* exit */
7117 BPF_MOV64_IMM(BPF_REG_0, 0),
7118 BPF_EXIT_INSN(),
7119 },
7120 .fixup_map1 = { 3 },
7121 .errstr = "R0 unbounded memory access",
7122 .result = REJECT
7123 },
7124 {
7125 "bounds check map access with off+size signed 32bit overflow. test1",
7126 .insns = {
7127 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7128 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7130 BPF_LD_MAP_FD(BPF_REG_1, 0),
7131 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7132 BPF_FUNC_map_lookup_elem),
7133 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7134 BPF_EXIT_INSN(),
7135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
7136 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7137 BPF_JMP_A(0),
7138 BPF_EXIT_INSN(),
7139 },
7140 .fixup_map1 = { 3 },
7141 .errstr = "map_value pointer and 2147483646",
7142 .result = REJECT
7143 },
7144 {
7145 "bounds check map access with off+size signed 32bit overflow. test2",
7146 .insns = {
7147 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7148 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7149 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7150 BPF_LD_MAP_FD(BPF_REG_1, 0),
7151 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7152 BPF_FUNC_map_lookup_elem),
7153 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7154 BPF_EXIT_INSN(),
7155 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7157 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7158 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7159 BPF_JMP_A(0),
7160 BPF_EXIT_INSN(),
7161 },
7162 .fixup_map1 = { 3 },
7163 .errstr = "pointer offset 1073741822",
7164 .result = REJECT
7165 },
7166 {
7167 "bounds check map access with off+size signed 32bit overflow. test3",
7168 .insns = {
7169 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7170 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7171 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7172 BPF_LD_MAP_FD(BPF_REG_1, 0),
7173 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7174 BPF_FUNC_map_lookup_elem),
7175 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7176 BPF_EXIT_INSN(),
7177 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
7178 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
7179 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
7180 BPF_JMP_A(0),
7181 BPF_EXIT_INSN(),
7182 },
7183 .fixup_map1 = { 3 },
7184 .errstr = "pointer offset -1073741822",
7185 .result = REJECT
7186 },
7187 {
7188 "bounds check map access with off+size signed 32bit overflow. test4",
7189 .insns = {
7190 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7191 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7193 BPF_LD_MAP_FD(BPF_REG_1, 0),
7194 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7195 BPF_FUNC_map_lookup_elem),
7196 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7197 BPF_EXIT_INSN(),
7198 BPF_MOV64_IMM(BPF_REG_1, 1000000),
7199 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
7200 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7201 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
7202 BPF_JMP_A(0),
7203 BPF_EXIT_INSN(),
7204 },
7205 .fixup_map1 = { 3 },
7206 .errstr = "map_value pointer and 1000000000000",
7207 .result = REJECT
7208 },
7209 {
7210 "pointer/scalar confusion in state equality check (way 1)",
7211 .insns = {
7212 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7213 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7215 BPF_LD_MAP_FD(BPF_REG_1, 0),
7216 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7217 BPF_FUNC_map_lookup_elem),
7218 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7219 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7220 BPF_JMP_A(1),
7221 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
7222 BPF_JMP_A(0),
7223 BPF_EXIT_INSN(),
7224 },
7225 .fixup_map1 = { 3 },
7226 .result = ACCEPT,
7227 .result_unpriv = REJECT,
7228 .errstr_unpriv = "R0 leaks addr as return value"
7229 },
7230 {
7231 "pointer/scalar confusion in state equality check (way 2)",
7232 .insns = {
7233 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7234 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7235 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7236 BPF_LD_MAP_FD(BPF_REG_1, 0),
7237 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7238 BPF_FUNC_map_lookup_elem),
7239 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
7240 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
7241 BPF_JMP_A(1),
7242 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7243 BPF_EXIT_INSN(),
7244 },
7245 .fixup_map1 = { 3 },
7246 .result = ACCEPT,
7247 .result_unpriv = REJECT,
7248 .errstr_unpriv = "R0 leaks addr as return value"
7249 },
7250 {
7251 "variable-offset ctx access",
7252 .insns = {
7253 /* Get an unknown value */
7254 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7255 /* Make it small and 4-byte aligned */
7256 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7257 /* add it to skb. We now have either &skb->len or
7258 * &skb->pkt_type, but we don't know which
7259 */
7260 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
7261 /* dereference it */
7262 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
7263 BPF_EXIT_INSN(),
7264 },
7265 .errstr = "variable ctx access var_off=(0x0; 0x4)",
7266 .result = REJECT,
7267 .prog_type = BPF_PROG_TYPE_LWT_IN,
7268 },
7269 {
7270 "variable-offset stack access",
7271 .insns = {
7272 /* Fill the top 8 bytes of the stack */
7273 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7274 /* Get an unknown value */
7275 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7276 /* Make it small and 4-byte aligned */
7277 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7278 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
7279 /* add it to fp. We now have either fp-4 or fp-8, but
7280 * we don't know which
7281 */
7282 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
7283 /* dereference it */
7284 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
7285 BPF_EXIT_INSN(),
7286 },
7287 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
7288 .result = REJECT,
7289 .prog_type = BPF_PROG_TYPE_LWT_IN,
7290 },
7291 {
7292 "indirect variable-offset stack access",
7293 .insns = {
7294 /* Fill the top 8 bytes of the stack */
7295 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7296 /* Get an unknown value */
7297 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7298 /* Make it small and 4-byte aligned */
7299 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7300 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
7301 /* add it to fp. We now have either fp-4 or fp-8, but
7302 * we don't know which
7303 */
7304 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
7305 /* dereference it indirectly */
7306 BPF_LD_MAP_FD(BPF_REG_1, 0),
7307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7308 BPF_FUNC_map_lookup_elem),
7309 BPF_MOV64_IMM(BPF_REG_0, 0),
7310 BPF_EXIT_INSN(),
7311 },
7312 .fixup_map1 = { 5 },
7313 .errstr = "variable stack read R2",
7314 .result = REJECT,
7315 .prog_type = BPF_PROG_TYPE_LWT_IN,
7316 },
7317 {
7318 "direct stack access with 32-bit wraparound. test1",
7319 .insns = {
7320 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7321 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7322 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7323 BPF_MOV32_IMM(BPF_REG_0, 0),
7324 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7325 BPF_EXIT_INSN()
7326 },
7327 .errstr = "fp pointer and 2147483647",
7328 .result = REJECT
7329 },
7330 {
7331 "direct stack access with 32-bit wraparound. test2",
7332 .insns = {
7333 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7334 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
7335 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
7336 BPF_MOV32_IMM(BPF_REG_0, 0),
7337 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7338 BPF_EXIT_INSN()
7339 },
7340 .errstr = "fp pointer and 1073741823",
7341 .result = REJECT
7342 },
7343 {
7344 "direct stack access with 32-bit wraparound. test3",
7345 .insns = {
7346 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7347 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
7348 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
7349 BPF_MOV32_IMM(BPF_REG_0, 0),
7350 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7351 BPF_EXIT_INSN()
7352 },
7353 .errstr = "fp pointer offset 1073741822",
7354 .result = REJECT
7355 },
7356 {
7357 "liveness pruning and write screening",
7358 .insns = {
7359 /* Get an unknown value */
7360 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7361 /* branch conditions teach us nothing about R2 */
7362 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
7363 BPF_MOV64_IMM(BPF_REG_0, 0),
7364 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
7365 BPF_MOV64_IMM(BPF_REG_0, 0),
7366 BPF_EXIT_INSN(),
7367 },
7368 .errstr = "R0 !read_ok",
7369 .result = REJECT,
7370 .prog_type = BPF_PROG_TYPE_LWT_IN,
7371 },
7372 {
7373 "varlen_map_value_access pruning",
7374 .insns = {
7375 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7376 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7378 BPF_LD_MAP_FD(BPF_REG_1, 0),
7379 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7380 BPF_FUNC_map_lookup_elem),
7381 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7382 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
7383 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
7384 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
7385 BPF_MOV32_IMM(BPF_REG_1, 0),
7386 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
7387 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7388 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
7389 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
7390 offsetof(struct test_val, foo)),
7391 BPF_EXIT_INSN(),
7392 },
7393 .fixup_map2 = { 3 },
7394 .errstr_unpriv = "R0 leaks addr",
7395 .errstr = "R0 unbounded memory access",
7396 .result_unpriv = REJECT,
7397 .result = REJECT,
7398 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7399 },
7400 {
7401 "invalid 64-bit BPF_END",
7402 .insns = {
7403 BPF_MOV32_IMM(BPF_REG_0, 0),
7404 {
7405 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
7406 .dst_reg = BPF_REG_0,
7407 .src_reg = 0,
7408 .off = 0,
7409 .imm = 32,
7410 },
7411 BPF_EXIT_INSN(),
7412 },
7413 .errstr = "BPF_END uses reserved fields",
7414 .result = REJECT,
7415 },
7416 {
7417 "meta access, test1",
7418 .insns = {
7419 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7420 offsetof(struct xdp_md, data_meta)),
7421 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7422 offsetof(struct xdp_md, data)),
7423 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7425 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7426 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7427 BPF_MOV64_IMM(BPF_REG_0, 0),
7428 BPF_EXIT_INSN(),
7429 },
7430 .result = ACCEPT,
7431 .prog_type = BPF_PROG_TYPE_XDP,
7432 },
7433 {
7434 "meta access, test2",
7435 .insns = {
7436 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7437 offsetof(struct xdp_md, data_meta)),
7438 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7439 offsetof(struct xdp_md, data)),
7440 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7441 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
7442 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7444 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7445 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7446 BPF_MOV64_IMM(BPF_REG_0, 0),
7447 BPF_EXIT_INSN(),
7448 },
7449 .result = REJECT,
7450 .errstr = "invalid access to packet, off=-8",
7451 .prog_type = BPF_PROG_TYPE_XDP,
7452 },
7453 {
7454 "meta access, test3",
7455 .insns = {
7456 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7457 offsetof(struct xdp_md, data_meta)),
7458 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7459 offsetof(struct xdp_md, data_end)),
7460 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7462 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7463 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7464 BPF_MOV64_IMM(BPF_REG_0, 0),
7465 BPF_EXIT_INSN(),
7466 },
7467 .result = REJECT,
7468 .errstr = "invalid access to packet",
7469 .prog_type = BPF_PROG_TYPE_XDP,
7470 },
7471 {
7472 "meta access, test4",
7473 .insns = {
7474 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7475 offsetof(struct xdp_md, data_meta)),
7476 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7477 offsetof(struct xdp_md, data_end)),
7478 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7479 offsetof(struct xdp_md, data)),
7480 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7481 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7482 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7483 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7484 BPF_MOV64_IMM(BPF_REG_0, 0),
7485 BPF_EXIT_INSN(),
7486 },
7487 .result = REJECT,
7488 .errstr = "invalid access to packet",
7489 .prog_type = BPF_PROG_TYPE_XDP,
7490 },
7491 {
7492 "meta access, test5",
7493 .insns = {
7494 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7495 offsetof(struct xdp_md, data_meta)),
7496 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7497 offsetof(struct xdp_md, data)),
7498 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7499 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7500 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
7501 BPF_MOV64_IMM(BPF_REG_2, -8),
7502 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7503 BPF_FUNC_xdp_adjust_meta),
7504 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
7505 BPF_MOV64_IMM(BPF_REG_0, 0),
7506 BPF_EXIT_INSN(),
7507 },
7508 .result = REJECT,
7509 .errstr = "R3 !read_ok",
7510 .prog_type = BPF_PROG_TYPE_XDP,
7511 },
7512 {
7513 "meta access, test6",
7514 .insns = {
7515 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7516 offsetof(struct xdp_md, data_meta)),
7517 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7518 offsetof(struct xdp_md, data)),
7519 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7520 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7521 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7523 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
7524 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7525 BPF_MOV64_IMM(BPF_REG_0, 0),
7526 BPF_EXIT_INSN(),
7527 },
7528 .result = REJECT,
7529 .errstr = "invalid access to packet",
7530 .prog_type = BPF_PROG_TYPE_XDP,
7531 },
7532 {
7533 "meta access, test7",
7534 .insns = {
7535 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7536 offsetof(struct xdp_md, data_meta)),
7537 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7538 offsetof(struct xdp_md, data)),
7539 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7540 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7541 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7542 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7543 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7544 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7545 BPF_MOV64_IMM(BPF_REG_0, 0),
7546 BPF_EXIT_INSN(),
7547 },
7548 .result = ACCEPT,
7549 .prog_type = BPF_PROG_TYPE_XDP,
7550 },
7551 {
7552 "meta access, test8",
7553 .insns = {
7554 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7555 offsetof(struct xdp_md, data_meta)),
7556 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7557 offsetof(struct xdp_md, data)),
7558 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
7560 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7561 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7562 BPF_MOV64_IMM(BPF_REG_0, 0),
7563 BPF_EXIT_INSN(),
7564 },
7565 .result = ACCEPT,
7566 .prog_type = BPF_PROG_TYPE_XDP,
7567 },
7568 {
7569 "meta access, test9",
7570 .insns = {
7571 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7572 offsetof(struct xdp_md, data_meta)),
7573 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7574 offsetof(struct xdp_md, data)),
7575 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7576 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
7577 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
7578 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7579 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7580 BPF_MOV64_IMM(BPF_REG_0, 0),
7581 BPF_EXIT_INSN(),
7582 },
7583 .result = REJECT,
7584 .errstr = "invalid access to packet",
7585 .prog_type = BPF_PROG_TYPE_XDP,
7586 },
7587 {
7588 "meta access, test10",
7589 .insns = {
7590 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7591 offsetof(struct xdp_md, data_meta)),
7592 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7593 offsetof(struct xdp_md, data)),
7594 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7595 offsetof(struct xdp_md, data_end)),
7596 BPF_MOV64_IMM(BPF_REG_5, 42),
7597 BPF_MOV64_IMM(BPF_REG_6, 24),
7598 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
7599 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
7600 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
7601 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
7602 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
7603 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
7604 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
7605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
7606 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
7607 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
7608 BPF_MOV64_IMM(BPF_REG_0, 0),
7609 BPF_EXIT_INSN(),
7610 },
7611 .result = REJECT,
7612 .errstr = "invalid access to packet",
7613 .prog_type = BPF_PROG_TYPE_XDP,
7614 },
7615 {
7616 "meta access, test11",
7617 .insns = {
7618 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7619 offsetof(struct xdp_md, data_meta)),
7620 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7621 offsetof(struct xdp_md, data)),
7622 BPF_MOV64_IMM(BPF_REG_5, 42),
7623 BPF_MOV64_IMM(BPF_REG_6, 24),
7624 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
7625 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
7626 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
7627 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
7628 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
7629 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
7630 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
7631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
7632 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
7633 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
7634 BPF_MOV64_IMM(BPF_REG_0, 0),
7635 BPF_EXIT_INSN(),
7636 },
7637 .result = ACCEPT,
7638 .prog_type = BPF_PROG_TYPE_XDP,
7639 },
7640 {
7641 "meta access, test12",
7642 .insns = {
7643 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7644 offsetof(struct xdp_md, data_meta)),
7645 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7646 offsetof(struct xdp_md, data)),
7647 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7648 offsetof(struct xdp_md, data_end)),
7649 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
7650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
7651 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
7652 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
7653 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
7654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
7655 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
7656 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7657 BPF_MOV64_IMM(BPF_REG_0, 0),
7658 BPF_EXIT_INSN(),
7659 },
7660 .result = ACCEPT,
7661 .prog_type = BPF_PROG_TYPE_XDP,
7662 },
7663 {
7664 "arithmetic ops make PTR_TO_CTX unusable",
7665 .insns = {
7666 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
7667 offsetof(struct __sk_buff, data) -
7668 offsetof(struct __sk_buff, mark)),
7669 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7670 offsetof(struct __sk_buff, mark)),
7671 BPF_EXIT_INSN(),
7672 },
7673 .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
7674 .result = REJECT,
7675 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7676 },
7677 {
7678 "pkt_end - pkt_start is allowed",
7679 .insns = {
7680 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7681 offsetof(struct __sk_buff, data_end)),
7682 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7683 offsetof(struct __sk_buff, data)),
7684 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
7685 BPF_EXIT_INSN(),
7686 },
7687 .result = ACCEPT,
7688 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7689 },
7690 {
7691 "XDP pkt read, pkt_end mangling, bad access 1",
7692 .insns = {
7693 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7694 offsetof(struct xdp_md, data)),
7695 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7696 offsetof(struct xdp_md, data_end)),
7697 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7698 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
7700 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7701 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7702 BPF_MOV64_IMM(BPF_REG_0, 0),
7703 BPF_EXIT_INSN(),
7704 },
7705 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
7706 .result = REJECT,
7707 .prog_type = BPF_PROG_TYPE_XDP,
7708 },
7709 {
7710 "XDP pkt read, pkt_end mangling, bad access 2",
7711 .insns = {
7712 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7713 offsetof(struct xdp_md, data)),
7714 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7715 offsetof(struct xdp_md, data_end)),
7716 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7718 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
7719 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7720 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7721 BPF_MOV64_IMM(BPF_REG_0, 0),
7722 BPF_EXIT_INSN(),
7723 },
7724 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
7725 .result = REJECT,
7726 .prog_type = BPF_PROG_TYPE_XDP,
7727 },
7728 {
7729 "XDP pkt read, pkt_data' > pkt_end, good access",
7730 .insns = {
7731 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7732 offsetof(struct xdp_md, data)),
7733 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7734 offsetof(struct xdp_md, data_end)),
7735 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7736 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7737 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7738 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7739 BPF_MOV64_IMM(BPF_REG_0, 0),
7740 BPF_EXIT_INSN(),
7741 },
7742 .result = ACCEPT,
7743 .prog_type = BPF_PROG_TYPE_XDP,
7744 },
7745 {
7746 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
7747 .insns = {
7748 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7749 offsetof(struct xdp_md, data)),
7750 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7751 offsetof(struct xdp_md, data_end)),
7752 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7753 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7754 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7755 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7756 BPF_MOV64_IMM(BPF_REG_0, 0),
7757 BPF_EXIT_INSN(),
7758 },
7759 .errstr = "R1 offset is outside of the packet",
7760 .result = REJECT,
7761 .prog_type = BPF_PROG_TYPE_XDP,
7762 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7763 },
7764 {
7765 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
7766 .insns = {
7767 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7768 offsetof(struct xdp_md, data)),
7769 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7770 offsetof(struct xdp_md, data_end)),
7771 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7773 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
7774 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7775 BPF_MOV64_IMM(BPF_REG_0, 0),
7776 BPF_EXIT_INSN(),
7777 },
7778 .errstr = "R1 offset is outside of the packet",
7779 .result = REJECT,
7780 .prog_type = BPF_PROG_TYPE_XDP,
7781 },
7782 {
7783 "XDP pkt read, pkt_end > pkt_data', good access",
7784 .insns = {
7785 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7786 offsetof(struct xdp_md, data)),
7787 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7788 offsetof(struct xdp_md, data_end)),
7789 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7791 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7792 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7793 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7794 BPF_MOV64_IMM(BPF_REG_0, 0),
7795 BPF_EXIT_INSN(),
7796 },
7797 .result = ACCEPT,
7798 .prog_type = BPF_PROG_TYPE_XDP,
7799 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7800 },
7801 {
7802 "XDP pkt read, pkt_end > pkt_data', bad access 1",
7803 .insns = {
7804 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7805 offsetof(struct xdp_md, data)),
7806 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7807 offsetof(struct xdp_md, data_end)),
7808 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7809 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7810 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7811 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7812 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7813 BPF_MOV64_IMM(BPF_REG_0, 0),
7814 BPF_EXIT_INSN(),
7815 },
7816 .errstr = "R1 offset is outside of the packet",
7817 .result = REJECT,
7818 .prog_type = BPF_PROG_TYPE_XDP,
7819 },
7820 {
7821 "XDP pkt read, pkt_end > pkt_data', bad access 2",
7822 .insns = {
7823 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7824 offsetof(struct xdp_md, data)),
7825 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7826 offsetof(struct xdp_md, data_end)),
7827 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7829 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7830 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7831 BPF_MOV64_IMM(BPF_REG_0, 0),
7832 BPF_EXIT_INSN(),
7833 },
7834 .errstr = "R1 offset is outside of the packet",
7835 .result = REJECT,
7836 .prog_type = BPF_PROG_TYPE_XDP,
7837 },
7838 {
7839 "XDP pkt read, pkt_data' < pkt_end, good access",
7840 .insns = {
7841 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7842 offsetof(struct xdp_md, data)),
7843 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7844 offsetof(struct xdp_md, data_end)),
7845 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7846 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7847 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7848 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7849 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7850 BPF_MOV64_IMM(BPF_REG_0, 0),
7851 BPF_EXIT_INSN(),
7852 },
7853 .result = ACCEPT,
7854 .prog_type = BPF_PROG_TYPE_XDP,
7855 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7856 },
7857 {
7858 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
7859 .insns = {
7860 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7861 offsetof(struct xdp_md, data)),
7862 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7863 offsetof(struct xdp_md, data_end)),
7864 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7865 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7866 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7867 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7868 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7869 BPF_MOV64_IMM(BPF_REG_0, 0),
7870 BPF_EXIT_INSN(),
7871 },
7872 .errstr = "R1 offset is outside of the packet",
7873 .result = REJECT,
7874 .prog_type = BPF_PROG_TYPE_XDP,
7875 },
7876 {
7877 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
7878 .insns = {
7879 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7880 offsetof(struct xdp_md, data)),
7881 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7882 offsetof(struct xdp_md, data_end)),
7883 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7885 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7886 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7887 BPF_MOV64_IMM(BPF_REG_0, 0),
7888 BPF_EXIT_INSN(),
7889 },
7890 .errstr = "R1 offset is outside of the packet",
7891 .result = REJECT,
7892 .prog_type = BPF_PROG_TYPE_XDP,
7893 },
7894 {
7895 "XDP pkt read, pkt_end < pkt_data', good access",
7896 .insns = {
7897 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7898 offsetof(struct xdp_md, data)),
7899 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7900 offsetof(struct xdp_md, data_end)),
7901 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7902 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7903 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
7904 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7905 BPF_MOV64_IMM(BPF_REG_0, 0),
7906 BPF_EXIT_INSN(),
7907 },
7908 .result = ACCEPT,
7909 .prog_type = BPF_PROG_TYPE_XDP,
7910 },
7911 {
7912 "XDP pkt read, pkt_end < pkt_data', bad access 1",
7913 .insns = {
7914 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7915 offsetof(struct xdp_md, data)),
7916 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7917 offsetof(struct xdp_md, data_end)),
7918 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7919 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7920 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
7921 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7922 BPF_MOV64_IMM(BPF_REG_0, 0),
7923 BPF_EXIT_INSN(),
7924 },
7925 .errstr = "R1 offset is outside of the packet",
7926 .result = REJECT,
7927 .prog_type = BPF_PROG_TYPE_XDP,
7928 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7929 },
7930 {
7931 "XDP pkt read, pkt_end < pkt_data', bad access 2",
7932 .insns = {
7933 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7934 offsetof(struct xdp_md, data)),
7935 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7936 offsetof(struct xdp_md, data_end)),
7937 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7938 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7939 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
7940 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7941 BPF_MOV64_IMM(BPF_REG_0, 0),
7942 BPF_EXIT_INSN(),
7943 },
7944 .errstr = "R1 offset is outside of the packet",
7945 .result = REJECT,
7946 .prog_type = BPF_PROG_TYPE_XDP,
7947 },
7948 {
7949 "XDP pkt read, pkt_data' >= pkt_end, good access",
7950 .insns = {
7951 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7952 offsetof(struct xdp_md, data)),
7953 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7954 offsetof(struct xdp_md, data_end)),
7955 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7956 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7957 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
7958 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7959 BPF_MOV64_IMM(BPF_REG_0, 0),
7960 BPF_EXIT_INSN(),
7961 },
7962 .result = ACCEPT,
7963 .prog_type = BPF_PROG_TYPE_XDP,
7964 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7965 },
7966 {
7967 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
7968 .insns = {
7969 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7970 offsetof(struct xdp_md, data)),
7971 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7972 offsetof(struct xdp_md, data_end)),
7973 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7974 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7975 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
7976 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7977 BPF_MOV64_IMM(BPF_REG_0, 0),
7978 BPF_EXIT_INSN(),
7979 },
7980 .errstr = "R1 offset is outside of the packet",
7981 .result = REJECT,
7982 .prog_type = BPF_PROG_TYPE_XDP,
7983 },
7984 {
7985 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
7986 .insns = {
7987 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7988 offsetof(struct xdp_md, data)),
7989 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7990 offsetof(struct xdp_md, data_end)),
7991 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7992 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7993 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
7994 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7995 BPF_MOV64_IMM(BPF_REG_0, 0),
7996 BPF_EXIT_INSN(),
7997 },
7998 .errstr = "R1 offset is outside of the packet",
7999 .result = REJECT,
8000 .prog_type = BPF_PROG_TYPE_XDP,
8001 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8002 },
8003 {
8004 "XDP pkt read, pkt_end >= pkt_data', good access",
8005 .insns = {
8006 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8007 offsetof(struct xdp_md, data)),
8008 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8009 offsetof(struct xdp_md, data_end)),
8010 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8012 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8013 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8014 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8015 BPF_MOV64_IMM(BPF_REG_0, 0),
8016 BPF_EXIT_INSN(),
8017 },
8018 .result = ACCEPT,
8019 .prog_type = BPF_PROG_TYPE_XDP,
8020 },
8021 {
8022 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
8023 .insns = {
8024 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8025 offsetof(struct xdp_md, data)),
8026 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8027 offsetof(struct xdp_md, data_end)),
8028 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8029 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8030 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8031 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8032 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8033 BPF_MOV64_IMM(BPF_REG_0, 0),
8034 BPF_EXIT_INSN(),
8035 },
8036 .errstr = "R1 offset is outside of the packet",
8037 .result = REJECT,
8038 .prog_type = BPF_PROG_TYPE_XDP,
8039 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8040 },
8041 {
8042 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
8043 .insns = {
8044 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8045 offsetof(struct xdp_md, data)),
8046 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8047 offsetof(struct xdp_md, data_end)),
8048 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8049 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8050 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8051 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8052 BPF_MOV64_IMM(BPF_REG_0, 0),
8053 BPF_EXIT_INSN(),
8054 },
8055 .errstr = "R1 offset is outside of the packet",
8056 .result = REJECT,
8057 .prog_type = BPF_PROG_TYPE_XDP,
8058 },
8059 {
8060 "XDP pkt read, pkt_data' <= pkt_end, good access",
8061 .insns = {
8062 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8063 offsetof(struct xdp_md, data)),
8064 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8065 offsetof(struct xdp_md, data_end)),
8066 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8067 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8068 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8069 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8070 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8071 BPF_MOV64_IMM(BPF_REG_0, 0),
8072 BPF_EXIT_INSN(),
8073 },
8074 .result = ACCEPT,
8075 .prog_type = BPF_PROG_TYPE_XDP,
8076 },
8077 {
8078 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
8079 .insns = {
8080 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8081 offsetof(struct xdp_md, data)),
8082 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8083 offsetof(struct xdp_md, data_end)),
8084 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8085 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8086 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8087 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8088 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8089 BPF_MOV64_IMM(BPF_REG_0, 0),
8090 BPF_EXIT_INSN(),
8091 },
8092 .errstr = "R1 offset is outside of the packet",
8093 .result = REJECT,
8094 .prog_type = BPF_PROG_TYPE_XDP,
8095 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8096 },
8097 {
8098 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
8099 .insns = {
8100 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8101 offsetof(struct xdp_md, data)),
8102 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8103 offsetof(struct xdp_md, data_end)),
8104 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8105 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8106 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8107 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8108 BPF_MOV64_IMM(BPF_REG_0, 0),
8109 BPF_EXIT_INSN(),
8110 },
8111 .errstr = "R1 offset is outside of the packet",
8112 .result = REJECT,
8113 .prog_type = BPF_PROG_TYPE_XDP,
8114 },
8115 {
8116 "XDP pkt read, pkt_end <= pkt_data', good access",
8117 .insns = {
8118 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8119 offsetof(struct xdp_md, data)),
8120 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8121 offsetof(struct xdp_md, data_end)),
8122 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8123 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8124 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8125 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8126 BPF_MOV64_IMM(BPF_REG_0, 0),
8127 BPF_EXIT_INSN(),
8128 },
8129 .result = ACCEPT,
8130 .prog_type = BPF_PROG_TYPE_XDP,
8131 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8132 },
8133 {
8134 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
8135 .insns = {
8136 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8137 offsetof(struct xdp_md, data)),
8138 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8139 offsetof(struct xdp_md, data_end)),
8140 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8141 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8142 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8143 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8144 BPF_MOV64_IMM(BPF_REG_0, 0),
8145 BPF_EXIT_INSN(),
8146 },
8147 .errstr = "R1 offset is outside of the packet",
8148 .result = REJECT,
8149 .prog_type = BPF_PROG_TYPE_XDP,
8150 },
8151 {
8152 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
8153 .insns = {
8154 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8155 offsetof(struct xdp_md, data)),
8156 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8157 offsetof(struct xdp_md, data_end)),
8158 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8159 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8160 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
8161 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8162 BPF_MOV64_IMM(BPF_REG_0, 0),
8163 BPF_EXIT_INSN(),
8164 },
8165 .errstr = "R1 offset is outside of the packet",
8166 .result = REJECT,
8167 .prog_type = BPF_PROG_TYPE_XDP,
8168 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8169 },
8170 {
8171 "XDP pkt read, pkt_meta' > pkt_data, good access",
8172 .insns = {
8173 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8174 offsetof(struct xdp_md, data_meta)),
8175 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8176 offsetof(struct xdp_md, data)),
8177 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8178 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8179 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8180 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8181 BPF_MOV64_IMM(BPF_REG_0, 0),
8182 BPF_EXIT_INSN(),
8183 },
8184 .result = ACCEPT,
8185 .prog_type = BPF_PROG_TYPE_XDP,
8186 },
8187 {
8188 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
8189 .insns = {
8190 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8191 offsetof(struct xdp_md, data_meta)),
8192 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8193 offsetof(struct xdp_md, data)),
8194 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8196 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8197 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8198 BPF_MOV64_IMM(BPF_REG_0, 0),
8199 BPF_EXIT_INSN(),
8200 },
8201 .errstr = "R1 offset is outside of the packet",
8202 .result = REJECT,
8203 .prog_type = BPF_PROG_TYPE_XDP,
8204 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8205 },
8206 {
8207 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
8208 .insns = {
8209 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8210 offsetof(struct xdp_md, data_meta)),
8211 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8212 offsetof(struct xdp_md, data)),
8213 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8215 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8216 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8217 BPF_MOV64_IMM(BPF_REG_0, 0),
8218 BPF_EXIT_INSN(),
8219 },
8220 .errstr = "R1 offset is outside of the packet",
8221 .result = REJECT,
8222 .prog_type = BPF_PROG_TYPE_XDP,
8223 },
8224 {
8225 "XDP pkt read, pkt_data > pkt_meta', good access",
8226 .insns = {
8227 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8228 offsetof(struct xdp_md, data_meta)),
8229 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8230 offsetof(struct xdp_md, data)),
8231 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8232 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8233 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8234 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8235 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8236 BPF_MOV64_IMM(BPF_REG_0, 0),
8237 BPF_EXIT_INSN(),
8238 },
8239 .result = ACCEPT,
8240 .prog_type = BPF_PROG_TYPE_XDP,
8241 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8242 },
8243 {
8244 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
8245 .insns = {
8246 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8247 offsetof(struct xdp_md, data_meta)),
8248 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8249 offsetof(struct xdp_md, data)),
8250 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8251 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8252 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8253 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8254 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8255 BPF_MOV64_IMM(BPF_REG_0, 0),
8256 BPF_EXIT_INSN(),
8257 },
8258 .errstr = "R1 offset is outside of the packet",
8259 .result = REJECT,
8260 .prog_type = BPF_PROG_TYPE_XDP,
8261 },
8262 {
8263 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
8264 .insns = {
8265 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8266 offsetof(struct xdp_md, data_meta)),
8267 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8268 offsetof(struct xdp_md, data)),
8269 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8271 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8272 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8273 BPF_MOV64_IMM(BPF_REG_0, 0),
8274 BPF_EXIT_INSN(),
8275 },
8276 .errstr = "R1 offset is outside of the packet",
8277 .result = REJECT,
8278 .prog_type = BPF_PROG_TYPE_XDP,
8279 },
8280 {
8281 "XDP pkt read, pkt_meta' < pkt_data, good access",
8282 .insns = {
8283 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8284 offsetof(struct xdp_md, data_meta)),
8285 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8286 offsetof(struct xdp_md, data)),
8287 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8288 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8289 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8290 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8291 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8292 BPF_MOV64_IMM(BPF_REG_0, 0),
8293 BPF_EXIT_INSN(),
8294 },
8295 .result = ACCEPT,
8296 .prog_type = BPF_PROG_TYPE_XDP,
8297 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8298 },
8299 {
8300 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
8301 .insns = {
8302 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8303 offsetof(struct xdp_md, data_meta)),
8304 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8305 offsetof(struct xdp_md, data)),
8306 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8308 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8309 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8310 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8311 BPF_MOV64_IMM(BPF_REG_0, 0),
8312 BPF_EXIT_INSN(),
8313 },
8314 .errstr = "R1 offset is outside of the packet",
8315 .result = REJECT,
8316 .prog_type = BPF_PROG_TYPE_XDP,
8317 },
8318 {
8319 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
8320 .insns = {
8321 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8322 offsetof(struct xdp_md, data_meta)),
8323 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8324 offsetof(struct xdp_md, data)),
8325 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8327 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8328 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8329 BPF_MOV64_IMM(BPF_REG_0, 0),
8330 BPF_EXIT_INSN(),
8331 },
8332 .errstr = "R1 offset is outside of the packet",
8333 .result = REJECT,
8334 .prog_type = BPF_PROG_TYPE_XDP,
8335 },
8336 {
8337 "XDP pkt read, pkt_data < pkt_meta', good access",
8338 .insns = {
8339 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8340 offsetof(struct xdp_md, data_meta)),
8341 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8342 offsetof(struct xdp_md, data)),
8343 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8344 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8345 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8346 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8347 BPF_MOV64_IMM(BPF_REG_0, 0),
8348 BPF_EXIT_INSN(),
8349 },
8350 .result = ACCEPT,
8351 .prog_type = BPF_PROG_TYPE_XDP,
8352 },
8353 {
8354 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
8355 .insns = {
8356 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8357 offsetof(struct xdp_md, data_meta)),
8358 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8359 offsetof(struct xdp_md, data)),
8360 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8362 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8363 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8364 BPF_MOV64_IMM(BPF_REG_0, 0),
8365 BPF_EXIT_INSN(),
8366 },
8367 .errstr = "R1 offset is outside of the packet",
8368 .result = REJECT,
8369 .prog_type = BPF_PROG_TYPE_XDP,
8370 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8371 },
8372 {
8373 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
8374 .insns = {
8375 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8376 offsetof(struct xdp_md, data_meta)),
8377 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8378 offsetof(struct xdp_md, data)),
8379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8380 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8381 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
8382 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8383 BPF_MOV64_IMM(BPF_REG_0, 0),
8384 BPF_EXIT_INSN(),
8385 },
8386 .errstr = "R1 offset is outside of the packet",
8387 .result = REJECT,
8388 .prog_type = BPF_PROG_TYPE_XDP,
8389 },
8390 {
8391 "XDP pkt read, pkt_meta' >= pkt_data, good access",
8392 .insns = {
8393 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8394 offsetof(struct xdp_md, data_meta)),
8395 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8396 offsetof(struct xdp_md, data)),
8397 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8398 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8399 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8400 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8401 BPF_MOV64_IMM(BPF_REG_0, 0),
8402 BPF_EXIT_INSN(),
8403 },
8404 .result = ACCEPT,
8405 .prog_type = BPF_PROG_TYPE_XDP,
8406 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8407 },
8408 {
8409 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
8410 .insns = {
8411 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8412 offsetof(struct xdp_md, data_meta)),
8413 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8414 offsetof(struct xdp_md, data)),
8415 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8416 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8417 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8418 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8419 BPF_MOV64_IMM(BPF_REG_0, 0),
8420 BPF_EXIT_INSN(),
8421 },
8422 .errstr = "R1 offset is outside of the packet",
8423 .result = REJECT,
8424 .prog_type = BPF_PROG_TYPE_XDP,
8425 },
8426 {
8427 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
8428 .insns = {
8429 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8430 offsetof(struct xdp_md, data_meta)),
8431 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8432 offsetof(struct xdp_md, data)),
8433 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8435 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8436 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8437 BPF_MOV64_IMM(BPF_REG_0, 0),
8438 BPF_EXIT_INSN(),
8439 },
8440 .errstr = "R1 offset is outside of the packet",
8441 .result = REJECT,
8442 .prog_type = BPF_PROG_TYPE_XDP,
8443 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8444 },
8445 {
8446 "XDP pkt read, pkt_data >= pkt_meta', good access",
8447 .insns = {
8448 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8449 offsetof(struct xdp_md, data_meta)),
8450 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8451 offsetof(struct xdp_md, data)),
8452 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8453 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8454 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8455 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8456 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8457 BPF_MOV64_IMM(BPF_REG_0, 0),
8458 BPF_EXIT_INSN(),
8459 },
8460 .result = ACCEPT,
8461 .prog_type = BPF_PROG_TYPE_XDP,
8462 },
8463 {
8464 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
8465 .insns = {
8466 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8467 offsetof(struct xdp_md, data_meta)),
8468 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8469 offsetof(struct xdp_md, data)),
8470 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8471 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8472 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8473 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8474 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8475 BPF_MOV64_IMM(BPF_REG_0, 0),
8476 BPF_EXIT_INSN(),
8477 },
8478 .errstr = "R1 offset is outside of the packet",
8479 .result = REJECT,
8480 .prog_type = BPF_PROG_TYPE_XDP,
8481 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8482 },
8483 {
8484 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
8485 .insns = {
8486 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8487 offsetof(struct xdp_md, data_meta)),
8488 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8489 offsetof(struct xdp_md, data)),
8490 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8492 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8493 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8494 BPF_MOV64_IMM(BPF_REG_0, 0),
8495 BPF_EXIT_INSN(),
8496 },
8497 .errstr = "R1 offset is outside of the packet",
8498 .result = REJECT,
8499 .prog_type = BPF_PROG_TYPE_XDP,
8500 },
8501 {
8502 "XDP pkt read, pkt_meta' <= pkt_data, good access",
8503 .insns = {
8504 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8505 offsetof(struct xdp_md, data_meta)),
8506 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8507 offsetof(struct xdp_md, data)),
8508 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8510 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8511 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8512 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8513 BPF_MOV64_IMM(BPF_REG_0, 0),
8514 BPF_EXIT_INSN(),
8515 },
8516 .result = ACCEPT,
8517 .prog_type = BPF_PROG_TYPE_XDP,
8518 },
8519 {
8520 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
8521 .insns = {
8522 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8523 offsetof(struct xdp_md, data_meta)),
8524 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8525 offsetof(struct xdp_md, data)),
8526 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8527 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8528 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8529 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8530 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8531 BPF_MOV64_IMM(BPF_REG_0, 0),
8532 BPF_EXIT_INSN(),
8533 },
8534 .errstr = "R1 offset is outside of the packet",
8535 .result = REJECT,
8536 .prog_type = BPF_PROG_TYPE_XDP,
8537 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8538 },
8539 {
8540 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
8541 .insns = {
8542 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8543 offsetof(struct xdp_md, data_meta)),
8544 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8545 offsetof(struct xdp_md, data)),
8546 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8547 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8548 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8549 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8550 BPF_MOV64_IMM(BPF_REG_0, 0),
8551 BPF_EXIT_INSN(),
8552 },
8553 .errstr = "R1 offset is outside of the packet",
8554 .result = REJECT,
8555 .prog_type = BPF_PROG_TYPE_XDP,
8556 },
8557 {
8558 "XDP pkt read, pkt_data <= pkt_meta', good access",
8559 .insns = {
8560 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8561 offsetof(struct xdp_md, data_meta)),
8562 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8563 offsetof(struct xdp_md, data)),
8564 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8566 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8567 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8568 BPF_MOV64_IMM(BPF_REG_0, 0),
8569 BPF_EXIT_INSN(),
8570 },
8571 .result = ACCEPT,
8572 .prog_type = BPF_PROG_TYPE_XDP,
8573 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8574 },
8575 {
8576 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
8577 .insns = {
8578 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8579 offsetof(struct xdp_md, data_meta)),
8580 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8581 offsetof(struct xdp_md, data)),
8582 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8584 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8585 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8586 BPF_MOV64_IMM(BPF_REG_0, 0),
8587 BPF_EXIT_INSN(),
8588 },
8589 .errstr = "R1 offset is outside of the packet",
8590 .result = REJECT,
8591 .prog_type = BPF_PROG_TYPE_XDP,
8592 },
8593 {
8594 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
8595 .insns = {
8596 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8597 offsetof(struct xdp_md, data_meta)),
8598 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8599 offsetof(struct xdp_md, data)),
8600 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8601 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8602 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
8603 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8604 BPF_MOV64_IMM(BPF_REG_0, 0),
8605 BPF_EXIT_INSN(),
8606 },
8607 .errstr = "R1 offset is outside of the packet",
8608 .result = REJECT,
8609 .prog_type = BPF_PROG_TYPE_XDP,
8610 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8611 },
8612 {
8613 "bpf_exit with invalid return code. test1",
8614 .insns = {
8615 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8616 BPF_EXIT_INSN(),
8617 },
8618 .errstr = "R0 has value (0x0; 0xffffffff)",
8619 .result = REJECT,
8620 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8621 },
8622 {
8623 "bpf_exit with invalid return code. test2",
8624 .insns = {
8625 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8626 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
8627 BPF_EXIT_INSN(),
8628 },
8629 .result = ACCEPT,
8630 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8631 },
8632 {
8633 "bpf_exit with invalid return code. test3",
8634 .insns = {
8635 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8636 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
8637 BPF_EXIT_INSN(),
8638 },
8639 .errstr = "R0 has value (0x0; 0x3)",
8640 .result = REJECT,
8641 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8642 },
8643 {
8644 "bpf_exit with invalid return code. test4",
8645 .insns = {
8646 BPF_MOV64_IMM(BPF_REG_0, 1),
8647 BPF_EXIT_INSN(),
8648 },
8649 .result = ACCEPT,
8650 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8651 },
8652 {
8653 "bpf_exit with invalid return code. test5",
8654 .insns = {
8655 BPF_MOV64_IMM(BPF_REG_0, 2),
8656 BPF_EXIT_INSN(),
8657 },
8658 .errstr = "R0 has value (0x2; 0x0)",
8659 .result = REJECT,
8660 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8661 },
8662 {
8663 "bpf_exit with invalid return code. test6",
8664 .insns = {
8665 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8666 BPF_EXIT_INSN(),
8667 },
8668 .errstr = "R0 is not a known value (ctx)",
8669 .result = REJECT,
8670 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8671 },
8672 {
8673 "bpf_exit with invalid return code. test7",
8674 .insns = {
8675 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8676 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
8677 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
8678 BPF_EXIT_INSN(),
8679 },
8680 .errstr = "R0 has unknown scalar value",
8681 .result = REJECT,
8682 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8683 },
8684 {
8685 "calls: basic sanity",
8686 .insns = {
8687 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8688 BPF_MOV64_IMM(BPF_REG_0, 1),
8689 BPF_EXIT_INSN(),
8690 BPF_MOV64_IMM(BPF_REG_0, 2),
8691 BPF_EXIT_INSN(),
8692 },
8693 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8694 .result = ACCEPT,
8695 },
8696 {
8697 "calls: not on unpriviledged",
8698 .insns = {
8699 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8700 BPF_MOV64_IMM(BPF_REG_0, 1),
8701 BPF_EXIT_INSN(),
8702 BPF_MOV64_IMM(BPF_REG_0, 2),
8703 BPF_EXIT_INSN(),
8704 },
8705 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
8706 .result_unpriv = REJECT,
8707 .result = ACCEPT,
8708 },
8709 {
8710 "calls: overlapping caller/callee",
8711 .insns = {
8712 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
8713 BPF_MOV64_IMM(BPF_REG_0, 1),
8714 BPF_EXIT_INSN(),
8715 },
8716 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8717 .errstr = "last insn is not an exit or jmp",
8718 .result = REJECT,
8719 },
8720 {
8721 "calls: wrong recursive calls",
8722 .insns = {
8723 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
8724 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
8725 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
8726 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
8727 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
8728 BPF_MOV64_IMM(BPF_REG_0, 1),
8729 BPF_EXIT_INSN(),
8730 },
8731 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8732 .errstr = "jump out of range",
8733 .result = REJECT,
8734 },
8735 {
8736 "calls: wrong src reg",
8737 .insns = {
8738 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
8739 BPF_MOV64_IMM(BPF_REG_0, 1),
8740 BPF_EXIT_INSN(),
8741 },
8742 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8743 .errstr = "BPF_CALL uses reserved fields",
8744 .result = REJECT,
8745 },
8746 {
8747 "calls: wrong off value",
8748 .insns = {
8749 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
8750 BPF_MOV64_IMM(BPF_REG_0, 1),
8751 BPF_EXIT_INSN(),
8752 BPF_MOV64_IMM(BPF_REG_0, 2),
8753 BPF_EXIT_INSN(),
8754 },
8755 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8756 .errstr = "BPF_CALL uses reserved fields",
8757 .result = REJECT,
8758 },
8759 {
8760 "calls: jump back loop",
8761 .insns = {
8762 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
8763 BPF_MOV64_IMM(BPF_REG_0, 1),
8764 BPF_EXIT_INSN(),
8765 },
8766 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8767 .errstr = "back-edge from insn 0 to 0",
8768 .result = REJECT,
8769 },
8770 {
8771 "calls: conditional call",
8772 .insns = {
8773 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8774 offsetof(struct __sk_buff, mark)),
8775 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
8776 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8777 BPF_MOV64_IMM(BPF_REG_0, 1),
8778 BPF_EXIT_INSN(),
8779 BPF_MOV64_IMM(BPF_REG_0, 2),
8780 BPF_EXIT_INSN(),
8781 },
8782 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8783 .errstr = "jump out of range",
8784 .result = REJECT,
8785 },
8786 {
8787 "calls: conditional call 2",
8788 .insns = {
8789 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8790 offsetof(struct __sk_buff, mark)),
8791 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
8792 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8793 BPF_MOV64_IMM(BPF_REG_0, 1),
8794 BPF_EXIT_INSN(),
8795 BPF_MOV64_IMM(BPF_REG_0, 2),
8796 BPF_EXIT_INSN(),
8797 BPF_MOV64_IMM(BPF_REG_0, 3),
8798 BPF_EXIT_INSN(),
8799 },
8800 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8801 .result = ACCEPT,
8802 },
8803 {
8804 "calls: conditional call 3",
8805 .insns = {
8806 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8807 offsetof(struct __sk_buff, mark)),
8808 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
8809 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
8810 BPF_MOV64_IMM(BPF_REG_0, 1),
8811 BPF_EXIT_INSN(),
8812 BPF_MOV64_IMM(BPF_REG_0, 1),
8813 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
8814 BPF_MOV64_IMM(BPF_REG_0, 3),
8815 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
8816 },
8817 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8818 .errstr = "back-edge from insn",
8819 .result = REJECT,
8820 },
8821 {
8822 "calls: conditional call 4",
8823 .insns = {
8824 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8825 offsetof(struct __sk_buff, mark)),
8826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
8827 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8828 BPF_MOV64_IMM(BPF_REG_0, 1),
8829 BPF_EXIT_INSN(),
8830 BPF_MOV64_IMM(BPF_REG_0, 1),
8831 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
8832 BPF_MOV64_IMM(BPF_REG_0, 3),
8833 BPF_EXIT_INSN(),
8834 },
8835 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8836 .result = ACCEPT,
8837 },
8838 {
8839 "calls: conditional call 5",
8840 .insns = {
8841 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8842 offsetof(struct __sk_buff, mark)),
8843 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
8844 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8845 BPF_MOV64_IMM(BPF_REG_0, 1),
8846 BPF_EXIT_INSN(),
8847 BPF_MOV64_IMM(BPF_REG_0, 1),
8848 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
8849 BPF_MOV64_IMM(BPF_REG_0, 3),
8850 BPF_EXIT_INSN(),
8851 },
8852 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8853 .errstr = "back-edge from insn",
8854 .result = REJECT,
8855 },
8856 {
8857 "calls: conditional call 6",
8858 .insns = {
8859 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8860 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
8861 BPF_EXIT_INSN(),
8862 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8863 offsetof(struct __sk_buff, mark)),
8864 BPF_EXIT_INSN(),
8865 },
8866 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8867 .errstr = "back-edge from insn",
8868 .result = REJECT,
8869 },
8870 {
8871 "calls: using r0 returned by callee",
8872 .insns = {
8873 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8874 BPF_EXIT_INSN(),
8875 BPF_MOV64_IMM(BPF_REG_0, 2),
8876 BPF_EXIT_INSN(),
8877 },
8878 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8879 .result = ACCEPT,
8880 },
8881 {
8882 "calls: using uninit r0 from callee",
8883 .insns = {
8884 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8885 BPF_EXIT_INSN(),
8886 BPF_EXIT_INSN(),
8887 },
8888 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8889 .errstr = "!read_ok",
8890 .result = REJECT,
8891 },
8892 {
8893 "calls: callee is using r1",
8894 .insns = {
8895 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8896 BPF_EXIT_INSN(),
8897 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8898 offsetof(struct __sk_buff, len)),
8899 BPF_EXIT_INSN(),
8900 },
8901 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
8902 .result = ACCEPT,
8903 },
8904 {
8905 "calls: callee using args1",
8906 .insns = {
8907 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8908 BPF_EXIT_INSN(),
8909 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8910 BPF_EXIT_INSN(),
8911 },
8912 .errstr_unpriv = "allowed for root only",
8913 .result_unpriv = REJECT,
8914 .result = ACCEPT,
8915 },
8916 {
8917 "calls: callee using wrong args2",
8918 .insns = {
8919 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8920 BPF_EXIT_INSN(),
8921 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8922 BPF_EXIT_INSN(),
8923 },
8924 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8925 .errstr = "R2 !read_ok",
8926 .result = REJECT,
8927 },
8928 {
8929 "calls: callee using two args",
8930 .insns = {
8931 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8932 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
8933 offsetof(struct __sk_buff, len)),
8934 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
8935 offsetof(struct __sk_buff, len)),
8936 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8937 BPF_EXIT_INSN(),
8938 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8939 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8940 BPF_EXIT_INSN(),
8941 },
8942 .errstr_unpriv = "allowed for root only",
8943 .result_unpriv = REJECT,
8944 .result = ACCEPT,
8945 },
8946 {
8947 "calls: callee changing pkt pointers",
8948 .insns = {
8949 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8950 offsetof(struct xdp_md, data)),
8951 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
8952 offsetof(struct xdp_md, data_end)),
8953 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
8954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
8955 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
8956 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8957 /* clear_all_pkt_pointers() has to walk all frames
8958 * to make sure that pkt pointers in the caller
8959 * are cleared when callee is calling a helper that
8960 * adjusts packet size
8961 */
8962 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
8963 BPF_MOV32_IMM(BPF_REG_0, 0),
8964 BPF_EXIT_INSN(),
8965 BPF_MOV64_IMM(BPF_REG_2, 0),
8966 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8967 BPF_FUNC_xdp_adjust_head),
8968 BPF_EXIT_INSN(),
8969 },
8970 .result = REJECT,
8971 .errstr = "R6 invalid mem access 'inv'",
8972 .prog_type = BPF_PROG_TYPE_XDP,
8973 },
8974 {
8975 "calls: two calls with args",
8976 .insns = {
8977 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8978 BPF_EXIT_INSN(),
8979 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8980 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
8981 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
8982 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8983 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8984 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
8985 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8986 BPF_EXIT_INSN(),
8987 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8988 offsetof(struct __sk_buff, len)),
8989 BPF_EXIT_INSN(),
8990 },
8991 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8992 .result = ACCEPT,
8993 },
8994 {
8995 "calls: calls with stack arith",
8996 .insns = {
8997 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
8999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9000 BPF_EXIT_INSN(),
9001 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
9002 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9003 BPF_EXIT_INSN(),
9004 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
9005 BPF_MOV64_IMM(BPF_REG_0, 42),
9006 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
9007 BPF_EXIT_INSN(),
9008 },
9009 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9010 .result = ACCEPT,
9011 },
9012 {
9013 "calls: calls with misaligned stack access",
9014 .insns = {
9015 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9016 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
9017 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9018 BPF_EXIT_INSN(),
9019 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
9020 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9021 BPF_EXIT_INSN(),
9022 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
9023 BPF_MOV64_IMM(BPF_REG_0, 42),
9024 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
9025 BPF_EXIT_INSN(),
9026 },
9027 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9028 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
9029 .errstr = "misaligned stack access",
9030 .result = REJECT,
9031 },
9032 {
9033 "calls: calls control flow, jump test",
9034 .insns = {
9035 BPF_MOV64_IMM(BPF_REG_0, 42),
9036 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9037 BPF_MOV64_IMM(BPF_REG_0, 43),
9038 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9039 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
9040 BPF_EXIT_INSN(),
9041 },
9042 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9043 .result = ACCEPT,
9044 },
9045 {
9046 "calls: calls control flow, jump test 2",
9047 .insns = {
9048 BPF_MOV64_IMM(BPF_REG_0, 42),
9049 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9050 BPF_MOV64_IMM(BPF_REG_0, 43),
9051 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9052 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
9053 BPF_EXIT_INSN(),
9054 },
9055 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9056 .errstr = "jump out of range from insn 1 to 4",
9057 .result = REJECT,
9058 },
9059 {
9060 "calls: two calls with bad jump",
9061 .insns = {
9062 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9063 BPF_EXIT_INSN(),
9064 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9065 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9066 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9067 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9068 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9069 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9070 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9071 BPF_EXIT_INSN(),
9072 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9073 offsetof(struct __sk_buff, len)),
9074 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
9075 BPF_EXIT_INSN(),
9076 },
9077 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9078 .errstr = "jump out of range from insn 11 to 9",
9079 .result = REJECT,
9080 },
9081 {
9082 "calls: recursive call. test1",
9083 .insns = {
9084 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9085 BPF_EXIT_INSN(),
9086 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
9087 BPF_EXIT_INSN(),
9088 },
9089 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9090 .errstr = "back-edge",
9091 .result = REJECT,
9092 },
9093 {
9094 "calls: recursive call. test2",
9095 .insns = {
9096 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9097 BPF_EXIT_INSN(),
9098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
9099 BPF_EXIT_INSN(),
9100 },
9101 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9102 .errstr = "back-edge",
9103 .result = REJECT,
9104 },
9105 {
9106 "calls: unreachable code",
9107 .insns = {
9108 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9109 BPF_EXIT_INSN(),
9110 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9111 BPF_EXIT_INSN(),
9112 BPF_MOV64_IMM(BPF_REG_0, 0),
9113 BPF_EXIT_INSN(),
9114 BPF_MOV64_IMM(BPF_REG_0, 0),
9115 BPF_EXIT_INSN(),
9116 },
9117 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9118 .errstr = "unreachable insn 6",
9119 .result = REJECT,
9120 },
9121 {
9122 "calls: invalid call",
9123 .insns = {
9124 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9125 BPF_EXIT_INSN(),
9126 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
9127 BPF_EXIT_INSN(),
9128 },
9129 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9130 .errstr = "invalid destination",
9131 .result = REJECT,
9132 },
9133 {
9134 "calls: invalid call 2",
9135 .insns = {
9136 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9137 BPF_EXIT_INSN(),
9138 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
9139 BPF_EXIT_INSN(),
9140 },
9141 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9142 .errstr = "invalid destination",
9143 .result = REJECT,
9144 },
9145 {
9146 "calls: jumping across function bodies. test1",
9147 .insns = {
9148 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9149 BPF_MOV64_IMM(BPF_REG_0, 0),
9150 BPF_EXIT_INSN(),
9151 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
9152 BPF_EXIT_INSN(),
9153 },
9154 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9155 .errstr = "jump out of range",
9156 .result = REJECT,
9157 },
9158 {
9159 "calls: jumping across function bodies. test2",
9160 .insns = {
9161 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
9162 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9163 BPF_MOV64_IMM(BPF_REG_0, 0),
9164 BPF_EXIT_INSN(),
9165 BPF_EXIT_INSN(),
9166 },
9167 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9168 .errstr = "jump out of range",
9169 .result = REJECT,
9170 },
9171 {
9172 "calls: call without exit",
9173 .insns = {
9174 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9175 BPF_EXIT_INSN(),
9176 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9177 BPF_EXIT_INSN(),
9178 BPF_MOV64_IMM(BPF_REG_0, 0),
9179 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
9180 },
9181 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9182 .errstr = "not an exit",
9183 .result = REJECT,
9184 },
9185 {
9186 "calls: call into middle of ld_imm64",
9187 .insns = {
9188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9190 BPF_MOV64_IMM(BPF_REG_0, 0),
9191 BPF_EXIT_INSN(),
9192 BPF_LD_IMM64(BPF_REG_0, 0),
9193 BPF_EXIT_INSN(),
9194 },
9195 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9196 .errstr = "last insn",
9197 .result = REJECT,
9198 },
9199 {
9200 "calls: call into middle of other call",
9201 .insns = {
9202 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9203 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9204 BPF_MOV64_IMM(BPF_REG_0, 0),
9205 BPF_EXIT_INSN(),
9206 BPF_MOV64_IMM(BPF_REG_0, 0),
9207 BPF_MOV64_IMM(BPF_REG_0, 0),
9208 BPF_EXIT_INSN(),
9209 },
9210 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9211 .errstr = "last insn",
9212 .result = REJECT,
9213 },
9214 {
9215 "calls: ld_abs with changing ctx data in callee",
9216 .insns = {
9217 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9218 BPF_LD_ABS(BPF_B, 0),
9219 BPF_LD_ABS(BPF_H, 0),
9220 BPF_LD_ABS(BPF_W, 0),
9221 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
9222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
9223 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
9224 BPF_LD_ABS(BPF_B, 0),
9225 BPF_LD_ABS(BPF_H, 0),
9226 BPF_LD_ABS(BPF_W, 0),
9227 BPF_EXIT_INSN(),
9228 BPF_MOV64_IMM(BPF_REG_2, 1),
9229 BPF_MOV64_IMM(BPF_REG_3, 2),
9230 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9231 BPF_FUNC_skb_vlan_push),
9232 BPF_EXIT_INSN(),
9233 },
9234 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9235 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
9236 .result = REJECT,
9237 },
9238 {
9239 "calls: two calls with bad fallthrough",
9240 .insns = {
9241 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9242 BPF_EXIT_INSN(),
9243 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9244 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9245 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9246 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9247 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9248 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9249 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9250 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
9251 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9252 offsetof(struct __sk_buff, len)),
9253 BPF_EXIT_INSN(),
9254 },
9255 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9256 .errstr = "not an exit",
9257 .result = REJECT,
9258 },
9259 {
9260 "calls: two calls with stack read",
9261 .insns = {
9262 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9263 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9264 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9265 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9266 BPF_EXIT_INSN(),
9267 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9268 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9269 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9270 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9271 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9272 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9273 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9274 BPF_EXIT_INSN(),
9275 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9276 BPF_EXIT_INSN(),
9277 },
9278 .prog_type = BPF_PROG_TYPE_XDP,
9279 .result = ACCEPT,
9280 },
9281 {
9282 "calls: two calls with stack write",
9283 .insns = {
9284 /* main prog */
9285 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9286 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9287 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9288 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9289 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9290 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9291 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
9292 BPF_EXIT_INSN(),
9293
9294 /* subprog 1 */
9295 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9296 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9297 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
9298 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
9299 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9300 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9301 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
9302 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
9303 /* write into stack frame of main prog */
9304 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9305 BPF_EXIT_INSN(),
9306
9307 /* subprog 2 */
9308 /* read from stack frame of main prog */
9309 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9310 BPF_EXIT_INSN(),
9311 },
9312 .prog_type = BPF_PROG_TYPE_XDP,
9313 .result = ACCEPT,
9314 },
9315 {
9316 "calls: stack overflow using two frames (pre-call access)",
9317 .insns = {
9318 /* prog 1 */
9319 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9320 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
9321 BPF_EXIT_INSN(),
9322
9323 /* prog 2 */
9324 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9325 BPF_MOV64_IMM(BPF_REG_0, 0),
9326 BPF_EXIT_INSN(),
9327 },
9328 .prog_type = BPF_PROG_TYPE_XDP,
9329 .errstr = "combined stack size",
9330 .result = REJECT,
9331 },
9332 {
9333 "calls: stack overflow using two frames (post-call access)",
9334 .insns = {
9335 /* prog 1 */
9336 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
9337 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9338 BPF_EXIT_INSN(),
9339
9340 /* prog 2 */
9341 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9342 BPF_MOV64_IMM(BPF_REG_0, 0),
9343 BPF_EXIT_INSN(),
9344 },
9345 .prog_type = BPF_PROG_TYPE_XDP,
9346 .errstr = "combined stack size",
9347 .result = REJECT,
9348 },
9349 {
9350 "calls: stack depth check using three frames. test1",
9351 .insns = {
9352 /* main */
9353 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
9354 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
9355 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
9356 BPF_MOV64_IMM(BPF_REG_0, 0),
9357 BPF_EXIT_INSN(),
9358 /* A */
9359 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
9360 BPF_EXIT_INSN(),
9361 /* B */
9362 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
9363 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9364 BPF_EXIT_INSN(),
9365 },
9366 .prog_type = BPF_PROG_TYPE_XDP,
9367 /* stack_main=32, stack_A=256, stack_B=64
9368 * and max(main+A, main+A+B) < 512
9369 */
9370 .result = ACCEPT,
9371 },
9372 {
9373 "calls: stack depth check using three frames. test2",
9374 .insns = {
9375 /* main */
9376 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
9377 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
9378 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
9379 BPF_MOV64_IMM(BPF_REG_0, 0),
9380 BPF_EXIT_INSN(),
9381 /* A */
9382 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9383 BPF_EXIT_INSN(),
9384 /* B */
9385 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
9386 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
9387 BPF_EXIT_INSN(),
9388 },
9389 .prog_type = BPF_PROG_TYPE_XDP,
9390 /* stack_main=32, stack_A=64, stack_B=256
9391 * and max(main+A, main+A+B) < 512
9392 */
9393 .result = ACCEPT,
9394 },
9395 {
9396 "calls: stack depth check using three frames. test3",
9397 .insns = {
9398 /* main */
9399 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9400 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
9401 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9402 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
9403 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
9404 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9405 BPF_MOV64_IMM(BPF_REG_0, 0),
9406 BPF_EXIT_INSN(),
9407 /* A */
9408 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
9409 BPF_EXIT_INSN(),
9410 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
9411 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
9412 /* B */
9413 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
9414 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
9415 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
9416 BPF_EXIT_INSN(),
9417 },
9418 .prog_type = BPF_PROG_TYPE_XDP,
9419 /* stack_main=64, stack_A=224, stack_B=256
9420 * and max(main+A, main+A+B) > 512
9421 */
9422 .errstr = "combined stack",
9423 .result = REJECT,
9424 },
9425 {
9426 "calls: stack depth check using three frames. test4",
9427 /* void main(void) {
9428 * func1(0);
9429 * func1(1);
9430 * func2(1);
9431 * }
9432 * void func1(int alloc_or_recurse) {
9433 * if (alloc_or_recurse) {
9434 * frame_pointer[-300] = 1;
9435 * } else {
9436 * func2(alloc_or_recurse);
9437 * }
9438 * }
9439 * void func2(int alloc_or_recurse) {
9440 * if (alloc_or_recurse) {
9441 * frame_pointer[-300] = 1;
9442 * }
9443 * }
9444 */
9445 .insns = {
9446 /* main */
9447 BPF_MOV64_IMM(BPF_REG_1, 0),
9448 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
9449 BPF_MOV64_IMM(BPF_REG_1, 1),
9450 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
9451 BPF_MOV64_IMM(BPF_REG_1, 1),
9452 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
9453 BPF_MOV64_IMM(BPF_REG_0, 0),
9454 BPF_EXIT_INSN(),
9455 /* A */
9456 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
9457 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9458 BPF_EXIT_INSN(),
9459 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
9460 BPF_EXIT_INSN(),
9461 /* B */
9462 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
9463 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9464 BPF_EXIT_INSN(),
9465 },
9466 .prog_type = BPF_PROG_TYPE_XDP,
9467 .result = REJECT,
9468 .errstr = "combined stack",
9469 },
9470 {
9471 "calls: stack depth check using three frames. test5",
9472 .insns = {
9473 /* main */
9474 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
9475 BPF_EXIT_INSN(),
9476 /* A */
9477 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
9478 BPF_EXIT_INSN(),
9479 /* B */
9480 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
9481 BPF_EXIT_INSN(),
9482 /* C */
9483 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
9484 BPF_EXIT_INSN(),
9485 /* D */
9486 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
9487 BPF_EXIT_INSN(),
9488 /* E */
9489 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
9490 BPF_EXIT_INSN(),
9491 /* F */
9492 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
9493 BPF_EXIT_INSN(),
9494 /* G */
9495 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
9496 BPF_EXIT_INSN(),
9497 /* H */
9498 BPF_MOV64_IMM(BPF_REG_0, 0),
9499 BPF_EXIT_INSN(),
9500 },
9501 .prog_type = BPF_PROG_TYPE_XDP,
9502 .errstr = "call stack",
9503 .result = REJECT,
9504 },
9505 {
9506 "calls: spill into caller stack frame",
9507 .insns = {
9508 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9509 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9511 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9512 BPF_EXIT_INSN(),
9513 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
9514 BPF_MOV64_IMM(BPF_REG_0, 0),
9515 BPF_EXIT_INSN(),
9516 },
9517 .prog_type = BPF_PROG_TYPE_XDP,
9518 .errstr = "cannot spill",
9519 .result = REJECT,
9520 },
9521 {
9522 "calls: write into caller stack frame",
9523 .insns = {
9524 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9525 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9526 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9527 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9528 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
9529 BPF_EXIT_INSN(),
9530 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
9531 BPF_MOV64_IMM(BPF_REG_0, 0),
9532 BPF_EXIT_INSN(),
9533 },
9534 .prog_type = BPF_PROG_TYPE_XDP,
9535 .result = ACCEPT,
9536 },
9537 {
9538 "calls: write into callee stack frame",
9539 .insns = {
9540 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9541 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
9542 BPF_EXIT_INSN(),
9543 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
9544 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
9545 BPF_EXIT_INSN(),
9546 },
9547 .prog_type = BPF_PROG_TYPE_XDP,
9548 .errstr = "cannot return stack pointer",
9549 .result = REJECT,
9550 },
9551 {
9552 "calls: two calls with stack write and void return",
9553 .insns = {
9554 /* main prog */
9555 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9556 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9557 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9558 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9560 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9561 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
9562 BPF_EXIT_INSN(),
9563
9564 /* subprog 1 */
9565 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9566 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9567 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9568 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9569 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9570 BPF_EXIT_INSN(),
9571
9572 /* subprog 2 */
9573 /* write into stack frame of main prog */
9574 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
9575 BPF_EXIT_INSN(), /* void return */
9576 },
9577 .prog_type = BPF_PROG_TYPE_XDP,
9578 .result = ACCEPT,
9579 },
9580 {
9581 "calls: ambiguous return value",
9582 .insns = {
9583 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9584 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
9585 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
9586 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9587 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9588 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
9589 BPF_EXIT_INSN(),
9590 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
9591 BPF_MOV64_IMM(BPF_REG_0, 0),
9592 BPF_EXIT_INSN(),
9593 },
9594 .errstr_unpriv = "allowed for root only",
9595 .result_unpriv = REJECT,
9596 .errstr = "R0 !read_ok",
9597 .result = REJECT,
9598 },
9599 {
9600 "calls: two calls that return map_value",
9601 .insns = {
9602 /* main prog */
9603 /* pass fp-16, fp-8 into a function */
9604 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9606 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9608 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9609
9610 /* fetch map_value_ptr from the stack of this function */
9611 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
9612 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
9613 /* write into map value */
9614 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9615 /* fetch secound map_value_ptr from the stack */
9616 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
9617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
9618 /* write into map value */
9619 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9620 BPF_MOV64_IMM(BPF_REG_0, 0),
9621 BPF_EXIT_INSN(),
9622
9623 /* subprog 1 */
9624 /* call 3rd function twice */
9625 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9626 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9627 /* first time with fp-8 */
9628 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9629 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9630 /* second time with fp-16 */
9631 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9632 BPF_EXIT_INSN(),
9633
9634 /* subprog 2 */
9635 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9636 /* lookup from map */
9637 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9638 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9639 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9640 BPF_LD_MAP_FD(BPF_REG_1, 0),
9641 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9642 BPF_FUNC_map_lookup_elem),
9643 /* write map_value_ptr into stack frame of main prog */
9644 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9645 BPF_MOV64_IMM(BPF_REG_0, 0),
9646 BPF_EXIT_INSN(), /* return 0 */
9647 },
9648 .prog_type = BPF_PROG_TYPE_XDP,
9649 .fixup_map1 = { 23 },
9650 .result = ACCEPT,
9651 },
9652 {
9653 "calls: two calls that return map_value with bool condition",
9654 .insns = {
9655 /* main prog */
9656 /* pass fp-16, fp-8 into a function */
9657 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9659 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9660 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9661 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9662 BPF_MOV64_IMM(BPF_REG_0, 0),
9663 BPF_EXIT_INSN(),
9664
9665 /* subprog 1 */
9666 /* call 3rd function twice */
9667 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9668 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9669 /* first time with fp-8 */
9670 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
9671 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
9672 /* fetch map_value_ptr from the stack of this function */
9673 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
9674 /* write into map value */
9675 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9676 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9677 /* second time with fp-16 */
9678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9679 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
9680 /* fetch secound map_value_ptr from the stack */
9681 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
9682 /* write into map value */
9683 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9684 BPF_EXIT_INSN(),
9685
9686 /* subprog 2 */
9687 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9688 /* lookup from map */
9689 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9690 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9691 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9692 BPF_LD_MAP_FD(BPF_REG_1, 0),
9693 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9694 BPF_FUNC_map_lookup_elem),
9695 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9696 BPF_MOV64_IMM(BPF_REG_0, 0),
9697 BPF_EXIT_INSN(), /* return 0 */
9698 /* write map_value_ptr into stack frame of main prog */
9699 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9700 BPF_MOV64_IMM(BPF_REG_0, 1),
9701 BPF_EXIT_INSN(), /* return 1 */
9702 },
9703 .prog_type = BPF_PROG_TYPE_XDP,
9704 .fixup_map1 = { 23 },
9705 .result = ACCEPT,
9706 },
9707 {
9708 "calls: two calls that return map_value with incorrect bool check",
9709 .insns = {
9710 /* main prog */
9711 /* pass fp-16, fp-8 into a function */
9712 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9716 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9717 BPF_MOV64_IMM(BPF_REG_0, 0),
9718 BPF_EXIT_INSN(),
9719
9720 /* subprog 1 */
9721 /* call 3rd function twice */
9722 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9723 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9724 /* first time with fp-8 */
9725 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
9726 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
9727 /* fetch map_value_ptr from the stack of this function */
9728 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
9729 /* write into map value */
9730 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9731 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9732 /* second time with fp-16 */
9733 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9734 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9735 /* fetch secound map_value_ptr from the stack */
9736 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
9737 /* write into map value */
9738 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9739 BPF_EXIT_INSN(),
9740
9741 /* subprog 2 */
9742 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9743 /* lookup from map */
9744 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9745 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9747 BPF_LD_MAP_FD(BPF_REG_1, 0),
9748 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9749 BPF_FUNC_map_lookup_elem),
9750 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9751 BPF_MOV64_IMM(BPF_REG_0, 0),
9752 BPF_EXIT_INSN(), /* return 0 */
9753 /* write map_value_ptr into stack frame of main prog */
9754 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9755 BPF_MOV64_IMM(BPF_REG_0, 1),
9756 BPF_EXIT_INSN(), /* return 1 */
9757 },
9758 .prog_type = BPF_PROG_TYPE_XDP,
9759 .fixup_map1 = { 23 },
9760 .result = REJECT,
9761 .errstr = "invalid read from stack off -16+0 size 8",
9762 },
9763 {
9764 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
9765 .insns = {
9766 /* main prog */
9767 /* pass fp-16, fp-8 into a function */
9768 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9770 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9771 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9772 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9773 BPF_MOV64_IMM(BPF_REG_0, 0),
9774 BPF_EXIT_INSN(),
9775
9776 /* subprog 1 */
9777 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9778 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9779 /* 1st lookup from map */
9780 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9781 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9782 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9783 BPF_LD_MAP_FD(BPF_REG_1, 0),
9784 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9785 BPF_FUNC_map_lookup_elem),
9786 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9787 BPF_MOV64_IMM(BPF_REG_8, 0),
9788 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9789 /* write map_value_ptr into stack frame of main prog at fp-8 */
9790 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9791 BPF_MOV64_IMM(BPF_REG_8, 1),
9792
9793 /* 2nd lookup from map */
9794 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
9795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9796 BPF_LD_MAP_FD(BPF_REG_1, 0),
9797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
9798 BPF_FUNC_map_lookup_elem),
9799 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9800 BPF_MOV64_IMM(BPF_REG_9, 0),
9801 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9802 /* write map_value_ptr into stack frame of main prog at fp-16 */
9803 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9804 BPF_MOV64_IMM(BPF_REG_9, 1),
9805
9806 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
9807 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
9808 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
9809 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
9810 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
9811 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
9812 BPF_EXIT_INSN(),
9813
9814 /* subprog 2 */
9815 /* if arg2 == 1 do *arg1 = 0 */
9816 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
9817 /* fetch map_value_ptr from the stack of this function */
9818 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
9819 /* write into map value */
9820 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9821
9822 /* if arg4 == 1 do *arg3 = 0 */
9823 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
9824 /* fetch map_value_ptr from the stack of this function */
9825 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
9826 /* write into map value */
9827 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
9828 BPF_EXIT_INSN(),
9829 },
9830 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9831 .fixup_map1 = { 12, 22 },
9832 .result = REJECT,
9833 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
9834 },
9835 {
9836 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
9837 .insns = {
9838 /* main prog */
9839 /* pass fp-16, fp-8 into a function */
9840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9842 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9843 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9844 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9845 BPF_MOV64_IMM(BPF_REG_0, 0),
9846 BPF_EXIT_INSN(),
9847
9848 /* subprog 1 */
9849 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9850 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9851 /* 1st lookup from map */
9852 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9853 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9854 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9855 BPF_LD_MAP_FD(BPF_REG_1, 0),
9856 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9857 BPF_FUNC_map_lookup_elem),
9858 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9859 BPF_MOV64_IMM(BPF_REG_8, 0),
9860 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9861 /* write map_value_ptr into stack frame of main prog at fp-8 */
9862 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9863 BPF_MOV64_IMM(BPF_REG_8, 1),
9864
9865 /* 2nd lookup from map */
9866 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
9867 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9868 BPF_LD_MAP_FD(BPF_REG_1, 0),
9869 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
9870 BPF_FUNC_map_lookup_elem),
9871 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9872 BPF_MOV64_IMM(BPF_REG_9, 0),
9873 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9874 /* write map_value_ptr into stack frame of main prog at fp-16 */
9875 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9876 BPF_MOV64_IMM(BPF_REG_9, 1),
9877
9878 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
9879 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
9880 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
9881 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
9882 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
9883 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
9884 BPF_EXIT_INSN(),
9885
9886 /* subprog 2 */
9887 /* if arg2 == 1 do *arg1 = 0 */
9888 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
9889 /* fetch map_value_ptr from the stack of this function */
9890 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
9891 /* write into map value */
9892 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9893
9894 /* if arg4 == 1 do *arg3 = 0 */
9895 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
9896 /* fetch map_value_ptr from the stack of this function */
9897 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
9898 /* write into map value */
9899 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9900 BPF_EXIT_INSN(),
9901 },
9902 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9903 .fixup_map1 = { 12, 22 },
9904 .result = ACCEPT,
9905 },
9906 {
9907 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
9908 .insns = {
9909 /* main prog */
9910 /* pass fp-16, fp-8 into a function */
9911 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9912 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9913 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9914 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9915 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
9916 BPF_MOV64_IMM(BPF_REG_0, 0),
9917 BPF_EXIT_INSN(),
9918
9919 /* subprog 1 */
9920 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9921 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9922 /* 1st lookup from map */
9923 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
9924 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9925 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
9926 BPF_LD_MAP_FD(BPF_REG_1, 0),
9927 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9928 BPF_FUNC_map_lookup_elem),
9929 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9930 BPF_MOV64_IMM(BPF_REG_8, 0),
9931 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9932 /* write map_value_ptr into stack frame of main prog at fp-8 */
9933 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
9934 BPF_MOV64_IMM(BPF_REG_8, 1),
9935
9936 /* 2nd lookup from map */
9937 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9938 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
9939 BPF_LD_MAP_FD(BPF_REG_1, 0),
9940 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9941 BPF_FUNC_map_lookup_elem),
9942 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9943 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
9944 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9945 /* write map_value_ptr into stack frame of main prog at fp-16 */
9946 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9947 BPF_MOV64_IMM(BPF_REG_9, 1),
9948
9949 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
9950 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
9951 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
9952 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
9953 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
9954 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
9955 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
9956
9957 /* subprog 2 */
9958 /* if arg2 == 1 do *arg1 = 0 */
9959 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
9960 /* fetch map_value_ptr from the stack of this function */
9961 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
9962 /* write into map value */
9963 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9964
9965 /* if arg4 == 1 do *arg3 = 0 */
9966 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
9967 /* fetch map_value_ptr from the stack of this function */
9968 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
9969 /* write into map value */
9970 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
9971 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
9972 },
9973 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9974 .fixup_map1 = { 12, 22 },
9975 .result = REJECT,
9976 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
9977 },
9978 {
9979 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
9980 .insns = {
9981 /* main prog */
9982 /* pass fp-16, fp-8 into a function */
9983 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9984 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9985 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9986 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9987 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9988 BPF_MOV64_IMM(BPF_REG_0, 0),
9989 BPF_EXIT_INSN(),
9990
9991 /* subprog 1 */
9992 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9993 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9994 /* 1st lookup from map */
9995 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9996 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9998 BPF_LD_MAP_FD(BPF_REG_1, 0),
9999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10000 BPF_FUNC_map_lookup_elem),
10001 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
10002 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10003 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10004 BPF_MOV64_IMM(BPF_REG_8, 0),
10005 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10006 BPF_MOV64_IMM(BPF_REG_8, 1),
10007
10008 /* 2nd lookup from map */
10009 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10010 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10011 BPF_LD_MAP_FD(BPF_REG_1, 0),
10012 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10013 BPF_FUNC_map_lookup_elem),
10014 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
10015 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10016 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10017 BPF_MOV64_IMM(BPF_REG_9, 0),
10018 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10019 BPF_MOV64_IMM(BPF_REG_9, 1),
10020
10021 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10022 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10023 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10024 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10025 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10026 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10027 BPF_EXIT_INSN(),
10028
10029 /* subprog 2 */
10030 /* if arg2 == 1 do *arg1 = 0 */
10031 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10032 /* fetch map_value_ptr from the stack of this function */
10033 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10034 /* write into map value */
10035 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10036
10037 /* if arg4 == 1 do *arg3 = 0 */
10038 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10039 /* fetch map_value_ptr from the stack of this function */
10040 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10041 /* write into map value */
10042 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10043 BPF_EXIT_INSN(),
10044 },
10045 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10046 .fixup_map1 = { 12, 22 },
10047 .result = ACCEPT,
10048 },
10049 {
10050 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
10051 .insns = {
10052 /* main prog */
10053 /* pass fp-16, fp-8 into a function */
10054 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10056 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10058 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10059 BPF_MOV64_IMM(BPF_REG_0, 0),
10060 BPF_EXIT_INSN(),
10061
10062 /* subprog 1 */
10063 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10064 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10065 /* 1st lookup from map */
10066 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10067 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10068 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10069 BPF_LD_MAP_FD(BPF_REG_1, 0),
10070 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10071 BPF_FUNC_map_lookup_elem),
10072 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
10073 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10074 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10075 BPF_MOV64_IMM(BPF_REG_8, 0),
10076 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10077 BPF_MOV64_IMM(BPF_REG_8, 1),
10078
10079 /* 2nd lookup from map */
10080 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10082 BPF_LD_MAP_FD(BPF_REG_1, 0),
10083 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10084 BPF_FUNC_map_lookup_elem),
10085 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
10086 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10087 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10088 BPF_MOV64_IMM(BPF_REG_9, 0),
10089 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10090 BPF_MOV64_IMM(BPF_REG_9, 1),
10091
10092 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10093 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10094 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10095 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10096 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10097 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10098 BPF_EXIT_INSN(),
10099
10100 /* subprog 2 */
10101 /* if arg2 == 1 do *arg1 = 0 */
10102 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10103 /* fetch map_value_ptr from the stack of this function */
10104 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10105 /* write into map value */
10106 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10107
10108 /* if arg4 == 0 do *arg3 = 0 */
10109 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
10110 /* fetch map_value_ptr from the stack of this function */
10111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10112 /* write into map value */
10113 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10114 BPF_EXIT_INSN(),
10115 },
10116 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10117 .fixup_map1 = { 12, 22 },
10118 .result = REJECT,
10119 .errstr = "R0 invalid mem access 'inv'",
10120 },
10121 {
10122 "calls: pkt_ptr spill into caller stack",
10123 .insns = {
10124 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10125 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10126 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10127 BPF_EXIT_INSN(),
10128
10129 /* subprog 1 */
10130 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10131 offsetof(struct __sk_buff, data)),
10132 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10133 offsetof(struct __sk_buff, data_end)),
10134 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10136 /* spill unchecked pkt_ptr into stack of caller */
10137 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10138 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10139 /* now the pkt range is verified, read pkt_ptr from stack */
10140 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10141 /* write 4 bytes into packet */
10142 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10143 BPF_EXIT_INSN(),
10144 },
10145 .result = ACCEPT,
10146 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10147 },
10148 {
10149 "calls: pkt_ptr spill into caller stack 2",
10150 .insns = {
10151 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10153 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10154 /* Marking is still kept, but not in all cases safe. */
10155 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10156 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10157 BPF_EXIT_INSN(),
10158
10159 /* subprog 1 */
10160 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10161 offsetof(struct __sk_buff, data)),
10162 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10163 offsetof(struct __sk_buff, data_end)),
10164 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10165 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10166 /* spill unchecked pkt_ptr into stack of caller */
10167 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10168 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10169 /* now the pkt range is verified, read pkt_ptr from stack */
10170 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10171 /* write 4 bytes into packet */
10172 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10173 BPF_EXIT_INSN(),
10174 },
10175 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10176 .errstr = "invalid access to packet",
10177 .result = REJECT,
10178 },
10179 {
10180 "calls: pkt_ptr spill into caller stack 3",
10181 .insns = {
10182 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10184 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10185 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
10186 /* Marking is still kept and safe here. */
10187 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10188 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10189 BPF_EXIT_INSN(),
10190
10191 /* subprog 1 */
10192 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10193 offsetof(struct __sk_buff, data)),
10194 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10195 offsetof(struct __sk_buff, data_end)),
10196 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10198 /* spill unchecked pkt_ptr into stack of caller */
10199 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10200 BPF_MOV64_IMM(BPF_REG_5, 0),
10201 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10202 BPF_MOV64_IMM(BPF_REG_5, 1),
10203 /* now the pkt range is verified, read pkt_ptr from stack */
10204 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10205 /* write 4 bytes into packet */
10206 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10207 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10208 BPF_EXIT_INSN(),
10209 },
10210 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10211 .result = ACCEPT,
10212 },
10213 {
10214 "calls: pkt_ptr spill into caller stack 4",
10215 .insns = {
10216 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10218 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10219 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
10220 /* Check marking propagated. */
10221 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10222 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10223 BPF_EXIT_INSN(),
10224
10225 /* subprog 1 */
10226 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10227 offsetof(struct __sk_buff, data)),
10228 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10229 offsetof(struct __sk_buff, data_end)),
10230 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10231 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10232 /* spill unchecked pkt_ptr into stack of caller */
10233 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10234 BPF_MOV64_IMM(BPF_REG_5, 0),
10235 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10236 BPF_MOV64_IMM(BPF_REG_5, 1),
10237 /* don't read back pkt_ptr from stack here */
10238 /* write 4 bytes into packet */
10239 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10240 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10241 BPF_EXIT_INSN(),
10242 },
10243 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10244 .result = ACCEPT,
10245 },
10246 {
10247 "calls: pkt_ptr spill into caller stack 5",
10248 .insns = {
10249 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10250 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10251 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
10252 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10253 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10254 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10255 BPF_EXIT_INSN(),
10256
10257 /* subprog 1 */
10258 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10259 offsetof(struct __sk_buff, data)),
10260 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10261 offsetof(struct __sk_buff, data_end)),
10262 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10264 BPF_MOV64_IMM(BPF_REG_5, 0),
10265 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10266 /* spill checked pkt_ptr into stack of caller */
10267 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10268 BPF_MOV64_IMM(BPF_REG_5, 1),
10269 /* don't read back pkt_ptr from stack here */
10270 /* write 4 bytes into packet */
10271 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10272 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10273 BPF_EXIT_INSN(),
10274 },
10275 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10276 .errstr = "same insn cannot be used with different",
10277 .result = REJECT,
10278 },
10279 {
10280 "calls: pkt_ptr spill into caller stack 6",
10281 .insns = {
10282 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10283 offsetof(struct __sk_buff, data_end)),
10284 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10285 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10286 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10288 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10289 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10290 BPF_EXIT_INSN(),
10291
10292 /* subprog 1 */
10293 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10294 offsetof(struct __sk_buff, data)),
10295 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10296 offsetof(struct __sk_buff, data_end)),
10297 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10298 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10299 BPF_MOV64_IMM(BPF_REG_5, 0),
10300 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10301 /* spill checked pkt_ptr into stack of caller */
10302 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10303 BPF_MOV64_IMM(BPF_REG_5, 1),
10304 /* don't read back pkt_ptr from stack here */
10305 /* write 4 bytes into packet */
10306 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10307 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10308 BPF_EXIT_INSN(),
10309 },
10310 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10311 .errstr = "R4 invalid mem access",
10312 .result = REJECT,
10313 },
10314 {
10315 "calls: pkt_ptr spill into caller stack 7",
10316 .insns = {
10317 BPF_MOV64_IMM(BPF_REG_2, 0),
10318 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10319 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10320 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10321 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10322 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10323 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10324 BPF_EXIT_INSN(),
10325
10326 /* subprog 1 */
10327 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10328 offsetof(struct __sk_buff, data)),
10329 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10330 offsetof(struct __sk_buff, data_end)),
10331 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10332 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10333 BPF_MOV64_IMM(BPF_REG_5, 0),
10334 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10335 /* spill checked pkt_ptr into stack of caller */
10336 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10337 BPF_MOV64_IMM(BPF_REG_5, 1),
10338 /* don't read back pkt_ptr from stack here */
10339 /* write 4 bytes into packet */
10340 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10341 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10342 BPF_EXIT_INSN(),
10343 },
10344 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10345 .errstr = "R4 invalid mem access",
10346 .result = REJECT,
10347 },
10348 {
10349 "calls: pkt_ptr spill into caller stack 8",
10350 .insns = {
10351 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10352 offsetof(struct __sk_buff, data)),
10353 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10354 offsetof(struct __sk_buff, data_end)),
10355 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10356 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10357 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
10358 BPF_EXIT_INSN(),
10359 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10361 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10362 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10363 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10364 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10365 BPF_EXIT_INSN(),
10366
10367 /* subprog 1 */
10368 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10369 offsetof(struct __sk_buff, data)),
10370 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10371 offsetof(struct __sk_buff, data_end)),
10372 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10373 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10374 BPF_MOV64_IMM(BPF_REG_5, 0),
10375 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10376 /* spill checked pkt_ptr into stack of caller */
10377 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10378 BPF_MOV64_IMM(BPF_REG_5, 1),
10379 /* don't read back pkt_ptr from stack here */
10380 /* write 4 bytes into packet */
10381 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10382 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10383 BPF_EXIT_INSN(),
10384 },
10385 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10386 .result = ACCEPT,
10387 },
10388 {
10389 "calls: pkt_ptr spill into caller stack 9",
10390 .insns = {
10391 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10392 offsetof(struct __sk_buff, data)),
10393 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10394 offsetof(struct __sk_buff, data_end)),
10395 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10396 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10397 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
10398 BPF_EXIT_INSN(),
10399 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10400 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10401 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10402 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10403 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10404 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10405 BPF_EXIT_INSN(),
10406
10407 /* subprog 1 */
10408 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10409 offsetof(struct __sk_buff, data)),
10410 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10411 offsetof(struct __sk_buff, data_end)),
10412 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10413 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10414 BPF_MOV64_IMM(BPF_REG_5, 0),
10415 /* spill unchecked pkt_ptr into stack of caller */
10416 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10417 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10418 BPF_MOV64_IMM(BPF_REG_5, 1),
10419 /* don't read back pkt_ptr from stack here */
10420 /* write 4 bytes into packet */
10421 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10422 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10423 BPF_EXIT_INSN(),
10424 },
10425 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10426 .errstr = "invalid access to packet",
10427 .result = REJECT,
10428 },
10429 {
10430 "calls: caller stack init to zero or map_value_or_null",
10431 .insns = {
10432 BPF_MOV64_IMM(BPF_REG_0, 0),
10433 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
10434 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10435 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10436 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10437 /* fetch map_value_or_null or const_zero from stack */
10438 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
10439 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10440 /* store into map_value */
10441 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
10442 BPF_EXIT_INSN(),
10443
10444 /* subprog 1 */
10445 /* if (ctx == 0) return; */
10446 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
10447 /* else bpf_map_lookup() and *(fp - 8) = r0 */
10448 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
10449 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10450 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10451 BPF_LD_MAP_FD(BPF_REG_1, 0),
10452 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10453 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10454 BPF_FUNC_map_lookup_elem),
10455 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
10456 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10457 BPF_EXIT_INSN(),
10458 },
10459 .fixup_map1 = { 13 },
10460 .result = ACCEPT,
10461 .prog_type = BPF_PROG_TYPE_XDP,
10462 },
10463 {
10464 "calls: stack init to zero and pruning",
10465 .insns = {
10466 /* first make allocated_stack 16 byte */
10467 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
10468 /* now fork the execution such that the false branch
10469 * of JGT insn will be verified second and it skisp zero
10470 * init of fp-8 stack slot. If stack liveness marking
10471 * is missing live_read marks from call map_lookup
10472 * processing then pruning will incorrectly assume
10473 * that fp-8 stack slot was unused in the fall-through
10474 * branch and will accept the program incorrectly
10475 */
10476 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
10477 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10478 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
10479 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10481 BPF_LD_MAP_FD(BPF_REG_1, 0),
10482 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10483 BPF_FUNC_map_lookup_elem),
10484 BPF_EXIT_INSN(),
10485 },
10486 .fixup_map2 = { 6 },
10487 .errstr = "invalid indirect read from stack off -8+0 size 8",
10488 .result = REJECT,
10489 .prog_type = BPF_PROG_TYPE_XDP,
10490 },
10491 {
10492 "search pruning: all branches should be verified (nop operation)",
10493 .insns = {
10494 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10495 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10496 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
10497 BPF_LD_MAP_FD(BPF_REG_1, 0),
10498 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
10499 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
10500 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
10501 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
10502 BPF_MOV64_IMM(BPF_REG_4, 0),
10503 BPF_JMP_A(1),
10504 BPF_MOV64_IMM(BPF_REG_4, 1),
10505 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
10506 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
10507 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
10508 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
10509 BPF_MOV64_IMM(BPF_REG_6, 0),
10510 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
10511 BPF_EXIT_INSN(),
10512 },
10513 .fixup_map1 = { 3 },
10514 .errstr = "R6 invalid mem access 'inv'",
10515 .result = REJECT,
10516 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10517 },
10518 {
10519 "search pruning: all branches should be verified (invalid stack access)",
10520 .insns = {
10521 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10523 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
10524 BPF_LD_MAP_FD(BPF_REG_1, 0),
10525 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
10526 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
10527 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
10528 BPF_MOV64_IMM(BPF_REG_4, 0),
10529 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
10530 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
10531 BPF_JMP_A(1),
10532 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
10533 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
10534 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
10535 BPF_EXIT_INSN(),
10536 },
10537 .fixup_map1 = { 3 },
10538 .errstr = "invalid read from stack off -16+0 size 8",
10539 .result = REJECT,
10540 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10541 },
10542 };
10543
10544 static int probe_filter_length(const struct bpf_insn *fp)
10545 {
10546 int len;
10547
10548 for (len = MAX_INSNS - 1; len > 0; --len)
10549 if (fp[len].code != 0 || fp[len].imm != 0)
10550 break;
10551 return len + 1;
10552 }
10553
10554 static int create_map(uint32_t size_value, uint32_t max_elem)
10555 {
10556 int fd;
10557
10558 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
10559 size_value, max_elem, BPF_F_NO_PREALLOC);
10560 if (fd < 0)
10561 printf("Failed to create hash map '%s'!\n", strerror(errno));
10562
10563 return fd;
10564 }
10565
10566 static int create_prog_array(void)
10567 {
10568 int fd;
10569
10570 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
10571 sizeof(int), 4, 0);
10572 if (fd < 0)
10573 printf("Failed to create prog array '%s'!\n", strerror(errno));
10574
10575 return fd;
10576 }
10577
10578 static int create_map_in_map(void)
10579 {
10580 int inner_map_fd, outer_map_fd;
10581
10582 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
10583 sizeof(int), 1, 0);
10584 if (inner_map_fd < 0) {
10585 printf("Failed to create array '%s'!\n", strerror(errno));
10586 return inner_map_fd;
10587 }
10588
10589 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
10590 sizeof(int), inner_map_fd, 1, 0);
10591 if (outer_map_fd < 0)
10592 printf("Failed to create array of maps '%s'!\n",
10593 strerror(errno));
10594
10595 close(inner_map_fd);
10596
10597 return outer_map_fd;
10598 }
10599
10600 static char bpf_vlog[32768];
10601
10602 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
10603 int *map_fds)
10604 {
10605 int *fixup_map1 = test->fixup_map1;
10606 int *fixup_map2 = test->fixup_map2;
10607 int *fixup_prog = test->fixup_prog;
10608 int *fixup_map_in_map = test->fixup_map_in_map;
10609
10610 /* Allocating HTs with 1 elem is fine here, since we only test
10611 * for verifier and not do a runtime lookup, so the only thing
10612 * that really matters is value size in this case.
10613 */
10614 if (*fixup_map1) {
10615 map_fds[0] = create_map(sizeof(long long), 1);
10616 do {
10617 prog[*fixup_map1].imm = map_fds[0];
10618 fixup_map1++;
10619 } while (*fixup_map1);
10620 }
10621
10622 if (*fixup_map2) {
10623 map_fds[1] = create_map(sizeof(struct test_val), 1);
10624 do {
10625 prog[*fixup_map2].imm = map_fds[1];
10626 fixup_map2++;
10627 } while (*fixup_map2);
10628 }
10629
10630 if (*fixup_prog) {
10631 map_fds[2] = create_prog_array();
10632 do {
10633 prog[*fixup_prog].imm = map_fds[2];
10634 fixup_prog++;
10635 } while (*fixup_prog);
10636 }
10637
10638 if (*fixup_map_in_map) {
10639 map_fds[3] = create_map_in_map();
10640 do {
10641 prog[*fixup_map_in_map].imm = map_fds[3];
10642 fixup_map_in_map++;
10643 } while (*fixup_map_in_map);
10644 }
10645 }
10646
10647 static void do_test_single(struct bpf_test *test, bool unpriv,
10648 int *passes, int *errors)
10649 {
10650 int fd_prog, expected_ret, reject_from_alignment;
10651 struct bpf_insn *prog = test->insns;
10652 int prog_len = probe_filter_length(prog);
10653 int prog_type = test->prog_type;
10654 int map_fds[MAX_NR_MAPS];
10655 const char *expected_err;
10656 int i;
10657
10658 for (i = 0; i < MAX_NR_MAPS; i++)
10659 map_fds[i] = -1;
10660
10661 do_test_fixup(test, prog, map_fds);
10662
10663 fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
10664 prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
10665 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
10666
10667 expected_ret = unpriv && test->result_unpriv != UNDEF ?
10668 test->result_unpriv : test->result;
10669 expected_err = unpriv && test->errstr_unpriv ?
10670 test->errstr_unpriv : test->errstr;
10671
10672 reject_from_alignment = fd_prog < 0 &&
10673 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
10674 strstr(bpf_vlog, "Unknown alignment.");
10675 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
10676 if (reject_from_alignment) {
10677 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
10678 strerror(errno));
10679 goto fail_log;
10680 }
10681 #endif
10682 if (expected_ret == ACCEPT) {
10683 if (fd_prog < 0 && !reject_from_alignment) {
10684 printf("FAIL\nFailed to load prog '%s'!\n",
10685 strerror(errno));
10686 goto fail_log;
10687 }
10688 } else {
10689 if (fd_prog >= 0) {
10690 printf("FAIL\nUnexpected success to load!\n");
10691 goto fail_log;
10692 }
10693 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
10694 printf("FAIL\nUnexpected error message!\n");
10695 goto fail_log;
10696 }
10697 }
10698
10699 (*passes)++;
10700 printf("OK%s\n", reject_from_alignment ?
10701 " (NOTE: reject due to unknown alignment)" : "");
10702 close_fds:
10703 close(fd_prog);
10704 for (i = 0; i < MAX_NR_MAPS; i++)
10705 close(map_fds[i]);
10706 sched_yield();
10707 return;
10708 fail_log:
10709 (*errors)++;
10710 printf("%s", bpf_vlog);
10711 goto close_fds;
10712 }
10713
10714 static bool is_admin(void)
10715 {
10716 cap_t caps;
10717 cap_flag_value_t sysadmin = CAP_CLEAR;
10718 const cap_value_t cap_val = CAP_SYS_ADMIN;
10719
10720 #ifdef CAP_IS_SUPPORTED
10721 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
10722 perror("cap_get_flag");
10723 return false;
10724 }
10725 #endif
10726 caps = cap_get_proc();
10727 if (!caps) {
10728 perror("cap_get_proc");
10729 return false;
10730 }
10731 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
10732 perror("cap_get_flag");
10733 if (cap_free(caps))
10734 perror("cap_free");
10735 return (sysadmin == CAP_SET);
10736 }
10737
10738 static int set_admin(bool admin)
10739 {
10740 cap_t caps;
10741 const cap_value_t cap_val = CAP_SYS_ADMIN;
10742 int ret = -1;
10743
10744 caps = cap_get_proc();
10745 if (!caps) {
10746 perror("cap_get_proc");
10747 return -1;
10748 }
10749 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
10750 admin ? CAP_SET : CAP_CLEAR)) {
10751 perror("cap_set_flag");
10752 goto out;
10753 }
10754 if (cap_set_proc(caps)) {
10755 perror("cap_set_proc");
10756 goto out;
10757 }
10758 ret = 0;
10759 out:
10760 if (cap_free(caps))
10761 perror("cap_free");
10762 return ret;
10763 }
10764
10765 static int do_test(bool unpriv, unsigned int from, unsigned int to)
10766 {
10767 int i, passes = 0, errors = 0;
10768
10769 for (i = from; i < to; i++) {
10770 struct bpf_test *test = &tests[i];
10771
10772 /* Program types that are not supported by non-root we
10773 * skip right away.
10774 */
10775 if (!test->prog_type) {
10776 if (!unpriv)
10777 set_admin(false);
10778 printf("#%d/u %s ", i, test->descr);
10779 do_test_single(test, true, &passes, &errors);
10780 if (!unpriv)
10781 set_admin(true);
10782 }
10783
10784 if (!unpriv) {
10785 printf("#%d/p %s ", i, test->descr);
10786 do_test_single(test, false, &passes, &errors);
10787 }
10788 }
10789
10790 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
10791 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
10792 }
10793
10794 int main(int argc, char **argv)
10795 {
10796 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
10797 struct rlimit rlim = { 1 << 20, 1 << 20 };
10798 unsigned int from = 0, to = ARRAY_SIZE(tests);
10799 bool unpriv = !is_admin();
10800
10801 if (argc == 3) {
10802 unsigned int l = atoi(argv[argc - 2]);
10803 unsigned int u = atoi(argv[argc - 1]);
10804
10805 if (l < to && u < to) {
10806 from = l;
10807 to = u + 1;
10808 }
10809 } else if (argc == 2) {
10810 unsigned int t = atoi(argv[argc - 1]);
10811
10812 if (t < to) {
10813 from = t;
10814 to = t + 1;
10815 }
10816 }
10817
10818 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
10819 return do_test(unpriv, from, to);
10820 }