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