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