1
2
3
4
5
6
7
8
9
10#include <stdio.h>
11#include <unistd.h>
12#include <linux/bpf.h>
13#include <errno.h>
14#include <linux/unistd.h>
15#include <string.h>
16#include <linux/filter.h>
17#include <stddef.h>
18#include <stdbool.h>
19#include <sys/resource.h>
20#include "libbpf.h"
21
22#define MAX_INSNS 512
23#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
24
25#define MAX_FIXUPS 8
26
27struct bpf_test {
28 const char *descr;
29 struct bpf_insn insns[MAX_INSNS];
30 int fixup[MAX_FIXUPS];
31 int prog_array_fixup[MAX_FIXUPS];
32 int test_val_map_fixup[MAX_FIXUPS];
33 const char *errstr;
34 const char *errstr_unpriv;
35 enum {
36 UNDEF,
37 ACCEPT,
38 REJECT
39 } result, result_unpriv;
40 enum bpf_prog_type prog_type;
41};
42
43
44
45
46#define MAX_ENTRIES 11
47struct test_val {
48 unsigned index;
49 int foo[MAX_ENTRIES];
50};
51
52struct other_val {
53 unsigned int action[32];
54};
55
56static struct bpf_test tests[] = {
57 {
58 "add+sub+mul",
59 .insns = {
60 BPF_MOV64_IMM(BPF_REG_1, 1),
61 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
62 BPF_MOV64_IMM(BPF_REG_2, 3),
63 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
64 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
65 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
66 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
67 BPF_EXIT_INSN(),
68 },
69 .result = ACCEPT,
70 },
71 {
72 "unreachable",
73 .insns = {
74 BPF_EXIT_INSN(),
75 BPF_EXIT_INSN(),
76 },
77 .errstr = "unreachable",
78 .result = REJECT,
79 },
80 {
81 "unreachable2",
82 .insns = {
83 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
84 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
85 BPF_EXIT_INSN(),
86 },
87 .errstr = "unreachable",
88 .result = REJECT,
89 },
90 {
91 "out of range jump",
92 .insns = {
93 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
94 BPF_EXIT_INSN(),
95 },
96 .errstr = "jump out of range",
97 .result = REJECT,
98 },
99 {
100 "out of range jump2",
101 .insns = {
102 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
103 BPF_EXIT_INSN(),
104 },
105 .errstr = "jump out of range",
106 .result = REJECT,
107 },
108 {
109 "test1 ld_imm64",
110 .insns = {
111 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
112 BPF_LD_IMM64(BPF_REG_0, 0),
113 BPF_LD_IMM64(BPF_REG_0, 0),
114 BPF_LD_IMM64(BPF_REG_0, 1),
115 BPF_LD_IMM64(BPF_REG_0, 1),
116 BPF_MOV64_IMM(BPF_REG_0, 2),
117 BPF_EXIT_INSN(),
118 },
119 .errstr = "invalid BPF_LD_IMM insn",
120 .errstr_unpriv = "R1 pointer comparison",
121 .result = REJECT,
122 },
123 {
124 "test2 ld_imm64",
125 .insns = {
126 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
127 BPF_LD_IMM64(BPF_REG_0, 0),
128 BPF_LD_IMM64(BPF_REG_0, 0),
129 BPF_LD_IMM64(BPF_REG_0, 1),
130 BPF_LD_IMM64(BPF_REG_0, 1),
131 BPF_EXIT_INSN(),
132 },
133 .errstr = "invalid BPF_LD_IMM insn",
134 .errstr_unpriv = "R1 pointer comparison",
135 .result = REJECT,
136 },
137 {
138 "test3 ld_imm64",
139 .insns = {
140 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
141 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
142 BPF_LD_IMM64(BPF_REG_0, 0),
143 BPF_LD_IMM64(BPF_REG_0, 0),
144 BPF_LD_IMM64(BPF_REG_0, 1),
145 BPF_LD_IMM64(BPF_REG_0, 1),
146 BPF_EXIT_INSN(),
147 },
148 .errstr = "invalid bpf_ld_imm64 insn",
149 .result = REJECT,
150 },
151 {
152 "test4 ld_imm64",
153 .insns = {
154 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
155 BPF_EXIT_INSN(),
156 },
157 .errstr = "invalid bpf_ld_imm64 insn",
158 .result = REJECT,
159 },
160 {
161 "test5 ld_imm64",
162 .insns = {
163 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
164 },
165 .errstr = "invalid bpf_ld_imm64 insn",
166 .result = REJECT,
167 },
168 {
169 "no bpf_exit",
170 .insns = {
171 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
172 },
173 .errstr = "jump out of range",
174 .result = REJECT,
175 },
176 {
177 "loop (back-edge)",
178 .insns = {
179 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
180 BPF_EXIT_INSN(),
181 },
182 .errstr = "back-edge",
183 .result = REJECT,
184 },
185 {
186 "loop2 (back-edge)",
187 .insns = {
188 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
189 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
190 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
191 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
192 BPF_EXIT_INSN(),
193 },
194 .errstr = "back-edge",
195 .result = REJECT,
196 },
197 {
198 "conditional loop",
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_JEQ, BPF_REG_1, 0, -3),
204 BPF_EXIT_INSN(),
205 },
206 .errstr = "back-edge",
207 .result = REJECT,
208 },
209 {
210 "read uninitialized register",
211 .insns = {
212 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
213 BPF_EXIT_INSN(),
214 },
215 .errstr = "R2 !read_ok",
216 .result = REJECT,
217 },
218 {
219 "read invalid register",
220 .insns = {
221 BPF_MOV64_REG(BPF_REG_0, -1),
222 BPF_EXIT_INSN(),
223 },
224 .errstr = "R15 is invalid",
225 .result = REJECT,
226 },
227 {
228 "program doesn't init R0 before exit",
229 .insns = {
230 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
231 BPF_EXIT_INSN(),
232 },
233 .errstr = "R0 !read_ok",
234 .result = REJECT,
235 },
236 {
237 "program doesn't init R0 before exit in all branches",
238 .insns = {
239 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
240 BPF_MOV64_IMM(BPF_REG_0, 1),
241 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
242 BPF_EXIT_INSN(),
243 },
244 .errstr = "R0 !read_ok",
245 .errstr_unpriv = "R1 pointer comparison",
246 .result = REJECT,
247 },
248 {
249 "stack out of bounds",
250 .insns = {
251 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
252 BPF_EXIT_INSN(),
253 },
254 .errstr = "invalid stack",
255 .result = REJECT,
256 },
257 {
258 "invalid call insn1",
259 .insns = {
260 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
261 BPF_EXIT_INSN(),
262 },
263 .errstr = "BPF_CALL uses reserved",
264 .result = REJECT,
265 },
266 {
267 "invalid call insn2",
268 .insns = {
269 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
270 BPF_EXIT_INSN(),
271 },
272 .errstr = "BPF_CALL uses reserved",
273 .result = REJECT,
274 },
275 {
276 "invalid function call",
277 .insns = {
278 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
279 BPF_EXIT_INSN(),
280 },
281 .errstr = "invalid func 1234567",
282 .result = REJECT,
283 },
284 {
285 "uninitialized stack1",
286 .insns = {
287 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
288 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
289 BPF_LD_MAP_FD(BPF_REG_1, 0),
290 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
291 BPF_EXIT_INSN(),
292 },
293 .fixup = {2},
294 .errstr = "invalid indirect read from stack",
295 .result = REJECT,
296 },
297 {
298 "uninitialized stack2",
299 .insns = {
300 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
301 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
302 BPF_EXIT_INSN(),
303 },
304 .errstr = "invalid read from stack",
305 .result = REJECT,
306 },
307 {
308 "invalid argument register",
309 .insns = {
310 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
311 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
312 BPF_EXIT_INSN(),
313 },
314 .errstr = "R1 !read_ok",
315 .result = REJECT,
316 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
317 },
318 {
319 "non-invalid argument register",
320 .insns = {
321 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
322 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
323 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
324 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_cgroup_classid),
325 BPF_EXIT_INSN(),
326 },
327 .result = ACCEPT,
328 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
329 },
330 {
331 "check valid spill/fill",
332 .insns = {
333
334 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
335
336
337 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
338
339
340
341 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
342 BPF_EXIT_INSN(),
343 },
344 .errstr_unpriv = "R0 leaks addr",
345 .result = ACCEPT,
346 .result_unpriv = REJECT,
347 },
348 {
349 "check valid spill/fill, skb mark",
350 .insns = {
351 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
352 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
353 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
354 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
355 offsetof(struct __sk_buff, mark)),
356 BPF_EXIT_INSN(),
357 },
358 .result = ACCEPT,
359 .result_unpriv = ACCEPT,
360 },
361 {
362 "check corrupted spill/fill",
363 .insns = {
364
365 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
366
367
368 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
369
370
371 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
372
373 BPF_EXIT_INSN(),
374 },
375 .errstr_unpriv = "attempt to corrupt spilled",
376 .errstr = "corrupted spill",
377 .result = REJECT,
378 },
379 {
380 "invalid src register in STX",
381 .insns = {
382 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
383 BPF_EXIT_INSN(),
384 },
385 .errstr = "R15 is invalid",
386 .result = REJECT,
387 },
388 {
389 "invalid dst register in STX",
390 .insns = {
391 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
392 BPF_EXIT_INSN(),
393 },
394 .errstr = "R14 is invalid",
395 .result = REJECT,
396 },
397 {
398 "invalid dst register in ST",
399 .insns = {
400 BPF_ST_MEM(BPF_B, 14, -1, -1),
401 BPF_EXIT_INSN(),
402 },
403 .errstr = "R14 is invalid",
404 .result = REJECT,
405 },
406 {
407 "invalid src register in LDX",
408 .insns = {
409 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
410 BPF_EXIT_INSN(),
411 },
412 .errstr = "R12 is invalid",
413 .result = REJECT,
414 },
415 {
416 "invalid dst register in LDX",
417 .insns = {
418 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
419 BPF_EXIT_INSN(),
420 },
421 .errstr = "R11 is invalid",
422 .result = REJECT,
423 },
424 {
425 "junk insn",
426 .insns = {
427 BPF_RAW_INSN(0, 0, 0, 0, 0),
428 BPF_EXIT_INSN(),
429 },
430 .errstr = "invalid BPF_LD_IMM",
431 .result = REJECT,
432 },
433 {
434 "junk insn2",
435 .insns = {
436 BPF_RAW_INSN(1, 0, 0, 0, 0),
437 BPF_EXIT_INSN(),
438 },
439 .errstr = "BPF_LDX uses reserved fields",
440 .result = REJECT,
441 },
442 {
443 "junk insn3",
444 .insns = {
445 BPF_RAW_INSN(-1, 0, 0, 0, 0),
446 BPF_EXIT_INSN(),
447 },
448 .errstr = "invalid BPF_ALU opcode f0",
449 .result = REJECT,
450 },
451 {
452 "junk insn4",
453 .insns = {
454 BPF_RAW_INSN(-1, -1, -1, -1, -1),
455 BPF_EXIT_INSN(),
456 },
457 .errstr = "invalid BPF_ALU opcode f0",
458 .result = REJECT,
459 },
460 {
461 "junk insn5",
462 .insns = {
463 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
464 BPF_EXIT_INSN(),
465 },
466 .errstr = "BPF_ALU uses reserved fields",
467 .result = REJECT,
468 },
469 {
470 "misaligned read from stack",
471 .insns = {
472 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
473 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
474 BPF_EXIT_INSN(),
475 },
476 .errstr = "misaligned access",
477 .result = REJECT,
478 },
479 {
480 "invalid map_fd for function call",
481 .insns = {
482 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
483 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
485 BPF_LD_MAP_FD(BPF_REG_1, 0),
486 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem),
487 BPF_EXIT_INSN(),
488 },
489 .errstr = "fd 0 is not pointing to valid bpf_map",
490 .result = REJECT,
491 },
492 {
493 "don't check return value before access",
494 .insns = {
495 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
496 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
497 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
498 BPF_LD_MAP_FD(BPF_REG_1, 0),
499 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
500 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
501 BPF_EXIT_INSN(),
502 },
503 .fixup = {3},
504 .errstr = "R0 invalid mem access 'map_value_or_null'",
505 .result = REJECT,
506 },
507 {
508 "access memory with incorrect alignment",
509 .insns = {
510 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
511 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
513 BPF_LD_MAP_FD(BPF_REG_1, 0),
514 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
515 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
516 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
517 BPF_EXIT_INSN(),
518 },
519 .fixup = {3},
520 .errstr = "misaligned access",
521 .result = REJECT,
522 },
523 {
524 "sometimes access memory with incorrect alignment",
525 .insns = {
526 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
527 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
528 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
529 BPF_LD_MAP_FD(BPF_REG_1, 0),
530 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
531 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
532 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
533 BPF_EXIT_INSN(),
534 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
535 BPF_EXIT_INSN(),
536 },
537 .fixup = {3},
538 .errstr = "R0 invalid mem access",
539 .errstr_unpriv = "R0 leaks addr",
540 .result = REJECT,
541 },
542 {
543 "jump test 1",
544 .insns = {
545 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
546 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
547 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
548 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
549 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
550 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
551 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
552 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
553 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
554 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
555 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
556 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
557 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
558 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
559 BPF_MOV64_IMM(BPF_REG_0, 0),
560 BPF_EXIT_INSN(),
561 },
562 .errstr_unpriv = "R1 pointer comparison",
563 .result_unpriv = REJECT,
564 .result = ACCEPT,
565 },
566 {
567 "jump test 2",
568 .insns = {
569 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
570 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
571 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
572 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
573 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
574 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
575 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
576 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
577 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
578 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
579 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
580 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
581 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
582 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
583 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
584 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
586 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
587 BPF_MOV64_IMM(BPF_REG_0, 0),
588 BPF_EXIT_INSN(),
589 },
590 .errstr_unpriv = "R1 pointer comparison",
591 .result_unpriv = REJECT,
592 .result = ACCEPT,
593 },
594 {
595 "jump test 3",
596 .insns = {
597 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
598 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
599 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
600 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
601 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
602 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
603 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
605 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
606 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
607 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
608 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
609 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
610 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
611 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
612 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
613 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
614 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
615 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
616 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
617 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
618 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
619 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
620 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
621 BPF_LD_MAP_FD(BPF_REG_1, 0),
622 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem),
623 BPF_EXIT_INSN(),
624 },
625 .fixup = {24},
626 .errstr_unpriv = "R1 pointer comparison",
627 .result_unpriv = REJECT,
628 .result = ACCEPT,
629 },
630 {
631 "jump test 4",
632 .insns = {
633 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
634 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
635 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
636 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
637 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
638 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
639 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
640 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
641 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
642 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
643 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
644 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
645 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
646 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
647 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
648 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
649 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
650 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
651 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
653 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
654 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
655 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
656 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
657 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
658 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
660 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
661 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
662 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
664 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
666 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
667 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
669 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
670 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
672 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
673 BPF_MOV64_IMM(BPF_REG_0, 0),
674 BPF_EXIT_INSN(),
675 },
676 .errstr_unpriv = "R1 pointer comparison",
677 .result_unpriv = REJECT,
678 .result = ACCEPT,
679 },
680 {
681 "jump test 5",
682 .insns = {
683 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
684 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
685 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
686 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
687 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
688 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
689 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
690 BPF_MOV64_IMM(BPF_REG_0, 0),
691 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
692 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
693 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
694 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
695 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
696 BPF_MOV64_IMM(BPF_REG_0, 0),
697 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
698 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
699 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
700 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
701 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
702 BPF_MOV64_IMM(BPF_REG_0, 0),
703 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
704 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
705 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
706 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
707 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
708 BPF_MOV64_IMM(BPF_REG_0, 0),
709 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
710 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
711 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
712 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
713 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
714 BPF_MOV64_IMM(BPF_REG_0, 0),
715 BPF_EXIT_INSN(),
716 },
717 .errstr_unpriv = "R1 pointer comparison",
718 .result_unpriv = REJECT,
719 .result = ACCEPT,
720 },
721 {
722 "access skb fields ok",
723 .insns = {
724 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
725 offsetof(struct __sk_buff, len)),
726 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
727 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
728 offsetof(struct __sk_buff, mark)),
729 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
730 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
731 offsetof(struct __sk_buff, pkt_type)),
732 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
733 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
734 offsetof(struct __sk_buff, queue_mapping)),
735 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
736 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
737 offsetof(struct __sk_buff, protocol)),
738 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
739 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
740 offsetof(struct __sk_buff, vlan_present)),
741 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
742 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
743 offsetof(struct __sk_buff, vlan_tci)),
744 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
745 BPF_EXIT_INSN(),
746 },
747 .result = ACCEPT,
748 },
749 {
750 "access skb fields bad1",
751 .insns = {
752 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
753 BPF_EXIT_INSN(),
754 },
755 .errstr = "invalid bpf_context access",
756 .result = REJECT,
757 },
758 {
759 "access skb fields bad2",
760 .insns = {
761 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
762 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
763 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
764 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
765 BPF_LD_MAP_FD(BPF_REG_1, 0),
766 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
767 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
768 BPF_EXIT_INSN(),
769 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
770 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
771 offsetof(struct __sk_buff, pkt_type)),
772 BPF_EXIT_INSN(),
773 },
774 .fixup = {4},
775 .errstr = "different pointers",
776 .errstr_unpriv = "R1 pointer comparison",
777 .result = REJECT,
778 },
779 {
780 "access skb fields bad3",
781 .insns = {
782 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
783 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
784 offsetof(struct __sk_buff, pkt_type)),
785 BPF_EXIT_INSN(),
786 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
787 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
789 BPF_LD_MAP_FD(BPF_REG_1, 0),
790 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
791 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
792 BPF_EXIT_INSN(),
793 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
794 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
795 },
796 .fixup = {6},
797 .errstr = "different pointers",
798 .errstr_unpriv = "R1 pointer comparison",
799 .result = REJECT,
800 },
801 {
802 "access skb fields bad4",
803 .insns = {
804 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
805 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
806 offsetof(struct __sk_buff, len)),
807 BPF_MOV64_IMM(BPF_REG_0, 0),
808 BPF_EXIT_INSN(),
809 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
810 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
812 BPF_LD_MAP_FD(BPF_REG_1, 0),
813 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
814 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
815 BPF_EXIT_INSN(),
816 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
817 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
818 },
819 .fixup = {7},
820 .errstr = "different pointers",
821 .errstr_unpriv = "R1 pointer comparison",
822 .result = REJECT,
823 },
824 {
825 "check skb->mark is not writeable by sockets",
826 .insns = {
827 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
828 offsetof(struct __sk_buff, mark)),
829 BPF_EXIT_INSN(),
830 },
831 .errstr = "invalid bpf_context access",
832 .errstr_unpriv = "R1 leaks addr",
833 .result = REJECT,
834 },
835 {
836 "check skb->tc_index is not writeable by sockets",
837 .insns = {
838 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
839 offsetof(struct __sk_buff, tc_index)),
840 BPF_EXIT_INSN(),
841 },
842 .errstr = "invalid bpf_context access",
843 .errstr_unpriv = "R1 leaks addr",
844 .result = REJECT,
845 },
846 {
847 "check non-u32 access to cb",
848 .insns = {
849 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_1,
850 offsetof(struct __sk_buff, cb[0])),
851 BPF_EXIT_INSN(),
852 },
853 .errstr = "invalid bpf_context access",
854 .errstr_unpriv = "R1 leaks addr",
855 .result = REJECT,
856 },
857 {
858 "check out of range skb->cb access",
859 .insns = {
860 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
861 offsetof(struct __sk_buff, cb[0]) + 256),
862 BPF_EXIT_INSN(),
863 },
864 .errstr = "invalid bpf_context access",
865 .errstr_unpriv = "",
866 .result = REJECT,
867 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
868 },
869 {
870 "write skb fields from socket prog",
871 .insns = {
872 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
873 offsetof(struct __sk_buff, cb[4])),
874 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
875 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
876 offsetof(struct __sk_buff, mark)),
877 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
878 offsetof(struct __sk_buff, tc_index)),
879 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
880 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
881 offsetof(struct __sk_buff, cb[0])),
882 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
883 offsetof(struct __sk_buff, cb[2])),
884 BPF_EXIT_INSN(),
885 },
886 .result = ACCEPT,
887 .errstr_unpriv = "R1 leaks addr",
888 .result_unpriv = REJECT,
889 },
890 {
891 "write skb fields from tc_cls_act prog",
892 .insns = {
893 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
894 offsetof(struct __sk_buff, cb[0])),
895 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
896 offsetof(struct __sk_buff, mark)),
897 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
898 offsetof(struct __sk_buff, tc_index)),
899 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
900 offsetof(struct __sk_buff, tc_index)),
901 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
902 offsetof(struct __sk_buff, cb[3])),
903 BPF_EXIT_INSN(),
904 },
905 .errstr_unpriv = "",
906 .result_unpriv = REJECT,
907 .result = ACCEPT,
908 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
909 },
910 {
911 "PTR_TO_STACK store/load",
912 .insns = {
913 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
914 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
915 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
916 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
917 BPF_EXIT_INSN(),
918 },
919 .result = ACCEPT,
920 },
921 {
922 "PTR_TO_STACK store/load - bad alignment on off",
923 .insns = {
924 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
925 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
926 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
927 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
928 BPF_EXIT_INSN(),
929 },
930 .result = REJECT,
931 .errstr = "misaligned access off -6 size 8",
932 },
933 {
934 "PTR_TO_STACK store/load - bad alignment on reg",
935 .insns = {
936 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
937 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
938 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
939 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
940 BPF_EXIT_INSN(),
941 },
942 .result = REJECT,
943 .errstr = "misaligned access off -2 size 8",
944 },
945 {
946 "PTR_TO_STACK store/load - out of bounds low",
947 .insns = {
948 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
949 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
950 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
951 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
952 BPF_EXIT_INSN(),
953 },
954 .result = REJECT,
955 .errstr = "invalid stack off=-79992 size=8",
956 },
957 {
958 "PTR_TO_STACK store/load - out of bounds high",
959 .insns = {
960 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
961 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
962 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
963 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
964 BPF_EXIT_INSN(),
965 },
966 .result = REJECT,
967 .errstr = "invalid stack off=0 size=8",
968 },
969 {
970 "unpriv: return pointer",
971 .insns = {
972 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
973 BPF_EXIT_INSN(),
974 },
975 .result = ACCEPT,
976 .result_unpriv = REJECT,
977 .errstr_unpriv = "R0 leaks addr",
978 },
979 {
980 "unpriv: add const to pointer",
981 .insns = {
982 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
983 BPF_MOV64_IMM(BPF_REG_0, 0),
984 BPF_EXIT_INSN(),
985 },
986 .result = ACCEPT,
987 .result_unpriv = REJECT,
988 .errstr_unpriv = "R1 pointer arithmetic",
989 },
990 {
991 "unpriv: add pointer to pointer",
992 .insns = {
993 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
994 BPF_MOV64_IMM(BPF_REG_0, 0),
995 BPF_EXIT_INSN(),
996 },
997 .result = ACCEPT,
998 .result_unpriv = REJECT,
999 .errstr_unpriv = "R1 pointer arithmetic",
1000 },
1001 {
1002 "unpriv: neg pointer",
1003 .insns = {
1004 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1005 BPF_MOV64_IMM(BPF_REG_0, 0),
1006 BPF_EXIT_INSN(),
1007 },
1008 .result = ACCEPT,
1009 .result_unpriv = REJECT,
1010 .errstr_unpriv = "R1 pointer arithmetic",
1011 },
1012 {
1013 "unpriv: cmp pointer with const",
1014 .insns = {
1015 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1016 BPF_MOV64_IMM(BPF_REG_0, 0),
1017 BPF_EXIT_INSN(),
1018 },
1019 .result = ACCEPT,
1020 .result_unpriv = REJECT,
1021 .errstr_unpriv = "R1 pointer comparison",
1022 },
1023 {
1024 "unpriv: cmp pointer with pointer",
1025 .insns = {
1026 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1027 BPF_MOV64_IMM(BPF_REG_0, 0),
1028 BPF_EXIT_INSN(),
1029 },
1030 .result = ACCEPT,
1031 .result_unpriv = REJECT,
1032 .errstr_unpriv = "R10 pointer comparison",
1033 },
1034 {
1035 "unpriv: check that printk is disallowed",
1036 .insns = {
1037 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1038 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1039 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1040 BPF_MOV64_IMM(BPF_REG_2, 8),
1041 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1042 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_trace_printk),
1043 BPF_MOV64_IMM(BPF_REG_0, 0),
1044 BPF_EXIT_INSN(),
1045 },
1046 .errstr_unpriv = "unknown func 6",
1047 .result_unpriv = REJECT,
1048 .result = ACCEPT,
1049 },
1050 {
1051 "unpriv: pass pointer to helper function",
1052 .insns = {
1053 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1054 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1056 BPF_LD_MAP_FD(BPF_REG_1, 0),
1057 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1058 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1059 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1060 BPF_MOV64_IMM(BPF_REG_0, 0),
1061 BPF_EXIT_INSN(),
1062 },
1063 .fixup = {3},
1064 .errstr_unpriv = "R4 leaks addr",
1065 .result_unpriv = REJECT,
1066 .result = ACCEPT,
1067 },
1068 {
1069 "unpriv: indirectly pass pointer on stack to helper function",
1070 .insns = {
1071 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1072 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1073 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1074 BPF_LD_MAP_FD(BPF_REG_1, 0),
1075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1076 BPF_MOV64_IMM(BPF_REG_0, 0),
1077 BPF_EXIT_INSN(),
1078 },
1079 .fixup = {3},
1080 .errstr = "invalid indirect read from stack off -8+0 size 8",
1081 .result = REJECT,
1082 },
1083 {
1084 "unpriv: mangle pointer on stack 1",
1085 .insns = {
1086 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1087 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1088 BPF_MOV64_IMM(BPF_REG_0, 0),
1089 BPF_EXIT_INSN(),
1090 },
1091 .errstr_unpriv = "attempt to corrupt spilled",
1092 .result_unpriv = REJECT,
1093 .result = ACCEPT,
1094 },
1095 {
1096 "unpriv: mangle pointer on stack 2",
1097 .insns = {
1098 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1099 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1100 BPF_MOV64_IMM(BPF_REG_0, 0),
1101 BPF_EXIT_INSN(),
1102 },
1103 .errstr_unpriv = "attempt to corrupt spilled",
1104 .result_unpriv = REJECT,
1105 .result = ACCEPT,
1106 },
1107 {
1108 "unpriv: read pointer from stack in small chunks",
1109 .insns = {
1110 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1111 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1112 BPF_MOV64_IMM(BPF_REG_0, 0),
1113 BPF_EXIT_INSN(),
1114 },
1115 .errstr = "invalid size",
1116 .result = REJECT,
1117 },
1118 {
1119 "unpriv: write pointer into ctx",
1120 .insns = {
1121 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1122 BPF_MOV64_IMM(BPF_REG_0, 0),
1123 BPF_EXIT_INSN(),
1124 },
1125 .errstr_unpriv = "R1 leaks addr",
1126 .result_unpriv = REJECT,
1127 .errstr = "invalid bpf_context access",
1128 .result = REJECT,
1129 },
1130 {
1131 "unpriv: write pointer into map elem value",
1132 .insns = {
1133 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1134 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1136 BPF_LD_MAP_FD(BPF_REG_1, 0),
1137 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1138 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1139 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1140 BPF_EXIT_INSN(),
1141 },
1142 .fixup = {3},
1143 .errstr_unpriv = "R0 leaks addr",
1144 .result_unpriv = REJECT,
1145 .result = ACCEPT,
1146 },
1147 {
1148 "unpriv: partial copy of pointer",
1149 .insns = {
1150 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1151 BPF_MOV64_IMM(BPF_REG_0, 0),
1152 BPF_EXIT_INSN(),
1153 },
1154 .errstr_unpriv = "R10 partial copy",
1155 .result_unpriv = REJECT,
1156 .result = ACCEPT,
1157 },
1158 {
1159 "unpriv: pass pointer to tail_call",
1160 .insns = {
1161 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1162 BPF_LD_MAP_FD(BPF_REG_2, 0),
1163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1164 BPF_MOV64_IMM(BPF_REG_0, 0),
1165 BPF_EXIT_INSN(),
1166 },
1167 .prog_array_fixup = {1},
1168 .errstr_unpriv = "R3 leaks addr into helper",
1169 .result_unpriv = REJECT,
1170 .result = ACCEPT,
1171 },
1172 {
1173 "unpriv: cmp map pointer with zero",
1174 .insns = {
1175 BPF_MOV64_IMM(BPF_REG_1, 0),
1176 BPF_LD_MAP_FD(BPF_REG_1, 0),
1177 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1178 BPF_MOV64_IMM(BPF_REG_0, 0),
1179 BPF_EXIT_INSN(),
1180 },
1181 .fixup = {1},
1182 .errstr_unpriv = "R1 pointer comparison",
1183 .result_unpriv = REJECT,
1184 .result = ACCEPT,
1185 },
1186 {
1187 "unpriv: write into frame pointer",
1188 .insns = {
1189 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1190 BPF_MOV64_IMM(BPF_REG_0, 0),
1191 BPF_EXIT_INSN(),
1192 },
1193 .errstr = "frame pointer is read only",
1194 .result = REJECT,
1195 },
1196 {
1197 "unpriv: cmp of frame pointer",
1198 .insns = {
1199 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1200 BPF_MOV64_IMM(BPF_REG_0, 0),
1201 BPF_EXIT_INSN(),
1202 },
1203 .errstr_unpriv = "R10 pointer comparison",
1204 .result_unpriv = REJECT,
1205 .result = ACCEPT,
1206 },
1207 {
1208 "unpriv: cmp of stack pointer",
1209 .insns = {
1210 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1213 BPF_MOV64_IMM(BPF_REG_0, 0),
1214 BPF_EXIT_INSN(),
1215 },
1216 .errstr_unpriv = "R2 pointer comparison",
1217 .result_unpriv = REJECT,
1218 .result = ACCEPT,
1219 },
1220 {
1221 "unpriv: obfuscate stack pointer",
1222 .insns = {
1223 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1224 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1225 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1226 BPF_MOV64_IMM(BPF_REG_0, 0),
1227 BPF_EXIT_INSN(),
1228 },
1229 .errstr_unpriv = "R2 pointer arithmetic",
1230 .result_unpriv = REJECT,
1231 .result = ACCEPT,
1232 },
1233 {
1234 "raw_stack: no skb_load_bytes",
1235 .insns = {
1236 BPF_MOV64_IMM(BPF_REG_2, 4),
1237 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1239 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1240 BPF_MOV64_IMM(BPF_REG_4, 8),
1241
1242 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1243 BPF_EXIT_INSN(),
1244 },
1245 .result = REJECT,
1246 .errstr = "invalid read from stack off -8+0 size 8",
1247 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1248 },
1249 {
1250 "raw_stack: skb_load_bytes, negative len",
1251 .insns = {
1252 BPF_MOV64_IMM(BPF_REG_2, 4),
1253 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1255 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1256 BPF_MOV64_IMM(BPF_REG_4, -8),
1257 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1258 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1259 BPF_EXIT_INSN(),
1260 },
1261 .result = REJECT,
1262 .errstr = "invalid stack type R3",
1263 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1264 },
1265 {
1266 "raw_stack: skb_load_bytes, negative len 2",
1267 .insns = {
1268 BPF_MOV64_IMM(BPF_REG_2, 4),
1269 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1271 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1272 BPF_MOV64_IMM(BPF_REG_4, ~0),
1273 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1274 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1275 BPF_EXIT_INSN(),
1276 },
1277 .result = REJECT,
1278 .errstr = "invalid stack type R3",
1279 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1280 },
1281 {
1282 "raw_stack: skb_load_bytes, zero len",
1283 .insns = {
1284 BPF_MOV64_IMM(BPF_REG_2, 4),
1285 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1286 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1287 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1288 BPF_MOV64_IMM(BPF_REG_4, 0),
1289 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1290 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1291 BPF_EXIT_INSN(),
1292 },
1293 .result = REJECT,
1294 .errstr = "invalid stack type R3",
1295 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1296 },
1297 {
1298 "raw_stack: skb_load_bytes, no init",
1299 .insns = {
1300 BPF_MOV64_IMM(BPF_REG_2, 4),
1301 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1303 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1304 BPF_MOV64_IMM(BPF_REG_4, 8),
1305 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1306 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1307 BPF_EXIT_INSN(),
1308 },
1309 .result = ACCEPT,
1310 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1311 },
1312 {
1313 "raw_stack: skb_load_bytes, init",
1314 .insns = {
1315 BPF_MOV64_IMM(BPF_REG_2, 4),
1316 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1317 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1318 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1319 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1320 BPF_MOV64_IMM(BPF_REG_4, 8),
1321 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1322 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1323 BPF_EXIT_INSN(),
1324 },
1325 .result = ACCEPT,
1326 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1327 },
1328 {
1329 "raw_stack: skb_load_bytes, spilled regs around bounds",
1330 .insns = {
1331 BPF_MOV64_IMM(BPF_REG_2, 4),
1332 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1333 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1334 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1335 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
1336 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1337 BPF_MOV64_IMM(BPF_REG_4, 8),
1338 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1339 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1340 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
1341 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1342 offsetof(struct __sk_buff, mark)),
1343 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1344 offsetof(struct __sk_buff, priority)),
1345 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1346 BPF_EXIT_INSN(),
1347 },
1348 .result = ACCEPT,
1349 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1350 },
1351 {
1352 "raw_stack: skb_load_bytes, spilled regs corruption",
1353 .insns = {
1354 BPF_MOV64_IMM(BPF_REG_2, 4),
1355 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1356 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1357 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1358 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1359 BPF_MOV64_IMM(BPF_REG_4, 8),
1360 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1361 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1362 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1363 offsetof(struct __sk_buff, mark)),
1364 BPF_EXIT_INSN(),
1365 },
1366 .result = REJECT,
1367 .errstr = "R0 invalid mem access 'inv'",
1368 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1369 },
1370 {
1371 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1372 .insns = {
1373 BPF_MOV64_IMM(BPF_REG_2, 4),
1374 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1375 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1376 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1377 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1378 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
1379 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1380 BPF_MOV64_IMM(BPF_REG_4, 8),
1381 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1382 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1383 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
1384 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
1385 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1386 offsetof(struct __sk_buff, mark)),
1387 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1388 offsetof(struct __sk_buff, priority)),
1389 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1390 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1391 offsetof(struct __sk_buff, pkt_type)),
1392 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1393 BPF_EXIT_INSN(),
1394 },
1395 .result = REJECT,
1396 .errstr = "R3 invalid mem access 'inv'",
1397 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1398 },
1399 {
1400 "raw_stack: skb_load_bytes, spilled regs + data",
1401 .insns = {
1402 BPF_MOV64_IMM(BPF_REG_2, 4),
1403 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
1405 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1406 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1407 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
1408 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1409 BPF_MOV64_IMM(BPF_REG_4, 8),
1410 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1411 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1412 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
1413 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
1414 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1415 offsetof(struct __sk_buff, mark)),
1416 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1417 offsetof(struct __sk_buff, priority)),
1418 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1419 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1420 BPF_EXIT_INSN(),
1421 },
1422 .result = ACCEPT,
1423 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1424 },
1425 {
1426 "raw_stack: skb_load_bytes, invalid access 1",
1427 .insns = {
1428 BPF_MOV64_IMM(BPF_REG_2, 4),
1429 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1430 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
1431 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1432 BPF_MOV64_IMM(BPF_REG_4, 8),
1433 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1434 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1435 BPF_EXIT_INSN(),
1436 },
1437 .result = REJECT,
1438 .errstr = "invalid stack type R3 off=-513 access_size=8",
1439 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1440 },
1441 {
1442 "raw_stack: skb_load_bytes, invalid access 2",
1443 .insns = {
1444 BPF_MOV64_IMM(BPF_REG_2, 4),
1445 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1446 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1447 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1448 BPF_MOV64_IMM(BPF_REG_4, 8),
1449 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1450 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1451 BPF_EXIT_INSN(),
1452 },
1453 .result = REJECT,
1454 .errstr = "invalid stack type R3 off=-1 access_size=8",
1455 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1456 },
1457 {
1458 "raw_stack: skb_load_bytes, invalid access 3",
1459 .insns = {
1460 BPF_MOV64_IMM(BPF_REG_2, 4),
1461 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1462 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
1463 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1464 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
1465 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1466 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1467 BPF_EXIT_INSN(),
1468 },
1469 .result = REJECT,
1470 .errstr = "invalid stack type R3 off=-1 access_size=-1",
1471 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1472 },
1473 {
1474 "raw_stack: skb_load_bytes, invalid access 4",
1475 .insns = {
1476 BPF_MOV64_IMM(BPF_REG_2, 4),
1477 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
1479 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1480 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1481 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1482 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1483 BPF_EXIT_INSN(),
1484 },
1485 .result = REJECT,
1486 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
1487 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1488 },
1489 {
1490 "raw_stack: skb_load_bytes, invalid access 5",
1491 .insns = {
1492 BPF_MOV64_IMM(BPF_REG_2, 4),
1493 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1495 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1496 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
1497 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1498 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1499 BPF_EXIT_INSN(),
1500 },
1501 .result = REJECT,
1502 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
1503 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1504 },
1505 {
1506 "raw_stack: skb_load_bytes, invalid access 6",
1507 .insns = {
1508 BPF_MOV64_IMM(BPF_REG_2, 4),
1509 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1511 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1512 BPF_MOV64_IMM(BPF_REG_4, 0),
1513 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1514 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1515 BPF_EXIT_INSN(),
1516 },
1517 .result = REJECT,
1518 .errstr = "invalid stack type R3 off=-512 access_size=0",
1519 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1520 },
1521 {
1522 "raw_stack: skb_load_bytes, large access",
1523 .insns = {
1524 BPF_MOV64_IMM(BPF_REG_2, 4),
1525 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1526 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
1527 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1528 BPF_MOV64_IMM(BPF_REG_4, 512),
1529 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1530 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1531 BPF_EXIT_INSN(),
1532 },
1533 .result = ACCEPT,
1534 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1535 },
1536 {
1537 "direct packet access: test1",
1538 .insns = {
1539 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1540 offsetof(struct __sk_buff, data)),
1541 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1542 offsetof(struct __sk_buff, data_end)),
1543 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1544 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1545 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1546 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1547 BPF_MOV64_IMM(BPF_REG_0, 0),
1548 BPF_EXIT_INSN(),
1549 },
1550 .result = ACCEPT,
1551 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1552 },
1553 {
1554 "direct packet access: test2",
1555 .insns = {
1556 BPF_MOV64_IMM(BPF_REG_0, 1),
1557 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
1558 offsetof(struct __sk_buff, data_end)),
1559 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1560 offsetof(struct __sk_buff, data)),
1561 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
1562 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
1563 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
1564 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
1565 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
1566 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
1567 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1568 offsetof(struct __sk_buff, data)),
1569 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
1570 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
1571 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
1572 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
1573 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
1574 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
1575 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1576 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1577 offsetof(struct __sk_buff, data_end)),
1578 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
1579 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
1580 BPF_MOV64_IMM(BPF_REG_0, 0),
1581 BPF_EXIT_INSN(),
1582 },
1583 .result = ACCEPT,
1584 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1585 },
1586 {
1587 "direct packet access: test3",
1588 .insns = {
1589 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1590 offsetof(struct __sk_buff, data)),
1591 BPF_MOV64_IMM(BPF_REG_0, 0),
1592 BPF_EXIT_INSN(),
1593 },
1594 .errstr = "invalid bpf_context access off=76",
1595 .result = REJECT,
1596 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
1597 },
1598 {
1599 "direct packet access: test4 (write)",
1600 .insns = {
1601 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1602 offsetof(struct __sk_buff, data)),
1603 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1604 offsetof(struct __sk_buff, data_end)),
1605 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1606 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1607 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1608 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1609 BPF_MOV64_IMM(BPF_REG_0, 0),
1610 BPF_EXIT_INSN(),
1611 },
1612 .result = ACCEPT,
1613 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1614 },
1615 {
1616 "direct packet access: test5 (pkt_end >= reg, good access)",
1617 .insns = {
1618 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1619 offsetof(struct __sk_buff, data)),
1620 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1621 offsetof(struct __sk_buff, data_end)),
1622 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1624 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1625 BPF_MOV64_IMM(BPF_REG_0, 1),
1626 BPF_EXIT_INSN(),
1627 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1628 BPF_MOV64_IMM(BPF_REG_0, 0),
1629 BPF_EXIT_INSN(),
1630 },
1631 .result = ACCEPT,
1632 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1633 },
1634 {
1635 "direct packet access: test6 (pkt_end >= reg, bad access)",
1636 .insns = {
1637 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1638 offsetof(struct __sk_buff, data)),
1639 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1640 offsetof(struct __sk_buff, data_end)),
1641 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1643 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1644 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1645 BPF_MOV64_IMM(BPF_REG_0, 1),
1646 BPF_EXIT_INSN(),
1647 BPF_MOV64_IMM(BPF_REG_0, 0),
1648 BPF_EXIT_INSN(),
1649 },
1650 .errstr = "invalid access to packet",
1651 .result = REJECT,
1652 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1653 },
1654 {
1655 "direct packet access: test7 (pkt_end >= reg, both accesses)",
1656 .insns = {
1657 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1658 offsetof(struct __sk_buff, data)),
1659 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1660 offsetof(struct __sk_buff, data_end)),
1661 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1662 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1663 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
1664 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1665 BPF_MOV64_IMM(BPF_REG_0, 1),
1666 BPF_EXIT_INSN(),
1667 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1668 BPF_MOV64_IMM(BPF_REG_0, 0),
1669 BPF_EXIT_INSN(),
1670 },
1671 .errstr = "invalid access to packet",
1672 .result = REJECT,
1673 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1674 },
1675 {
1676 "direct packet access: test8 (double test, variant 1)",
1677 .insns = {
1678 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1679 offsetof(struct __sk_buff, data)),
1680 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1681 offsetof(struct __sk_buff, data_end)),
1682 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1683 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1684 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
1685 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1686 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1687 BPF_MOV64_IMM(BPF_REG_0, 1),
1688 BPF_EXIT_INSN(),
1689 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1690 BPF_MOV64_IMM(BPF_REG_0, 0),
1691 BPF_EXIT_INSN(),
1692 },
1693 .result = ACCEPT,
1694 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1695 },
1696 {
1697 "direct packet access: test9 (double test, variant 2)",
1698 .insns = {
1699 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1700 offsetof(struct __sk_buff, data)),
1701 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1702 offsetof(struct __sk_buff, data_end)),
1703 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1704 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1705 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
1706 BPF_MOV64_IMM(BPF_REG_0, 1),
1707 BPF_EXIT_INSN(),
1708 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1709 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1710 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1711 BPF_MOV64_IMM(BPF_REG_0, 0),
1712 BPF_EXIT_INSN(),
1713 },
1714 .result = ACCEPT,
1715 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1716 },
1717 {
1718 "direct packet access: test10 (write invalid)",
1719 .insns = {
1720 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1721 offsetof(struct __sk_buff, data)),
1722 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1723 offsetof(struct __sk_buff, data_end)),
1724 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1725 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1726 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1727 BPF_MOV64_IMM(BPF_REG_0, 0),
1728 BPF_EXIT_INSN(),
1729 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1730 BPF_MOV64_IMM(BPF_REG_0, 0),
1731 BPF_EXIT_INSN(),
1732 },
1733 .errstr = "invalid access to packet",
1734 .result = REJECT,
1735 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1736 },
1737 {
1738 "helper access to packet: test1, valid packet_ptr range",
1739 .insns = {
1740 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1741 offsetof(struct xdp_md, data)),
1742 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1743 offsetof(struct xdp_md, data_end)),
1744 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1746 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1747 BPF_LD_MAP_FD(BPF_REG_1, 0),
1748 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1749 BPF_MOV64_IMM(BPF_REG_4, 0),
1750 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1751 BPF_MOV64_IMM(BPF_REG_0, 0),
1752 BPF_EXIT_INSN(),
1753 },
1754 .fixup = {5},
1755 .result_unpriv = ACCEPT,
1756 .result = ACCEPT,
1757 .prog_type = BPF_PROG_TYPE_XDP,
1758 },
1759 {
1760 "helper access to packet: test2, unchecked packet_ptr",
1761 .insns = {
1762 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1763 offsetof(struct xdp_md, data)),
1764 BPF_LD_MAP_FD(BPF_REG_1, 0),
1765 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1766 BPF_MOV64_IMM(BPF_REG_0, 0),
1767 BPF_EXIT_INSN(),
1768 },
1769 .fixup = {1},
1770 .result = REJECT,
1771 .errstr = "invalid access to packet",
1772 .prog_type = BPF_PROG_TYPE_XDP,
1773 },
1774 {
1775 "helper access to packet: test3, variable add",
1776 .insns = {
1777 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1778 offsetof(struct xdp_md, data)),
1779 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1780 offsetof(struct xdp_md, data_end)),
1781 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1782 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1783 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1784 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1785 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1786 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1787 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1789 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1790 BPF_LD_MAP_FD(BPF_REG_1, 0),
1791 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1792 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1793 BPF_MOV64_IMM(BPF_REG_0, 0),
1794 BPF_EXIT_INSN(),
1795 },
1796 .fixup = {11},
1797 .result = ACCEPT,
1798 .prog_type = BPF_PROG_TYPE_XDP,
1799 },
1800 {
1801 "helper access to packet: test4, packet_ptr with bad range",
1802 .insns = {
1803 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1804 offsetof(struct xdp_md, data)),
1805 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1806 offsetof(struct xdp_md, data_end)),
1807 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1809 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1810 BPF_MOV64_IMM(BPF_REG_0, 0),
1811 BPF_EXIT_INSN(),
1812 BPF_LD_MAP_FD(BPF_REG_1, 0),
1813 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1814 BPF_MOV64_IMM(BPF_REG_0, 0),
1815 BPF_EXIT_INSN(),
1816 },
1817 .fixup = {7},
1818 .result = REJECT,
1819 .errstr = "invalid access to packet",
1820 .prog_type = BPF_PROG_TYPE_XDP,
1821 },
1822 {
1823 "helper access to packet: test5, packet_ptr with too short range",
1824 .insns = {
1825 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1826 offsetof(struct xdp_md, data)),
1827 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1828 offsetof(struct xdp_md, data_end)),
1829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1830 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1831 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1832 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1833 BPF_LD_MAP_FD(BPF_REG_1, 0),
1834 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1835 BPF_MOV64_IMM(BPF_REG_0, 0),
1836 BPF_EXIT_INSN(),
1837 },
1838 .fixup = {6},
1839 .result = REJECT,
1840 .errstr = "invalid access to packet",
1841 .prog_type = BPF_PROG_TYPE_XDP,
1842 },
1843 {
1844 "helper access to packet: test6, cls valid packet_ptr range",
1845 .insns = {
1846 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1847 offsetof(struct __sk_buff, data)),
1848 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1849 offsetof(struct __sk_buff, data_end)),
1850 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1851 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1852 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
1853 BPF_LD_MAP_FD(BPF_REG_1, 0),
1854 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1855 BPF_MOV64_IMM(BPF_REG_4, 0),
1856 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_update_elem),
1857 BPF_MOV64_IMM(BPF_REG_0, 0),
1858 BPF_EXIT_INSN(),
1859 },
1860 .fixup = {5},
1861 .result = ACCEPT,
1862 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1863 },
1864 {
1865 "helper access to packet: test7, cls unchecked packet_ptr",
1866 .insns = {
1867 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1868 offsetof(struct __sk_buff, data)),
1869 BPF_LD_MAP_FD(BPF_REG_1, 0),
1870 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1871 BPF_MOV64_IMM(BPF_REG_0, 0),
1872 BPF_EXIT_INSN(),
1873 },
1874 .fixup = {1},
1875 .result = REJECT,
1876 .errstr = "invalid access to packet",
1877 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1878 },
1879 {
1880 "helper access to packet: test8, cls variable add",
1881 .insns = {
1882 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1883 offsetof(struct __sk_buff, data)),
1884 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1885 offsetof(struct __sk_buff, data_end)),
1886 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
1888 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
1889 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
1890 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1891 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
1892 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
1893 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
1894 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
1895 BPF_LD_MAP_FD(BPF_REG_1, 0),
1896 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
1897 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1898 BPF_MOV64_IMM(BPF_REG_0, 0),
1899 BPF_EXIT_INSN(),
1900 },
1901 .fixup = {11},
1902 .result = ACCEPT,
1903 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1904 },
1905 {
1906 "helper access to packet: test9, cls packet_ptr with bad range",
1907 .insns = {
1908 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1909 offsetof(struct __sk_buff, data)),
1910 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1911 offsetof(struct __sk_buff, data_end)),
1912 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1913 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
1914 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
1915 BPF_MOV64_IMM(BPF_REG_0, 0),
1916 BPF_EXIT_INSN(),
1917 BPF_LD_MAP_FD(BPF_REG_1, 0),
1918 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1919 BPF_MOV64_IMM(BPF_REG_0, 0),
1920 BPF_EXIT_INSN(),
1921 },
1922 .fixup = {7},
1923 .result = REJECT,
1924 .errstr = "invalid access to packet",
1925 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1926 },
1927 {
1928 "helper access to packet: test10, cls packet_ptr with too short range",
1929 .insns = {
1930 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1931 offsetof(struct __sk_buff, data)),
1932 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1933 offsetof(struct __sk_buff, data_end)),
1934 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
1935 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
1936 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
1937 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
1938 BPF_LD_MAP_FD(BPF_REG_1, 0),
1939 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1940 BPF_MOV64_IMM(BPF_REG_0, 0),
1941 BPF_EXIT_INSN(),
1942 },
1943 .fixup = {6},
1944 .result = REJECT,
1945 .errstr = "invalid access to packet",
1946 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1947 },
1948 {
1949 "helper access to packet: test11, cls unsuitable helper 1",
1950 .insns = {
1951 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1952 offsetof(struct __sk_buff, data)),
1953 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1954 offsetof(struct __sk_buff, data_end)),
1955 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
1956 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1957 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
1958 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
1959 BPF_MOV64_IMM(BPF_REG_2, 0),
1960 BPF_MOV64_IMM(BPF_REG_4, 42),
1961 BPF_MOV64_IMM(BPF_REG_5, 0),
1962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_store_bytes),
1963 BPF_MOV64_IMM(BPF_REG_0, 0),
1964 BPF_EXIT_INSN(),
1965 },
1966 .result = REJECT,
1967 .errstr = "helper access to the packet",
1968 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1969 },
1970 {
1971 "helper access to packet: test12, cls unsuitable helper 2",
1972 .insns = {
1973 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1974 offsetof(struct __sk_buff, data)),
1975 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1976 offsetof(struct __sk_buff, data_end)),
1977 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1978 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
1979 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
1980 BPF_MOV64_IMM(BPF_REG_2, 0),
1981 BPF_MOV64_IMM(BPF_REG_4, 4),
1982 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
1983 BPF_MOV64_IMM(BPF_REG_0, 0),
1984 BPF_EXIT_INSN(),
1985 },
1986 .result = REJECT,
1987 .errstr = "helper access to the packet",
1988 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1989 },
1990 {
1991 "helper access to packet: test13, cls helper ok",
1992 .insns = {
1993 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
1994 offsetof(struct __sk_buff, data)),
1995 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1996 offsetof(struct __sk_buff, data_end)),
1997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
1998 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1999 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2000 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2001 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2002 BPF_MOV64_IMM(BPF_REG_2, 4),
2003 BPF_MOV64_IMM(BPF_REG_3, 0),
2004 BPF_MOV64_IMM(BPF_REG_4, 0),
2005 BPF_MOV64_IMM(BPF_REG_5, 0),
2006 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2007 BPF_MOV64_IMM(BPF_REG_0, 0),
2008 BPF_EXIT_INSN(),
2009 },
2010 .result = ACCEPT,
2011 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2012 },
2013 {
2014 "helper access to packet: test14, cls helper fail sub",
2015 .insns = {
2016 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2017 offsetof(struct __sk_buff, data)),
2018 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2019 offsetof(struct __sk_buff, data_end)),
2020 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2021 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2022 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2023 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2024 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2025 BPF_MOV64_IMM(BPF_REG_2, 4),
2026 BPF_MOV64_IMM(BPF_REG_3, 0),
2027 BPF_MOV64_IMM(BPF_REG_4, 0),
2028 BPF_MOV64_IMM(BPF_REG_5, 0),
2029 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2030 BPF_MOV64_IMM(BPF_REG_0, 0),
2031 BPF_EXIT_INSN(),
2032 },
2033 .result = REJECT,
2034 .errstr = "type=inv expected=fp",
2035 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2036 },
2037 {
2038 "helper access to packet: test15, cls helper fail range 1",
2039 .insns = {
2040 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2041 offsetof(struct __sk_buff, data)),
2042 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2043 offsetof(struct __sk_buff, data_end)),
2044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2045 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2046 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2047 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2048 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2049 BPF_MOV64_IMM(BPF_REG_2, 8),
2050 BPF_MOV64_IMM(BPF_REG_3, 0),
2051 BPF_MOV64_IMM(BPF_REG_4, 0),
2052 BPF_MOV64_IMM(BPF_REG_5, 0),
2053 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2054 BPF_MOV64_IMM(BPF_REG_0, 0),
2055 BPF_EXIT_INSN(),
2056 },
2057 .result = REJECT,
2058 .errstr = "invalid access to packet",
2059 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2060 },
2061 {
2062 "helper access to packet: test16, cls helper fail range 2",
2063 .insns = {
2064 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2065 offsetof(struct __sk_buff, data)),
2066 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2067 offsetof(struct __sk_buff, data_end)),
2068 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2069 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2071 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2072 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2073 BPF_MOV64_IMM(BPF_REG_2, -9),
2074 BPF_MOV64_IMM(BPF_REG_3, 0),
2075 BPF_MOV64_IMM(BPF_REG_4, 0),
2076 BPF_MOV64_IMM(BPF_REG_5, 0),
2077 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2078 BPF_MOV64_IMM(BPF_REG_0, 0),
2079 BPF_EXIT_INSN(),
2080 },
2081 .result = REJECT,
2082 .errstr = "invalid access to packet",
2083 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2084 },
2085 {
2086 "helper access to packet: test17, cls helper fail range 3",
2087 .insns = {
2088 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2089 offsetof(struct __sk_buff, data)),
2090 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2091 offsetof(struct __sk_buff, data_end)),
2092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2093 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2094 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2095 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2096 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2097 BPF_MOV64_IMM(BPF_REG_2, ~0),
2098 BPF_MOV64_IMM(BPF_REG_3, 0),
2099 BPF_MOV64_IMM(BPF_REG_4, 0),
2100 BPF_MOV64_IMM(BPF_REG_5, 0),
2101 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2102 BPF_MOV64_IMM(BPF_REG_0, 0),
2103 BPF_EXIT_INSN(),
2104 },
2105 .result = REJECT,
2106 .errstr = "invalid access to packet",
2107 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2108 },
2109 {
2110 "helper access to packet: test18, cls helper fail range zero",
2111 .insns = {
2112 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2113 offsetof(struct __sk_buff, data)),
2114 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2115 offsetof(struct __sk_buff, data_end)),
2116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2117 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2118 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2119 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2120 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2121 BPF_MOV64_IMM(BPF_REG_2, 0),
2122 BPF_MOV64_IMM(BPF_REG_3, 0),
2123 BPF_MOV64_IMM(BPF_REG_4, 0),
2124 BPF_MOV64_IMM(BPF_REG_5, 0),
2125 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2126 BPF_MOV64_IMM(BPF_REG_0, 0),
2127 BPF_EXIT_INSN(),
2128 },
2129 .result = REJECT,
2130 .errstr = "invalid access to packet",
2131 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2132 },
2133 {
2134 "helper access to packet: test19, pkt end as input",
2135 .insns = {
2136 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2137 offsetof(struct __sk_buff, data)),
2138 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2139 offsetof(struct __sk_buff, data_end)),
2140 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2141 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2142 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2143 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2144 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2145 BPF_MOV64_IMM(BPF_REG_2, 4),
2146 BPF_MOV64_IMM(BPF_REG_3, 0),
2147 BPF_MOV64_IMM(BPF_REG_4, 0),
2148 BPF_MOV64_IMM(BPF_REG_5, 0),
2149 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2150 BPF_MOV64_IMM(BPF_REG_0, 0),
2151 BPF_EXIT_INSN(),
2152 },
2153 .result = REJECT,
2154 .errstr = "R1 type=pkt_end expected=fp",
2155 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2156 },
2157 {
2158 "helper access to packet: test20, wrong reg",
2159 .insns = {
2160 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2161 offsetof(struct __sk_buff, data)),
2162 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2163 offsetof(struct __sk_buff, data_end)),
2164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2165 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2166 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2167 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2168 BPF_MOV64_IMM(BPF_REG_2, 4),
2169 BPF_MOV64_IMM(BPF_REG_3, 0),
2170 BPF_MOV64_IMM(BPF_REG_4, 0),
2171 BPF_MOV64_IMM(BPF_REG_5, 0),
2172 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff),
2173 BPF_MOV64_IMM(BPF_REG_0, 0),
2174 BPF_EXIT_INSN(),
2175 },
2176 .result = REJECT,
2177 .errstr = "invalid access to packet",
2178 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2179 },
2180 {
2181 "valid map access into an array with a constant",
2182 .insns = {
2183 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2184 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2186 BPF_LD_MAP_FD(BPF_REG_1, 0),
2187 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2188 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2189 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2190 BPF_EXIT_INSN(),
2191 },
2192 .test_val_map_fixup = {3},
2193 .errstr_unpriv = "R0 leaks addr",
2194 .result_unpriv = REJECT,
2195 .result = ACCEPT,
2196 },
2197 {
2198 "valid map access into an array with a register",
2199 .insns = {
2200 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2201 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2203 BPF_LD_MAP_FD(BPF_REG_1, 0),
2204 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2205 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2206 BPF_MOV64_IMM(BPF_REG_1, 4),
2207 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2208 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2209 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2210 BPF_EXIT_INSN(),
2211 },
2212 .test_val_map_fixup = {3},
2213 .errstr_unpriv = "R0 leaks addr",
2214 .result_unpriv = REJECT,
2215 .result = ACCEPT,
2216 },
2217 {
2218 "valid map access into an array with a variable",
2219 .insns = {
2220 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2221 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2223 BPF_LD_MAP_FD(BPF_REG_1, 0),
2224 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2225 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2226 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2227 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2228 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2229 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2230 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2231 BPF_EXIT_INSN(),
2232 },
2233 .test_val_map_fixup = {3},
2234 .errstr_unpriv = "R0 leaks addr",
2235 .result_unpriv = REJECT,
2236 .result = ACCEPT,
2237 },
2238 {
2239 "valid map access into an array with a signed variable",
2240 .insns = {
2241 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2242 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2243 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2244 BPF_LD_MAP_FD(BPF_REG_1, 0),
2245 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2246 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2247 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2248 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2249 BPF_MOV32_IMM(BPF_REG_1, 0),
2250 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2251 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2252 BPF_MOV32_IMM(BPF_REG_1, 0),
2253 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2254 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2255 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2256 BPF_EXIT_INSN(),
2257 },
2258 .test_val_map_fixup = {3},
2259 .errstr_unpriv = "R0 leaks addr",
2260 .result_unpriv = REJECT,
2261 .result = ACCEPT,
2262 },
2263 {
2264 "invalid map access into an array with a constant",
2265 .insns = {
2266 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2267 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2268 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2269 BPF_LD_MAP_FD(BPF_REG_1, 0),
2270 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2271 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2272 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
2273 offsetof(struct test_val, foo)),
2274 BPF_EXIT_INSN(),
2275 },
2276 .test_val_map_fixup = {3},
2277 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
2278 .result = REJECT,
2279 },
2280 {
2281 "invalid map access into an array with a register",
2282 .insns = {
2283 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2284 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2285 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2286 BPF_LD_MAP_FD(BPF_REG_1, 0),
2287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2288 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2289 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
2290 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2291 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2292 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2293 BPF_EXIT_INSN(),
2294 },
2295 .test_val_map_fixup = {3},
2296 .errstr = "R0 min value is outside of the array range",
2297 .result = REJECT,
2298 },
2299 {
2300 "invalid map access into an array with a variable",
2301 .insns = {
2302 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2303 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2305 BPF_LD_MAP_FD(BPF_REG_1, 0),
2306 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2307 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2308 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2309 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2310 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2311 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2312 BPF_EXIT_INSN(),
2313 },
2314 .test_val_map_fixup = {3},
2315 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2316 .result = REJECT,
2317 },
2318 {
2319 "invalid map access into an array with no floor check",
2320 .insns = {
2321 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2322 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2324 BPF_LD_MAP_FD(BPF_REG_1, 0),
2325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2326 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2327 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2328 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2329 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2330 BPF_MOV32_IMM(BPF_REG_1, 0),
2331 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2332 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2333 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2334 BPF_EXIT_INSN(),
2335 },
2336 .test_val_map_fixup = {3},
2337 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2338 .result = REJECT,
2339 },
2340 {
2341 "invalid map access into an array with a invalid max check",
2342 .insns = {
2343 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2344 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2346 BPF_LD_MAP_FD(BPF_REG_1, 0),
2347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2348 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
2349 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2350 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
2351 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2352 BPF_MOV32_IMM(BPF_REG_1, 0),
2353 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2354 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
2355 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
2356 BPF_EXIT_INSN(),
2357 },
2358 .test_val_map_fixup = {3},
2359 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
2360 .result = REJECT,
2361 },
2362 {
2363 "invalid map access into an array with a invalid max check",
2364 .insns = {
2365 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2366 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2368 BPF_LD_MAP_FD(BPF_REG_1, 0),
2369 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2370 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
2371 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
2372 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2373 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2374 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2375 BPF_LD_MAP_FD(BPF_REG_1, 0),
2376 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2377 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
2378 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
2379 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, offsetof(struct test_val, foo)),
2380 BPF_EXIT_INSN(),
2381 },
2382 .test_val_map_fixup = {3, 11},
2383 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
2384 .result = REJECT,
2385 },
2386};
2387
2388static int probe_filter_length(struct bpf_insn *fp)
2389{
2390 int len = 0;
2391
2392 for (len = MAX_INSNS - 1; len > 0; --len)
2393 if (fp[len].code != 0 || fp[len].imm != 0)
2394 break;
2395
2396 return len + 1;
2397}
2398
2399static int create_map(size_t val_size, int num)
2400{
2401 int map_fd;
2402
2403 map_fd = bpf_create_map(BPF_MAP_TYPE_HASH,
2404 sizeof(long long), val_size, num, 0);
2405 if (map_fd < 0)
2406 printf("failed to create map '%s'\n", strerror(errno));
2407
2408 return map_fd;
2409}
2410
2411static int create_prog_array(void)
2412{
2413 int map_fd;
2414
2415 map_fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY,
2416 sizeof(int), sizeof(int), 4, 0);
2417 if (map_fd < 0)
2418 printf("failed to create prog_array '%s'\n", strerror(errno));
2419
2420 return map_fd;
2421}
2422
2423static int test(void)
2424{
2425 int prog_fd, i, pass_cnt = 0, err_cnt = 0;
2426 bool unpriv = geteuid() != 0;
2427
2428 for (i = 0; i < ARRAY_SIZE(tests); i++) {
2429 struct bpf_insn *prog = tests[i].insns;
2430 int prog_type = tests[i].prog_type;
2431 int prog_len = probe_filter_length(prog);
2432 int *fixup = tests[i].fixup;
2433 int *prog_array_fixup = tests[i].prog_array_fixup;
2434 int *test_val_map_fixup = tests[i].test_val_map_fixup;
2435 int expected_result;
2436 const char *expected_errstr;
2437 int map_fd = -1, prog_array_fd = -1, test_val_map_fd = -1;
2438
2439 if (*fixup) {
2440 map_fd = create_map(sizeof(long long), 1024);
2441
2442 do {
2443 prog[*fixup].imm = map_fd;
2444 fixup++;
2445 } while (*fixup);
2446 }
2447 if (*prog_array_fixup) {
2448 prog_array_fd = create_prog_array();
2449
2450 do {
2451 prog[*prog_array_fixup].imm = prog_array_fd;
2452 prog_array_fixup++;
2453 } while (*prog_array_fixup);
2454 }
2455 if (*test_val_map_fixup) {
2456
2457 if (unpriv)
2458 continue;
2459 test_val_map_fd = create_map(sizeof(struct test_val),
2460 256);
2461 do {
2462 prog[*test_val_map_fixup].imm = test_val_map_fd;
2463 test_val_map_fixup++;
2464 } while (*test_val_map_fixup);
2465 }
2466
2467 printf("#%d %s ", i, tests[i].descr);
2468
2469 prog_fd = bpf_prog_load(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
2470 prog, prog_len * sizeof(struct bpf_insn),
2471 "GPL", 0);
2472
2473 if (unpriv && tests[i].result_unpriv != UNDEF)
2474 expected_result = tests[i].result_unpriv;
2475 else
2476 expected_result = tests[i].result;
2477
2478 if (unpriv && tests[i].errstr_unpriv)
2479 expected_errstr = tests[i].errstr_unpriv;
2480 else
2481 expected_errstr = tests[i].errstr;
2482
2483 if (expected_result == ACCEPT) {
2484 if (prog_fd < 0) {
2485 printf("FAIL\nfailed to load prog '%s'\n",
2486 strerror(errno));
2487 printf("%s", bpf_log_buf);
2488 err_cnt++;
2489 goto fail;
2490 }
2491 } else {
2492 if (prog_fd >= 0) {
2493 printf("FAIL\nunexpected success to load\n");
2494 printf("%s", bpf_log_buf);
2495 err_cnt++;
2496 goto fail;
2497 }
2498 if (strstr(bpf_log_buf, expected_errstr) == 0) {
2499 printf("FAIL\nunexpected error message: %s",
2500 bpf_log_buf);
2501 err_cnt++;
2502 goto fail;
2503 }
2504 }
2505
2506 pass_cnt++;
2507 printf("OK\n");
2508fail:
2509 if (map_fd >= 0)
2510 close(map_fd);
2511 if (prog_array_fd >= 0)
2512 close(prog_array_fd);
2513 if (test_val_map_fd >= 0)
2514 close(test_val_map_fd);
2515 close(prog_fd);
2516
2517 }
2518 printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, err_cnt);
2519
2520 return 0;
2521}
2522
2523int main(void)
2524{
2525 struct rlimit r = {1 << 20, 1 << 20};
2526
2527 setrlimit(RLIMIT_MEMLOCK, &r);
2528 return test();
2529}
2530