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