]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - tools/testing/selftests/bpf/test_verifier.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[mirror_ubuntu-hirsute-kernel.git] / tools / testing / selftests / bpf / test_verifier.c
1 /*
2 * Testsuite for eBPF verifier
3 *
4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5 * Copyright (c) 2017 Facebook
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General Public
9 * License as published by the Free Software Foundation.
10 */
11
12 #include <endian.h>
13 #include <asm/types.h>
14 #include <linux/types.h>
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stddef.h>
22 #include <stdbool.h>
23 #include <sched.h>
24 #include <limits.h>
25
26 #include <sys/capability.h>
27
28 #include <linux/unistd.h>
29 #include <linux/filter.h>
30 #include <linux/bpf_perf_event.h>
31 #include <linux/bpf.h>
32 #include <linux/if_ether.h>
33
34 #include <bpf/bpf.h>
35
36 #ifdef HAVE_GENHDR
37 # include "autoconf.h"
38 #else
39 # if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
40 # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
41 # endif
42 #endif
43 #include "bpf_rlimit.h"
44 #include "bpf_rand.h"
45 #include "../../../include/linux/filter.h"
46
47 #ifndef ARRAY_SIZE
48 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
49 #endif
50
51 #define MAX_INSNS BPF_MAXINSNS
52 #define MAX_FIXUPS 8
53 #define MAX_NR_MAPS 7
54 #define POINTER_VALUE 0xcafe4all
55 #define TEST_DATA_LEN 64
56
57 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
58 #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
59
60 #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
61 static bool unpriv_disabled = false;
62
63 struct bpf_test {
64 const char *descr;
65 struct bpf_insn insns[MAX_INSNS];
66 int fixup_map1[MAX_FIXUPS];
67 int fixup_map2[MAX_FIXUPS];
68 int fixup_map3[MAX_FIXUPS];
69 int fixup_map4[MAX_FIXUPS];
70 int fixup_prog1[MAX_FIXUPS];
71 int fixup_prog2[MAX_FIXUPS];
72 int fixup_map_in_map[MAX_FIXUPS];
73 const char *errstr;
74 const char *errstr_unpriv;
75 uint32_t retval;
76 enum {
77 UNDEF,
78 ACCEPT,
79 REJECT
80 } result, result_unpriv;
81 enum bpf_prog_type prog_type;
82 uint8_t flags;
83 __u8 data[TEST_DATA_LEN];
84 void (*fill_helper)(struct bpf_test *self);
85 };
86
87 /* Note we want this to be 64 bit aligned so that the end of our array is
88 * actually the end of the structure.
89 */
90 #define MAX_ENTRIES 11
91
92 struct test_val {
93 unsigned int index;
94 int foo[MAX_ENTRIES];
95 };
96
97 struct other_val {
98 long long foo;
99 long long bar;
100 };
101
102 static void bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
103 {
104 /* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
105 #define PUSH_CNT 51
106 unsigned int len = BPF_MAXINSNS;
107 struct bpf_insn *insn = self->insns;
108 int i = 0, j, k = 0;
109
110 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
111 loop:
112 for (j = 0; j < PUSH_CNT; j++) {
113 insn[i++] = BPF_LD_ABS(BPF_B, 0);
114 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
115 i++;
116 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
117 insn[i++] = BPF_MOV64_IMM(BPF_REG_2, 1);
118 insn[i++] = BPF_MOV64_IMM(BPF_REG_3, 2);
119 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
120 BPF_FUNC_skb_vlan_push),
121 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
122 i++;
123 }
124
125 for (j = 0; j < PUSH_CNT; j++) {
126 insn[i++] = BPF_LD_ABS(BPF_B, 0);
127 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
128 i++;
129 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
130 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
131 BPF_FUNC_skb_vlan_pop),
132 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
133 i++;
134 }
135 if (++k < 5)
136 goto loop;
137
138 for (; i < len - 1; i++)
139 insn[i] = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, 0xbef);
140 insn[len - 1] = BPF_EXIT_INSN();
141 }
142
143 static void bpf_fill_jump_around_ld_abs(struct bpf_test *self)
144 {
145 struct bpf_insn *insn = self->insns;
146 unsigned int len = BPF_MAXINSNS;
147 int i = 0;
148
149 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
150 insn[i++] = BPF_LD_ABS(BPF_B, 0);
151 insn[i] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 10, len - i - 2);
152 i++;
153 while (i < len - 1)
154 insn[i++] = BPF_LD_ABS(BPF_B, 1);
155 insn[i] = BPF_EXIT_INSN();
156 }
157
158 static void bpf_fill_rand_ld_dw(struct bpf_test *self)
159 {
160 struct bpf_insn *insn = self->insns;
161 uint64_t res = 0;
162 int i = 0;
163
164 insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0);
165 while (i < self->retval) {
166 uint64_t val = bpf_semi_rand_get();
167 struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) };
168
169 res ^= val;
170 insn[i++] = tmp[0];
171 insn[i++] = tmp[1];
172 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
173 }
174 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
175 insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32);
176 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
177 insn[i] = BPF_EXIT_INSN();
178 res ^= (res >> 32);
179 self->retval = (uint32_t)res;
180 }
181
182 static struct bpf_test tests[] = {
183 {
184 "add+sub+mul",
185 .insns = {
186 BPF_MOV64_IMM(BPF_REG_1, 1),
187 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
188 BPF_MOV64_IMM(BPF_REG_2, 3),
189 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
190 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
191 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
192 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
193 BPF_EXIT_INSN(),
194 },
195 .result = ACCEPT,
196 .retval = -3,
197 },
198 {
199 "DIV32 by 0, zero check 1",
200 .insns = {
201 BPF_MOV32_IMM(BPF_REG_0, 42),
202 BPF_MOV32_IMM(BPF_REG_1, 0),
203 BPF_MOV32_IMM(BPF_REG_2, 1),
204 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
205 BPF_EXIT_INSN(),
206 },
207 .result = ACCEPT,
208 .retval = 42,
209 },
210 {
211 "DIV32 by 0, zero check 2",
212 .insns = {
213 BPF_MOV32_IMM(BPF_REG_0, 42),
214 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
215 BPF_MOV32_IMM(BPF_REG_2, 1),
216 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
217 BPF_EXIT_INSN(),
218 },
219 .result = ACCEPT,
220 .retval = 42,
221 },
222 {
223 "DIV64 by 0, zero check",
224 .insns = {
225 BPF_MOV32_IMM(BPF_REG_0, 42),
226 BPF_MOV32_IMM(BPF_REG_1, 0),
227 BPF_MOV32_IMM(BPF_REG_2, 1),
228 BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
229 BPF_EXIT_INSN(),
230 },
231 .result = ACCEPT,
232 .retval = 42,
233 },
234 {
235 "MOD32 by 0, zero check 1",
236 .insns = {
237 BPF_MOV32_IMM(BPF_REG_0, 42),
238 BPF_MOV32_IMM(BPF_REG_1, 0),
239 BPF_MOV32_IMM(BPF_REG_2, 1),
240 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
241 BPF_EXIT_INSN(),
242 },
243 .result = ACCEPT,
244 .retval = 42,
245 },
246 {
247 "MOD32 by 0, zero check 2",
248 .insns = {
249 BPF_MOV32_IMM(BPF_REG_0, 42),
250 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
251 BPF_MOV32_IMM(BPF_REG_2, 1),
252 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
253 BPF_EXIT_INSN(),
254 },
255 .result = ACCEPT,
256 .retval = 42,
257 },
258 {
259 "MOD64 by 0, zero check",
260 .insns = {
261 BPF_MOV32_IMM(BPF_REG_0, 42),
262 BPF_MOV32_IMM(BPF_REG_1, 0),
263 BPF_MOV32_IMM(BPF_REG_2, 1),
264 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
265 BPF_EXIT_INSN(),
266 },
267 .result = ACCEPT,
268 .retval = 42,
269 },
270 {
271 "DIV32 by 0, zero check ok, cls",
272 .insns = {
273 BPF_MOV32_IMM(BPF_REG_0, 42),
274 BPF_MOV32_IMM(BPF_REG_1, 2),
275 BPF_MOV32_IMM(BPF_REG_2, 16),
276 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
277 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
278 BPF_EXIT_INSN(),
279 },
280 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
281 .result = ACCEPT,
282 .retval = 8,
283 },
284 {
285 "DIV32 by 0, zero check 1, cls",
286 .insns = {
287 BPF_MOV32_IMM(BPF_REG_1, 0),
288 BPF_MOV32_IMM(BPF_REG_0, 1),
289 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
290 BPF_EXIT_INSN(),
291 },
292 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
293 .result = ACCEPT,
294 .retval = 0,
295 },
296 {
297 "DIV32 by 0, zero check 2, cls",
298 .insns = {
299 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
300 BPF_MOV32_IMM(BPF_REG_0, 1),
301 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
302 BPF_EXIT_INSN(),
303 },
304 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
305 .result = ACCEPT,
306 .retval = 0,
307 },
308 {
309 "DIV64 by 0, zero check, cls",
310 .insns = {
311 BPF_MOV32_IMM(BPF_REG_1, 0),
312 BPF_MOV32_IMM(BPF_REG_0, 1),
313 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
314 BPF_EXIT_INSN(),
315 },
316 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
317 .result = ACCEPT,
318 .retval = 0,
319 },
320 {
321 "MOD32 by 0, zero check ok, cls",
322 .insns = {
323 BPF_MOV32_IMM(BPF_REG_0, 42),
324 BPF_MOV32_IMM(BPF_REG_1, 3),
325 BPF_MOV32_IMM(BPF_REG_2, 5),
326 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
327 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
328 BPF_EXIT_INSN(),
329 },
330 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
331 .result = ACCEPT,
332 .retval = 2,
333 },
334 {
335 "MOD32 by 0, zero check 1, cls",
336 .insns = {
337 BPF_MOV32_IMM(BPF_REG_1, 0),
338 BPF_MOV32_IMM(BPF_REG_0, 1),
339 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
340 BPF_EXIT_INSN(),
341 },
342 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
343 .result = ACCEPT,
344 .retval = 1,
345 },
346 {
347 "MOD32 by 0, zero check 2, cls",
348 .insns = {
349 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
350 BPF_MOV32_IMM(BPF_REG_0, 1),
351 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
352 BPF_EXIT_INSN(),
353 },
354 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
355 .result = ACCEPT,
356 .retval = 1,
357 },
358 {
359 "MOD64 by 0, zero check 1, cls",
360 .insns = {
361 BPF_MOV32_IMM(BPF_REG_1, 0),
362 BPF_MOV32_IMM(BPF_REG_0, 2),
363 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
364 BPF_EXIT_INSN(),
365 },
366 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
367 .result = ACCEPT,
368 .retval = 2,
369 },
370 {
371 "MOD64 by 0, zero check 2, cls",
372 .insns = {
373 BPF_MOV32_IMM(BPF_REG_1, 0),
374 BPF_MOV32_IMM(BPF_REG_0, -1),
375 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
376 BPF_EXIT_INSN(),
377 },
378 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
379 .result = ACCEPT,
380 .retval = -1,
381 },
382 /* Just make sure that JITs used udiv/umod as otherwise we get
383 * an exception from INT_MIN/-1 overflow similarly as with div
384 * by zero.
385 */
386 {
387 "DIV32 overflow, check 1",
388 .insns = {
389 BPF_MOV32_IMM(BPF_REG_1, -1),
390 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
391 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
392 BPF_EXIT_INSN(),
393 },
394 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
395 .result = ACCEPT,
396 .retval = 0,
397 },
398 {
399 "DIV32 overflow, check 2",
400 .insns = {
401 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
402 BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
403 BPF_EXIT_INSN(),
404 },
405 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
406 .result = ACCEPT,
407 .retval = 0,
408 },
409 {
410 "DIV64 overflow, check 1",
411 .insns = {
412 BPF_MOV64_IMM(BPF_REG_1, -1),
413 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
414 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
415 BPF_EXIT_INSN(),
416 },
417 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
418 .result = ACCEPT,
419 .retval = 0,
420 },
421 {
422 "DIV64 overflow, check 2",
423 .insns = {
424 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
425 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
426 BPF_EXIT_INSN(),
427 },
428 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
429 .result = ACCEPT,
430 .retval = 0,
431 },
432 {
433 "MOD32 overflow, check 1",
434 .insns = {
435 BPF_MOV32_IMM(BPF_REG_1, -1),
436 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
437 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
438 BPF_EXIT_INSN(),
439 },
440 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
441 .result = ACCEPT,
442 .retval = INT_MIN,
443 },
444 {
445 "MOD32 overflow, check 2",
446 .insns = {
447 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
448 BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
449 BPF_EXIT_INSN(),
450 },
451 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
452 .result = ACCEPT,
453 .retval = INT_MIN,
454 },
455 {
456 "MOD64 overflow, check 1",
457 .insns = {
458 BPF_MOV64_IMM(BPF_REG_1, -1),
459 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
460 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
461 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
462 BPF_MOV32_IMM(BPF_REG_0, 0),
463 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
464 BPF_MOV32_IMM(BPF_REG_0, 1),
465 BPF_EXIT_INSN(),
466 },
467 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
468 .result = ACCEPT,
469 .retval = 1,
470 },
471 {
472 "MOD64 overflow, check 2",
473 .insns = {
474 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
475 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
476 BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
477 BPF_MOV32_IMM(BPF_REG_0, 0),
478 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
479 BPF_MOV32_IMM(BPF_REG_0, 1),
480 BPF_EXIT_INSN(),
481 },
482 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
483 .result = ACCEPT,
484 .retval = 1,
485 },
486 {
487 "xor32 zero extend check",
488 .insns = {
489 BPF_MOV32_IMM(BPF_REG_2, -1),
490 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
491 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
492 BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
493 BPF_MOV32_IMM(BPF_REG_0, 2),
494 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
495 BPF_MOV32_IMM(BPF_REG_0, 1),
496 BPF_EXIT_INSN(),
497 },
498 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
499 .result = ACCEPT,
500 .retval = 1,
501 },
502 {
503 "empty prog",
504 .insns = {
505 },
506 .errstr = "unknown opcode 00",
507 .result = REJECT,
508 },
509 {
510 "only exit insn",
511 .insns = {
512 BPF_EXIT_INSN(),
513 },
514 .errstr = "R0 !read_ok",
515 .result = REJECT,
516 },
517 {
518 "unreachable",
519 .insns = {
520 BPF_EXIT_INSN(),
521 BPF_EXIT_INSN(),
522 },
523 .errstr = "unreachable",
524 .result = REJECT,
525 },
526 {
527 "unreachable2",
528 .insns = {
529 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
530 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
531 BPF_EXIT_INSN(),
532 },
533 .errstr = "unreachable",
534 .result = REJECT,
535 },
536 {
537 "out of range jump",
538 .insns = {
539 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
540 BPF_EXIT_INSN(),
541 },
542 .errstr = "jump out of range",
543 .result = REJECT,
544 },
545 {
546 "out of range jump2",
547 .insns = {
548 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
549 BPF_EXIT_INSN(),
550 },
551 .errstr = "jump out of range",
552 .result = REJECT,
553 },
554 {
555 "test1 ld_imm64",
556 .insns = {
557 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
558 BPF_LD_IMM64(BPF_REG_0, 0),
559 BPF_LD_IMM64(BPF_REG_0, 0),
560 BPF_LD_IMM64(BPF_REG_0, 1),
561 BPF_LD_IMM64(BPF_REG_0, 1),
562 BPF_MOV64_IMM(BPF_REG_0, 2),
563 BPF_EXIT_INSN(),
564 },
565 .errstr = "invalid BPF_LD_IMM insn",
566 .errstr_unpriv = "R1 pointer comparison",
567 .result = REJECT,
568 },
569 {
570 "test2 ld_imm64",
571 .insns = {
572 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
573 BPF_LD_IMM64(BPF_REG_0, 0),
574 BPF_LD_IMM64(BPF_REG_0, 0),
575 BPF_LD_IMM64(BPF_REG_0, 1),
576 BPF_LD_IMM64(BPF_REG_0, 1),
577 BPF_EXIT_INSN(),
578 },
579 .errstr = "invalid BPF_LD_IMM insn",
580 .errstr_unpriv = "R1 pointer comparison",
581 .result = REJECT,
582 },
583 {
584 "test3 ld_imm64",
585 .insns = {
586 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
587 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
588 BPF_LD_IMM64(BPF_REG_0, 0),
589 BPF_LD_IMM64(BPF_REG_0, 0),
590 BPF_LD_IMM64(BPF_REG_0, 1),
591 BPF_LD_IMM64(BPF_REG_0, 1),
592 BPF_EXIT_INSN(),
593 },
594 .errstr = "invalid bpf_ld_imm64 insn",
595 .result = REJECT,
596 },
597 {
598 "test4 ld_imm64",
599 .insns = {
600 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
601 BPF_EXIT_INSN(),
602 },
603 .errstr = "invalid bpf_ld_imm64 insn",
604 .result = REJECT,
605 },
606 {
607 "test5 ld_imm64",
608 .insns = {
609 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
610 },
611 .errstr = "invalid bpf_ld_imm64 insn",
612 .result = REJECT,
613 },
614 {
615 "test6 ld_imm64",
616 .insns = {
617 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
618 BPF_RAW_INSN(0, 0, 0, 0, 0),
619 BPF_EXIT_INSN(),
620 },
621 .result = ACCEPT,
622 },
623 {
624 "test7 ld_imm64",
625 .insns = {
626 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
627 BPF_RAW_INSN(0, 0, 0, 0, 1),
628 BPF_EXIT_INSN(),
629 },
630 .result = ACCEPT,
631 .retval = 1,
632 },
633 {
634 "test8 ld_imm64",
635 .insns = {
636 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
637 BPF_RAW_INSN(0, 0, 0, 0, 1),
638 BPF_EXIT_INSN(),
639 },
640 .errstr = "uses reserved fields",
641 .result = REJECT,
642 },
643 {
644 "test9 ld_imm64",
645 .insns = {
646 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
647 BPF_RAW_INSN(0, 0, 0, 1, 1),
648 BPF_EXIT_INSN(),
649 },
650 .errstr = "invalid bpf_ld_imm64 insn",
651 .result = REJECT,
652 },
653 {
654 "test10 ld_imm64",
655 .insns = {
656 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
657 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
658 BPF_EXIT_INSN(),
659 },
660 .errstr = "invalid bpf_ld_imm64 insn",
661 .result = REJECT,
662 },
663 {
664 "test11 ld_imm64",
665 .insns = {
666 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
667 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
668 BPF_EXIT_INSN(),
669 },
670 .errstr = "invalid bpf_ld_imm64 insn",
671 .result = REJECT,
672 },
673 {
674 "test12 ld_imm64",
675 .insns = {
676 BPF_MOV64_IMM(BPF_REG_1, 0),
677 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
678 BPF_RAW_INSN(0, 0, 0, 0, 1),
679 BPF_EXIT_INSN(),
680 },
681 .errstr = "not pointing to valid bpf_map",
682 .result = REJECT,
683 },
684 {
685 "test13 ld_imm64",
686 .insns = {
687 BPF_MOV64_IMM(BPF_REG_1, 0),
688 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
689 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
690 BPF_EXIT_INSN(),
691 },
692 .errstr = "invalid bpf_ld_imm64 insn",
693 .result = REJECT,
694 },
695 {
696 "arsh32 on imm",
697 .insns = {
698 BPF_MOV64_IMM(BPF_REG_0, 1),
699 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
700 BPF_EXIT_INSN(),
701 },
702 .result = REJECT,
703 .errstr = "unknown opcode c4",
704 },
705 {
706 "arsh32 on reg",
707 .insns = {
708 BPF_MOV64_IMM(BPF_REG_0, 1),
709 BPF_MOV64_IMM(BPF_REG_1, 5),
710 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
711 BPF_EXIT_INSN(),
712 },
713 .result = REJECT,
714 .errstr = "unknown opcode cc",
715 },
716 {
717 "arsh64 on imm",
718 .insns = {
719 BPF_MOV64_IMM(BPF_REG_0, 1),
720 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
721 BPF_EXIT_INSN(),
722 },
723 .result = ACCEPT,
724 },
725 {
726 "arsh64 on reg",
727 .insns = {
728 BPF_MOV64_IMM(BPF_REG_0, 1),
729 BPF_MOV64_IMM(BPF_REG_1, 5),
730 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
731 BPF_EXIT_INSN(),
732 },
733 .result = ACCEPT,
734 },
735 {
736 "no bpf_exit",
737 .insns = {
738 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
739 },
740 .errstr = "not an exit",
741 .result = REJECT,
742 },
743 {
744 "loop (back-edge)",
745 .insns = {
746 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
747 BPF_EXIT_INSN(),
748 },
749 .errstr = "back-edge",
750 .result = REJECT,
751 },
752 {
753 "loop2 (back-edge)",
754 .insns = {
755 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
756 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
757 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
758 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
759 BPF_EXIT_INSN(),
760 },
761 .errstr = "back-edge",
762 .result = REJECT,
763 },
764 {
765 "conditional loop",
766 .insns = {
767 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
768 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
769 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
770 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
771 BPF_EXIT_INSN(),
772 },
773 .errstr = "back-edge",
774 .result = REJECT,
775 },
776 {
777 "read uninitialized register",
778 .insns = {
779 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
780 BPF_EXIT_INSN(),
781 },
782 .errstr = "R2 !read_ok",
783 .result = REJECT,
784 },
785 {
786 "read invalid register",
787 .insns = {
788 BPF_MOV64_REG(BPF_REG_0, -1),
789 BPF_EXIT_INSN(),
790 },
791 .errstr = "R15 is invalid",
792 .result = REJECT,
793 },
794 {
795 "program doesn't init R0 before exit",
796 .insns = {
797 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
798 BPF_EXIT_INSN(),
799 },
800 .errstr = "R0 !read_ok",
801 .result = REJECT,
802 },
803 {
804 "program doesn't init R0 before exit in all branches",
805 .insns = {
806 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
807 BPF_MOV64_IMM(BPF_REG_0, 1),
808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
809 BPF_EXIT_INSN(),
810 },
811 .errstr = "R0 !read_ok",
812 .errstr_unpriv = "R1 pointer comparison",
813 .result = REJECT,
814 },
815 {
816 "stack out of bounds",
817 .insns = {
818 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
819 BPF_EXIT_INSN(),
820 },
821 .errstr = "invalid stack",
822 .result = REJECT,
823 },
824 {
825 "invalid call insn1",
826 .insns = {
827 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
828 BPF_EXIT_INSN(),
829 },
830 .errstr = "unknown opcode 8d",
831 .result = REJECT,
832 },
833 {
834 "invalid call insn2",
835 .insns = {
836 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
837 BPF_EXIT_INSN(),
838 },
839 .errstr = "BPF_CALL uses reserved",
840 .result = REJECT,
841 },
842 {
843 "invalid function call",
844 .insns = {
845 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
846 BPF_EXIT_INSN(),
847 },
848 .errstr = "invalid func unknown#1234567",
849 .result = REJECT,
850 },
851 {
852 "uninitialized stack1",
853 .insns = {
854 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
855 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
856 BPF_LD_MAP_FD(BPF_REG_1, 0),
857 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
858 BPF_FUNC_map_lookup_elem),
859 BPF_EXIT_INSN(),
860 },
861 .fixup_map1 = { 2 },
862 .errstr = "invalid indirect read from stack",
863 .result = REJECT,
864 },
865 {
866 "uninitialized stack2",
867 .insns = {
868 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
869 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
870 BPF_EXIT_INSN(),
871 },
872 .errstr = "invalid read from stack",
873 .result = REJECT,
874 },
875 {
876 "invalid fp arithmetic",
877 /* If this gets ever changed, make sure JITs can deal with it. */
878 .insns = {
879 BPF_MOV64_IMM(BPF_REG_0, 0),
880 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
881 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
882 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
883 BPF_EXIT_INSN(),
884 },
885 .errstr = "R1 subtraction from stack pointer",
886 .result = REJECT,
887 },
888 {
889 "non-invalid fp arithmetic",
890 .insns = {
891 BPF_MOV64_IMM(BPF_REG_0, 0),
892 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
893 BPF_EXIT_INSN(),
894 },
895 .result = ACCEPT,
896 },
897 {
898 "invalid argument register",
899 .insns = {
900 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
901 BPF_FUNC_get_cgroup_classid),
902 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
903 BPF_FUNC_get_cgroup_classid),
904 BPF_EXIT_INSN(),
905 },
906 .errstr = "R1 !read_ok",
907 .result = REJECT,
908 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
909 },
910 {
911 "non-invalid argument register",
912 .insns = {
913 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
914 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
915 BPF_FUNC_get_cgroup_classid),
916 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
917 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
918 BPF_FUNC_get_cgroup_classid),
919 BPF_EXIT_INSN(),
920 },
921 .result = ACCEPT,
922 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
923 },
924 {
925 "check valid spill/fill",
926 .insns = {
927 /* spill R1(ctx) into stack */
928 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
929 /* fill it back into R2 */
930 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
931 /* should be able to access R0 = *(R2 + 8) */
932 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
933 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
934 BPF_EXIT_INSN(),
935 },
936 .errstr_unpriv = "R0 leaks addr",
937 .result = ACCEPT,
938 .result_unpriv = REJECT,
939 .retval = POINTER_VALUE,
940 },
941 {
942 "check valid spill/fill, skb mark",
943 .insns = {
944 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
945 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
946 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
947 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
948 offsetof(struct __sk_buff, mark)),
949 BPF_EXIT_INSN(),
950 },
951 .result = ACCEPT,
952 .result_unpriv = ACCEPT,
953 },
954 {
955 "check corrupted spill/fill",
956 .insns = {
957 /* spill R1(ctx) into stack */
958 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
959 /* mess up with R1 pointer on stack */
960 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
961 /* fill back into R0 should fail */
962 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
963 BPF_EXIT_INSN(),
964 },
965 .errstr_unpriv = "attempt to corrupt spilled",
966 .errstr = "corrupted spill",
967 .result = REJECT,
968 },
969 {
970 "invalid src register in STX",
971 .insns = {
972 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
973 BPF_EXIT_INSN(),
974 },
975 .errstr = "R15 is invalid",
976 .result = REJECT,
977 },
978 {
979 "invalid dst register in STX",
980 .insns = {
981 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
982 BPF_EXIT_INSN(),
983 },
984 .errstr = "R14 is invalid",
985 .result = REJECT,
986 },
987 {
988 "invalid dst register in ST",
989 .insns = {
990 BPF_ST_MEM(BPF_B, 14, -1, -1),
991 BPF_EXIT_INSN(),
992 },
993 .errstr = "R14 is invalid",
994 .result = REJECT,
995 },
996 {
997 "invalid src register in LDX",
998 .insns = {
999 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
1000 BPF_EXIT_INSN(),
1001 },
1002 .errstr = "R12 is invalid",
1003 .result = REJECT,
1004 },
1005 {
1006 "invalid dst register in LDX",
1007 .insns = {
1008 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
1009 BPF_EXIT_INSN(),
1010 },
1011 .errstr = "R11 is invalid",
1012 .result = REJECT,
1013 },
1014 {
1015 "junk insn",
1016 .insns = {
1017 BPF_RAW_INSN(0, 0, 0, 0, 0),
1018 BPF_EXIT_INSN(),
1019 },
1020 .errstr = "unknown opcode 00",
1021 .result = REJECT,
1022 },
1023 {
1024 "junk insn2",
1025 .insns = {
1026 BPF_RAW_INSN(1, 0, 0, 0, 0),
1027 BPF_EXIT_INSN(),
1028 },
1029 .errstr = "BPF_LDX uses reserved fields",
1030 .result = REJECT,
1031 },
1032 {
1033 "junk insn3",
1034 .insns = {
1035 BPF_RAW_INSN(-1, 0, 0, 0, 0),
1036 BPF_EXIT_INSN(),
1037 },
1038 .errstr = "unknown opcode ff",
1039 .result = REJECT,
1040 },
1041 {
1042 "junk insn4",
1043 .insns = {
1044 BPF_RAW_INSN(-1, -1, -1, -1, -1),
1045 BPF_EXIT_INSN(),
1046 },
1047 .errstr = "unknown opcode ff",
1048 .result = REJECT,
1049 },
1050 {
1051 "junk insn5",
1052 .insns = {
1053 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
1054 BPF_EXIT_INSN(),
1055 },
1056 .errstr = "BPF_ALU uses reserved fields",
1057 .result = REJECT,
1058 },
1059 {
1060 "misaligned read from stack",
1061 .insns = {
1062 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1063 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
1064 BPF_EXIT_INSN(),
1065 },
1066 .errstr = "misaligned stack access",
1067 .result = REJECT,
1068 },
1069 {
1070 "invalid map_fd for function call",
1071 .insns = {
1072 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1073 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
1074 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1075 BPF_LD_MAP_FD(BPF_REG_1, 0),
1076 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1077 BPF_FUNC_map_delete_elem),
1078 BPF_EXIT_INSN(),
1079 },
1080 .errstr = "fd 0 is not pointing to valid bpf_map",
1081 .result = REJECT,
1082 },
1083 {
1084 "don't check return value before access",
1085 .insns = {
1086 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1087 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1088 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1089 BPF_LD_MAP_FD(BPF_REG_1, 0),
1090 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1091 BPF_FUNC_map_lookup_elem),
1092 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1093 BPF_EXIT_INSN(),
1094 },
1095 .fixup_map1 = { 3 },
1096 .errstr = "R0 invalid mem access 'map_value_or_null'",
1097 .result = REJECT,
1098 },
1099 {
1100 "access memory with incorrect alignment",
1101 .insns = {
1102 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1105 BPF_LD_MAP_FD(BPF_REG_1, 0),
1106 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1107 BPF_FUNC_map_lookup_elem),
1108 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1109 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
1110 BPF_EXIT_INSN(),
1111 },
1112 .fixup_map1 = { 3 },
1113 .errstr = "misaligned value access",
1114 .result = REJECT,
1115 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1116 },
1117 {
1118 "sometimes access memory with incorrect alignment",
1119 .insns = {
1120 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1121 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1123 BPF_LD_MAP_FD(BPF_REG_1, 0),
1124 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1125 BPF_FUNC_map_lookup_elem),
1126 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1127 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1128 BPF_EXIT_INSN(),
1129 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
1130 BPF_EXIT_INSN(),
1131 },
1132 .fixup_map1 = { 3 },
1133 .errstr = "R0 invalid mem access",
1134 .errstr_unpriv = "R0 leaks addr",
1135 .result = REJECT,
1136 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1137 },
1138 {
1139 "jump test 1",
1140 .insns = {
1141 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1142 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
1143 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1144 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1145 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
1146 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
1147 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
1148 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
1149 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
1150 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
1151 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
1152 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
1153 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1154 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
1155 BPF_MOV64_IMM(BPF_REG_0, 0),
1156 BPF_EXIT_INSN(),
1157 },
1158 .errstr_unpriv = "R1 pointer comparison",
1159 .result_unpriv = REJECT,
1160 .result = ACCEPT,
1161 },
1162 {
1163 "jump test 2",
1164 .insns = {
1165 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1166 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
1167 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1168 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
1169 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
1170 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1171 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1172 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
1173 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1174 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
1175 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
1176 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1177 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
1178 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
1179 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1180 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1181 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1182 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1183 BPF_MOV64_IMM(BPF_REG_0, 0),
1184 BPF_EXIT_INSN(),
1185 },
1186 .errstr_unpriv = "R1 pointer comparison",
1187 .result_unpriv = REJECT,
1188 .result = ACCEPT,
1189 },
1190 {
1191 "jump test 3",
1192 .insns = {
1193 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1194 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1195 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1196 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1197 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
1198 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
1199 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1200 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1201 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
1202 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
1203 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
1205 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1206 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
1207 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
1209 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
1210 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
1211 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
1213 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1214 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
1215 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1216 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
1217 BPF_LD_MAP_FD(BPF_REG_1, 0),
1218 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1219 BPF_FUNC_map_delete_elem),
1220 BPF_EXIT_INSN(),
1221 },
1222 .fixup_map1 = { 24 },
1223 .errstr_unpriv = "R1 pointer comparison",
1224 .result_unpriv = REJECT,
1225 .result = ACCEPT,
1226 .retval = -ENOENT,
1227 },
1228 {
1229 "jump test 4",
1230 .insns = {
1231 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1232 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1233 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1234 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1235 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1236 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1237 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1238 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1239 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1240 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1244 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1245 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1246 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1247 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1248 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1251 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1252 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1253 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1254 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1255 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1257 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1260 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1261 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1262 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1264 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1265 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1266 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1268 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1269 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1270 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1271 BPF_MOV64_IMM(BPF_REG_0, 0),
1272 BPF_EXIT_INSN(),
1273 },
1274 .errstr_unpriv = "R1 pointer comparison",
1275 .result_unpriv = REJECT,
1276 .result = ACCEPT,
1277 },
1278 {
1279 "jump test 5",
1280 .insns = {
1281 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1282 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1283 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1284 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1285 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1286 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1287 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1288 BPF_MOV64_IMM(BPF_REG_0, 0),
1289 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1290 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1291 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1292 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1293 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1294 BPF_MOV64_IMM(BPF_REG_0, 0),
1295 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1296 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1297 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1298 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1299 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1300 BPF_MOV64_IMM(BPF_REG_0, 0),
1301 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1302 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1303 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1304 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1305 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1306 BPF_MOV64_IMM(BPF_REG_0, 0),
1307 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1308 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1309 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1310 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1311 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1312 BPF_MOV64_IMM(BPF_REG_0, 0),
1313 BPF_EXIT_INSN(),
1314 },
1315 .errstr_unpriv = "R1 pointer comparison",
1316 .result_unpriv = REJECT,
1317 .result = ACCEPT,
1318 },
1319 {
1320 "access skb fields ok",
1321 .insns = {
1322 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1323 offsetof(struct __sk_buff, len)),
1324 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1325 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1326 offsetof(struct __sk_buff, mark)),
1327 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1328 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1329 offsetof(struct __sk_buff, pkt_type)),
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, queue_mapping)),
1333 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1334 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1335 offsetof(struct __sk_buff, protocol)),
1336 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1337 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1338 offsetof(struct __sk_buff, vlan_present)),
1339 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1340 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1341 offsetof(struct __sk_buff, vlan_tci)),
1342 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1343 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1344 offsetof(struct __sk_buff, napi_id)),
1345 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1346 BPF_EXIT_INSN(),
1347 },
1348 .result = ACCEPT,
1349 },
1350 {
1351 "access skb fields bad1",
1352 .insns = {
1353 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
1354 BPF_EXIT_INSN(),
1355 },
1356 .errstr = "invalid bpf_context access",
1357 .result = REJECT,
1358 },
1359 {
1360 "access skb fields bad2",
1361 .insns = {
1362 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
1363 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1364 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1366 BPF_LD_MAP_FD(BPF_REG_1, 0),
1367 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1368 BPF_FUNC_map_lookup_elem),
1369 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1370 BPF_EXIT_INSN(),
1371 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1372 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1373 offsetof(struct __sk_buff, pkt_type)),
1374 BPF_EXIT_INSN(),
1375 },
1376 .fixup_map1 = { 4 },
1377 .errstr = "different pointers",
1378 .errstr_unpriv = "R1 pointer comparison",
1379 .result = REJECT,
1380 },
1381 {
1382 "access skb fields bad3",
1383 .insns = {
1384 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1385 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1386 offsetof(struct __sk_buff, pkt_type)),
1387 BPF_EXIT_INSN(),
1388 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1389 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1391 BPF_LD_MAP_FD(BPF_REG_1, 0),
1392 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1393 BPF_FUNC_map_lookup_elem),
1394 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1395 BPF_EXIT_INSN(),
1396 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1397 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
1398 },
1399 .fixup_map1 = { 6 },
1400 .errstr = "different pointers",
1401 .errstr_unpriv = "R1 pointer comparison",
1402 .result = REJECT,
1403 },
1404 {
1405 "access skb fields bad4",
1406 .insns = {
1407 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
1408 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1409 offsetof(struct __sk_buff, len)),
1410 BPF_MOV64_IMM(BPF_REG_0, 0),
1411 BPF_EXIT_INSN(),
1412 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1413 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1414 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1415 BPF_LD_MAP_FD(BPF_REG_1, 0),
1416 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1417 BPF_FUNC_map_lookup_elem),
1418 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1419 BPF_EXIT_INSN(),
1420 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1421 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1422 },
1423 .fixup_map1 = { 7 },
1424 .errstr = "different pointers",
1425 .errstr_unpriv = "R1 pointer comparison",
1426 .result = REJECT,
1427 },
1428 {
1429 "invalid access __sk_buff family",
1430 .insns = {
1431 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1432 offsetof(struct __sk_buff, family)),
1433 BPF_EXIT_INSN(),
1434 },
1435 .errstr = "invalid bpf_context access",
1436 .result = REJECT,
1437 },
1438 {
1439 "invalid access __sk_buff remote_ip4",
1440 .insns = {
1441 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1442 offsetof(struct __sk_buff, remote_ip4)),
1443 BPF_EXIT_INSN(),
1444 },
1445 .errstr = "invalid bpf_context access",
1446 .result = REJECT,
1447 },
1448 {
1449 "invalid access __sk_buff local_ip4",
1450 .insns = {
1451 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1452 offsetof(struct __sk_buff, local_ip4)),
1453 BPF_EXIT_INSN(),
1454 },
1455 .errstr = "invalid bpf_context access",
1456 .result = REJECT,
1457 },
1458 {
1459 "invalid access __sk_buff remote_ip6",
1460 .insns = {
1461 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1462 offsetof(struct __sk_buff, remote_ip6)),
1463 BPF_EXIT_INSN(),
1464 },
1465 .errstr = "invalid bpf_context access",
1466 .result = REJECT,
1467 },
1468 {
1469 "invalid access __sk_buff local_ip6",
1470 .insns = {
1471 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1472 offsetof(struct __sk_buff, local_ip6)),
1473 BPF_EXIT_INSN(),
1474 },
1475 .errstr = "invalid bpf_context access",
1476 .result = REJECT,
1477 },
1478 {
1479 "invalid access __sk_buff remote_port",
1480 .insns = {
1481 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1482 offsetof(struct __sk_buff, remote_port)),
1483 BPF_EXIT_INSN(),
1484 },
1485 .errstr = "invalid bpf_context access",
1486 .result = REJECT,
1487 },
1488 {
1489 "invalid access __sk_buff remote_port",
1490 .insns = {
1491 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1492 offsetof(struct __sk_buff, local_port)),
1493 BPF_EXIT_INSN(),
1494 },
1495 .errstr = "invalid bpf_context access",
1496 .result = REJECT,
1497 },
1498 {
1499 "valid access __sk_buff family",
1500 .insns = {
1501 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1502 offsetof(struct __sk_buff, family)),
1503 BPF_EXIT_INSN(),
1504 },
1505 .result = ACCEPT,
1506 .prog_type = BPF_PROG_TYPE_SK_SKB,
1507 },
1508 {
1509 "valid access __sk_buff remote_ip4",
1510 .insns = {
1511 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1512 offsetof(struct __sk_buff, remote_ip4)),
1513 BPF_EXIT_INSN(),
1514 },
1515 .result = ACCEPT,
1516 .prog_type = BPF_PROG_TYPE_SK_SKB,
1517 },
1518 {
1519 "valid access __sk_buff local_ip4",
1520 .insns = {
1521 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1522 offsetof(struct __sk_buff, local_ip4)),
1523 BPF_EXIT_INSN(),
1524 },
1525 .result = ACCEPT,
1526 .prog_type = BPF_PROG_TYPE_SK_SKB,
1527 },
1528 {
1529 "valid access __sk_buff remote_ip6",
1530 .insns = {
1531 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1532 offsetof(struct __sk_buff, remote_ip6[0])),
1533 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1534 offsetof(struct __sk_buff, remote_ip6[1])),
1535 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1536 offsetof(struct __sk_buff, remote_ip6[2])),
1537 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1538 offsetof(struct __sk_buff, remote_ip6[3])),
1539 BPF_EXIT_INSN(),
1540 },
1541 .result = ACCEPT,
1542 .prog_type = BPF_PROG_TYPE_SK_SKB,
1543 },
1544 {
1545 "valid access __sk_buff local_ip6",
1546 .insns = {
1547 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1548 offsetof(struct __sk_buff, local_ip6[0])),
1549 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1550 offsetof(struct __sk_buff, local_ip6[1])),
1551 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1552 offsetof(struct __sk_buff, local_ip6[2])),
1553 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1554 offsetof(struct __sk_buff, local_ip6[3])),
1555 BPF_EXIT_INSN(),
1556 },
1557 .result = ACCEPT,
1558 .prog_type = BPF_PROG_TYPE_SK_SKB,
1559 },
1560 {
1561 "valid access __sk_buff remote_port",
1562 .insns = {
1563 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1564 offsetof(struct __sk_buff, remote_port)),
1565 BPF_EXIT_INSN(),
1566 },
1567 .result = ACCEPT,
1568 .prog_type = BPF_PROG_TYPE_SK_SKB,
1569 },
1570 {
1571 "valid access __sk_buff remote_port",
1572 .insns = {
1573 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1574 offsetof(struct __sk_buff, local_port)),
1575 BPF_EXIT_INSN(),
1576 },
1577 .result = ACCEPT,
1578 .prog_type = BPF_PROG_TYPE_SK_SKB,
1579 },
1580 {
1581 "invalid access of tc_classid for SK_SKB",
1582 .insns = {
1583 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1584 offsetof(struct __sk_buff, tc_classid)),
1585 BPF_EXIT_INSN(),
1586 },
1587 .result = REJECT,
1588 .prog_type = BPF_PROG_TYPE_SK_SKB,
1589 .errstr = "invalid bpf_context access",
1590 },
1591 {
1592 "invalid access of skb->mark for SK_SKB",
1593 .insns = {
1594 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1595 offsetof(struct __sk_buff, mark)),
1596 BPF_EXIT_INSN(),
1597 },
1598 .result = REJECT,
1599 .prog_type = BPF_PROG_TYPE_SK_SKB,
1600 .errstr = "invalid bpf_context access",
1601 },
1602 {
1603 "check skb->mark is not writeable by SK_SKB",
1604 .insns = {
1605 BPF_MOV64_IMM(BPF_REG_0, 0),
1606 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1607 offsetof(struct __sk_buff, mark)),
1608 BPF_EXIT_INSN(),
1609 },
1610 .result = REJECT,
1611 .prog_type = BPF_PROG_TYPE_SK_SKB,
1612 .errstr = "invalid bpf_context access",
1613 },
1614 {
1615 "check skb->tc_index is writeable by SK_SKB",
1616 .insns = {
1617 BPF_MOV64_IMM(BPF_REG_0, 0),
1618 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1619 offsetof(struct __sk_buff, tc_index)),
1620 BPF_EXIT_INSN(),
1621 },
1622 .result = ACCEPT,
1623 .prog_type = BPF_PROG_TYPE_SK_SKB,
1624 },
1625 {
1626 "check skb->priority is writeable by SK_SKB",
1627 .insns = {
1628 BPF_MOV64_IMM(BPF_REG_0, 0),
1629 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1630 offsetof(struct __sk_buff, priority)),
1631 BPF_EXIT_INSN(),
1632 },
1633 .result = ACCEPT,
1634 .prog_type = BPF_PROG_TYPE_SK_SKB,
1635 },
1636 {
1637 "direct packet read for SK_SKB",
1638 .insns = {
1639 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1640 offsetof(struct __sk_buff, data)),
1641 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1642 offsetof(struct __sk_buff, data_end)),
1643 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1645 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1646 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1647 BPF_MOV64_IMM(BPF_REG_0, 0),
1648 BPF_EXIT_INSN(),
1649 },
1650 .result = ACCEPT,
1651 .prog_type = BPF_PROG_TYPE_SK_SKB,
1652 },
1653 {
1654 "direct packet write for SK_SKB",
1655 .insns = {
1656 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1657 offsetof(struct __sk_buff, data)),
1658 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1659 offsetof(struct __sk_buff, data_end)),
1660 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1662 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1663 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1664 BPF_MOV64_IMM(BPF_REG_0, 0),
1665 BPF_EXIT_INSN(),
1666 },
1667 .result = ACCEPT,
1668 .prog_type = BPF_PROG_TYPE_SK_SKB,
1669 },
1670 {
1671 "overlapping checks for direct packet access SK_SKB",
1672 .insns = {
1673 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1674 offsetof(struct __sk_buff, data)),
1675 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1676 offsetof(struct __sk_buff, data_end)),
1677 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1679 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1680 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1681 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1682 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1683 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1684 BPF_MOV64_IMM(BPF_REG_0, 0),
1685 BPF_EXIT_INSN(),
1686 },
1687 .result = ACCEPT,
1688 .prog_type = BPF_PROG_TYPE_SK_SKB,
1689 },
1690 {
1691 "valid access family in SK_MSG",
1692 .insns = {
1693 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1694 offsetof(struct sk_msg_md, family)),
1695 BPF_EXIT_INSN(),
1696 },
1697 .result = ACCEPT,
1698 .prog_type = BPF_PROG_TYPE_SK_MSG,
1699 },
1700 {
1701 "valid access remote_ip4 in SK_MSG",
1702 .insns = {
1703 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1704 offsetof(struct sk_msg_md, remote_ip4)),
1705 BPF_EXIT_INSN(),
1706 },
1707 .result = ACCEPT,
1708 .prog_type = BPF_PROG_TYPE_SK_MSG,
1709 },
1710 {
1711 "valid access local_ip4 in SK_MSG",
1712 .insns = {
1713 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1714 offsetof(struct sk_msg_md, local_ip4)),
1715 BPF_EXIT_INSN(),
1716 },
1717 .result = ACCEPT,
1718 .prog_type = BPF_PROG_TYPE_SK_MSG,
1719 },
1720 {
1721 "valid access remote_port in SK_MSG",
1722 .insns = {
1723 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1724 offsetof(struct sk_msg_md, remote_port)),
1725 BPF_EXIT_INSN(),
1726 },
1727 .result = ACCEPT,
1728 .prog_type = BPF_PROG_TYPE_SK_MSG,
1729 },
1730 {
1731 "valid access local_port in SK_MSG",
1732 .insns = {
1733 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1734 offsetof(struct sk_msg_md, local_port)),
1735 BPF_EXIT_INSN(),
1736 },
1737 .result = ACCEPT,
1738 .prog_type = BPF_PROG_TYPE_SK_MSG,
1739 },
1740 {
1741 "valid access remote_ip6 in SK_MSG",
1742 .insns = {
1743 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1744 offsetof(struct sk_msg_md, remote_ip6[0])),
1745 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1746 offsetof(struct sk_msg_md, remote_ip6[1])),
1747 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1748 offsetof(struct sk_msg_md, remote_ip6[2])),
1749 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1750 offsetof(struct sk_msg_md, remote_ip6[3])),
1751 BPF_EXIT_INSN(),
1752 },
1753 .result = ACCEPT,
1754 .prog_type = BPF_PROG_TYPE_SK_SKB,
1755 },
1756 {
1757 "valid access local_ip6 in SK_MSG",
1758 .insns = {
1759 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1760 offsetof(struct sk_msg_md, local_ip6[0])),
1761 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1762 offsetof(struct sk_msg_md, local_ip6[1])),
1763 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1764 offsetof(struct sk_msg_md, local_ip6[2])),
1765 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1766 offsetof(struct sk_msg_md, local_ip6[3])),
1767 BPF_EXIT_INSN(),
1768 },
1769 .result = ACCEPT,
1770 .prog_type = BPF_PROG_TYPE_SK_SKB,
1771 },
1772 {
1773 "invalid 64B read of family in SK_MSG",
1774 .insns = {
1775 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1776 offsetof(struct sk_msg_md, family)),
1777 BPF_EXIT_INSN(),
1778 },
1779 .errstr = "invalid bpf_context access",
1780 .result = REJECT,
1781 .prog_type = BPF_PROG_TYPE_SK_MSG,
1782 },
1783 {
1784 "invalid read past end of SK_MSG",
1785 .insns = {
1786 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1787 offsetof(struct sk_msg_md, local_port) + 4),
1788 BPF_EXIT_INSN(),
1789 },
1790 .errstr = "R0 !read_ok",
1791 .result = REJECT,
1792 .prog_type = BPF_PROG_TYPE_SK_MSG,
1793 },
1794 {
1795 "invalid read offset in SK_MSG",
1796 .insns = {
1797 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1798 offsetof(struct sk_msg_md, family) + 1),
1799 BPF_EXIT_INSN(),
1800 },
1801 .errstr = "invalid bpf_context access",
1802 .result = REJECT,
1803 .prog_type = BPF_PROG_TYPE_SK_MSG,
1804 },
1805 {
1806 "direct packet read for SK_MSG",
1807 .insns = {
1808 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1809 offsetof(struct sk_msg_md, data)),
1810 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1811 offsetof(struct sk_msg_md, data_end)),
1812 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1813 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1814 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1815 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1816 BPF_MOV64_IMM(BPF_REG_0, 0),
1817 BPF_EXIT_INSN(),
1818 },
1819 .result = ACCEPT,
1820 .prog_type = BPF_PROG_TYPE_SK_MSG,
1821 },
1822 {
1823 "direct packet write for SK_MSG",
1824 .insns = {
1825 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1826 offsetof(struct sk_msg_md, data)),
1827 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1828 offsetof(struct sk_msg_md, data_end)),
1829 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1830 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1831 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1832 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1833 BPF_MOV64_IMM(BPF_REG_0, 0),
1834 BPF_EXIT_INSN(),
1835 },
1836 .result = ACCEPT,
1837 .prog_type = BPF_PROG_TYPE_SK_MSG,
1838 },
1839 {
1840 "overlapping checks for direct packet access SK_MSG",
1841 .insns = {
1842 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1843 offsetof(struct sk_msg_md, data)),
1844 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1845 offsetof(struct sk_msg_md, data_end)),
1846 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1847 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1848 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1849 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1851 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1852 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1853 BPF_MOV64_IMM(BPF_REG_0, 0),
1854 BPF_EXIT_INSN(),
1855 },
1856 .result = ACCEPT,
1857 .prog_type = BPF_PROG_TYPE_SK_MSG,
1858 },
1859 {
1860 "check skb->mark is not writeable by sockets",
1861 .insns = {
1862 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1863 offsetof(struct __sk_buff, mark)),
1864 BPF_EXIT_INSN(),
1865 },
1866 .errstr = "invalid bpf_context access",
1867 .errstr_unpriv = "R1 leaks addr",
1868 .result = REJECT,
1869 },
1870 {
1871 "check skb->tc_index is not writeable by sockets",
1872 .insns = {
1873 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1874 offsetof(struct __sk_buff, tc_index)),
1875 BPF_EXIT_INSN(),
1876 },
1877 .errstr = "invalid bpf_context access",
1878 .errstr_unpriv = "R1 leaks addr",
1879 .result = REJECT,
1880 },
1881 {
1882 "check cb access: byte",
1883 .insns = {
1884 BPF_MOV64_IMM(BPF_REG_0, 0),
1885 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1886 offsetof(struct __sk_buff, cb[0])),
1887 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1888 offsetof(struct __sk_buff, cb[0]) + 1),
1889 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1890 offsetof(struct __sk_buff, cb[0]) + 2),
1891 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1892 offsetof(struct __sk_buff, cb[0]) + 3),
1893 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1894 offsetof(struct __sk_buff, cb[1])),
1895 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1896 offsetof(struct __sk_buff, cb[1]) + 1),
1897 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1898 offsetof(struct __sk_buff, cb[1]) + 2),
1899 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1900 offsetof(struct __sk_buff, cb[1]) + 3),
1901 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1902 offsetof(struct __sk_buff, cb[2])),
1903 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1904 offsetof(struct __sk_buff, cb[2]) + 1),
1905 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1906 offsetof(struct __sk_buff, cb[2]) + 2),
1907 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1908 offsetof(struct __sk_buff, cb[2]) + 3),
1909 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1910 offsetof(struct __sk_buff, cb[3])),
1911 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1912 offsetof(struct __sk_buff, cb[3]) + 1),
1913 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1914 offsetof(struct __sk_buff, cb[3]) + 2),
1915 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1916 offsetof(struct __sk_buff, cb[3]) + 3),
1917 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1918 offsetof(struct __sk_buff, cb[4])),
1919 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1920 offsetof(struct __sk_buff, cb[4]) + 1),
1921 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1922 offsetof(struct __sk_buff, cb[4]) + 2),
1923 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1924 offsetof(struct __sk_buff, cb[4]) + 3),
1925 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1926 offsetof(struct __sk_buff, cb[0])),
1927 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1928 offsetof(struct __sk_buff, cb[0]) + 1),
1929 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1930 offsetof(struct __sk_buff, cb[0]) + 2),
1931 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1932 offsetof(struct __sk_buff, cb[0]) + 3),
1933 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1934 offsetof(struct __sk_buff, cb[1])),
1935 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1936 offsetof(struct __sk_buff, cb[1]) + 1),
1937 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1938 offsetof(struct __sk_buff, cb[1]) + 2),
1939 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1940 offsetof(struct __sk_buff, cb[1]) + 3),
1941 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1942 offsetof(struct __sk_buff, cb[2])),
1943 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1944 offsetof(struct __sk_buff, cb[2]) + 1),
1945 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1946 offsetof(struct __sk_buff, cb[2]) + 2),
1947 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1948 offsetof(struct __sk_buff, cb[2]) + 3),
1949 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1950 offsetof(struct __sk_buff, cb[3])),
1951 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1952 offsetof(struct __sk_buff, cb[3]) + 1),
1953 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1954 offsetof(struct __sk_buff, cb[3]) + 2),
1955 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1956 offsetof(struct __sk_buff, cb[3]) + 3),
1957 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1958 offsetof(struct __sk_buff, cb[4])),
1959 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1960 offsetof(struct __sk_buff, cb[4]) + 1),
1961 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1962 offsetof(struct __sk_buff, cb[4]) + 2),
1963 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1964 offsetof(struct __sk_buff, cb[4]) + 3),
1965 BPF_EXIT_INSN(),
1966 },
1967 .result = ACCEPT,
1968 },
1969 {
1970 "__sk_buff->hash, offset 0, byte store not permitted",
1971 .insns = {
1972 BPF_MOV64_IMM(BPF_REG_0, 0),
1973 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1974 offsetof(struct __sk_buff, hash)),
1975 BPF_EXIT_INSN(),
1976 },
1977 .errstr = "invalid bpf_context access",
1978 .result = REJECT,
1979 },
1980 {
1981 "__sk_buff->tc_index, offset 3, byte store not permitted",
1982 .insns = {
1983 BPF_MOV64_IMM(BPF_REG_0, 0),
1984 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1985 offsetof(struct __sk_buff, tc_index) + 3),
1986 BPF_EXIT_INSN(),
1987 },
1988 .errstr = "invalid bpf_context access",
1989 .result = REJECT,
1990 },
1991 {
1992 "check skb->hash byte load permitted",
1993 .insns = {
1994 BPF_MOV64_IMM(BPF_REG_0, 0),
1995 #if __BYTE_ORDER == __LITTLE_ENDIAN
1996 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1997 offsetof(struct __sk_buff, hash)),
1998 #else
1999 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2000 offsetof(struct __sk_buff, hash) + 3),
2001 #endif
2002 BPF_EXIT_INSN(),
2003 },
2004 .result = ACCEPT,
2005 },
2006 {
2007 "check skb->hash byte load not permitted 1",
2008 .insns = {
2009 BPF_MOV64_IMM(BPF_REG_0, 0),
2010 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2011 offsetof(struct __sk_buff, hash) + 1),
2012 BPF_EXIT_INSN(),
2013 },
2014 .errstr = "invalid bpf_context access",
2015 .result = REJECT,
2016 },
2017 {
2018 "check skb->hash byte load not permitted 2",
2019 .insns = {
2020 BPF_MOV64_IMM(BPF_REG_0, 0),
2021 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2022 offsetof(struct __sk_buff, hash) + 2),
2023 BPF_EXIT_INSN(),
2024 },
2025 .errstr = "invalid bpf_context access",
2026 .result = REJECT,
2027 },
2028 {
2029 "check skb->hash byte load not permitted 3",
2030 .insns = {
2031 BPF_MOV64_IMM(BPF_REG_0, 0),
2032 #if __BYTE_ORDER == __LITTLE_ENDIAN
2033 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2034 offsetof(struct __sk_buff, hash) + 3),
2035 #else
2036 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2037 offsetof(struct __sk_buff, hash)),
2038 #endif
2039 BPF_EXIT_INSN(),
2040 },
2041 .errstr = "invalid bpf_context access",
2042 .result = REJECT,
2043 },
2044 {
2045 "check cb access: byte, wrong type",
2046 .insns = {
2047 BPF_MOV64_IMM(BPF_REG_0, 0),
2048 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
2049 offsetof(struct __sk_buff, cb[0])),
2050 BPF_EXIT_INSN(),
2051 },
2052 .errstr = "invalid bpf_context access",
2053 .result = REJECT,
2054 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2055 },
2056 {
2057 "check cb access: half",
2058 .insns = {
2059 BPF_MOV64_IMM(BPF_REG_0, 0),
2060 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2061 offsetof(struct __sk_buff, cb[0])),
2062 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2063 offsetof(struct __sk_buff, cb[0]) + 2),
2064 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2065 offsetof(struct __sk_buff, cb[1])),
2066 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2067 offsetof(struct __sk_buff, cb[1]) + 2),
2068 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2069 offsetof(struct __sk_buff, cb[2])),
2070 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2071 offsetof(struct __sk_buff, cb[2]) + 2),
2072 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2073 offsetof(struct __sk_buff, cb[3])),
2074 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2075 offsetof(struct __sk_buff, cb[3]) + 2),
2076 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2077 offsetof(struct __sk_buff, cb[4])),
2078 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2079 offsetof(struct __sk_buff, cb[4]) + 2),
2080 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2081 offsetof(struct __sk_buff, cb[0])),
2082 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2083 offsetof(struct __sk_buff, cb[0]) + 2),
2084 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2085 offsetof(struct __sk_buff, cb[1])),
2086 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2087 offsetof(struct __sk_buff, cb[1]) + 2),
2088 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2089 offsetof(struct __sk_buff, cb[2])),
2090 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2091 offsetof(struct __sk_buff, cb[2]) + 2),
2092 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2093 offsetof(struct __sk_buff, cb[3])),
2094 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2095 offsetof(struct __sk_buff, cb[3]) + 2),
2096 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2097 offsetof(struct __sk_buff, cb[4])),
2098 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2099 offsetof(struct __sk_buff, cb[4]) + 2),
2100 BPF_EXIT_INSN(),
2101 },
2102 .result = ACCEPT,
2103 },
2104 {
2105 "check cb access: half, unaligned",
2106 .insns = {
2107 BPF_MOV64_IMM(BPF_REG_0, 0),
2108 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2109 offsetof(struct __sk_buff, cb[0]) + 1),
2110 BPF_EXIT_INSN(),
2111 },
2112 .errstr = "misaligned context access",
2113 .result = REJECT,
2114 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2115 },
2116 {
2117 "check __sk_buff->hash, offset 0, half store not permitted",
2118 .insns = {
2119 BPF_MOV64_IMM(BPF_REG_0, 0),
2120 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2121 offsetof(struct __sk_buff, hash)),
2122 BPF_EXIT_INSN(),
2123 },
2124 .errstr = "invalid bpf_context access",
2125 .result = REJECT,
2126 },
2127 {
2128 "check __sk_buff->tc_index, offset 2, half store not permitted",
2129 .insns = {
2130 BPF_MOV64_IMM(BPF_REG_0, 0),
2131 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2132 offsetof(struct __sk_buff, tc_index) + 2),
2133 BPF_EXIT_INSN(),
2134 },
2135 .errstr = "invalid bpf_context access",
2136 .result = REJECT,
2137 },
2138 {
2139 "check skb->hash half load permitted",
2140 .insns = {
2141 BPF_MOV64_IMM(BPF_REG_0, 0),
2142 #if __BYTE_ORDER == __LITTLE_ENDIAN
2143 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2144 offsetof(struct __sk_buff, hash)),
2145 #else
2146 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2147 offsetof(struct __sk_buff, hash) + 2),
2148 #endif
2149 BPF_EXIT_INSN(),
2150 },
2151 .result = ACCEPT,
2152 },
2153 {
2154 "check skb->hash half load not permitted",
2155 .insns = {
2156 BPF_MOV64_IMM(BPF_REG_0, 0),
2157 #if __BYTE_ORDER == __LITTLE_ENDIAN
2158 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2159 offsetof(struct __sk_buff, hash) + 2),
2160 #else
2161 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2162 offsetof(struct __sk_buff, hash)),
2163 #endif
2164 BPF_EXIT_INSN(),
2165 },
2166 .errstr = "invalid bpf_context access",
2167 .result = REJECT,
2168 },
2169 {
2170 "check cb access: half, wrong type",
2171 .insns = {
2172 BPF_MOV64_IMM(BPF_REG_0, 0),
2173 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2174 offsetof(struct __sk_buff, cb[0])),
2175 BPF_EXIT_INSN(),
2176 },
2177 .errstr = "invalid bpf_context access",
2178 .result = REJECT,
2179 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2180 },
2181 {
2182 "check cb access: word",
2183 .insns = {
2184 BPF_MOV64_IMM(BPF_REG_0, 0),
2185 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2186 offsetof(struct __sk_buff, cb[0])),
2187 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2188 offsetof(struct __sk_buff, cb[1])),
2189 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2190 offsetof(struct __sk_buff, cb[2])),
2191 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2192 offsetof(struct __sk_buff, cb[3])),
2193 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2194 offsetof(struct __sk_buff, cb[4])),
2195 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2196 offsetof(struct __sk_buff, cb[0])),
2197 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2198 offsetof(struct __sk_buff, cb[1])),
2199 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2200 offsetof(struct __sk_buff, cb[2])),
2201 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2202 offsetof(struct __sk_buff, cb[3])),
2203 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2204 offsetof(struct __sk_buff, cb[4])),
2205 BPF_EXIT_INSN(),
2206 },
2207 .result = ACCEPT,
2208 },
2209 {
2210 "check cb access: word, unaligned 1",
2211 .insns = {
2212 BPF_MOV64_IMM(BPF_REG_0, 0),
2213 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2214 offsetof(struct __sk_buff, cb[0]) + 2),
2215 BPF_EXIT_INSN(),
2216 },
2217 .errstr = "misaligned context access",
2218 .result = REJECT,
2219 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2220 },
2221 {
2222 "check cb access: word, unaligned 2",
2223 .insns = {
2224 BPF_MOV64_IMM(BPF_REG_0, 0),
2225 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2226 offsetof(struct __sk_buff, cb[4]) + 1),
2227 BPF_EXIT_INSN(),
2228 },
2229 .errstr = "misaligned context access",
2230 .result = REJECT,
2231 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2232 },
2233 {
2234 "check cb access: word, unaligned 3",
2235 .insns = {
2236 BPF_MOV64_IMM(BPF_REG_0, 0),
2237 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2238 offsetof(struct __sk_buff, cb[4]) + 2),
2239 BPF_EXIT_INSN(),
2240 },
2241 .errstr = "misaligned context access",
2242 .result = REJECT,
2243 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2244 },
2245 {
2246 "check cb access: word, unaligned 4",
2247 .insns = {
2248 BPF_MOV64_IMM(BPF_REG_0, 0),
2249 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2250 offsetof(struct __sk_buff, cb[4]) + 3),
2251 BPF_EXIT_INSN(),
2252 },
2253 .errstr = "misaligned context access",
2254 .result = REJECT,
2255 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2256 },
2257 {
2258 "check cb access: double",
2259 .insns = {
2260 BPF_MOV64_IMM(BPF_REG_0, 0),
2261 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2262 offsetof(struct __sk_buff, cb[0])),
2263 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2264 offsetof(struct __sk_buff, cb[2])),
2265 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2266 offsetof(struct __sk_buff, cb[0])),
2267 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2268 offsetof(struct __sk_buff, cb[2])),
2269 BPF_EXIT_INSN(),
2270 },
2271 .result = ACCEPT,
2272 },
2273 {
2274 "check cb access: double, unaligned 1",
2275 .insns = {
2276 BPF_MOV64_IMM(BPF_REG_0, 0),
2277 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2278 offsetof(struct __sk_buff, cb[1])),
2279 BPF_EXIT_INSN(),
2280 },
2281 .errstr = "misaligned context access",
2282 .result = REJECT,
2283 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2284 },
2285 {
2286 "check cb access: double, unaligned 2",
2287 .insns = {
2288 BPF_MOV64_IMM(BPF_REG_0, 0),
2289 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2290 offsetof(struct __sk_buff, cb[3])),
2291 BPF_EXIT_INSN(),
2292 },
2293 .errstr = "misaligned context access",
2294 .result = REJECT,
2295 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2296 },
2297 {
2298 "check cb access: double, oob 1",
2299 .insns = {
2300 BPF_MOV64_IMM(BPF_REG_0, 0),
2301 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2302 offsetof(struct __sk_buff, cb[4])),
2303 BPF_EXIT_INSN(),
2304 },
2305 .errstr = "invalid bpf_context access",
2306 .result = REJECT,
2307 },
2308 {
2309 "check cb access: double, oob 2",
2310 .insns = {
2311 BPF_MOV64_IMM(BPF_REG_0, 0),
2312 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2313 offsetof(struct __sk_buff, cb[4])),
2314 BPF_EXIT_INSN(),
2315 },
2316 .errstr = "invalid bpf_context access",
2317 .result = REJECT,
2318 },
2319 {
2320 "check __sk_buff->ifindex dw store not permitted",
2321 .insns = {
2322 BPF_MOV64_IMM(BPF_REG_0, 0),
2323 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2324 offsetof(struct __sk_buff, ifindex)),
2325 BPF_EXIT_INSN(),
2326 },
2327 .errstr = "invalid bpf_context access",
2328 .result = REJECT,
2329 },
2330 {
2331 "check __sk_buff->ifindex dw load not permitted",
2332 .insns = {
2333 BPF_MOV64_IMM(BPF_REG_0, 0),
2334 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2335 offsetof(struct __sk_buff, ifindex)),
2336 BPF_EXIT_INSN(),
2337 },
2338 .errstr = "invalid bpf_context access",
2339 .result = REJECT,
2340 },
2341 {
2342 "check cb access: double, wrong type",
2343 .insns = {
2344 BPF_MOV64_IMM(BPF_REG_0, 0),
2345 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2346 offsetof(struct __sk_buff, cb[0])),
2347 BPF_EXIT_INSN(),
2348 },
2349 .errstr = "invalid bpf_context access",
2350 .result = REJECT,
2351 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2352 },
2353 {
2354 "check out of range skb->cb access",
2355 .insns = {
2356 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2357 offsetof(struct __sk_buff, cb[0]) + 256),
2358 BPF_EXIT_INSN(),
2359 },
2360 .errstr = "invalid bpf_context access",
2361 .errstr_unpriv = "",
2362 .result = REJECT,
2363 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
2364 },
2365 {
2366 "write skb fields from socket prog",
2367 .insns = {
2368 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2369 offsetof(struct __sk_buff, cb[4])),
2370 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2371 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2372 offsetof(struct __sk_buff, mark)),
2373 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2374 offsetof(struct __sk_buff, tc_index)),
2375 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2376 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2377 offsetof(struct __sk_buff, cb[0])),
2378 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2379 offsetof(struct __sk_buff, cb[2])),
2380 BPF_EXIT_INSN(),
2381 },
2382 .result = ACCEPT,
2383 .errstr_unpriv = "R1 leaks addr",
2384 .result_unpriv = REJECT,
2385 },
2386 {
2387 "write skb fields from tc_cls_act prog",
2388 .insns = {
2389 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2390 offsetof(struct __sk_buff, cb[0])),
2391 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2392 offsetof(struct __sk_buff, mark)),
2393 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2394 offsetof(struct __sk_buff, tc_index)),
2395 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2396 offsetof(struct __sk_buff, tc_index)),
2397 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2398 offsetof(struct __sk_buff, cb[3])),
2399 BPF_EXIT_INSN(),
2400 },
2401 .errstr_unpriv = "",
2402 .result_unpriv = REJECT,
2403 .result = ACCEPT,
2404 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2405 },
2406 {
2407 "PTR_TO_STACK store/load",
2408 .insns = {
2409 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2411 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2412 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2413 BPF_EXIT_INSN(),
2414 },
2415 .result = ACCEPT,
2416 .retval = 0xfaceb00c,
2417 },
2418 {
2419 "PTR_TO_STACK store/load - bad alignment on off",
2420 .insns = {
2421 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2423 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2424 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2425 BPF_EXIT_INSN(),
2426 },
2427 .result = REJECT,
2428 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
2429 },
2430 {
2431 "PTR_TO_STACK store/load - bad alignment on reg",
2432 .insns = {
2433 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2435 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2436 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2437 BPF_EXIT_INSN(),
2438 },
2439 .result = REJECT,
2440 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
2441 },
2442 {
2443 "PTR_TO_STACK store/load - out of bounds low",
2444 .insns = {
2445 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2446 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
2447 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2448 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2449 BPF_EXIT_INSN(),
2450 },
2451 .result = REJECT,
2452 .errstr = "invalid stack off=-79992 size=8",
2453 },
2454 {
2455 "PTR_TO_STACK store/load - out of bounds high",
2456 .insns = {
2457 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2458 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2459 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2460 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2461 BPF_EXIT_INSN(),
2462 },
2463 .result = REJECT,
2464 .errstr = "invalid stack off=0 size=8",
2465 },
2466 {
2467 "unpriv: return pointer",
2468 .insns = {
2469 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
2470 BPF_EXIT_INSN(),
2471 },
2472 .result = ACCEPT,
2473 .result_unpriv = REJECT,
2474 .errstr_unpriv = "R0 leaks addr",
2475 .retval = POINTER_VALUE,
2476 },
2477 {
2478 "unpriv: add const to pointer",
2479 .insns = {
2480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2481 BPF_MOV64_IMM(BPF_REG_0, 0),
2482 BPF_EXIT_INSN(),
2483 },
2484 .result = ACCEPT,
2485 },
2486 {
2487 "unpriv: add pointer to pointer",
2488 .insns = {
2489 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2490 BPF_MOV64_IMM(BPF_REG_0, 0),
2491 BPF_EXIT_INSN(),
2492 },
2493 .result = REJECT,
2494 .errstr = "R1 pointer += pointer",
2495 },
2496 {
2497 "unpriv: neg pointer",
2498 .insns = {
2499 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
2500 BPF_MOV64_IMM(BPF_REG_0, 0),
2501 BPF_EXIT_INSN(),
2502 },
2503 .result = ACCEPT,
2504 .result_unpriv = REJECT,
2505 .errstr_unpriv = "R1 pointer arithmetic",
2506 },
2507 {
2508 "unpriv: cmp pointer with const",
2509 .insns = {
2510 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2511 BPF_MOV64_IMM(BPF_REG_0, 0),
2512 BPF_EXIT_INSN(),
2513 },
2514 .result = ACCEPT,
2515 .result_unpriv = REJECT,
2516 .errstr_unpriv = "R1 pointer comparison",
2517 },
2518 {
2519 "unpriv: cmp pointer with pointer",
2520 .insns = {
2521 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
2522 BPF_MOV64_IMM(BPF_REG_0, 0),
2523 BPF_EXIT_INSN(),
2524 },
2525 .result = ACCEPT,
2526 .result_unpriv = REJECT,
2527 .errstr_unpriv = "R10 pointer comparison",
2528 },
2529 {
2530 "unpriv: check that printk is disallowed",
2531 .insns = {
2532 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2533 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2535 BPF_MOV64_IMM(BPF_REG_2, 8),
2536 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2537 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2538 BPF_FUNC_trace_printk),
2539 BPF_MOV64_IMM(BPF_REG_0, 0),
2540 BPF_EXIT_INSN(),
2541 },
2542 .errstr_unpriv = "unknown func bpf_trace_printk#6",
2543 .result_unpriv = REJECT,
2544 .result = ACCEPT,
2545 },
2546 {
2547 "unpriv: pass pointer to helper function",
2548 .insns = {
2549 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2550 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2552 BPF_LD_MAP_FD(BPF_REG_1, 0),
2553 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2554 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2555 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2556 BPF_FUNC_map_update_elem),
2557 BPF_MOV64_IMM(BPF_REG_0, 0),
2558 BPF_EXIT_INSN(),
2559 },
2560 .fixup_map1 = { 3 },
2561 .errstr_unpriv = "R4 leaks addr",
2562 .result_unpriv = REJECT,
2563 .result = ACCEPT,
2564 },
2565 {
2566 "unpriv: indirectly pass pointer on stack to helper function",
2567 .insns = {
2568 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2569 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2570 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2571 BPF_LD_MAP_FD(BPF_REG_1, 0),
2572 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2573 BPF_FUNC_map_lookup_elem),
2574 BPF_MOV64_IMM(BPF_REG_0, 0),
2575 BPF_EXIT_INSN(),
2576 },
2577 .fixup_map1 = { 3 },
2578 .errstr = "invalid indirect read from stack off -8+0 size 8",
2579 .result = REJECT,
2580 },
2581 {
2582 "unpriv: mangle pointer on stack 1",
2583 .insns = {
2584 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2585 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
2586 BPF_MOV64_IMM(BPF_REG_0, 0),
2587 BPF_EXIT_INSN(),
2588 },
2589 .errstr_unpriv = "attempt to corrupt spilled",
2590 .result_unpriv = REJECT,
2591 .result = ACCEPT,
2592 },
2593 {
2594 "unpriv: mangle pointer on stack 2",
2595 .insns = {
2596 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2597 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2598 BPF_MOV64_IMM(BPF_REG_0, 0),
2599 BPF_EXIT_INSN(),
2600 },
2601 .errstr_unpriv = "attempt to corrupt spilled",
2602 .result_unpriv = REJECT,
2603 .result = ACCEPT,
2604 },
2605 {
2606 "unpriv: read pointer from stack in small chunks",
2607 .insns = {
2608 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2609 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2610 BPF_MOV64_IMM(BPF_REG_0, 0),
2611 BPF_EXIT_INSN(),
2612 },
2613 .errstr = "invalid size",
2614 .result = REJECT,
2615 },
2616 {
2617 "unpriv: write pointer into ctx",
2618 .insns = {
2619 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2620 BPF_MOV64_IMM(BPF_REG_0, 0),
2621 BPF_EXIT_INSN(),
2622 },
2623 .errstr_unpriv = "R1 leaks addr",
2624 .result_unpriv = REJECT,
2625 .errstr = "invalid bpf_context access",
2626 .result = REJECT,
2627 },
2628 {
2629 "unpriv: spill/fill of ctx",
2630 .insns = {
2631 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2632 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2633 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2634 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2635 BPF_MOV64_IMM(BPF_REG_0, 0),
2636 BPF_EXIT_INSN(),
2637 },
2638 .result = ACCEPT,
2639 },
2640 {
2641 "unpriv: spill/fill of ctx 2",
2642 .insns = {
2643 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2645 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2646 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2647 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2648 BPF_FUNC_get_hash_recalc),
2649 BPF_MOV64_IMM(BPF_REG_0, 0),
2650 BPF_EXIT_INSN(),
2651 },
2652 .result = ACCEPT,
2653 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2654 },
2655 {
2656 "unpriv: spill/fill of ctx 3",
2657 .insns = {
2658 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2659 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2660 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2661 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2662 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2663 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2664 BPF_FUNC_get_hash_recalc),
2665 BPF_EXIT_INSN(),
2666 },
2667 .result = REJECT,
2668 .errstr = "R1 type=fp expected=ctx",
2669 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2670 },
2671 {
2672 "unpriv: spill/fill of ctx 4",
2673 .insns = {
2674 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2675 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2676 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2677 BPF_MOV64_IMM(BPF_REG_0, 1),
2678 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2679 BPF_REG_0, -8, 0),
2680 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2681 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2682 BPF_FUNC_get_hash_recalc),
2683 BPF_EXIT_INSN(),
2684 },
2685 .result = REJECT,
2686 .errstr = "R1 type=inv expected=ctx",
2687 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2688 },
2689 {
2690 "unpriv: spill/fill of different pointers stx",
2691 .insns = {
2692 BPF_MOV64_IMM(BPF_REG_3, 42),
2693 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2695 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2696 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2697 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2698 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2699 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2700 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2701 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2702 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2703 offsetof(struct __sk_buff, mark)),
2704 BPF_MOV64_IMM(BPF_REG_0, 0),
2705 BPF_EXIT_INSN(),
2706 },
2707 .result = REJECT,
2708 .errstr = "same insn cannot be used with different pointers",
2709 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2710 },
2711 {
2712 "unpriv: spill/fill of different pointers ldx",
2713 .insns = {
2714 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2716 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2717 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2719 -(__s32)offsetof(struct bpf_perf_event_data,
2720 sample_period) - 8),
2721 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2722 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2723 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2724 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2725 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2726 offsetof(struct bpf_perf_event_data,
2727 sample_period)),
2728 BPF_MOV64_IMM(BPF_REG_0, 0),
2729 BPF_EXIT_INSN(),
2730 },
2731 .result = REJECT,
2732 .errstr = "same insn cannot be used with different pointers",
2733 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2734 },
2735 {
2736 "unpriv: write pointer into map elem value",
2737 .insns = {
2738 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2739 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2740 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2741 BPF_LD_MAP_FD(BPF_REG_1, 0),
2742 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2743 BPF_FUNC_map_lookup_elem),
2744 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2745 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2746 BPF_EXIT_INSN(),
2747 },
2748 .fixup_map1 = { 3 },
2749 .errstr_unpriv = "R0 leaks addr",
2750 .result_unpriv = REJECT,
2751 .result = ACCEPT,
2752 },
2753 {
2754 "unpriv: partial copy of pointer",
2755 .insns = {
2756 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2757 BPF_MOV64_IMM(BPF_REG_0, 0),
2758 BPF_EXIT_INSN(),
2759 },
2760 .errstr_unpriv = "R10 partial copy",
2761 .result_unpriv = REJECT,
2762 .result = ACCEPT,
2763 },
2764 {
2765 "unpriv: pass pointer to tail_call",
2766 .insns = {
2767 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2768 BPF_LD_MAP_FD(BPF_REG_2, 0),
2769 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2770 BPF_FUNC_tail_call),
2771 BPF_MOV64_IMM(BPF_REG_0, 0),
2772 BPF_EXIT_INSN(),
2773 },
2774 .fixup_prog1 = { 1 },
2775 .errstr_unpriv = "R3 leaks addr into helper",
2776 .result_unpriv = REJECT,
2777 .result = ACCEPT,
2778 },
2779 {
2780 "unpriv: cmp map pointer with zero",
2781 .insns = {
2782 BPF_MOV64_IMM(BPF_REG_1, 0),
2783 BPF_LD_MAP_FD(BPF_REG_1, 0),
2784 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2785 BPF_MOV64_IMM(BPF_REG_0, 0),
2786 BPF_EXIT_INSN(),
2787 },
2788 .fixup_map1 = { 1 },
2789 .errstr_unpriv = "R1 pointer comparison",
2790 .result_unpriv = REJECT,
2791 .result = ACCEPT,
2792 },
2793 {
2794 "unpriv: write into frame pointer",
2795 .insns = {
2796 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2797 BPF_MOV64_IMM(BPF_REG_0, 0),
2798 BPF_EXIT_INSN(),
2799 },
2800 .errstr = "frame pointer is read only",
2801 .result = REJECT,
2802 },
2803 {
2804 "unpriv: spill/fill frame pointer",
2805 .insns = {
2806 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2808 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2809 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2810 BPF_MOV64_IMM(BPF_REG_0, 0),
2811 BPF_EXIT_INSN(),
2812 },
2813 .errstr = "frame pointer is read only",
2814 .result = REJECT,
2815 },
2816 {
2817 "unpriv: cmp of frame pointer",
2818 .insns = {
2819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2820 BPF_MOV64_IMM(BPF_REG_0, 0),
2821 BPF_EXIT_INSN(),
2822 },
2823 .errstr_unpriv = "R10 pointer comparison",
2824 .result_unpriv = REJECT,
2825 .result = ACCEPT,
2826 },
2827 {
2828 "unpriv: adding of fp",
2829 .insns = {
2830 BPF_MOV64_IMM(BPF_REG_0, 0),
2831 BPF_MOV64_IMM(BPF_REG_1, 0),
2832 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2833 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2834 BPF_EXIT_INSN(),
2835 },
2836 .result = ACCEPT,
2837 },
2838 {
2839 "unpriv: cmp of stack pointer",
2840 .insns = {
2841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2843 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2844 BPF_MOV64_IMM(BPF_REG_0, 0),
2845 BPF_EXIT_INSN(),
2846 },
2847 .errstr_unpriv = "R2 pointer comparison",
2848 .result_unpriv = REJECT,
2849 .result = ACCEPT,
2850 },
2851 {
2852 "runtime/jit: tail_call within bounds, prog once",
2853 .insns = {
2854 BPF_MOV64_IMM(BPF_REG_3, 0),
2855 BPF_LD_MAP_FD(BPF_REG_2, 0),
2856 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2857 BPF_FUNC_tail_call),
2858 BPF_MOV64_IMM(BPF_REG_0, 1),
2859 BPF_EXIT_INSN(),
2860 },
2861 .fixup_prog1 = { 1 },
2862 .result = ACCEPT,
2863 .retval = 42,
2864 },
2865 {
2866 "runtime/jit: tail_call within bounds, prog loop",
2867 .insns = {
2868 BPF_MOV64_IMM(BPF_REG_3, 1),
2869 BPF_LD_MAP_FD(BPF_REG_2, 0),
2870 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2871 BPF_FUNC_tail_call),
2872 BPF_MOV64_IMM(BPF_REG_0, 1),
2873 BPF_EXIT_INSN(),
2874 },
2875 .fixup_prog1 = { 1 },
2876 .result = ACCEPT,
2877 .retval = 41,
2878 },
2879 {
2880 "runtime/jit: tail_call within bounds, no prog",
2881 .insns = {
2882 BPF_MOV64_IMM(BPF_REG_3, 2),
2883 BPF_LD_MAP_FD(BPF_REG_2, 0),
2884 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2885 BPF_FUNC_tail_call),
2886 BPF_MOV64_IMM(BPF_REG_0, 1),
2887 BPF_EXIT_INSN(),
2888 },
2889 .fixup_prog1 = { 1 },
2890 .result = ACCEPT,
2891 .retval = 1,
2892 },
2893 {
2894 "runtime/jit: tail_call out of bounds",
2895 .insns = {
2896 BPF_MOV64_IMM(BPF_REG_3, 256),
2897 BPF_LD_MAP_FD(BPF_REG_2, 0),
2898 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2899 BPF_FUNC_tail_call),
2900 BPF_MOV64_IMM(BPF_REG_0, 2),
2901 BPF_EXIT_INSN(),
2902 },
2903 .fixup_prog1 = { 1 },
2904 .result = ACCEPT,
2905 .retval = 2,
2906 },
2907 {
2908 "runtime/jit: pass negative index to tail_call",
2909 .insns = {
2910 BPF_MOV64_IMM(BPF_REG_3, -1),
2911 BPF_LD_MAP_FD(BPF_REG_2, 0),
2912 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2913 BPF_FUNC_tail_call),
2914 BPF_MOV64_IMM(BPF_REG_0, 2),
2915 BPF_EXIT_INSN(),
2916 },
2917 .fixup_prog1 = { 1 },
2918 .result = ACCEPT,
2919 .retval = 2,
2920 },
2921 {
2922 "runtime/jit: pass > 32bit index to tail_call",
2923 .insns = {
2924 BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
2925 BPF_LD_MAP_FD(BPF_REG_2, 0),
2926 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2927 BPF_FUNC_tail_call),
2928 BPF_MOV64_IMM(BPF_REG_0, 2),
2929 BPF_EXIT_INSN(),
2930 },
2931 .fixup_prog1 = { 2 },
2932 .result = ACCEPT,
2933 .retval = 42,
2934 },
2935 {
2936 "stack pointer arithmetic",
2937 .insns = {
2938 BPF_MOV64_IMM(BPF_REG_1, 4),
2939 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2940 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2941 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2943 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2944 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2945 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2946 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2947 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2948 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2949 BPF_MOV64_IMM(BPF_REG_0, 0),
2950 BPF_EXIT_INSN(),
2951 },
2952 .result = ACCEPT,
2953 },
2954 {
2955 "raw_stack: no skb_load_bytes",
2956 .insns = {
2957 BPF_MOV64_IMM(BPF_REG_2, 4),
2958 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2960 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2961 BPF_MOV64_IMM(BPF_REG_4, 8),
2962 /* Call to skb_load_bytes() omitted. */
2963 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2964 BPF_EXIT_INSN(),
2965 },
2966 .result = REJECT,
2967 .errstr = "invalid read from stack off -8+0 size 8",
2968 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2969 },
2970 {
2971 "raw_stack: skb_load_bytes, negative len",
2972 .insns = {
2973 BPF_MOV64_IMM(BPF_REG_2, 4),
2974 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2975 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2976 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2977 BPF_MOV64_IMM(BPF_REG_4, -8),
2978 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2979 BPF_FUNC_skb_load_bytes),
2980 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2981 BPF_EXIT_INSN(),
2982 },
2983 .result = REJECT,
2984 .errstr = "R4 min value is negative",
2985 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2986 },
2987 {
2988 "raw_stack: skb_load_bytes, negative len 2",
2989 .insns = {
2990 BPF_MOV64_IMM(BPF_REG_2, 4),
2991 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2992 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2993 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2994 BPF_MOV64_IMM(BPF_REG_4, ~0),
2995 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2996 BPF_FUNC_skb_load_bytes),
2997 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2998 BPF_EXIT_INSN(),
2999 },
3000 .result = REJECT,
3001 .errstr = "R4 min value is negative",
3002 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3003 },
3004 {
3005 "raw_stack: skb_load_bytes, zero len",
3006 .insns = {
3007 BPF_MOV64_IMM(BPF_REG_2, 4),
3008 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3009 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3010 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3011 BPF_MOV64_IMM(BPF_REG_4, 0),
3012 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3013 BPF_FUNC_skb_load_bytes),
3014 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3015 BPF_EXIT_INSN(),
3016 },
3017 .result = REJECT,
3018 .errstr = "invalid stack type R3",
3019 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3020 },
3021 {
3022 "raw_stack: skb_load_bytes, no init",
3023 .insns = {
3024 BPF_MOV64_IMM(BPF_REG_2, 4),
3025 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3027 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3028 BPF_MOV64_IMM(BPF_REG_4, 8),
3029 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3030 BPF_FUNC_skb_load_bytes),
3031 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3032 BPF_EXIT_INSN(),
3033 },
3034 .result = ACCEPT,
3035 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3036 },
3037 {
3038 "raw_stack: skb_load_bytes, init",
3039 .insns = {
3040 BPF_MOV64_IMM(BPF_REG_2, 4),
3041 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3042 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3043 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
3044 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3045 BPF_MOV64_IMM(BPF_REG_4, 8),
3046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3047 BPF_FUNC_skb_load_bytes),
3048 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3049 BPF_EXIT_INSN(),
3050 },
3051 .result = ACCEPT,
3052 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3053 },
3054 {
3055 "raw_stack: skb_load_bytes, spilled regs around bounds",
3056 .insns = {
3057 BPF_MOV64_IMM(BPF_REG_2, 4),
3058 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3059 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3060 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3061 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3062 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3063 BPF_MOV64_IMM(BPF_REG_4, 8),
3064 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3065 BPF_FUNC_skb_load_bytes),
3066 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3067 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3068 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3069 offsetof(struct __sk_buff, mark)),
3070 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3071 offsetof(struct __sk_buff, priority)),
3072 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3073 BPF_EXIT_INSN(),
3074 },
3075 .result = ACCEPT,
3076 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3077 },
3078 {
3079 "raw_stack: skb_load_bytes, spilled regs corruption",
3080 .insns = {
3081 BPF_MOV64_IMM(BPF_REG_2, 4),
3082 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3083 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3084 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3085 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3086 BPF_MOV64_IMM(BPF_REG_4, 8),
3087 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3088 BPF_FUNC_skb_load_bytes),
3089 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3090 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3091 offsetof(struct __sk_buff, mark)),
3092 BPF_EXIT_INSN(),
3093 },
3094 .result = REJECT,
3095 .errstr = "R0 invalid mem access 'inv'",
3096 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3097 },
3098 {
3099 "raw_stack: skb_load_bytes, spilled regs corruption 2",
3100 .insns = {
3101 BPF_MOV64_IMM(BPF_REG_2, 4),
3102 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3104 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3105 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3106 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3107 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3108 BPF_MOV64_IMM(BPF_REG_4, 8),
3109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3110 BPF_FUNC_skb_load_bytes),
3111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3112 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3113 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
3114 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3115 offsetof(struct __sk_buff, mark)),
3116 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3117 offsetof(struct __sk_buff, priority)),
3118 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3119 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
3120 offsetof(struct __sk_buff, pkt_type)),
3121 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3122 BPF_EXIT_INSN(),
3123 },
3124 .result = REJECT,
3125 .errstr = "R3 invalid mem access 'inv'",
3126 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3127 },
3128 {
3129 "raw_stack: skb_load_bytes, spilled regs + data",
3130 .insns = {
3131 BPF_MOV64_IMM(BPF_REG_2, 4),
3132 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3134 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3135 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3136 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3137 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3138 BPF_MOV64_IMM(BPF_REG_4, 8),
3139 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3140 BPF_FUNC_skb_load_bytes),
3141 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3142 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3143 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
3144 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3145 offsetof(struct __sk_buff, mark)),
3146 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3147 offsetof(struct __sk_buff, priority)),
3148 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3149 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3150 BPF_EXIT_INSN(),
3151 },
3152 .result = ACCEPT,
3153 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3154 },
3155 {
3156 "raw_stack: skb_load_bytes, invalid access 1",
3157 .insns = {
3158 BPF_MOV64_IMM(BPF_REG_2, 4),
3159 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
3161 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3162 BPF_MOV64_IMM(BPF_REG_4, 8),
3163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3164 BPF_FUNC_skb_load_bytes),
3165 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3166 BPF_EXIT_INSN(),
3167 },
3168 .result = REJECT,
3169 .errstr = "invalid stack type R3 off=-513 access_size=8",
3170 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3171 },
3172 {
3173 "raw_stack: skb_load_bytes, invalid access 2",
3174 .insns = {
3175 BPF_MOV64_IMM(BPF_REG_2, 4),
3176 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3177 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3178 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3179 BPF_MOV64_IMM(BPF_REG_4, 8),
3180 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3181 BPF_FUNC_skb_load_bytes),
3182 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3183 BPF_EXIT_INSN(),
3184 },
3185 .result = REJECT,
3186 .errstr = "invalid stack type R3 off=-1 access_size=8",
3187 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3188 },
3189 {
3190 "raw_stack: skb_load_bytes, invalid access 3",
3191 .insns = {
3192 BPF_MOV64_IMM(BPF_REG_2, 4),
3193 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
3195 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3196 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3197 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3198 BPF_FUNC_skb_load_bytes),
3199 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3200 BPF_EXIT_INSN(),
3201 },
3202 .result = REJECT,
3203 .errstr = "R4 min value is negative",
3204 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3205 },
3206 {
3207 "raw_stack: skb_load_bytes, invalid access 4",
3208 .insns = {
3209 BPF_MOV64_IMM(BPF_REG_2, 4),
3210 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3212 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3213 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
3214 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3215 BPF_FUNC_skb_load_bytes),
3216 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3217 BPF_EXIT_INSN(),
3218 },
3219 .result = REJECT,
3220 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
3221 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3222 },
3223 {
3224 "raw_stack: skb_load_bytes, invalid access 5",
3225 .insns = {
3226 BPF_MOV64_IMM(BPF_REG_2, 4),
3227 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3228 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3229 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3230 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
3231 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3232 BPF_FUNC_skb_load_bytes),
3233 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3234 BPF_EXIT_INSN(),
3235 },
3236 .result = REJECT,
3237 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
3238 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3239 },
3240 {
3241 "raw_stack: skb_load_bytes, invalid access 6",
3242 .insns = {
3243 BPF_MOV64_IMM(BPF_REG_2, 4),
3244 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3245 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3246 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3247 BPF_MOV64_IMM(BPF_REG_4, 0),
3248 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3249 BPF_FUNC_skb_load_bytes),
3250 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3251 BPF_EXIT_INSN(),
3252 },
3253 .result = REJECT,
3254 .errstr = "invalid stack type R3 off=-512 access_size=0",
3255 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3256 },
3257 {
3258 "raw_stack: skb_load_bytes, large access",
3259 .insns = {
3260 BPF_MOV64_IMM(BPF_REG_2, 4),
3261 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3262 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3263 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3264 BPF_MOV64_IMM(BPF_REG_4, 512),
3265 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3266 BPF_FUNC_skb_load_bytes),
3267 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3268 BPF_EXIT_INSN(),
3269 },
3270 .result = ACCEPT,
3271 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3272 },
3273 {
3274 "context stores via ST",
3275 .insns = {
3276 BPF_MOV64_IMM(BPF_REG_0, 0),
3277 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
3278 BPF_EXIT_INSN(),
3279 },
3280 .errstr = "BPF_ST stores into R1 context is not allowed",
3281 .result = REJECT,
3282 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3283 },
3284 {
3285 "context stores via XADD",
3286 .insns = {
3287 BPF_MOV64_IMM(BPF_REG_0, 0),
3288 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
3289 BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
3290 BPF_EXIT_INSN(),
3291 },
3292 .errstr = "BPF_XADD stores into R1 context is not allowed",
3293 .result = REJECT,
3294 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3295 },
3296 {
3297 "direct packet access: test1",
3298 .insns = {
3299 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3300 offsetof(struct __sk_buff, data)),
3301 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3302 offsetof(struct __sk_buff, data_end)),
3303 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3305 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3306 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3307 BPF_MOV64_IMM(BPF_REG_0, 0),
3308 BPF_EXIT_INSN(),
3309 },
3310 .result = ACCEPT,
3311 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3312 },
3313 {
3314 "direct packet access: test2",
3315 .insns = {
3316 BPF_MOV64_IMM(BPF_REG_0, 1),
3317 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
3318 offsetof(struct __sk_buff, data_end)),
3319 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3320 offsetof(struct __sk_buff, data)),
3321 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3322 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
3323 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
3324 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
3325 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
3326 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
3327 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3328 offsetof(struct __sk_buff, data)),
3329 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
3330 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3331 offsetof(struct __sk_buff, len)),
3332 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
3333 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
3334 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
3335 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
3336 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
3337 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
3338 offsetof(struct __sk_buff, data_end)),
3339 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3340 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
3341 BPF_MOV64_IMM(BPF_REG_0, 0),
3342 BPF_EXIT_INSN(),
3343 },
3344 .result = ACCEPT,
3345 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3346 },
3347 {
3348 "direct packet access: test3",
3349 .insns = {
3350 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3351 offsetof(struct __sk_buff, data)),
3352 BPF_MOV64_IMM(BPF_REG_0, 0),
3353 BPF_EXIT_INSN(),
3354 },
3355 .errstr = "invalid bpf_context access off=76",
3356 .result = REJECT,
3357 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
3358 },
3359 {
3360 "direct packet access: test4 (write)",
3361 .insns = {
3362 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3363 offsetof(struct __sk_buff, data)),
3364 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3365 offsetof(struct __sk_buff, data_end)),
3366 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3368 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3369 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3370 BPF_MOV64_IMM(BPF_REG_0, 0),
3371 BPF_EXIT_INSN(),
3372 },
3373 .result = ACCEPT,
3374 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3375 },
3376 {
3377 "direct packet access: test5 (pkt_end >= reg, good access)",
3378 .insns = {
3379 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3380 offsetof(struct __sk_buff, data)),
3381 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3382 offsetof(struct __sk_buff, data_end)),
3383 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3384 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3385 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3386 BPF_MOV64_IMM(BPF_REG_0, 1),
3387 BPF_EXIT_INSN(),
3388 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3389 BPF_MOV64_IMM(BPF_REG_0, 0),
3390 BPF_EXIT_INSN(),
3391 },
3392 .result = ACCEPT,
3393 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3394 },
3395 {
3396 "direct packet access: test6 (pkt_end >= reg, bad access)",
3397 .insns = {
3398 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3399 offsetof(struct __sk_buff, data)),
3400 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3401 offsetof(struct __sk_buff, data_end)),
3402 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3403 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3404 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3405 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3406 BPF_MOV64_IMM(BPF_REG_0, 1),
3407 BPF_EXIT_INSN(),
3408 BPF_MOV64_IMM(BPF_REG_0, 0),
3409 BPF_EXIT_INSN(),
3410 },
3411 .errstr = "invalid access to packet",
3412 .result = REJECT,
3413 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3414 },
3415 {
3416 "direct packet access: test7 (pkt_end >= reg, both accesses)",
3417 .insns = {
3418 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3419 offsetof(struct __sk_buff, data)),
3420 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3421 offsetof(struct __sk_buff, data_end)),
3422 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3424 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3425 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3426 BPF_MOV64_IMM(BPF_REG_0, 1),
3427 BPF_EXIT_INSN(),
3428 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3429 BPF_MOV64_IMM(BPF_REG_0, 0),
3430 BPF_EXIT_INSN(),
3431 },
3432 .errstr = "invalid access to packet",
3433 .result = REJECT,
3434 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3435 },
3436 {
3437 "direct packet access: test8 (double test, variant 1)",
3438 .insns = {
3439 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3440 offsetof(struct __sk_buff, data)),
3441 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3442 offsetof(struct __sk_buff, data_end)),
3443 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3445 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
3446 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3447 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3448 BPF_MOV64_IMM(BPF_REG_0, 1),
3449 BPF_EXIT_INSN(),
3450 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3451 BPF_MOV64_IMM(BPF_REG_0, 0),
3452 BPF_EXIT_INSN(),
3453 },
3454 .result = ACCEPT,
3455 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3456 },
3457 {
3458 "direct packet access: test9 (double test, variant 2)",
3459 .insns = {
3460 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3461 offsetof(struct __sk_buff, data)),
3462 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3463 offsetof(struct __sk_buff, data_end)),
3464 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3465 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3466 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3467 BPF_MOV64_IMM(BPF_REG_0, 1),
3468 BPF_EXIT_INSN(),
3469 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3470 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3471 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3472 BPF_MOV64_IMM(BPF_REG_0, 0),
3473 BPF_EXIT_INSN(),
3474 },
3475 .result = ACCEPT,
3476 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3477 },
3478 {
3479 "direct packet access: test10 (write invalid)",
3480 .insns = {
3481 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3482 offsetof(struct __sk_buff, data)),
3483 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3484 offsetof(struct __sk_buff, data_end)),
3485 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3486 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3487 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3488 BPF_MOV64_IMM(BPF_REG_0, 0),
3489 BPF_EXIT_INSN(),
3490 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3491 BPF_MOV64_IMM(BPF_REG_0, 0),
3492 BPF_EXIT_INSN(),
3493 },
3494 .errstr = "invalid access to packet",
3495 .result = REJECT,
3496 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3497 },
3498 {
3499 "direct packet access: test11 (shift, good access)",
3500 .insns = {
3501 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3502 offsetof(struct __sk_buff, data)),
3503 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3504 offsetof(struct __sk_buff, data_end)),
3505 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3506 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3507 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3508 BPF_MOV64_IMM(BPF_REG_3, 144),
3509 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3511 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
3512 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3513 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3514 BPF_MOV64_IMM(BPF_REG_0, 1),
3515 BPF_EXIT_INSN(),
3516 BPF_MOV64_IMM(BPF_REG_0, 0),
3517 BPF_EXIT_INSN(),
3518 },
3519 .result = ACCEPT,
3520 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3521 .retval = 1,
3522 },
3523 {
3524 "direct packet access: test12 (and, good access)",
3525 .insns = {
3526 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3527 offsetof(struct __sk_buff, data)),
3528 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3529 offsetof(struct __sk_buff, data_end)),
3530 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3531 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3532 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3533 BPF_MOV64_IMM(BPF_REG_3, 144),
3534 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3536 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3537 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3538 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3539 BPF_MOV64_IMM(BPF_REG_0, 1),
3540 BPF_EXIT_INSN(),
3541 BPF_MOV64_IMM(BPF_REG_0, 0),
3542 BPF_EXIT_INSN(),
3543 },
3544 .result = ACCEPT,
3545 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3546 .retval = 1,
3547 },
3548 {
3549 "direct packet access: test13 (branches, good access)",
3550 .insns = {
3551 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3552 offsetof(struct __sk_buff, data)),
3553 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3554 offsetof(struct __sk_buff, data_end)),
3555 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3557 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
3558 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3559 offsetof(struct __sk_buff, mark)),
3560 BPF_MOV64_IMM(BPF_REG_4, 1),
3561 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
3562 BPF_MOV64_IMM(BPF_REG_3, 14),
3563 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
3564 BPF_MOV64_IMM(BPF_REG_3, 24),
3565 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3566 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3567 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3568 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3569 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3570 BPF_MOV64_IMM(BPF_REG_0, 1),
3571 BPF_EXIT_INSN(),
3572 BPF_MOV64_IMM(BPF_REG_0, 0),
3573 BPF_EXIT_INSN(),
3574 },
3575 .result = ACCEPT,
3576 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3577 .retval = 1,
3578 },
3579 {
3580 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
3581 .insns = {
3582 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3583 offsetof(struct __sk_buff, data)),
3584 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3585 offsetof(struct __sk_buff, data_end)),
3586 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3588 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
3589 BPF_MOV64_IMM(BPF_REG_5, 12),
3590 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
3591 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3592 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3593 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
3594 BPF_MOV64_IMM(BPF_REG_0, 1),
3595 BPF_EXIT_INSN(),
3596 BPF_MOV64_IMM(BPF_REG_0, 0),
3597 BPF_EXIT_INSN(),
3598 },
3599 .result = ACCEPT,
3600 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3601 .retval = 1,
3602 },
3603 {
3604 "direct packet access: test15 (spill with xadd)",
3605 .insns = {
3606 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3607 offsetof(struct __sk_buff, data)),
3608 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3609 offsetof(struct __sk_buff, data_end)),
3610 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3611 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3612 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3613 BPF_MOV64_IMM(BPF_REG_5, 4096),
3614 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
3615 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
3616 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
3617 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
3618 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
3619 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
3620 BPF_MOV64_IMM(BPF_REG_0, 0),
3621 BPF_EXIT_INSN(),
3622 },
3623 .errstr = "R2 invalid mem access 'inv'",
3624 .result = REJECT,
3625 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3626 },
3627 {
3628 "direct packet access: test16 (arith on data_end)",
3629 .insns = {
3630 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3631 offsetof(struct __sk_buff, data)),
3632 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3633 offsetof(struct __sk_buff, data_end)),
3634 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3635 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3636 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
3637 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3638 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3639 BPF_MOV64_IMM(BPF_REG_0, 0),
3640 BPF_EXIT_INSN(),
3641 },
3642 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
3643 .result = REJECT,
3644 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3645 },
3646 {
3647 "direct packet access: test17 (pruning, alignment)",
3648 .insns = {
3649 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3650 offsetof(struct __sk_buff, data)),
3651 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3652 offsetof(struct __sk_buff, data_end)),
3653 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3654 offsetof(struct __sk_buff, mark)),
3655 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3656 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
3657 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
3658 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3659 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
3660 BPF_MOV64_IMM(BPF_REG_0, 0),
3661 BPF_EXIT_INSN(),
3662 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3663 BPF_JMP_A(-6),
3664 },
3665 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
3666 .result = REJECT,
3667 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3668 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
3669 },
3670 {
3671 "direct packet access: test18 (imm += pkt_ptr, 1)",
3672 .insns = {
3673 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3674 offsetof(struct __sk_buff, data)),
3675 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3676 offsetof(struct __sk_buff, data_end)),
3677 BPF_MOV64_IMM(BPF_REG_0, 8),
3678 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3679 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3680 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3681 BPF_MOV64_IMM(BPF_REG_0, 0),
3682 BPF_EXIT_INSN(),
3683 },
3684 .result = ACCEPT,
3685 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3686 },
3687 {
3688 "direct packet access: test19 (imm += pkt_ptr, 2)",
3689 .insns = {
3690 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3691 offsetof(struct __sk_buff, data)),
3692 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3693 offsetof(struct __sk_buff, data_end)),
3694 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3696 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
3697 BPF_MOV64_IMM(BPF_REG_4, 4),
3698 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3699 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
3700 BPF_MOV64_IMM(BPF_REG_0, 0),
3701 BPF_EXIT_INSN(),
3702 },
3703 .result = ACCEPT,
3704 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3705 },
3706 {
3707 "direct packet access: test20 (x += pkt_ptr, 1)",
3708 .insns = {
3709 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3710 offsetof(struct __sk_buff, data)),
3711 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3712 offsetof(struct __sk_buff, data_end)),
3713 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3714 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3715 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3716 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
3717 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3718 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3719 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3721 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3722 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3723 BPF_MOV64_IMM(BPF_REG_0, 0),
3724 BPF_EXIT_INSN(),
3725 },
3726 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3727 .result = ACCEPT,
3728 },
3729 {
3730 "direct packet access: test21 (x += pkt_ptr, 2)",
3731 .insns = {
3732 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3733 offsetof(struct __sk_buff, data)),
3734 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3735 offsetof(struct __sk_buff, data_end)),
3736 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3738 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3739 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3740 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3741 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3742 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
3743 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3744 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3746 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3747 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3748 BPF_MOV64_IMM(BPF_REG_0, 0),
3749 BPF_EXIT_INSN(),
3750 },
3751 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3752 .result = ACCEPT,
3753 },
3754 {
3755 "direct packet access: test22 (x += pkt_ptr, 3)",
3756 .insns = {
3757 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3758 offsetof(struct __sk_buff, data)),
3759 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3760 offsetof(struct __sk_buff, data_end)),
3761 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3762 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3763 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3764 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3765 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3766 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3767 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3768 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3769 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3770 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3771 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
3772 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3773 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3775 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3776 BPF_MOV64_IMM(BPF_REG_2, 1),
3777 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3778 BPF_MOV64_IMM(BPF_REG_0, 0),
3779 BPF_EXIT_INSN(),
3780 },
3781 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3782 .result = ACCEPT,
3783 },
3784 {
3785 "direct packet access: test23 (x += pkt_ptr, 4)",
3786 .insns = {
3787 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3788 offsetof(struct __sk_buff, data)),
3789 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3790 offsetof(struct __sk_buff, data_end)),
3791 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3792 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3793 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3794 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3795 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3796 BPF_MOV64_IMM(BPF_REG_0, 31),
3797 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3798 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3799 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3800 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3801 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3802 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3803 BPF_MOV64_IMM(BPF_REG_0, 0),
3804 BPF_EXIT_INSN(),
3805 },
3806 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3807 .result = REJECT,
3808 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
3809 },
3810 {
3811 "direct packet access: test24 (x += pkt_ptr, 5)",
3812 .insns = {
3813 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3814 offsetof(struct __sk_buff, data)),
3815 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3816 offsetof(struct __sk_buff, data_end)),
3817 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3818 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3819 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3820 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3821 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3822 BPF_MOV64_IMM(BPF_REG_0, 64),
3823 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3824 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3825 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3826 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
3827 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3828 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3829 BPF_MOV64_IMM(BPF_REG_0, 0),
3830 BPF_EXIT_INSN(),
3831 },
3832 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3833 .result = ACCEPT,
3834 },
3835 {
3836 "direct packet access: test25 (marking on <, good access)",
3837 .insns = {
3838 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3839 offsetof(struct __sk_buff, data)),
3840 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3841 offsetof(struct __sk_buff, data_end)),
3842 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3843 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3844 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
3845 BPF_MOV64_IMM(BPF_REG_0, 0),
3846 BPF_EXIT_INSN(),
3847 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3848 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3849 },
3850 .result = ACCEPT,
3851 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3852 },
3853 {
3854 "direct packet access: test26 (marking on <, bad access)",
3855 .insns = {
3856 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3857 offsetof(struct __sk_buff, data)),
3858 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3859 offsetof(struct __sk_buff, data_end)),
3860 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3861 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3862 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
3863 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3864 BPF_MOV64_IMM(BPF_REG_0, 0),
3865 BPF_EXIT_INSN(),
3866 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
3867 },
3868 .result = REJECT,
3869 .errstr = "invalid access to packet",
3870 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3871 },
3872 {
3873 "direct packet access: test27 (marking on <=, good access)",
3874 .insns = {
3875 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3876 offsetof(struct __sk_buff, data)),
3877 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3878 offsetof(struct __sk_buff, data_end)),
3879 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3880 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3881 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
3882 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3883 BPF_MOV64_IMM(BPF_REG_0, 1),
3884 BPF_EXIT_INSN(),
3885 },
3886 .result = ACCEPT,
3887 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3888 .retval = 1,
3889 },
3890 {
3891 "direct packet access: test28 (marking on <=, bad access)",
3892 .insns = {
3893 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3894 offsetof(struct __sk_buff, data)),
3895 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3896 offsetof(struct __sk_buff, data_end)),
3897 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3898 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3899 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
3900 BPF_MOV64_IMM(BPF_REG_0, 1),
3901 BPF_EXIT_INSN(),
3902 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3903 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3904 },
3905 .result = REJECT,
3906 .errstr = "invalid access to packet",
3907 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3908 },
3909 {
3910 "helper access to packet: test1, valid packet_ptr range",
3911 .insns = {
3912 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3913 offsetof(struct xdp_md, data)),
3914 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3915 offsetof(struct xdp_md, data_end)),
3916 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3917 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3918 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3919 BPF_LD_MAP_FD(BPF_REG_1, 0),
3920 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3921 BPF_MOV64_IMM(BPF_REG_4, 0),
3922 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3923 BPF_FUNC_map_update_elem),
3924 BPF_MOV64_IMM(BPF_REG_0, 0),
3925 BPF_EXIT_INSN(),
3926 },
3927 .fixup_map1 = { 5 },
3928 .result_unpriv = ACCEPT,
3929 .result = ACCEPT,
3930 .prog_type = BPF_PROG_TYPE_XDP,
3931 },
3932 {
3933 "helper access to packet: test2, unchecked packet_ptr",
3934 .insns = {
3935 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3936 offsetof(struct xdp_md, data)),
3937 BPF_LD_MAP_FD(BPF_REG_1, 0),
3938 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3939 BPF_FUNC_map_lookup_elem),
3940 BPF_MOV64_IMM(BPF_REG_0, 0),
3941 BPF_EXIT_INSN(),
3942 },
3943 .fixup_map1 = { 1 },
3944 .result = REJECT,
3945 .errstr = "invalid access to packet",
3946 .prog_type = BPF_PROG_TYPE_XDP,
3947 },
3948 {
3949 "helper access to packet: test3, variable add",
3950 .insns = {
3951 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3952 offsetof(struct xdp_md, data)),
3953 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3954 offsetof(struct xdp_md, data_end)),
3955 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3956 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3957 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3958 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3959 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3960 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3961 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3962 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3963 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3964 BPF_LD_MAP_FD(BPF_REG_1, 0),
3965 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
3966 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3967 BPF_FUNC_map_lookup_elem),
3968 BPF_MOV64_IMM(BPF_REG_0, 0),
3969 BPF_EXIT_INSN(),
3970 },
3971 .fixup_map1 = { 11 },
3972 .result = ACCEPT,
3973 .prog_type = BPF_PROG_TYPE_XDP,
3974 },
3975 {
3976 "helper access to packet: test4, packet_ptr with bad range",
3977 .insns = {
3978 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3979 offsetof(struct xdp_md, data)),
3980 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3981 offsetof(struct xdp_md, data_end)),
3982 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3983 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3984 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3985 BPF_MOV64_IMM(BPF_REG_0, 0),
3986 BPF_EXIT_INSN(),
3987 BPF_LD_MAP_FD(BPF_REG_1, 0),
3988 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3989 BPF_FUNC_map_lookup_elem),
3990 BPF_MOV64_IMM(BPF_REG_0, 0),
3991 BPF_EXIT_INSN(),
3992 },
3993 .fixup_map1 = { 7 },
3994 .result = REJECT,
3995 .errstr = "invalid access to packet",
3996 .prog_type = BPF_PROG_TYPE_XDP,
3997 },
3998 {
3999 "helper access to packet: test5, packet_ptr with too short range",
4000 .insns = {
4001 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4002 offsetof(struct xdp_md, data)),
4003 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4004 offsetof(struct xdp_md, data_end)),
4005 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4006 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4008 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4009 BPF_LD_MAP_FD(BPF_REG_1, 0),
4010 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4011 BPF_FUNC_map_lookup_elem),
4012 BPF_MOV64_IMM(BPF_REG_0, 0),
4013 BPF_EXIT_INSN(),
4014 },
4015 .fixup_map1 = { 6 },
4016 .result = REJECT,
4017 .errstr = "invalid access to packet",
4018 .prog_type = BPF_PROG_TYPE_XDP,
4019 },
4020 {
4021 "helper access to packet: test6, cls valid packet_ptr range",
4022 .insns = {
4023 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4024 offsetof(struct __sk_buff, data)),
4025 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4026 offsetof(struct __sk_buff, data_end)),
4027 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4028 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4029 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
4030 BPF_LD_MAP_FD(BPF_REG_1, 0),
4031 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
4032 BPF_MOV64_IMM(BPF_REG_4, 0),
4033 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4034 BPF_FUNC_map_update_elem),
4035 BPF_MOV64_IMM(BPF_REG_0, 0),
4036 BPF_EXIT_INSN(),
4037 },
4038 .fixup_map1 = { 5 },
4039 .result = ACCEPT,
4040 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4041 },
4042 {
4043 "helper access to packet: test7, cls unchecked packet_ptr",
4044 .insns = {
4045 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4046 offsetof(struct __sk_buff, data)),
4047 BPF_LD_MAP_FD(BPF_REG_1, 0),
4048 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4049 BPF_FUNC_map_lookup_elem),
4050 BPF_MOV64_IMM(BPF_REG_0, 0),
4051 BPF_EXIT_INSN(),
4052 },
4053 .fixup_map1 = { 1 },
4054 .result = REJECT,
4055 .errstr = "invalid access to packet",
4056 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4057 },
4058 {
4059 "helper access to packet: test8, cls variable add",
4060 .insns = {
4061 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4062 offsetof(struct __sk_buff, data)),
4063 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4064 offsetof(struct __sk_buff, data_end)),
4065 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
4067 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
4068 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
4069 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4070 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
4071 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
4072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
4073 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
4074 BPF_LD_MAP_FD(BPF_REG_1, 0),
4075 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
4076 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4077 BPF_FUNC_map_lookup_elem),
4078 BPF_MOV64_IMM(BPF_REG_0, 0),
4079 BPF_EXIT_INSN(),
4080 },
4081 .fixup_map1 = { 11 },
4082 .result = ACCEPT,
4083 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4084 },
4085 {
4086 "helper access to packet: test9, cls packet_ptr with bad range",
4087 .insns = {
4088 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4089 offsetof(struct __sk_buff, data)),
4090 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4091 offsetof(struct __sk_buff, data_end)),
4092 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4093 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
4094 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
4095 BPF_MOV64_IMM(BPF_REG_0, 0),
4096 BPF_EXIT_INSN(),
4097 BPF_LD_MAP_FD(BPF_REG_1, 0),
4098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4099 BPF_FUNC_map_lookup_elem),
4100 BPF_MOV64_IMM(BPF_REG_0, 0),
4101 BPF_EXIT_INSN(),
4102 },
4103 .fixup_map1 = { 7 },
4104 .result = REJECT,
4105 .errstr = "invalid access to packet",
4106 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4107 },
4108 {
4109 "helper access to packet: test10, cls packet_ptr with too short range",
4110 .insns = {
4111 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4112 offsetof(struct __sk_buff, data)),
4113 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4114 offsetof(struct __sk_buff, data_end)),
4115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4116 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4118 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4119 BPF_LD_MAP_FD(BPF_REG_1, 0),
4120 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4121 BPF_FUNC_map_lookup_elem),
4122 BPF_MOV64_IMM(BPF_REG_0, 0),
4123 BPF_EXIT_INSN(),
4124 },
4125 .fixup_map1 = { 6 },
4126 .result = REJECT,
4127 .errstr = "invalid access to packet",
4128 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4129 },
4130 {
4131 "helper access to packet: test11, cls unsuitable helper 1",
4132 .insns = {
4133 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4134 offsetof(struct __sk_buff, data)),
4135 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4136 offsetof(struct __sk_buff, data_end)),
4137 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4138 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4139 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
4140 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
4141 BPF_MOV64_IMM(BPF_REG_2, 0),
4142 BPF_MOV64_IMM(BPF_REG_4, 42),
4143 BPF_MOV64_IMM(BPF_REG_5, 0),
4144 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4145 BPF_FUNC_skb_store_bytes),
4146 BPF_MOV64_IMM(BPF_REG_0, 0),
4147 BPF_EXIT_INSN(),
4148 },
4149 .result = REJECT,
4150 .errstr = "helper access to the packet",
4151 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4152 },
4153 {
4154 "helper access to packet: test12, cls unsuitable helper 2",
4155 .insns = {
4156 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4157 offsetof(struct __sk_buff, data)),
4158 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4159 offsetof(struct __sk_buff, data_end)),
4160 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4161 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
4162 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
4163 BPF_MOV64_IMM(BPF_REG_2, 0),
4164 BPF_MOV64_IMM(BPF_REG_4, 4),
4165 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4166 BPF_FUNC_skb_load_bytes),
4167 BPF_MOV64_IMM(BPF_REG_0, 0),
4168 BPF_EXIT_INSN(),
4169 },
4170 .result = REJECT,
4171 .errstr = "helper access to the packet",
4172 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4173 },
4174 {
4175 "helper access to packet: test13, cls helper ok",
4176 .insns = {
4177 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4178 offsetof(struct __sk_buff, data)),
4179 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4180 offsetof(struct __sk_buff, data_end)),
4181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4182 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4184 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4185 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4186 BPF_MOV64_IMM(BPF_REG_2, 4),
4187 BPF_MOV64_IMM(BPF_REG_3, 0),
4188 BPF_MOV64_IMM(BPF_REG_4, 0),
4189 BPF_MOV64_IMM(BPF_REG_5, 0),
4190 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4191 BPF_FUNC_csum_diff),
4192 BPF_MOV64_IMM(BPF_REG_0, 0),
4193 BPF_EXIT_INSN(),
4194 },
4195 .result = ACCEPT,
4196 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4197 },
4198 {
4199 "helper access to packet: test14, cls helper ok sub",
4200 .insns = {
4201 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4202 offsetof(struct __sk_buff, data)),
4203 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4204 offsetof(struct __sk_buff, data_end)),
4205 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4206 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4208 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4209 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
4210 BPF_MOV64_IMM(BPF_REG_2, 4),
4211 BPF_MOV64_IMM(BPF_REG_3, 0),
4212 BPF_MOV64_IMM(BPF_REG_4, 0),
4213 BPF_MOV64_IMM(BPF_REG_5, 0),
4214 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4215 BPF_FUNC_csum_diff),
4216 BPF_MOV64_IMM(BPF_REG_0, 0),
4217 BPF_EXIT_INSN(),
4218 },
4219 .result = ACCEPT,
4220 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4221 },
4222 {
4223 "helper access to packet: test15, cls helper fail sub",
4224 .insns = {
4225 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4226 offsetof(struct __sk_buff, data)),
4227 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4228 offsetof(struct __sk_buff, data_end)),
4229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4230 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4231 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4232 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4233 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
4234 BPF_MOV64_IMM(BPF_REG_2, 4),
4235 BPF_MOV64_IMM(BPF_REG_3, 0),
4236 BPF_MOV64_IMM(BPF_REG_4, 0),
4237 BPF_MOV64_IMM(BPF_REG_5, 0),
4238 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4239 BPF_FUNC_csum_diff),
4240 BPF_MOV64_IMM(BPF_REG_0, 0),
4241 BPF_EXIT_INSN(),
4242 },
4243 .result = REJECT,
4244 .errstr = "invalid access to packet",
4245 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4246 },
4247 {
4248 "helper access to packet: test16, cls helper fail range 1",
4249 .insns = {
4250 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4251 offsetof(struct __sk_buff, data)),
4252 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4253 offsetof(struct __sk_buff, data_end)),
4254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4255 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4256 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4257 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4258 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4259 BPF_MOV64_IMM(BPF_REG_2, 8),
4260 BPF_MOV64_IMM(BPF_REG_3, 0),
4261 BPF_MOV64_IMM(BPF_REG_4, 0),
4262 BPF_MOV64_IMM(BPF_REG_5, 0),
4263 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4264 BPF_FUNC_csum_diff),
4265 BPF_MOV64_IMM(BPF_REG_0, 0),
4266 BPF_EXIT_INSN(),
4267 },
4268 .result = REJECT,
4269 .errstr = "invalid access to packet",
4270 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4271 },
4272 {
4273 "helper access to packet: test17, cls helper fail range 2",
4274 .insns = {
4275 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4276 offsetof(struct __sk_buff, data)),
4277 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4278 offsetof(struct __sk_buff, data_end)),
4279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4280 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4282 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4283 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4284 BPF_MOV64_IMM(BPF_REG_2, -9),
4285 BPF_MOV64_IMM(BPF_REG_3, 0),
4286 BPF_MOV64_IMM(BPF_REG_4, 0),
4287 BPF_MOV64_IMM(BPF_REG_5, 0),
4288 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4289 BPF_FUNC_csum_diff),
4290 BPF_MOV64_IMM(BPF_REG_0, 0),
4291 BPF_EXIT_INSN(),
4292 },
4293 .result = REJECT,
4294 .errstr = "R2 min value is negative",
4295 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4296 },
4297 {
4298 "helper access to packet: test18, cls helper fail range 3",
4299 .insns = {
4300 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4301 offsetof(struct __sk_buff, data)),
4302 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4303 offsetof(struct __sk_buff, data_end)),
4304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4305 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4307 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4308 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4309 BPF_MOV64_IMM(BPF_REG_2, ~0),
4310 BPF_MOV64_IMM(BPF_REG_3, 0),
4311 BPF_MOV64_IMM(BPF_REG_4, 0),
4312 BPF_MOV64_IMM(BPF_REG_5, 0),
4313 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4314 BPF_FUNC_csum_diff),
4315 BPF_MOV64_IMM(BPF_REG_0, 0),
4316 BPF_EXIT_INSN(),
4317 },
4318 .result = REJECT,
4319 .errstr = "R2 min value is negative",
4320 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4321 },
4322 {
4323 "helper access to packet: test19, cls helper range zero",
4324 .insns = {
4325 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4326 offsetof(struct __sk_buff, data)),
4327 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4328 offsetof(struct __sk_buff, data_end)),
4329 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4330 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4332 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4333 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4334 BPF_MOV64_IMM(BPF_REG_2, 0),
4335 BPF_MOV64_IMM(BPF_REG_3, 0),
4336 BPF_MOV64_IMM(BPF_REG_4, 0),
4337 BPF_MOV64_IMM(BPF_REG_5, 0),
4338 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4339 BPF_FUNC_csum_diff),
4340 BPF_MOV64_IMM(BPF_REG_0, 0),
4341 BPF_EXIT_INSN(),
4342 },
4343 .result = ACCEPT,
4344 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4345 },
4346 {
4347 "helper access to packet: test20, pkt end as input",
4348 .insns = {
4349 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4350 offsetof(struct __sk_buff, data)),
4351 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4352 offsetof(struct __sk_buff, data_end)),
4353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4354 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4355 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4356 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4357 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
4358 BPF_MOV64_IMM(BPF_REG_2, 4),
4359 BPF_MOV64_IMM(BPF_REG_3, 0),
4360 BPF_MOV64_IMM(BPF_REG_4, 0),
4361 BPF_MOV64_IMM(BPF_REG_5, 0),
4362 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4363 BPF_FUNC_csum_diff),
4364 BPF_MOV64_IMM(BPF_REG_0, 0),
4365 BPF_EXIT_INSN(),
4366 },
4367 .result = REJECT,
4368 .errstr = "R1 type=pkt_end expected=fp",
4369 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4370 },
4371 {
4372 "helper access to packet: test21, wrong reg",
4373 .insns = {
4374 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4375 offsetof(struct __sk_buff, data)),
4376 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4377 offsetof(struct __sk_buff, data_end)),
4378 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4380 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4381 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4382 BPF_MOV64_IMM(BPF_REG_2, 4),
4383 BPF_MOV64_IMM(BPF_REG_3, 0),
4384 BPF_MOV64_IMM(BPF_REG_4, 0),
4385 BPF_MOV64_IMM(BPF_REG_5, 0),
4386 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4387 BPF_FUNC_csum_diff),
4388 BPF_MOV64_IMM(BPF_REG_0, 0),
4389 BPF_EXIT_INSN(),
4390 },
4391 .result = REJECT,
4392 .errstr = "invalid access to packet",
4393 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4394 },
4395 {
4396 "valid map access into an array with a constant",
4397 .insns = {
4398 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4399 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4400 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4401 BPF_LD_MAP_FD(BPF_REG_1, 0),
4402 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4403 BPF_FUNC_map_lookup_elem),
4404 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4405 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4406 offsetof(struct test_val, foo)),
4407 BPF_EXIT_INSN(),
4408 },
4409 .fixup_map2 = { 3 },
4410 .errstr_unpriv = "R0 leaks addr",
4411 .result_unpriv = REJECT,
4412 .result = ACCEPT,
4413 },
4414 {
4415 "valid map access into an array with a register",
4416 .insns = {
4417 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4418 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4420 BPF_LD_MAP_FD(BPF_REG_1, 0),
4421 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4422 BPF_FUNC_map_lookup_elem),
4423 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4424 BPF_MOV64_IMM(BPF_REG_1, 4),
4425 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4426 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4427 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4428 offsetof(struct test_val, foo)),
4429 BPF_EXIT_INSN(),
4430 },
4431 .fixup_map2 = { 3 },
4432 .errstr_unpriv = "R0 leaks addr",
4433 .result_unpriv = REJECT,
4434 .result = ACCEPT,
4435 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4436 },
4437 {
4438 "valid map access into an array with a variable",
4439 .insns = {
4440 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4441 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4442 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4443 BPF_LD_MAP_FD(BPF_REG_1, 0),
4444 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4445 BPF_FUNC_map_lookup_elem),
4446 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4447 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4448 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
4449 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4450 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4451 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4452 offsetof(struct test_val, foo)),
4453 BPF_EXIT_INSN(),
4454 },
4455 .fixup_map2 = { 3 },
4456 .errstr_unpriv = "R0 leaks addr",
4457 .result_unpriv = REJECT,
4458 .result = ACCEPT,
4459 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4460 },
4461 {
4462 "valid map access into an array with a signed variable",
4463 .insns = {
4464 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4465 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4466 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4467 BPF_LD_MAP_FD(BPF_REG_1, 0),
4468 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4469 BPF_FUNC_map_lookup_elem),
4470 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
4471 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4472 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
4473 BPF_MOV32_IMM(BPF_REG_1, 0),
4474 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4475 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4476 BPF_MOV32_IMM(BPF_REG_1, 0),
4477 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4478 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4479 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4480 offsetof(struct test_val, foo)),
4481 BPF_EXIT_INSN(),
4482 },
4483 .fixup_map2 = { 3 },
4484 .errstr_unpriv = "R0 leaks addr",
4485 .result_unpriv = REJECT,
4486 .result = ACCEPT,
4487 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4488 },
4489 {
4490 "invalid map access into an array with a constant",
4491 .insns = {
4492 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4493 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4495 BPF_LD_MAP_FD(BPF_REG_1, 0),
4496 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4497 BPF_FUNC_map_lookup_elem),
4498 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4499 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
4500 offsetof(struct test_val, foo)),
4501 BPF_EXIT_INSN(),
4502 },
4503 .fixup_map2 = { 3 },
4504 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
4505 .result = REJECT,
4506 },
4507 {
4508 "invalid map access into an array with a register",
4509 .insns = {
4510 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4511 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4513 BPF_LD_MAP_FD(BPF_REG_1, 0),
4514 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4515 BPF_FUNC_map_lookup_elem),
4516 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4517 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
4518 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4519 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4520 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4521 offsetof(struct test_val, foo)),
4522 BPF_EXIT_INSN(),
4523 },
4524 .fixup_map2 = { 3 },
4525 .errstr = "R0 min value is outside of the array range",
4526 .result = REJECT,
4527 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4528 },
4529 {
4530 "invalid map access into an array with a variable",
4531 .insns = {
4532 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4535 BPF_LD_MAP_FD(BPF_REG_1, 0),
4536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4537 BPF_FUNC_map_lookup_elem),
4538 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4539 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4540 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4541 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4542 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4543 offsetof(struct test_val, foo)),
4544 BPF_EXIT_INSN(),
4545 },
4546 .fixup_map2 = { 3 },
4547 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
4548 .result = REJECT,
4549 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4550 },
4551 {
4552 "invalid map access into an array with no floor check",
4553 .insns = {
4554 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4555 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4557 BPF_LD_MAP_FD(BPF_REG_1, 0),
4558 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4559 BPF_FUNC_map_lookup_elem),
4560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4561 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4562 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4563 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4564 BPF_MOV32_IMM(BPF_REG_1, 0),
4565 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4566 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4567 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4568 offsetof(struct test_val, foo)),
4569 BPF_EXIT_INSN(),
4570 },
4571 .fixup_map2 = { 3 },
4572 .errstr_unpriv = "R0 leaks addr",
4573 .errstr = "R0 unbounded memory access",
4574 .result_unpriv = REJECT,
4575 .result = REJECT,
4576 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4577 },
4578 {
4579 "invalid map access into an array with a invalid max check",
4580 .insns = {
4581 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4582 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4584 BPF_LD_MAP_FD(BPF_REG_1, 0),
4585 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4586 BPF_FUNC_map_lookup_elem),
4587 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4588 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4589 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
4590 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
4591 BPF_MOV32_IMM(BPF_REG_1, 0),
4592 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4593 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4594 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4595 offsetof(struct test_val, foo)),
4596 BPF_EXIT_INSN(),
4597 },
4598 .fixup_map2 = { 3 },
4599 .errstr_unpriv = "R0 leaks addr",
4600 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
4601 .result_unpriv = REJECT,
4602 .result = REJECT,
4603 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4604 },
4605 {
4606 "invalid map access into an array with a invalid max check",
4607 .insns = {
4608 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4609 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4610 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4611 BPF_LD_MAP_FD(BPF_REG_1, 0),
4612 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4613 BPF_FUNC_map_lookup_elem),
4614 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4615 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4616 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4617 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4618 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4619 BPF_LD_MAP_FD(BPF_REG_1, 0),
4620 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4621 BPF_FUNC_map_lookup_elem),
4622 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4623 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
4624 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
4625 offsetof(struct test_val, foo)),
4626 BPF_EXIT_INSN(),
4627 },
4628 .fixup_map2 = { 3, 11 },
4629 .errstr = "R0 pointer += pointer",
4630 .result = REJECT,
4631 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4632 },
4633 {
4634 "multiple registers share map_lookup_elem result",
4635 .insns = {
4636 BPF_MOV64_IMM(BPF_REG_1, 10),
4637 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4638 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4639 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4640 BPF_LD_MAP_FD(BPF_REG_1, 0),
4641 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4642 BPF_FUNC_map_lookup_elem),
4643 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4644 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4645 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4646 BPF_EXIT_INSN(),
4647 },
4648 .fixup_map1 = { 4 },
4649 .result = ACCEPT,
4650 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4651 },
4652 {
4653 "alu ops on ptr_to_map_value_or_null, 1",
4654 .insns = {
4655 BPF_MOV64_IMM(BPF_REG_1, 10),
4656 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4657 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4659 BPF_LD_MAP_FD(BPF_REG_1, 0),
4660 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4661 BPF_FUNC_map_lookup_elem),
4662 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
4664 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
4665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4666 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4667 BPF_EXIT_INSN(),
4668 },
4669 .fixup_map1 = { 4 },
4670 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4671 .result = REJECT,
4672 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4673 },
4674 {
4675 "alu ops on ptr_to_map_value_or_null, 2",
4676 .insns = {
4677 BPF_MOV64_IMM(BPF_REG_1, 10),
4678 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4679 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4681 BPF_LD_MAP_FD(BPF_REG_1, 0),
4682 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4683 BPF_FUNC_map_lookup_elem),
4684 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4685 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
4686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4687 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4688 BPF_EXIT_INSN(),
4689 },
4690 .fixup_map1 = { 4 },
4691 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4692 .result = REJECT,
4693 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4694 },
4695 {
4696 "alu ops on ptr_to_map_value_or_null, 3",
4697 .insns = {
4698 BPF_MOV64_IMM(BPF_REG_1, 10),
4699 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4700 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4701 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4702 BPF_LD_MAP_FD(BPF_REG_1, 0),
4703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4704 BPF_FUNC_map_lookup_elem),
4705 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4706 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4707 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4708 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4709 BPF_EXIT_INSN(),
4710 },
4711 .fixup_map1 = { 4 },
4712 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4713 .result = REJECT,
4714 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4715 },
4716 {
4717 "invalid memory access with multiple map_lookup_elem calls",
4718 .insns = {
4719 BPF_MOV64_IMM(BPF_REG_1, 10),
4720 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4721 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4722 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4723 BPF_LD_MAP_FD(BPF_REG_1, 0),
4724 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4725 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4726 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4727 BPF_FUNC_map_lookup_elem),
4728 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4729 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4730 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4731 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4732 BPF_FUNC_map_lookup_elem),
4733 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4734 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4735 BPF_EXIT_INSN(),
4736 },
4737 .fixup_map1 = { 4 },
4738 .result = REJECT,
4739 .errstr = "R4 !read_ok",
4740 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4741 },
4742 {
4743 "valid indirect map_lookup_elem access with 2nd lookup in branch",
4744 .insns = {
4745 BPF_MOV64_IMM(BPF_REG_1, 10),
4746 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4747 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4748 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4749 BPF_LD_MAP_FD(BPF_REG_1, 0),
4750 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4751 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4752 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4753 BPF_FUNC_map_lookup_elem),
4754 BPF_MOV64_IMM(BPF_REG_2, 10),
4755 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
4756 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4757 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4758 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4759 BPF_FUNC_map_lookup_elem),
4760 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4761 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4762 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4763 BPF_EXIT_INSN(),
4764 },
4765 .fixup_map1 = { 4 },
4766 .result = ACCEPT,
4767 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4768 },
4769 {
4770 "invalid map access from else condition",
4771 .insns = {
4772 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4773 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4775 BPF_LD_MAP_FD(BPF_REG_1, 0),
4776 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
4777 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4778 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4779 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
4780 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4781 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4782 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4783 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
4784 BPF_EXIT_INSN(),
4785 },
4786 .fixup_map2 = { 3 },
4787 .errstr = "R0 unbounded memory access",
4788 .result = REJECT,
4789 .errstr_unpriv = "R0 leaks addr",
4790 .result_unpriv = REJECT,
4791 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4792 },
4793 {
4794 "constant register |= constant should keep constant type",
4795 .insns = {
4796 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4798 BPF_MOV64_IMM(BPF_REG_2, 34),
4799 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
4800 BPF_MOV64_IMM(BPF_REG_3, 0),
4801 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4802 BPF_EXIT_INSN(),
4803 },
4804 .result = ACCEPT,
4805 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4806 },
4807 {
4808 "constant register |= constant should not bypass stack boundary checks",
4809 .insns = {
4810 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4812 BPF_MOV64_IMM(BPF_REG_2, 34),
4813 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
4814 BPF_MOV64_IMM(BPF_REG_3, 0),
4815 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4816 BPF_EXIT_INSN(),
4817 },
4818 .errstr = "invalid stack type R1 off=-48 access_size=58",
4819 .result = REJECT,
4820 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4821 },
4822 {
4823 "constant register |= constant register should keep constant type",
4824 .insns = {
4825 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4826 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4827 BPF_MOV64_IMM(BPF_REG_2, 34),
4828 BPF_MOV64_IMM(BPF_REG_4, 13),
4829 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4830 BPF_MOV64_IMM(BPF_REG_3, 0),
4831 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4832 BPF_EXIT_INSN(),
4833 },
4834 .result = ACCEPT,
4835 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4836 },
4837 {
4838 "constant register |= constant register should not bypass stack boundary checks",
4839 .insns = {
4840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4842 BPF_MOV64_IMM(BPF_REG_2, 34),
4843 BPF_MOV64_IMM(BPF_REG_4, 24),
4844 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4845 BPF_MOV64_IMM(BPF_REG_3, 0),
4846 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4847 BPF_EXIT_INSN(),
4848 },
4849 .errstr = "invalid stack type R1 off=-48 access_size=58",
4850 .result = REJECT,
4851 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4852 },
4853 {
4854 "invalid direct packet write for LWT_IN",
4855 .insns = {
4856 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4857 offsetof(struct __sk_buff, data)),
4858 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4859 offsetof(struct __sk_buff, data_end)),
4860 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4861 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4862 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4863 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4864 BPF_MOV64_IMM(BPF_REG_0, 0),
4865 BPF_EXIT_INSN(),
4866 },
4867 .errstr = "cannot write into packet",
4868 .result = REJECT,
4869 .prog_type = BPF_PROG_TYPE_LWT_IN,
4870 },
4871 {
4872 "invalid direct packet write for LWT_OUT",
4873 .insns = {
4874 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4875 offsetof(struct __sk_buff, data)),
4876 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4877 offsetof(struct __sk_buff, data_end)),
4878 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4879 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4880 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4881 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4882 BPF_MOV64_IMM(BPF_REG_0, 0),
4883 BPF_EXIT_INSN(),
4884 },
4885 .errstr = "cannot write into packet",
4886 .result = REJECT,
4887 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4888 },
4889 {
4890 "direct packet write for LWT_XMIT",
4891 .insns = {
4892 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4893 offsetof(struct __sk_buff, data)),
4894 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4895 offsetof(struct __sk_buff, data_end)),
4896 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4898 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4899 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4900 BPF_MOV64_IMM(BPF_REG_0, 0),
4901 BPF_EXIT_INSN(),
4902 },
4903 .result = ACCEPT,
4904 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4905 },
4906 {
4907 "direct packet read for LWT_IN",
4908 .insns = {
4909 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4910 offsetof(struct __sk_buff, data)),
4911 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4912 offsetof(struct __sk_buff, data_end)),
4913 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4914 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4915 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4916 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4917 BPF_MOV64_IMM(BPF_REG_0, 0),
4918 BPF_EXIT_INSN(),
4919 },
4920 .result = ACCEPT,
4921 .prog_type = BPF_PROG_TYPE_LWT_IN,
4922 },
4923 {
4924 "direct packet read for LWT_OUT",
4925 .insns = {
4926 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4927 offsetof(struct __sk_buff, data)),
4928 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4929 offsetof(struct __sk_buff, data_end)),
4930 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4931 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4932 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4933 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4934 BPF_MOV64_IMM(BPF_REG_0, 0),
4935 BPF_EXIT_INSN(),
4936 },
4937 .result = ACCEPT,
4938 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4939 },
4940 {
4941 "direct packet read for LWT_XMIT",
4942 .insns = {
4943 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4944 offsetof(struct __sk_buff, data)),
4945 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4946 offsetof(struct __sk_buff, data_end)),
4947 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4948 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4949 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4950 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4951 BPF_MOV64_IMM(BPF_REG_0, 0),
4952 BPF_EXIT_INSN(),
4953 },
4954 .result = ACCEPT,
4955 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4956 },
4957 {
4958 "overlapping checks for direct packet access",
4959 .insns = {
4960 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4961 offsetof(struct __sk_buff, data)),
4962 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4963 offsetof(struct __sk_buff, data_end)),
4964 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4965 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4966 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
4967 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
4969 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
4970 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
4971 BPF_MOV64_IMM(BPF_REG_0, 0),
4972 BPF_EXIT_INSN(),
4973 },
4974 .result = ACCEPT,
4975 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4976 },
4977 {
4978 "make headroom for LWT_XMIT",
4979 .insns = {
4980 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
4981 BPF_MOV64_IMM(BPF_REG_2, 34),
4982 BPF_MOV64_IMM(BPF_REG_3, 0),
4983 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
4984 /* split for s390 to succeed */
4985 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4986 BPF_MOV64_IMM(BPF_REG_2, 42),
4987 BPF_MOV64_IMM(BPF_REG_3, 0),
4988 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
4989 BPF_MOV64_IMM(BPF_REG_0, 0),
4990 BPF_EXIT_INSN(),
4991 },
4992 .result = ACCEPT,
4993 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4994 },
4995 {
4996 "invalid access of tc_classid for LWT_IN",
4997 .insns = {
4998 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4999 offsetof(struct __sk_buff, tc_classid)),
5000 BPF_EXIT_INSN(),
5001 },
5002 .result = REJECT,
5003 .errstr = "invalid bpf_context access",
5004 },
5005 {
5006 "invalid access of tc_classid for LWT_OUT",
5007 .insns = {
5008 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5009 offsetof(struct __sk_buff, tc_classid)),
5010 BPF_EXIT_INSN(),
5011 },
5012 .result = REJECT,
5013 .errstr = "invalid bpf_context access",
5014 },
5015 {
5016 "invalid access of tc_classid for LWT_XMIT",
5017 .insns = {
5018 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5019 offsetof(struct __sk_buff, tc_classid)),
5020 BPF_EXIT_INSN(),
5021 },
5022 .result = REJECT,
5023 .errstr = "invalid bpf_context access",
5024 },
5025 {
5026 "leak pointer into ctx 1",
5027 .insns = {
5028 BPF_MOV64_IMM(BPF_REG_0, 0),
5029 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5030 offsetof(struct __sk_buff, cb[0])),
5031 BPF_LD_MAP_FD(BPF_REG_2, 0),
5032 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
5033 offsetof(struct __sk_buff, cb[0])),
5034 BPF_EXIT_INSN(),
5035 },
5036 .fixup_map1 = { 2 },
5037 .errstr_unpriv = "R2 leaks addr into mem",
5038 .result_unpriv = REJECT,
5039 .result = REJECT,
5040 .errstr = "BPF_XADD stores into R1 context is not allowed",
5041 },
5042 {
5043 "leak pointer into ctx 2",
5044 .insns = {
5045 BPF_MOV64_IMM(BPF_REG_0, 0),
5046 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5047 offsetof(struct __sk_buff, cb[0])),
5048 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
5049 offsetof(struct __sk_buff, cb[0])),
5050 BPF_EXIT_INSN(),
5051 },
5052 .errstr_unpriv = "R10 leaks addr into mem",
5053 .result_unpriv = REJECT,
5054 .result = REJECT,
5055 .errstr = "BPF_XADD stores into R1 context is not allowed",
5056 },
5057 {
5058 "leak pointer into ctx 3",
5059 .insns = {
5060 BPF_MOV64_IMM(BPF_REG_0, 0),
5061 BPF_LD_MAP_FD(BPF_REG_2, 0),
5062 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
5063 offsetof(struct __sk_buff, cb[0])),
5064 BPF_EXIT_INSN(),
5065 },
5066 .fixup_map1 = { 1 },
5067 .errstr_unpriv = "R2 leaks addr into ctx",
5068 .result_unpriv = REJECT,
5069 .result = ACCEPT,
5070 },
5071 {
5072 "leak pointer into map val",
5073 .insns = {
5074 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5075 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5076 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5077 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5078 BPF_LD_MAP_FD(BPF_REG_1, 0),
5079 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5080 BPF_FUNC_map_lookup_elem),
5081 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5082 BPF_MOV64_IMM(BPF_REG_3, 0),
5083 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
5084 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
5085 BPF_MOV64_IMM(BPF_REG_0, 0),
5086 BPF_EXIT_INSN(),
5087 },
5088 .fixup_map1 = { 4 },
5089 .errstr_unpriv = "R6 leaks addr into mem",
5090 .result_unpriv = REJECT,
5091 .result = ACCEPT,
5092 },
5093 {
5094 "helper access to map: full range",
5095 .insns = {
5096 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5098 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5099 BPF_LD_MAP_FD(BPF_REG_1, 0),
5100 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5101 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5102 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5103 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5104 BPF_MOV64_IMM(BPF_REG_3, 0),
5105 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5106 BPF_EXIT_INSN(),
5107 },
5108 .fixup_map2 = { 3 },
5109 .result = ACCEPT,
5110 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5111 },
5112 {
5113 "helper access to map: partial range",
5114 .insns = {
5115 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5117 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5118 BPF_LD_MAP_FD(BPF_REG_1, 0),
5119 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5120 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5121 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5122 BPF_MOV64_IMM(BPF_REG_2, 8),
5123 BPF_MOV64_IMM(BPF_REG_3, 0),
5124 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5125 BPF_EXIT_INSN(),
5126 },
5127 .fixup_map2 = { 3 },
5128 .result = ACCEPT,
5129 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5130 },
5131 {
5132 "helper access to map: empty range",
5133 .insns = {
5134 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5136 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5137 BPF_LD_MAP_FD(BPF_REG_1, 0),
5138 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5139 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5140 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5141 BPF_MOV64_IMM(BPF_REG_2, 0),
5142 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5143 BPF_EXIT_INSN(),
5144 },
5145 .fixup_map2 = { 3 },
5146 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
5147 .result = REJECT,
5148 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5149 },
5150 {
5151 "helper access to map: out-of-bound range",
5152 .insns = {
5153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5155 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5156 BPF_LD_MAP_FD(BPF_REG_1, 0),
5157 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5158 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5159 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5160 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
5161 BPF_MOV64_IMM(BPF_REG_3, 0),
5162 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5163 BPF_EXIT_INSN(),
5164 },
5165 .fixup_map2 = { 3 },
5166 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
5167 .result = REJECT,
5168 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5169 },
5170 {
5171 "helper access to map: negative range",
5172 .insns = {
5173 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5175 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5176 BPF_LD_MAP_FD(BPF_REG_1, 0),
5177 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5178 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5179 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5180 BPF_MOV64_IMM(BPF_REG_2, -8),
5181 BPF_MOV64_IMM(BPF_REG_3, 0),
5182 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5183 BPF_EXIT_INSN(),
5184 },
5185 .fixup_map2 = { 3 },
5186 .errstr = "R2 min value is negative",
5187 .result = REJECT,
5188 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5189 },
5190 {
5191 "helper access to adjusted map (via const imm): full range",
5192 .insns = {
5193 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5195 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5196 BPF_LD_MAP_FD(BPF_REG_1, 0),
5197 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5198 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5199 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5200 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5201 offsetof(struct test_val, foo)),
5202 BPF_MOV64_IMM(BPF_REG_2,
5203 sizeof(struct test_val) -
5204 offsetof(struct test_val, foo)),
5205 BPF_MOV64_IMM(BPF_REG_3, 0),
5206 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5207 BPF_EXIT_INSN(),
5208 },
5209 .fixup_map2 = { 3 },
5210 .result = ACCEPT,
5211 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5212 },
5213 {
5214 "helper access to adjusted map (via const imm): partial range",
5215 .insns = {
5216 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5218 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5219 BPF_LD_MAP_FD(BPF_REG_1, 0),
5220 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5221 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5222 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5223 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5224 offsetof(struct test_val, foo)),
5225 BPF_MOV64_IMM(BPF_REG_2, 8),
5226 BPF_MOV64_IMM(BPF_REG_3, 0),
5227 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5228 BPF_EXIT_INSN(),
5229 },
5230 .fixup_map2 = { 3 },
5231 .result = ACCEPT,
5232 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5233 },
5234 {
5235 "helper access to adjusted map (via const imm): empty range",
5236 .insns = {
5237 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5239 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5240 BPF_LD_MAP_FD(BPF_REG_1, 0),
5241 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5243 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5244 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5245 offsetof(struct test_val, foo)),
5246 BPF_MOV64_IMM(BPF_REG_2, 0),
5247 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5248 BPF_EXIT_INSN(),
5249 },
5250 .fixup_map2 = { 3 },
5251 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
5252 .result = REJECT,
5253 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5254 },
5255 {
5256 "helper access to adjusted map (via const imm): out-of-bound range",
5257 .insns = {
5258 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5260 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5261 BPF_LD_MAP_FD(BPF_REG_1, 0),
5262 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5266 offsetof(struct test_val, foo)),
5267 BPF_MOV64_IMM(BPF_REG_2,
5268 sizeof(struct test_val) -
5269 offsetof(struct test_val, foo) + 8),
5270 BPF_MOV64_IMM(BPF_REG_3, 0),
5271 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5272 BPF_EXIT_INSN(),
5273 },
5274 .fixup_map2 = { 3 },
5275 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5276 .result = REJECT,
5277 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5278 },
5279 {
5280 "helper access to adjusted map (via const imm): negative range (> adjustment)",
5281 .insns = {
5282 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5284 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5285 BPF_LD_MAP_FD(BPF_REG_1, 0),
5286 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5287 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5288 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5289 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5290 offsetof(struct test_val, foo)),
5291 BPF_MOV64_IMM(BPF_REG_2, -8),
5292 BPF_MOV64_IMM(BPF_REG_3, 0),
5293 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5294 BPF_EXIT_INSN(),
5295 },
5296 .fixup_map2 = { 3 },
5297 .errstr = "R2 min value is negative",
5298 .result = REJECT,
5299 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5300 },
5301 {
5302 "helper access to adjusted map (via const imm): negative range (< adjustment)",
5303 .insns = {
5304 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5305 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5306 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5307 BPF_LD_MAP_FD(BPF_REG_1, 0),
5308 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5309 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5310 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5311 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5312 offsetof(struct test_val, foo)),
5313 BPF_MOV64_IMM(BPF_REG_2, -1),
5314 BPF_MOV64_IMM(BPF_REG_3, 0),
5315 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5316 BPF_EXIT_INSN(),
5317 },
5318 .fixup_map2 = { 3 },
5319 .errstr = "R2 min value is negative",
5320 .result = REJECT,
5321 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5322 },
5323 {
5324 "helper access to adjusted map (via const reg): full range",
5325 .insns = {
5326 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5327 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5328 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5329 BPF_LD_MAP_FD(BPF_REG_1, 0),
5330 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5331 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5332 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5333 BPF_MOV64_IMM(BPF_REG_3,
5334 offsetof(struct test_val, foo)),
5335 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5336 BPF_MOV64_IMM(BPF_REG_2,
5337 sizeof(struct test_val) -
5338 offsetof(struct test_val, foo)),
5339 BPF_MOV64_IMM(BPF_REG_3, 0),
5340 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5341 BPF_EXIT_INSN(),
5342 },
5343 .fixup_map2 = { 3 },
5344 .result = ACCEPT,
5345 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5346 },
5347 {
5348 "helper access to adjusted map (via const reg): partial range",
5349 .insns = {
5350 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5351 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5352 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5353 BPF_LD_MAP_FD(BPF_REG_1, 0),
5354 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5355 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5356 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5357 BPF_MOV64_IMM(BPF_REG_3,
5358 offsetof(struct test_val, foo)),
5359 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5360 BPF_MOV64_IMM(BPF_REG_2, 8),
5361 BPF_MOV64_IMM(BPF_REG_3, 0),
5362 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5363 BPF_EXIT_INSN(),
5364 },
5365 .fixup_map2 = { 3 },
5366 .result = ACCEPT,
5367 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5368 },
5369 {
5370 "helper access to adjusted map (via const reg): empty range",
5371 .insns = {
5372 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5373 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5374 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5375 BPF_LD_MAP_FD(BPF_REG_1, 0),
5376 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5377 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5378 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5379 BPF_MOV64_IMM(BPF_REG_3, 0),
5380 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5381 BPF_MOV64_IMM(BPF_REG_2, 0),
5382 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5383 BPF_EXIT_INSN(),
5384 },
5385 .fixup_map2 = { 3 },
5386 .errstr = "R1 min value is outside of the array range",
5387 .result = REJECT,
5388 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5389 },
5390 {
5391 "helper access to adjusted map (via const reg): out-of-bound range",
5392 .insns = {
5393 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5395 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5396 BPF_LD_MAP_FD(BPF_REG_1, 0),
5397 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5398 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5399 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5400 BPF_MOV64_IMM(BPF_REG_3,
5401 offsetof(struct test_val, foo)),
5402 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5403 BPF_MOV64_IMM(BPF_REG_2,
5404 sizeof(struct test_val) -
5405 offsetof(struct test_val, foo) + 8),
5406 BPF_MOV64_IMM(BPF_REG_3, 0),
5407 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5408 BPF_EXIT_INSN(),
5409 },
5410 .fixup_map2 = { 3 },
5411 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5412 .result = REJECT,
5413 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5414 },
5415 {
5416 "helper access to adjusted map (via const reg): negative range (> adjustment)",
5417 .insns = {
5418 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5420 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5421 BPF_LD_MAP_FD(BPF_REG_1, 0),
5422 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5423 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5424 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5425 BPF_MOV64_IMM(BPF_REG_3,
5426 offsetof(struct test_val, foo)),
5427 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5428 BPF_MOV64_IMM(BPF_REG_2, -8),
5429 BPF_MOV64_IMM(BPF_REG_3, 0),
5430 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5431 BPF_EXIT_INSN(),
5432 },
5433 .fixup_map2 = { 3 },
5434 .errstr = "R2 min value is negative",
5435 .result = REJECT,
5436 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5437 },
5438 {
5439 "helper access to adjusted map (via const reg): negative range (< adjustment)",
5440 .insns = {
5441 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5442 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5443 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5444 BPF_LD_MAP_FD(BPF_REG_1, 0),
5445 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5446 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5447 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5448 BPF_MOV64_IMM(BPF_REG_3,
5449 offsetof(struct test_val, foo)),
5450 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5451 BPF_MOV64_IMM(BPF_REG_2, -1),
5452 BPF_MOV64_IMM(BPF_REG_3, 0),
5453 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5454 BPF_EXIT_INSN(),
5455 },
5456 .fixup_map2 = { 3 },
5457 .errstr = "R2 min value is negative",
5458 .result = REJECT,
5459 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5460 },
5461 {
5462 "helper access to adjusted map (via variable): full range",
5463 .insns = {
5464 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5465 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5466 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5467 BPF_LD_MAP_FD(BPF_REG_1, 0),
5468 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5469 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5470 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5471 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5472 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5473 offsetof(struct test_val, foo), 4),
5474 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5475 BPF_MOV64_IMM(BPF_REG_2,
5476 sizeof(struct test_val) -
5477 offsetof(struct test_val, foo)),
5478 BPF_MOV64_IMM(BPF_REG_3, 0),
5479 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5480 BPF_EXIT_INSN(),
5481 },
5482 .fixup_map2 = { 3 },
5483 .result = ACCEPT,
5484 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5485 },
5486 {
5487 "helper access to adjusted map (via variable): partial range",
5488 .insns = {
5489 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5490 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5491 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5492 BPF_LD_MAP_FD(BPF_REG_1, 0),
5493 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5494 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5495 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5496 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5497 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5498 offsetof(struct test_val, foo), 4),
5499 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5500 BPF_MOV64_IMM(BPF_REG_2, 8),
5501 BPF_MOV64_IMM(BPF_REG_3, 0),
5502 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5503 BPF_EXIT_INSN(),
5504 },
5505 .fixup_map2 = { 3 },
5506 .result = ACCEPT,
5507 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5508 },
5509 {
5510 "helper access to adjusted map (via variable): empty range",
5511 .insns = {
5512 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5513 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5514 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5515 BPF_LD_MAP_FD(BPF_REG_1, 0),
5516 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5517 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5518 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5519 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5520 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5521 offsetof(struct test_val, foo), 3),
5522 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5523 BPF_MOV64_IMM(BPF_REG_2, 0),
5524 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5525 BPF_EXIT_INSN(),
5526 },
5527 .fixup_map2 = { 3 },
5528 .errstr = "R1 min value is outside of the array range",
5529 .result = REJECT,
5530 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5531 },
5532 {
5533 "helper access to adjusted map (via variable): no max check",
5534 .insns = {
5535 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5536 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5537 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5538 BPF_LD_MAP_FD(BPF_REG_1, 0),
5539 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5540 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5541 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5542 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5543 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5544 BPF_MOV64_IMM(BPF_REG_2, 1),
5545 BPF_MOV64_IMM(BPF_REG_3, 0),
5546 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5547 BPF_EXIT_INSN(),
5548 },
5549 .fixup_map2 = { 3 },
5550 .errstr = "R1 unbounded memory access",
5551 .result = REJECT,
5552 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5553 },
5554 {
5555 "helper access to adjusted map (via variable): wrong max check",
5556 .insns = {
5557 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5559 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5560 BPF_LD_MAP_FD(BPF_REG_1, 0),
5561 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5562 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5563 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5564 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5565 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5566 offsetof(struct test_val, foo), 4),
5567 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5568 BPF_MOV64_IMM(BPF_REG_2,
5569 sizeof(struct test_val) -
5570 offsetof(struct test_val, foo) + 1),
5571 BPF_MOV64_IMM(BPF_REG_3, 0),
5572 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5573 BPF_EXIT_INSN(),
5574 },
5575 .fixup_map2 = { 3 },
5576 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
5577 .result = REJECT,
5578 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5579 },
5580 {
5581 "helper access to map: bounds check using <, good access",
5582 .insns = {
5583 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5584 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5585 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5586 BPF_LD_MAP_FD(BPF_REG_1, 0),
5587 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5588 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5589 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5590 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5591 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
5592 BPF_MOV64_IMM(BPF_REG_0, 0),
5593 BPF_EXIT_INSN(),
5594 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5595 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5596 BPF_MOV64_IMM(BPF_REG_0, 0),
5597 BPF_EXIT_INSN(),
5598 },
5599 .fixup_map2 = { 3 },
5600 .result = ACCEPT,
5601 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5602 },
5603 {
5604 "helper access to map: bounds check using <, bad access",
5605 .insns = {
5606 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5608 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5609 BPF_LD_MAP_FD(BPF_REG_1, 0),
5610 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5611 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5612 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5613 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5614 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
5615 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5616 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5617 BPF_MOV64_IMM(BPF_REG_0, 0),
5618 BPF_EXIT_INSN(),
5619 BPF_MOV64_IMM(BPF_REG_0, 0),
5620 BPF_EXIT_INSN(),
5621 },
5622 .fixup_map2 = { 3 },
5623 .result = REJECT,
5624 .errstr = "R1 unbounded memory access",
5625 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5626 },
5627 {
5628 "helper access to map: bounds check using <=, good access",
5629 .insns = {
5630 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5632 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5633 BPF_LD_MAP_FD(BPF_REG_1, 0),
5634 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5635 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5636 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5637 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5638 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
5639 BPF_MOV64_IMM(BPF_REG_0, 0),
5640 BPF_EXIT_INSN(),
5641 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5642 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5643 BPF_MOV64_IMM(BPF_REG_0, 0),
5644 BPF_EXIT_INSN(),
5645 },
5646 .fixup_map2 = { 3 },
5647 .result = ACCEPT,
5648 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5649 },
5650 {
5651 "helper access to map: bounds check using <=, bad access",
5652 .insns = {
5653 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5655 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5656 BPF_LD_MAP_FD(BPF_REG_1, 0),
5657 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5658 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5659 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5660 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5661 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
5662 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5663 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5664 BPF_MOV64_IMM(BPF_REG_0, 0),
5665 BPF_EXIT_INSN(),
5666 BPF_MOV64_IMM(BPF_REG_0, 0),
5667 BPF_EXIT_INSN(),
5668 },
5669 .fixup_map2 = { 3 },
5670 .result = REJECT,
5671 .errstr = "R1 unbounded memory access",
5672 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5673 },
5674 {
5675 "helper access to map: bounds check using s<, good access",
5676 .insns = {
5677 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5679 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5680 BPF_LD_MAP_FD(BPF_REG_1, 0),
5681 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5683 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5684 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5685 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5686 BPF_MOV64_IMM(BPF_REG_0, 0),
5687 BPF_EXIT_INSN(),
5688 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
5689 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5690 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5691 BPF_MOV64_IMM(BPF_REG_0, 0),
5692 BPF_EXIT_INSN(),
5693 },
5694 .fixup_map2 = { 3 },
5695 .result = ACCEPT,
5696 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5697 },
5698 {
5699 "helper access to map: bounds check using s<, good access 2",
5700 .insns = {
5701 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5703 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5704 BPF_LD_MAP_FD(BPF_REG_1, 0),
5705 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5706 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5707 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5708 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5709 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5710 BPF_MOV64_IMM(BPF_REG_0, 0),
5711 BPF_EXIT_INSN(),
5712 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5713 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5714 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5715 BPF_MOV64_IMM(BPF_REG_0, 0),
5716 BPF_EXIT_INSN(),
5717 },
5718 .fixup_map2 = { 3 },
5719 .result = ACCEPT,
5720 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5721 },
5722 {
5723 "helper access to map: bounds check using s<, bad access",
5724 .insns = {
5725 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5727 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5728 BPF_LD_MAP_FD(BPF_REG_1, 0),
5729 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5730 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5731 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5732 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5733 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5734 BPF_MOV64_IMM(BPF_REG_0, 0),
5735 BPF_EXIT_INSN(),
5736 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5737 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5738 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5739 BPF_MOV64_IMM(BPF_REG_0, 0),
5740 BPF_EXIT_INSN(),
5741 },
5742 .fixup_map2 = { 3 },
5743 .result = REJECT,
5744 .errstr = "R1 min value is negative",
5745 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5746 },
5747 {
5748 "helper access to map: bounds check using s<=, good access",
5749 .insns = {
5750 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5751 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5752 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5753 BPF_LD_MAP_FD(BPF_REG_1, 0),
5754 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5756 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5757 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5758 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5759 BPF_MOV64_IMM(BPF_REG_0, 0),
5760 BPF_EXIT_INSN(),
5761 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
5762 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5763 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5764 BPF_MOV64_IMM(BPF_REG_0, 0),
5765 BPF_EXIT_INSN(),
5766 },
5767 .fixup_map2 = { 3 },
5768 .result = ACCEPT,
5769 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5770 },
5771 {
5772 "helper access to map: bounds check using s<=, good access 2",
5773 .insns = {
5774 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5775 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5776 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5777 BPF_LD_MAP_FD(BPF_REG_1, 0),
5778 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5779 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5780 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5781 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5782 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5783 BPF_MOV64_IMM(BPF_REG_0, 0),
5784 BPF_EXIT_INSN(),
5785 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5786 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5787 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5788 BPF_MOV64_IMM(BPF_REG_0, 0),
5789 BPF_EXIT_INSN(),
5790 },
5791 .fixup_map2 = { 3 },
5792 .result = ACCEPT,
5793 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5794 },
5795 {
5796 "helper access to map: bounds check using s<=, bad access",
5797 .insns = {
5798 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5799 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5800 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5801 BPF_LD_MAP_FD(BPF_REG_1, 0),
5802 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5803 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5804 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5805 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5806 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5807 BPF_MOV64_IMM(BPF_REG_0, 0),
5808 BPF_EXIT_INSN(),
5809 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5810 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5811 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5812 BPF_MOV64_IMM(BPF_REG_0, 0),
5813 BPF_EXIT_INSN(),
5814 },
5815 .fixup_map2 = { 3 },
5816 .result = REJECT,
5817 .errstr = "R1 min value is negative",
5818 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5819 },
5820 {
5821 "map lookup helper access to map",
5822 .insns = {
5823 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5825 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5826 BPF_LD_MAP_FD(BPF_REG_1, 0),
5827 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5828 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5829 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5830 BPF_LD_MAP_FD(BPF_REG_1, 0),
5831 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5832 BPF_EXIT_INSN(),
5833 },
5834 .fixup_map3 = { 3, 8 },
5835 .result = ACCEPT,
5836 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5837 },
5838 {
5839 "map update helper access to map",
5840 .insns = {
5841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5843 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5844 BPF_LD_MAP_FD(BPF_REG_1, 0),
5845 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5847 BPF_MOV64_IMM(BPF_REG_4, 0),
5848 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
5849 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5850 BPF_LD_MAP_FD(BPF_REG_1, 0),
5851 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
5852 BPF_EXIT_INSN(),
5853 },
5854 .fixup_map3 = { 3, 10 },
5855 .result = ACCEPT,
5856 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5857 },
5858 {
5859 "map update helper access to map: wrong size",
5860 .insns = {
5861 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5863 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5864 BPF_LD_MAP_FD(BPF_REG_1, 0),
5865 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5866 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5867 BPF_MOV64_IMM(BPF_REG_4, 0),
5868 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
5869 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5870 BPF_LD_MAP_FD(BPF_REG_1, 0),
5871 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
5872 BPF_EXIT_INSN(),
5873 },
5874 .fixup_map1 = { 3 },
5875 .fixup_map3 = { 10 },
5876 .result = REJECT,
5877 .errstr = "invalid access to map value, value_size=8 off=0 size=16",
5878 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5879 },
5880 {
5881 "map helper access to adjusted map (via const imm)",
5882 .insns = {
5883 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5885 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5886 BPF_LD_MAP_FD(BPF_REG_1, 0),
5887 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5888 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5889 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5890 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
5891 offsetof(struct other_val, bar)),
5892 BPF_LD_MAP_FD(BPF_REG_1, 0),
5893 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5894 BPF_EXIT_INSN(),
5895 },
5896 .fixup_map3 = { 3, 9 },
5897 .result = ACCEPT,
5898 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5899 },
5900 {
5901 "map helper access to adjusted map (via const imm): out-of-bound 1",
5902 .insns = {
5903 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5904 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5905 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5906 BPF_LD_MAP_FD(BPF_REG_1, 0),
5907 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5908 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5909 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5910 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
5911 sizeof(struct other_val) - 4),
5912 BPF_LD_MAP_FD(BPF_REG_1, 0),
5913 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5914 BPF_EXIT_INSN(),
5915 },
5916 .fixup_map3 = { 3, 9 },
5917 .result = REJECT,
5918 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
5919 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5920 },
5921 {
5922 "map helper access to adjusted map (via const imm): out-of-bound 2",
5923 .insns = {
5924 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5925 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5926 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5927 BPF_LD_MAP_FD(BPF_REG_1, 0),
5928 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5929 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5930 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5931 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5932 BPF_LD_MAP_FD(BPF_REG_1, 0),
5933 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5934 BPF_EXIT_INSN(),
5935 },
5936 .fixup_map3 = { 3, 9 },
5937 .result = REJECT,
5938 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
5939 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5940 },
5941 {
5942 "map helper access to adjusted map (via const reg)",
5943 .insns = {
5944 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5946 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5947 BPF_LD_MAP_FD(BPF_REG_1, 0),
5948 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5949 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5950 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5951 BPF_MOV64_IMM(BPF_REG_3,
5952 offsetof(struct other_val, bar)),
5953 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5954 BPF_LD_MAP_FD(BPF_REG_1, 0),
5955 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5956 BPF_EXIT_INSN(),
5957 },
5958 .fixup_map3 = { 3, 10 },
5959 .result = ACCEPT,
5960 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5961 },
5962 {
5963 "map helper access to adjusted map (via const reg): out-of-bound 1",
5964 .insns = {
5965 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5967 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5968 BPF_LD_MAP_FD(BPF_REG_1, 0),
5969 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5970 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5971 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5972 BPF_MOV64_IMM(BPF_REG_3,
5973 sizeof(struct other_val) - 4),
5974 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5975 BPF_LD_MAP_FD(BPF_REG_1, 0),
5976 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5977 BPF_EXIT_INSN(),
5978 },
5979 .fixup_map3 = { 3, 10 },
5980 .result = REJECT,
5981 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
5982 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5983 },
5984 {
5985 "map helper access to adjusted map (via const reg): out-of-bound 2",
5986 .insns = {
5987 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5988 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5989 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5990 BPF_LD_MAP_FD(BPF_REG_1, 0),
5991 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5992 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5993 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5994 BPF_MOV64_IMM(BPF_REG_3, -4),
5995 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5996 BPF_LD_MAP_FD(BPF_REG_1, 0),
5997 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5998 BPF_EXIT_INSN(),
5999 },
6000 .fixup_map3 = { 3, 10 },
6001 .result = REJECT,
6002 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
6003 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6004 },
6005 {
6006 "map helper access to adjusted map (via variable)",
6007 .insns = {
6008 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6009 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6010 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6011 BPF_LD_MAP_FD(BPF_REG_1, 0),
6012 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6013 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6014 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6015 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6016 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6017 offsetof(struct other_val, bar), 4),
6018 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6019 BPF_LD_MAP_FD(BPF_REG_1, 0),
6020 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6021 BPF_EXIT_INSN(),
6022 },
6023 .fixup_map3 = { 3, 11 },
6024 .result = ACCEPT,
6025 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6026 },
6027 {
6028 "map helper access to adjusted map (via variable): no max check",
6029 .insns = {
6030 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6031 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6032 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6033 BPF_LD_MAP_FD(BPF_REG_1, 0),
6034 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6035 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6036 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6037 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6038 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6039 BPF_LD_MAP_FD(BPF_REG_1, 0),
6040 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6041 BPF_EXIT_INSN(),
6042 },
6043 .fixup_map3 = { 3, 10 },
6044 .result = REJECT,
6045 .errstr = "R2 unbounded memory access, make sure to bounds check any array access into a map",
6046 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6047 },
6048 {
6049 "map helper access to adjusted map (via variable): wrong max check",
6050 .insns = {
6051 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6053 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6054 BPF_LD_MAP_FD(BPF_REG_1, 0),
6055 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6057 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6058 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6059 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6060 offsetof(struct other_val, bar) + 1, 4),
6061 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6062 BPF_LD_MAP_FD(BPF_REG_1, 0),
6063 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6064 BPF_EXIT_INSN(),
6065 },
6066 .fixup_map3 = { 3, 11 },
6067 .result = REJECT,
6068 .errstr = "invalid access to map value, value_size=16 off=9 size=8",
6069 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6070 },
6071 {
6072 "map element value is preserved across register spilling",
6073 .insns = {
6074 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6075 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6076 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6077 BPF_LD_MAP_FD(BPF_REG_1, 0),
6078 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6079 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6080 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6081 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6083 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6084 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6085 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6086 BPF_EXIT_INSN(),
6087 },
6088 .fixup_map2 = { 3 },
6089 .errstr_unpriv = "R0 leaks addr",
6090 .result = ACCEPT,
6091 .result_unpriv = REJECT,
6092 },
6093 {
6094 "map element value or null is marked on register spilling",
6095 .insns = {
6096 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6098 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6099 BPF_LD_MAP_FD(BPF_REG_1, 0),
6100 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6101 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
6103 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6104 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6105 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6106 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6107 BPF_EXIT_INSN(),
6108 },
6109 .fixup_map2 = { 3 },
6110 .errstr_unpriv = "R0 leaks addr",
6111 .result = ACCEPT,
6112 .result_unpriv = REJECT,
6113 },
6114 {
6115 "map element value store of cleared call register",
6116 .insns = {
6117 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6118 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6119 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6120 BPF_LD_MAP_FD(BPF_REG_1, 0),
6121 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6122 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
6123 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
6124 BPF_EXIT_INSN(),
6125 },
6126 .fixup_map2 = { 3 },
6127 .errstr_unpriv = "R1 !read_ok",
6128 .errstr = "R1 !read_ok",
6129 .result = REJECT,
6130 .result_unpriv = REJECT,
6131 },
6132 {
6133 "map element value with unaligned store",
6134 .insns = {
6135 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6136 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6137 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6138 BPF_LD_MAP_FD(BPF_REG_1, 0),
6139 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6140 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
6141 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6142 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6143 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
6144 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
6145 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6146 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
6147 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
6148 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
6149 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
6150 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
6151 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
6152 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
6153 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
6154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
6155 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
6156 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
6157 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
6158 BPF_EXIT_INSN(),
6159 },
6160 .fixup_map2 = { 3 },
6161 .errstr_unpriv = "R0 leaks addr",
6162 .result = ACCEPT,
6163 .result_unpriv = REJECT,
6164 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6165 },
6166 {
6167 "map element value with unaligned load",
6168 .insns = {
6169 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6170 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6171 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6172 BPF_LD_MAP_FD(BPF_REG_1, 0),
6173 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6174 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6175 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6176 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
6177 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6178 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6179 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
6180 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6181 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
6182 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
6183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
6184 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6185 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
6186 BPF_EXIT_INSN(),
6187 },
6188 .fixup_map2 = { 3 },
6189 .errstr_unpriv = "R0 leaks addr",
6190 .result = ACCEPT,
6191 .result_unpriv = REJECT,
6192 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6193 },
6194 {
6195 "map element value illegal alu op, 1",
6196 .insns = {
6197 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6198 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6199 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6200 BPF_LD_MAP_FD(BPF_REG_1, 0),
6201 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6202 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6203 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
6204 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6205 BPF_EXIT_INSN(),
6206 },
6207 .fixup_map2 = { 3 },
6208 .errstr = "R0 bitwise operator &= on pointer",
6209 .result = REJECT,
6210 },
6211 {
6212 "map element value illegal alu op, 2",
6213 .insns = {
6214 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6216 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6217 BPF_LD_MAP_FD(BPF_REG_1, 0),
6218 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6219 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6220 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
6221 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6222 BPF_EXIT_INSN(),
6223 },
6224 .fixup_map2 = { 3 },
6225 .errstr = "R0 32-bit pointer arithmetic prohibited",
6226 .result = REJECT,
6227 },
6228 {
6229 "map element value illegal alu op, 3",
6230 .insns = {
6231 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6232 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6233 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6234 BPF_LD_MAP_FD(BPF_REG_1, 0),
6235 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6236 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6237 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
6238 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6239 BPF_EXIT_INSN(),
6240 },
6241 .fixup_map2 = { 3 },
6242 .errstr = "R0 pointer arithmetic with /= operator",
6243 .result = REJECT,
6244 },
6245 {
6246 "map element value illegal alu op, 4",
6247 .insns = {
6248 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6249 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6250 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6251 BPF_LD_MAP_FD(BPF_REG_1, 0),
6252 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6253 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6254 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
6255 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6256 BPF_EXIT_INSN(),
6257 },
6258 .fixup_map2 = { 3 },
6259 .errstr_unpriv = "R0 pointer arithmetic prohibited",
6260 .errstr = "invalid mem access 'inv'",
6261 .result = REJECT,
6262 .result_unpriv = REJECT,
6263 },
6264 {
6265 "map element value illegal alu op, 5",
6266 .insns = {
6267 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6268 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6269 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6270 BPF_LD_MAP_FD(BPF_REG_1, 0),
6271 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6272 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6273 BPF_MOV64_IMM(BPF_REG_3, 4096),
6274 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6275 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6276 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6277 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
6278 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
6279 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6280 BPF_EXIT_INSN(),
6281 },
6282 .fixup_map2 = { 3 },
6283 .errstr = "R0 invalid mem access 'inv'",
6284 .result = REJECT,
6285 },
6286 {
6287 "map element value is preserved across register spilling",
6288 .insns = {
6289 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6290 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6291 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6292 BPF_LD_MAP_FD(BPF_REG_1, 0),
6293 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6294 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6295 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
6296 offsetof(struct test_val, foo)),
6297 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6298 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6299 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6300 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6301 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6302 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6303 BPF_EXIT_INSN(),
6304 },
6305 .fixup_map2 = { 3 },
6306 .errstr_unpriv = "R0 leaks addr",
6307 .result = ACCEPT,
6308 .result_unpriv = REJECT,
6309 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6310 },
6311 {
6312 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
6313 .insns = {
6314 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6316 BPF_MOV64_IMM(BPF_REG_0, 0),
6317 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6318 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6319 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6320 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6321 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6322 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6323 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6324 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6325 BPF_MOV64_IMM(BPF_REG_2, 16),
6326 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6327 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6328 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6329 BPF_MOV64_IMM(BPF_REG_4, 0),
6330 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6331 BPF_MOV64_IMM(BPF_REG_3, 0),
6332 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6333 BPF_MOV64_IMM(BPF_REG_0, 0),
6334 BPF_EXIT_INSN(),
6335 },
6336 .result = ACCEPT,
6337 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6338 },
6339 {
6340 "helper access to variable memory: stack, bitwise AND, zero included",
6341 .insns = {
6342 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6344 BPF_MOV64_IMM(BPF_REG_2, 16),
6345 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6346 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6347 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6348 BPF_MOV64_IMM(BPF_REG_3, 0),
6349 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6350 BPF_EXIT_INSN(),
6351 },
6352 .errstr = "invalid indirect read from stack off -64+0 size 64",
6353 .result = REJECT,
6354 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6355 },
6356 {
6357 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
6358 .insns = {
6359 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6361 BPF_MOV64_IMM(BPF_REG_2, 16),
6362 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6363 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6364 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
6365 BPF_MOV64_IMM(BPF_REG_4, 0),
6366 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6367 BPF_MOV64_IMM(BPF_REG_3, 0),
6368 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6369 BPF_MOV64_IMM(BPF_REG_0, 0),
6370 BPF_EXIT_INSN(),
6371 },
6372 .errstr = "invalid stack type R1 off=-64 access_size=65",
6373 .result = REJECT,
6374 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6375 },
6376 {
6377 "helper access to variable memory: stack, JMP, correct bounds",
6378 .insns = {
6379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6380 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6381 BPF_MOV64_IMM(BPF_REG_0, 0),
6382 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6383 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6384 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6385 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6386 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6387 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6388 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6389 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6390 BPF_MOV64_IMM(BPF_REG_2, 16),
6391 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6392 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6393 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
6394 BPF_MOV64_IMM(BPF_REG_4, 0),
6395 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6396 BPF_MOV64_IMM(BPF_REG_3, 0),
6397 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6398 BPF_MOV64_IMM(BPF_REG_0, 0),
6399 BPF_EXIT_INSN(),
6400 },
6401 .result = ACCEPT,
6402 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6403 },
6404 {
6405 "helper access to variable memory: stack, JMP (signed), correct bounds",
6406 .insns = {
6407 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6408 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6409 BPF_MOV64_IMM(BPF_REG_0, 0),
6410 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6411 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6412 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6413 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6414 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6415 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6416 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6417 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6418 BPF_MOV64_IMM(BPF_REG_2, 16),
6419 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6420 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6421 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
6422 BPF_MOV64_IMM(BPF_REG_4, 0),
6423 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6424 BPF_MOV64_IMM(BPF_REG_3, 0),
6425 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6426 BPF_MOV64_IMM(BPF_REG_0, 0),
6427 BPF_EXIT_INSN(),
6428 },
6429 .result = ACCEPT,
6430 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6431 },
6432 {
6433 "helper access to variable memory: stack, JMP, bounds + offset",
6434 .insns = {
6435 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6437 BPF_MOV64_IMM(BPF_REG_2, 16),
6438 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6439 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6440 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
6441 BPF_MOV64_IMM(BPF_REG_4, 0),
6442 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
6443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6444 BPF_MOV64_IMM(BPF_REG_3, 0),
6445 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6446 BPF_MOV64_IMM(BPF_REG_0, 0),
6447 BPF_EXIT_INSN(),
6448 },
6449 .errstr = "invalid stack type R1 off=-64 access_size=65",
6450 .result = REJECT,
6451 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6452 },
6453 {
6454 "helper access to variable memory: stack, JMP, wrong max",
6455 .insns = {
6456 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6458 BPF_MOV64_IMM(BPF_REG_2, 16),
6459 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6460 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6461 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
6462 BPF_MOV64_IMM(BPF_REG_4, 0),
6463 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6464 BPF_MOV64_IMM(BPF_REG_3, 0),
6465 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6466 BPF_MOV64_IMM(BPF_REG_0, 0),
6467 BPF_EXIT_INSN(),
6468 },
6469 .errstr = "invalid stack type R1 off=-64 access_size=65",
6470 .result = REJECT,
6471 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6472 },
6473 {
6474 "helper access to variable memory: stack, JMP, no max check",
6475 .insns = {
6476 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6478 BPF_MOV64_IMM(BPF_REG_2, 16),
6479 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6480 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6481 BPF_MOV64_IMM(BPF_REG_4, 0),
6482 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6483 BPF_MOV64_IMM(BPF_REG_3, 0),
6484 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6485 BPF_MOV64_IMM(BPF_REG_0, 0),
6486 BPF_EXIT_INSN(),
6487 },
6488 /* because max wasn't checked, signed min is negative */
6489 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
6490 .result = REJECT,
6491 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6492 },
6493 {
6494 "helper access to variable memory: stack, JMP, no min check",
6495 .insns = {
6496 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6497 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6498 BPF_MOV64_IMM(BPF_REG_2, 16),
6499 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6500 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6501 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
6502 BPF_MOV64_IMM(BPF_REG_3, 0),
6503 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6504 BPF_MOV64_IMM(BPF_REG_0, 0),
6505 BPF_EXIT_INSN(),
6506 },
6507 .errstr = "invalid indirect read from stack off -64+0 size 64",
6508 .result = REJECT,
6509 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6510 },
6511 {
6512 "helper access to variable memory: stack, JMP (signed), no min check",
6513 .insns = {
6514 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6516 BPF_MOV64_IMM(BPF_REG_2, 16),
6517 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6518 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6519 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
6520 BPF_MOV64_IMM(BPF_REG_3, 0),
6521 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6522 BPF_MOV64_IMM(BPF_REG_0, 0),
6523 BPF_EXIT_INSN(),
6524 },
6525 .errstr = "R2 min value is negative",
6526 .result = REJECT,
6527 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6528 },
6529 {
6530 "helper access to variable memory: map, JMP, correct bounds",
6531 .insns = {
6532 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6534 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6535 BPF_LD_MAP_FD(BPF_REG_1, 0),
6536 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6537 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6538 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6539 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6540 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6541 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6542 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6543 sizeof(struct test_val), 4),
6544 BPF_MOV64_IMM(BPF_REG_4, 0),
6545 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6546 BPF_MOV64_IMM(BPF_REG_3, 0),
6547 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6548 BPF_MOV64_IMM(BPF_REG_0, 0),
6549 BPF_EXIT_INSN(),
6550 },
6551 .fixup_map2 = { 3 },
6552 .result = ACCEPT,
6553 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6554 },
6555 {
6556 "helper access to variable memory: map, JMP, wrong max",
6557 .insns = {
6558 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6560 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6561 BPF_LD_MAP_FD(BPF_REG_1, 0),
6562 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6563 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6564 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6565 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6566 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6567 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6568 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6569 sizeof(struct test_val) + 1, 4),
6570 BPF_MOV64_IMM(BPF_REG_4, 0),
6571 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6572 BPF_MOV64_IMM(BPF_REG_3, 0),
6573 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6574 BPF_MOV64_IMM(BPF_REG_0, 0),
6575 BPF_EXIT_INSN(),
6576 },
6577 .fixup_map2 = { 3 },
6578 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
6579 .result = REJECT,
6580 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6581 },
6582 {
6583 "helper access to variable memory: map adjusted, JMP, correct bounds",
6584 .insns = {
6585 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6587 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6588 BPF_LD_MAP_FD(BPF_REG_1, 0),
6589 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6590 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6591 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6593 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6594 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6595 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6596 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6597 sizeof(struct test_val) - 20, 4),
6598 BPF_MOV64_IMM(BPF_REG_4, 0),
6599 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6600 BPF_MOV64_IMM(BPF_REG_3, 0),
6601 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6602 BPF_MOV64_IMM(BPF_REG_0, 0),
6603 BPF_EXIT_INSN(),
6604 },
6605 .fixup_map2 = { 3 },
6606 .result = ACCEPT,
6607 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6608 },
6609 {
6610 "helper access to variable memory: map adjusted, JMP, wrong max",
6611 .insns = {
6612 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6613 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6614 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6615 BPF_LD_MAP_FD(BPF_REG_1, 0),
6616 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6618 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6619 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6620 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6621 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6622 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6623 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6624 sizeof(struct test_val) - 19, 4),
6625 BPF_MOV64_IMM(BPF_REG_4, 0),
6626 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6627 BPF_MOV64_IMM(BPF_REG_3, 0),
6628 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6629 BPF_MOV64_IMM(BPF_REG_0, 0),
6630 BPF_EXIT_INSN(),
6631 },
6632 .fixup_map2 = { 3 },
6633 .errstr = "R1 min value is outside of the array range",
6634 .result = REJECT,
6635 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6636 },
6637 {
6638 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
6639 .insns = {
6640 BPF_MOV64_IMM(BPF_REG_1, 0),
6641 BPF_MOV64_IMM(BPF_REG_2, 0),
6642 BPF_MOV64_IMM(BPF_REG_3, 0),
6643 BPF_MOV64_IMM(BPF_REG_4, 0),
6644 BPF_MOV64_IMM(BPF_REG_5, 0),
6645 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6646 BPF_EXIT_INSN(),
6647 },
6648 .result = ACCEPT,
6649 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6650 },
6651 {
6652 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
6653 .insns = {
6654 BPF_MOV64_IMM(BPF_REG_1, 0),
6655 BPF_MOV64_IMM(BPF_REG_2, 1),
6656 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6657 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6658 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6659 BPF_MOV64_IMM(BPF_REG_3, 0),
6660 BPF_MOV64_IMM(BPF_REG_4, 0),
6661 BPF_MOV64_IMM(BPF_REG_5, 0),
6662 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6663 BPF_EXIT_INSN(),
6664 },
6665 .errstr = "R1 type=inv expected=fp",
6666 .result = REJECT,
6667 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6668 },
6669 {
6670 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
6671 .insns = {
6672 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6674 BPF_MOV64_IMM(BPF_REG_2, 0),
6675 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6676 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
6677 BPF_MOV64_IMM(BPF_REG_3, 0),
6678 BPF_MOV64_IMM(BPF_REG_4, 0),
6679 BPF_MOV64_IMM(BPF_REG_5, 0),
6680 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6681 BPF_EXIT_INSN(),
6682 },
6683 .result = ACCEPT,
6684 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6685 },
6686 {
6687 "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
6688 .insns = {
6689 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6690 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6691 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6692 BPF_LD_MAP_FD(BPF_REG_1, 0),
6693 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6694 BPF_FUNC_map_lookup_elem),
6695 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6696 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6697 BPF_MOV64_IMM(BPF_REG_2, 0),
6698 BPF_MOV64_IMM(BPF_REG_3, 0),
6699 BPF_MOV64_IMM(BPF_REG_4, 0),
6700 BPF_MOV64_IMM(BPF_REG_5, 0),
6701 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6702 BPF_EXIT_INSN(),
6703 },
6704 .fixup_map1 = { 3 },
6705 .result = ACCEPT,
6706 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6707 },
6708 {
6709 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
6710 .insns = {
6711 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6712 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6714 BPF_LD_MAP_FD(BPF_REG_1, 0),
6715 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6716 BPF_FUNC_map_lookup_elem),
6717 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6718 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6719 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
6720 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6721 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6722 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6723 BPF_MOV64_IMM(BPF_REG_3, 0),
6724 BPF_MOV64_IMM(BPF_REG_4, 0),
6725 BPF_MOV64_IMM(BPF_REG_5, 0),
6726 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6727 BPF_EXIT_INSN(),
6728 },
6729 .fixup_map1 = { 3 },
6730 .result = ACCEPT,
6731 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6732 },
6733 {
6734 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
6735 .insns = {
6736 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6737 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6739 BPF_LD_MAP_FD(BPF_REG_1, 0),
6740 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6741 BPF_FUNC_map_lookup_elem),
6742 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6743 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6744 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6745 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6746 BPF_MOV64_IMM(BPF_REG_3, 0),
6747 BPF_MOV64_IMM(BPF_REG_4, 0),
6748 BPF_MOV64_IMM(BPF_REG_5, 0),
6749 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6750 BPF_EXIT_INSN(),
6751 },
6752 .fixup_map1 = { 3 },
6753 .result = ACCEPT,
6754 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6755 },
6756 {
6757 "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
6758 .insns = {
6759 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6760 offsetof(struct __sk_buff, data)),
6761 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6762 offsetof(struct __sk_buff, data_end)),
6763 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
6764 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
6765 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
6766 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
6767 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
6768 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6769 BPF_MOV64_IMM(BPF_REG_3, 0),
6770 BPF_MOV64_IMM(BPF_REG_4, 0),
6771 BPF_MOV64_IMM(BPF_REG_5, 0),
6772 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6773 BPF_EXIT_INSN(),
6774 },
6775 .result = ACCEPT,
6776 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6777 .retval = 0 /* csum_diff of 64-byte packet */,
6778 },
6779 {
6780 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6781 .insns = {
6782 BPF_MOV64_IMM(BPF_REG_1, 0),
6783 BPF_MOV64_IMM(BPF_REG_2, 0),
6784 BPF_MOV64_IMM(BPF_REG_3, 0),
6785 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6786 BPF_EXIT_INSN(),
6787 },
6788 .errstr = "R1 type=inv expected=fp",
6789 .result = REJECT,
6790 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6791 },
6792 {
6793 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6794 .insns = {
6795 BPF_MOV64_IMM(BPF_REG_1, 0),
6796 BPF_MOV64_IMM(BPF_REG_2, 1),
6797 BPF_MOV64_IMM(BPF_REG_3, 0),
6798 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6799 BPF_EXIT_INSN(),
6800 },
6801 .errstr = "R1 type=inv expected=fp",
6802 .result = REJECT,
6803 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6804 },
6805 {
6806 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6807 .insns = {
6808 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6809 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6810 BPF_MOV64_IMM(BPF_REG_2, 0),
6811 BPF_MOV64_IMM(BPF_REG_3, 0),
6812 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6813 BPF_EXIT_INSN(),
6814 },
6815 .result = ACCEPT,
6816 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6817 },
6818 {
6819 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6820 .insns = {
6821 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6822 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6824 BPF_LD_MAP_FD(BPF_REG_1, 0),
6825 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6827 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6828 BPF_MOV64_IMM(BPF_REG_2, 0),
6829 BPF_MOV64_IMM(BPF_REG_3, 0),
6830 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6831 BPF_EXIT_INSN(),
6832 },
6833 .fixup_map1 = { 3 },
6834 .result = ACCEPT,
6835 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6836 },
6837 {
6838 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6839 .insns = {
6840 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6843 BPF_LD_MAP_FD(BPF_REG_1, 0),
6844 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6845 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6846 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6847 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6848 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6850 BPF_MOV64_IMM(BPF_REG_3, 0),
6851 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6852 BPF_EXIT_INSN(),
6853 },
6854 .fixup_map1 = { 3 },
6855 .result = ACCEPT,
6856 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6857 },
6858 {
6859 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6860 .insns = {
6861 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6862 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6863 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6864 BPF_LD_MAP_FD(BPF_REG_1, 0),
6865 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6866 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6867 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6868 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6869 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
6870 BPF_MOV64_IMM(BPF_REG_3, 0),
6871 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6872 BPF_EXIT_INSN(),
6873 },
6874 .fixup_map1 = { 3 },
6875 .result = ACCEPT,
6876 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6877 },
6878 {
6879 "helper access to variable memory: 8 bytes leak",
6880 .insns = {
6881 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6883 BPF_MOV64_IMM(BPF_REG_0, 0),
6884 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6885 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6886 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6887 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6888 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6889 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6890 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6891 BPF_MOV64_IMM(BPF_REG_2, 1),
6892 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6893 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6894 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
6895 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6896 BPF_MOV64_IMM(BPF_REG_3, 0),
6897 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6898 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6899 BPF_EXIT_INSN(),
6900 },
6901 .errstr = "invalid indirect read from stack off -64+32 size 64",
6902 .result = REJECT,
6903 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6904 },
6905 {
6906 "helper access to variable memory: 8 bytes no leak (init memory)",
6907 .insns = {
6908 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6909 BPF_MOV64_IMM(BPF_REG_0, 0),
6910 BPF_MOV64_IMM(BPF_REG_0, 0),
6911 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6912 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6913 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6914 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6915 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6916 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6917 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6918 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6919 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6920 BPF_MOV64_IMM(BPF_REG_2, 0),
6921 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
6922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
6923 BPF_MOV64_IMM(BPF_REG_3, 0),
6924 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6925 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6926 BPF_EXIT_INSN(),
6927 },
6928 .result = ACCEPT,
6929 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6930 },
6931 {
6932 "invalid and of negative number",
6933 .insns = {
6934 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6935 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6936 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6937 BPF_LD_MAP_FD(BPF_REG_1, 0),
6938 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6939 BPF_FUNC_map_lookup_elem),
6940 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6941 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6942 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
6943 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
6944 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6945 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
6946 offsetof(struct test_val, foo)),
6947 BPF_EXIT_INSN(),
6948 },
6949 .fixup_map2 = { 3 },
6950 .errstr = "R0 max value is outside of the array range",
6951 .result = REJECT,
6952 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6953 },
6954 {
6955 "invalid range check",
6956 .insns = {
6957 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6958 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6960 BPF_LD_MAP_FD(BPF_REG_1, 0),
6961 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6962 BPF_FUNC_map_lookup_elem),
6963 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
6964 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6965 BPF_MOV64_IMM(BPF_REG_9, 1),
6966 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
6967 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
6968 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
6969 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
6970 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
6971 BPF_MOV32_IMM(BPF_REG_3, 1),
6972 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
6973 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
6974 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
6975 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
6976 BPF_MOV64_REG(BPF_REG_0, 0),
6977 BPF_EXIT_INSN(),
6978 },
6979 .fixup_map2 = { 3 },
6980 .errstr = "R0 max value is outside of the array range",
6981 .result = REJECT,
6982 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6983 },
6984 {
6985 "map in map access",
6986 .insns = {
6987 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6988 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6989 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6990 BPF_LD_MAP_FD(BPF_REG_1, 0),
6991 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6992 BPF_FUNC_map_lookup_elem),
6993 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6994 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6995 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6996 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6997 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6998 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6999 BPF_FUNC_map_lookup_elem),
7000 BPF_MOV64_REG(BPF_REG_0, 0),
7001 BPF_EXIT_INSN(),
7002 },
7003 .fixup_map_in_map = { 3 },
7004 .result = ACCEPT,
7005 },
7006 {
7007 "invalid inner map pointer",
7008 .insns = {
7009 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7010 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7012 BPF_LD_MAP_FD(BPF_REG_1, 0),
7013 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7014 BPF_FUNC_map_lookup_elem),
7015 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7016 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7017 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7018 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7019 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7020 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7022 BPF_FUNC_map_lookup_elem),
7023 BPF_MOV64_REG(BPF_REG_0, 0),
7024 BPF_EXIT_INSN(),
7025 },
7026 .fixup_map_in_map = { 3 },
7027 .errstr = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
7028 .result = REJECT,
7029 },
7030 {
7031 "forgot null checking on the inner map pointer",
7032 .insns = {
7033 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7034 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7035 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7036 BPF_LD_MAP_FD(BPF_REG_1, 0),
7037 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7038 BPF_FUNC_map_lookup_elem),
7039 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7040 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7042 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7043 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7044 BPF_FUNC_map_lookup_elem),
7045 BPF_MOV64_REG(BPF_REG_0, 0),
7046 BPF_EXIT_INSN(),
7047 },
7048 .fixup_map_in_map = { 3 },
7049 .errstr = "R1 type=map_value_or_null expected=map_ptr",
7050 .result = REJECT,
7051 },
7052 {
7053 "ld_abs: check calling conv, r1",
7054 .insns = {
7055 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7056 BPF_MOV64_IMM(BPF_REG_1, 0),
7057 BPF_LD_ABS(BPF_W, -0x200000),
7058 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7059 BPF_EXIT_INSN(),
7060 },
7061 .errstr = "R1 !read_ok",
7062 .result = REJECT,
7063 },
7064 {
7065 "ld_abs: check calling conv, r2",
7066 .insns = {
7067 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7068 BPF_MOV64_IMM(BPF_REG_2, 0),
7069 BPF_LD_ABS(BPF_W, -0x200000),
7070 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7071 BPF_EXIT_INSN(),
7072 },
7073 .errstr = "R2 !read_ok",
7074 .result = REJECT,
7075 },
7076 {
7077 "ld_abs: check calling conv, r3",
7078 .insns = {
7079 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7080 BPF_MOV64_IMM(BPF_REG_3, 0),
7081 BPF_LD_ABS(BPF_W, -0x200000),
7082 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7083 BPF_EXIT_INSN(),
7084 },
7085 .errstr = "R3 !read_ok",
7086 .result = REJECT,
7087 },
7088 {
7089 "ld_abs: check calling conv, r4",
7090 .insns = {
7091 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7092 BPF_MOV64_IMM(BPF_REG_4, 0),
7093 BPF_LD_ABS(BPF_W, -0x200000),
7094 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7095 BPF_EXIT_INSN(),
7096 },
7097 .errstr = "R4 !read_ok",
7098 .result = REJECT,
7099 },
7100 {
7101 "ld_abs: check calling conv, r5",
7102 .insns = {
7103 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7104 BPF_MOV64_IMM(BPF_REG_5, 0),
7105 BPF_LD_ABS(BPF_W, -0x200000),
7106 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7107 BPF_EXIT_INSN(),
7108 },
7109 .errstr = "R5 !read_ok",
7110 .result = REJECT,
7111 },
7112 {
7113 "ld_abs: check calling conv, r7",
7114 .insns = {
7115 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7116 BPF_MOV64_IMM(BPF_REG_7, 0),
7117 BPF_LD_ABS(BPF_W, -0x200000),
7118 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7119 BPF_EXIT_INSN(),
7120 },
7121 .result = ACCEPT,
7122 },
7123 {
7124 "ld_abs: tests on r6 and skb data reload helper",
7125 .insns = {
7126 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7127 BPF_LD_ABS(BPF_B, 0),
7128 BPF_LD_ABS(BPF_H, 0),
7129 BPF_LD_ABS(BPF_W, 0),
7130 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
7131 BPF_MOV64_IMM(BPF_REG_6, 0),
7132 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
7133 BPF_MOV64_IMM(BPF_REG_2, 1),
7134 BPF_MOV64_IMM(BPF_REG_3, 2),
7135 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7136 BPF_FUNC_skb_vlan_push),
7137 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
7138 BPF_LD_ABS(BPF_B, 0),
7139 BPF_LD_ABS(BPF_H, 0),
7140 BPF_LD_ABS(BPF_W, 0),
7141 BPF_MOV64_IMM(BPF_REG_0, 42),
7142 BPF_EXIT_INSN(),
7143 },
7144 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7145 .result = ACCEPT,
7146 .retval = 42 /* ultimate return value */,
7147 },
7148 {
7149 "ld_ind: check calling conv, r1",
7150 .insns = {
7151 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7152 BPF_MOV64_IMM(BPF_REG_1, 1),
7153 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
7154 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7155 BPF_EXIT_INSN(),
7156 },
7157 .errstr = "R1 !read_ok",
7158 .result = REJECT,
7159 },
7160 {
7161 "ld_ind: check calling conv, r2",
7162 .insns = {
7163 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7164 BPF_MOV64_IMM(BPF_REG_2, 1),
7165 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
7166 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7167 BPF_EXIT_INSN(),
7168 },
7169 .errstr = "R2 !read_ok",
7170 .result = REJECT,
7171 },
7172 {
7173 "ld_ind: check calling conv, r3",
7174 .insns = {
7175 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7176 BPF_MOV64_IMM(BPF_REG_3, 1),
7177 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
7178 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7179 BPF_EXIT_INSN(),
7180 },
7181 .errstr = "R3 !read_ok",
7182 .result = REJECT,
7183 },
7184 {
7185 "ld_ind: check calling conv, r4",
7186 .insns = {
7187 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7188 BPF_MOV64_IMM(BPF_REG_4, 1),
7189 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
7190 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7191 BPF_EXIT_INSN(),
7192 },
7193 .errstr = "R4 !read_ok",
7194 .result = REJECT,
7195 },
7196 {
7197 "ld_ind: check calling conv, r5",
7198 .insns = {
7199 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7200 BPF_MOV64_IMM(BPF_REG_5, 1),
7201 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
7202 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7203 BPF_EXIT_INSN(),
7204 },
7205 .errstr = "R5 !read_ok",
7206 .result = REJECT,
7207 },
7208 {
7209 "ld_ind: check calling conv, r7",
7210 .insns = {
7211 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7212 BPF_MOV64_IMM(BPF_REG_7, 1),
7213 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
7214 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7215 BPF_EXIT_INSN(),
7216 },
7217 .result = ACCEPT,
7218 .retval = 1,
7219 },
7220 {
7221 "check bpf_perf_event_data->sample_period byte load permitted",
7222 .insns = {
7223 BPF_MOV64_IMM(BPF_REG_0, 0),
7224 #if __BYTE_ORDER == __LITTLE_ENDIAN
7225 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7226 offsetof(struct bpf_perf_event_data, sample_period)),
7227 #else
7228 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7229 offsetof(struct bpf_perf_event_data, sample_period) + 7),
7230 #endif
7231 BPF_EXIT_INSN(),
7232 },
7233 .result = ACCEPT,
7234 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7235 },
7236 {
7237 "check bpf_perf_event_data->sample_period half load permitted",
7238 .insns = {
7239 BPF_MOV64_IMM(BPF_REG_0, 0),
7240 #if __BYTE_ORDER == __LITTLE_ENDIAN
7241 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7242 offsetof(struct bpf_perf_event_data, sample_period)),
7243 #else
7244 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7245 offsetof(struct bpf_perf_event_data, sample_period) + 6),
7246 #endif
7247 BPF_EXIT_INSN(),
7248 },
7249 .result = ACCEPT,
7250 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7251 },
7252 {
7253 "check bpf_perf_event_data->sample_period word load permitted",
7254 .insns = {
7255 BPF_MOV64_IMM(BPF_REG_0, 0),
7256 #if __BYTE_ORDER == __LITTLE_ENDIAN
7257 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7258 offsetof(struct bpf_perf_event_data, sample_period)),
7259 #else
7260 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7261 offsetof(struct bpf_perf_event_data, sample_period) + 4),
7262 #endif
7263 BPF_EXIT_INSN(),
7264 },
7265 .result = ACCEPT,
7266 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7267 },
7268 {
7269 "check bpf_perf_event_data->sample_period dword load permitted",
7270 .insns = {
7271 BPF_MOV64_IMM(BPF_REG_0, 0),
7272 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
7273 offsetof(struct bpf_perf_event_data, sample_period)),
7274 BPF_EXIT_INSN(),
7275 },
7276 .result = ACCEPT,
7277 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7278 },
7279 {
7280 "check skb->data half load not permitted",
7281 .insns = {
7282 BPF_MOV64_IMM(BPF_REG_0, 0),
7283 #if __BYTE_ORDER == __LITTLE_ENDIAN
7284 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7285 offsetof(struct __sk_buff, data)),
7286 #else
7287 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7288 offsetof(struct __sk_buff, data) + 2),
7289 #endif
7290 BPF_EXIT_INSN(),
7291 },
7292 .result = REJECT,
7293 .errstr = "invalid bpf_context access",
7294 },
7295 {
7296 "check skb->tc_classid half load not permitted for lwt prog",
7297 .insns = {
7298 BPF_MOV64_IMM(BPF_REG_0, 0),
7299 #if __BYTE_ORDER == __LITTLE_ENDIAN
7300 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7301 offsetof(struct __sk_buff, tc_classid)),
7302 #else
7303 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7304 offsetof(struct __sk_buff, tc_classid) + 2),
7305 #endif
7306 BPF_EXIT_INSN(),
7307 },
7308 .result = REJECT,
7309 .errstr = "invalid bpf_context access",
7310 .prog_type = BPF_PROG_TYPE_LWT_IN,
7311 },
7312 {
7313 "bounds checks mixing signed and unsigned, positive bounds",
7314 .insns = {
7315 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7316 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7317 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7318 BPF_LD_MAP_FD(BPF_REG_1, 0),
7319 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7320 BPF_FUNC_map_lookup_elem),
7321 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7322 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7323 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7324 BPF_MOV64_IMM(BPF_REG_2, 2),
7325 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
7326 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
7327 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7328 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7329 BPF_MOV64_IMM(BPF_REG_0, 0),
7330 BPF_EXIT_INSN(),
7331 },
7332 .fixup_map1 = { 3 },
7333 .errstr = "unbounded min value",
7334 .result = REJECT,
7335 },
7336 {
7337 "bounds checks mixing signed and unsigned",
7338 .insns = {
7339 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7340 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7341 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7342 BPF_LD_MAP_FD(BPF_REG_1, 0),
7343 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7344 BPF_FUNC_map_lookup_elem),
7345 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7346 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7347 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7348 BPF_MOV64_IMM(BPF_REG_2, -1),
7349 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7350 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7351 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7352 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7353 BPF_MOV64_IMM(BPF_REG_0, 0),
7354 BPF_EXIT_INSN(),
7355 },
7356 .fixup_map1 = { 3 },
7357 .errstr = "unbounded min value",
7358 .result = REJECT,
7359 },
7360 {
7361 "bounds checks mixing signed and unsigned, variant 2",
7362 .insns = {
7363 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7364 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7366 BPF_LD_MAP_FD(BPF_REG_1, 0),
7367 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7368 BPF_FUNC_map_lookup_elem),
7369 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7370 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7371 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7372 BPF_MOV64_IMM(BPF_REG_2, -1),
7373 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7374 BPF_MOV64_IMM(BPF_REG_8, 0),
7375 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
7376 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7377 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7378 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7379 BPF_MOV64_IMM(BPF_REG_0, 0),
7380 BPF_EXIT_INSN(),
7381 },
7382 .fixup_map1 = { 3 },
7383 .errstr = "unbounded min value",
7384 .result = REJECT,
7385 },
7386 {
7387 "bounds checks mixing signed and unsigned, variant 3",
7388 .insns = {
7389 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7390 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7392 BPF_LD_MAP_FD(BPF_REG_1, 0),
7393 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7394 BPF_FUNC_map_lookup_elem),
7395 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7396 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7397 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7398 BPF_MOV64_IMM(BPF_REG_2, -1),
7399 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
7400 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
7401 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7402 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7403 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7404 BPF_MOV64_IMM(BPF_REG_0, 0),
7405 BPF_EXIT_INSN(),
7406 },
7407 .fixup_map1 = { 3 },
7408 .errstr = "unbounded min value",
7409 .result = REJECT,
7410 },
7411 {
7412 "bounds checks mixing signed and unsigned, variant 4",
7413 .insns = {
7414 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7415 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7416 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7417 BPF_LD_MAP_FD(BPF_REG_1, 0),
7418 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7419 BPF_FUNC_map_lookup_elem),
7420 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7421 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7422 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7423 BPF_MOV64_IMM(BPF_REG_2, 1),
7424 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
7425 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7426 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7427 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7428 BPF_MOV64_IMM(BPF_REG_0, 0),
7429 BPF_EXIT_INSN(),
7430 },
7431 .fixup_map1 = { 3 },
7432 .result = ACCEPT,
7433 },
7434 {
7435 "bounds checks mixing signed and unsigned, variant 5",
7436 .insns = {
7437 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7438 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7439 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7440 BPF_LD_MAP_FD(BPF_REG_1, 0),
7441 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7442 BPF_FUNC_map_lookup_elem),
7443 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7444 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7445 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7446 BPF_MOV64_IMM(BPF_REG_2, -1),
7447 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7448 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
7449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
7450 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
7451 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7452 BPF_MOV64_IMM(BPF_REG_0, 0),
7453 BPF_EXIT_INSN(),
7454 },
7455 .fixup_map1 = { 3 },
7456 .errstr = "unbounded min value",
7457 .result = REJECT,
7458 },
7459 {
7460 "bounds checks mixing signed and unsigned, variant 6",
7461 .insns = {
7462 BPF_MOV64_IMM(BPF_REG_2, 0),
7463 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
7464 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
7465 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7466 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
7467 BPF_MOV64_IMM(BPF_REG_6, -1),
7468 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
7469 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
7470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
7471 BPF_MOV64_IMM(BPF_REG_5, 0),
7472 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
7473 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7474 BPF_FUNC_skb_load_bytes),
7475 BPF_MOV64_IMM(BPF_REG_0, 0),
7476 BPF_EXIT_INSN(),
7477 },
7478 .errstr = "R4 min value is negative, either use unsigned",
7479 .result = REJECT,
7480 },
7481 {
7482 "bounds checks mixing signed and unsigned, variant 7",
7483 .insns = {
7484 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7485 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7486 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7487 BPF_LD_MAP_FD(BPF_REG_1, 0),
7488 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7489 BPF_FUNC_map_lookup_elem),
7490 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7491 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7492 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7493 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
7494 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7495 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7496 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7497 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7498 BPF_MOV64_IMM(BPF_REG_0, 0),
7499 BPF_EXIT_INSN(),
7500 },
7501 .fixup_map1 = { 3 },
7502 .result = ACCEPT,
7503 },
7504 {
7505 "bounds checks mixing signed and unsigned, variant 8",
7506 .insns = {
7507 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7508 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7510 BPF_LD_MAP_FD(BPF_REG_1, 0),
7511 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7512 BPF_FUNC_map_lookup_elem),
7513 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7514 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7515 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7516 BPF_MOV64_IMM(BPF_REG_2, -1),
7517 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7518 BPF_MOV64_IMM(BPF_REG_0, 0),
7519 BPF_EXIT_INSN(),
7520 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7521 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7522 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7523 BPF_MOV64_IMM(BPF_REG_0, 0),
7524 BPF_EXIT_INSN(),
7525 },
7526 .fixup_map1 = { 3 },
7527 .errstr = "unbounded min value",
7528 .result = REJECT,
7529 },
7530 {
7531 "bounds checks mixing signed and unsigned, variant 9",
7532 .insns = {
7533 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7534 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7536 BPF_LD_MAP_FD(BPF_REG_1, 0),
7537 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7538 BPF_FUNC_map_lookup_elem),
7539 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
7540 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7541 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7542 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
7543 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7544 BPF_MOV64_IMM(BPF_REG_0, 0),
7545 BPF_EXIT_INSN(),
7546 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7547 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7548 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7549 BPF_MOV64_IMM(BPF_REG_0, 0),
7550 BPF_EXIT_INSN(),
7551 },
7552 .fixup_map1 = { 3 },
7553 .result = ACCEPT,
7554 },
7555 {
7556 "bounds checks mixing signed and unsigned, variant 10",
7557 .insns = {
7558 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7559 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7560 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7561 BPF_LD_MAP_FD(BPF_REG_1, 0),
7562 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7563 BPF_FUNC_map_lookup_elem),
7564 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7565 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7566 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7567 BPF_MOV64_IMM(BPF_REG_2, 0),
7568 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7569 BPF_MOV64_IMM(BPF_REG_0, 0),
7570 BPF_EXIT_INSN(),
7571 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7572 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7573 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7574 BPF_MOV64_IMM(BPF_REG_0, 0),
7575 BPF_EXIT_INSN(),
7576 },
7577 .fixup_map1 = { 3 },
7578 .errstr = "unbounded min value",
7579 .result = REJECT,
7580 },
7581 {
7582 "bounds checks mixing signed and unsigned, variant 11",
7583 .insns = {
7584 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7585 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7587 BPF_LD_MAP_FD(BPF_REG_1, 0),
7588 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7589 BPF_FUNC_map_lookup_elem),
7590 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7591 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7592 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7593 BPF_MOV64_IMM(BPF_REG_2, -1),
7594 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7595 /* Dead branch. */
7596 BPF_MOV64_IMM(BPF_REG_0, 0),
7597 BPF_EXIT_INSN(),
7598 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7599 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7600 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7601 BPF_MOV64_IMM(BPF_REG_0, 0),
7602 BPF_EXIT_INSN(),
7603 },
7604 .fixup_map1 = { 3 },
7605 .errstr = "unbounded min value",
7606 .result = REJECT,
7607 },
7608 {
7609 "bounds checks mixing signed and unsigned, variant 12",
7610 .insns = {
7611 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7612 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7613 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7614 BPF_LD_MAP_FD(BPF_REG_1, 0),
7615 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7616 BPF_FUNC_map_lookup_elem),
7617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7618 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7619 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7620 BPF_MOV64_IMM(BPF_REG_2, -6),
7621 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7622 BPF_MOV64_IMM(BPF_REG_0, 0),
7623 BPF_EXIT_INSN(),
7624 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7625 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7626 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7627 BPF_MOV64_IMM(BPF_REG_0, 0),
7628 BPF_EXIT_INSN(),
7629 },
7630 .fixup_map1 = { 3 },
7631 .errstr = "unbounded min value",
7632 .result = REJECT,
7633 },
7634 {
7635 "bounds checks mixing signed and unsigned, variant 13",
7636 .insns = {
7637 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7638 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7639 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7640 BPF_LD_MAP_FD(BPF_REG_1, 0),
7641 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7642 BPF_FUNC_map_lookup_elem),
7643 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7644 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7645 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7646 BPF_MOV64_IMM(BPF_REG_2, 2),
7647 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7648 BPF_MOV64_IMM(BPF_REG_7, 1),
7649 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
7650 BPF_MOV64_IMM(BPF_REG_0, 0),
7651 BPF_EXIT_INSN(),
7652 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
7653 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
7654 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
7655 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7656 BPF_MOV64_IMM(BPF_REG_0, 0),
7657 BPF_EXIT_INSN(),
7658 },
7659 .fixup_map1 = { 3 },
7660 .errstr = "unbounded min value",
7661 .result = REJECT,
7662 },
7663 {
7664 "bounds checks mixing signed and unsigned, variant 14",
7665 .insns = {
7666 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
7667 offsetof(struct __sk_buff, mark)),
7668 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7669 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7670 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7671 BPF_LD_MAP_FD(BPF_REG_1, 0),
7672 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7673 BPF_FUNC_map_lookup_elem),
7674 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7675 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7676 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7677 BPF_MOV64_IMM(BPF_REG_2, -1),
7678 BPF_MOV64_IMM(BPF_REG_8, 2),
7679 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
7680 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
7681 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7682 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7683 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7684 BPF_MOV64_IMM(BPF_REG_0, 0),
7685 BPF_EXIT_INSN(),
7686 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
7687 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
7688 },
7689 .fixup_map1 = { 4 },
7690 .errstr = "R0 invalid mem access 'inv'",
7691 .result = REJECT,
7692 },
7693 {
7694 "bounds checks mixing signed and unsigned, variant 15",
7695 .insns = {
7696 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7697 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7698 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7699 BPF_LD_MAP_FD(BPF_REG_1, 0),
7700 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7701 BPF_FUNC_map_lookup_elem),
7702 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7703 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7704 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7705 BPF_MOV64_IMM(BPF_REG_2, -6),
7706 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7707 BPF_MOV64_IMM(BPF_REG_0, 0),
7708 BPF_EXIT_INSN(),
7709 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7710 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
7711 BPF_MOV64_IMM(BPF_REG_0, 0),
7712 BPF_EXIT_INSN(),
7713 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7714 BPF_MOV64_IMM(BPF_REG_0, 0),
7715 BPF_EXIT_INSN(),
7716 },
7717 .fixup_map1 = { 3 },
7718 .errstr = "unbounded min value",
7719 .result = REJECT,
7720 .result_unpriv = REJECT,
7721 },
7722 {
7723 "subtraction bounds (map value) variant 1",
7724 .insns = {
7725 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7726 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7727 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7728 BPF_LD_MAP_FD(BPF_REG_1, 0),
7729 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7730 BPF_FUNC_map_lookup_elem),
7731 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7732 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7733 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
7734 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7735 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
7736 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7737 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
7738 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7739 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7740 BPF_EXIT_INSN(),
7741 BPF_MOV64_IMM(BPF_REG_0, 0),
7742 BPF_EXIT_INSN(),
7743 },
7744 .fixup_map1 = { 3 },
7745 .errstr = "R0 max value is outside of the array range",
7746 .result = REJECT,
7747 },
7748 {
7749 "subtraction bounds (map value) variant 2",
7750 .insns = {
7751 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7752 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7753 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7754 BPF_LD_MAP_FD(BPF_REG_1, 0),
7755 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7756 BPF_FUNC_map_lookup_elem),
7757 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7758 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7759 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
7760 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7761 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
7762 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7763 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7764 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7765 BPF_EXIT_INSN(),
7766 BPF_MOV64_IMM(BPF_REG_0, 0),
7767 BPF_EXIT_INSN(),
7768 },
7769 .fixup_map1 = { 3 },
7770 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
7771 .result = REJECT,
7772 },
7773 {
7774 "bounds check based on zero-extended MOV",
7775 .insns = {
7776 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7777 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7778 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7779 BPF_LD_MAP_FD(BPF_REG_1, 0),
7780 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7781 BPF_FUNC_map_lookup_elem),
7782 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7783 /* r2 = 0x0000'0000'ffff'ffff */
7784 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
7785 /* r2 = 0 */
7786 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
7787 /* no-op */
7788 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7789 /* access at offset 0 */
7790 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7791 /* exit */
7792 BPF_MOV64_IMM(BPF_REG_0, 0),
7793 BPF_EXIT_INSN(),
7794 },
7795 .fixup_map1 = { 3 },
7796 .result = ACCEPT
7797 },
7798 {
7799 "bounds check based on sign-extended MOV. test1",
7800 .insns = {
7801 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7802 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7803 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7804 BPF_LD_MAP_FD(BPF_REG_1, 0),
7805 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7806 BPF_FUNC_map_lookup_elem),
7807 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7808 /* r2 = 0xffff'ffff'ffff'ffff */
7809 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
7810 /* r2 = 0xffff'ffff */
7811 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
7812 /* r0 = <oob pointer> */
7813 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7814 /* access to OOB pointer */
7815 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7816 /* exit */
7817 BPF_MOV64_IMM(BPF_REG_0, 0),
7818 BPF_EXIT_INSN(),
7819 },
7820 .fixup_map1 = { 3 },
7821 .errstr = "map_value pointer and 4294967295",
7822 .result = REJECT
7823 },
7824 {
7825 "bounds check based on sign-extended MOV. test2",
7826 .insns = {
7827 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7828 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7830 BPF_LD_MAP_FD(BPF_REG_1, 0),
7831 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7832 BPF_FUNC_map_lookup_elem),
7833 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7834 /* r2 = 0xffff'ffff'ffff'ffff */
7835 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
7836 /* r2 = 0xfff'ffff */
7837 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
7838 /* r0 = <oob pointer> */
7839 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7840 /* access to OOB pointer */
7841 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7842 /* exit */
7843 BPF_MOV64_IMM(BPF_REG_0, 0),
7844 BPF_EXIT_INSN(),
7845 },
7846 .fixup_map1 = { 3 },
7847 .errstr = "R0 min value is outside of the array range",
7848 .result = REJECT
7849 },
7850 {
7851 "bounds check based on reg_off + var_off + insn_off. test1",
7852 .insns = {
7853 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
7854 offsetof(struct __sk_buff, mark)),
7855 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7856 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7857 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7858 BPF_LD_MAP_FD(BPF_REG_1, 0),
7859 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7860 BPF_FUNC_map_lookup_elem),
7861 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7862 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
7863 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
7864 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
7865 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
7866 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
7867 BPF_MOV64_IMM(BPF_REG_0, 0),
7868 BPF_EXIT_INSN(),
7869 },
7870 .fixup_map1 = { 4 },
7871 .errstr = "value_size=8 off=1073741825",
7872 .result = REJECT,
7873 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7874 },
7875 {
7876 "bounds check based on reg_off + var_off + insn_off. test2",
7877 .insns = {
7878 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
7879 offsetof(struct __sk_buff, mark)),
7880 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7881 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7883 BPF_LD_MAP_FD(BPF_REG_1, 0),
7884 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7885 BPF_FUNC_map_lookup_elem),
7886 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7887 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
7888 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
7889 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
7890 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
7891 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
7892 BPF_MOV64_IMM(BPF_REG_0, 0),
7893 BPF_EXIT_INSN(),
7894 },
7895 .fixup_map1 = { 4 },
7896 .errstr = "value 1073741823",
7897 .result = REJECT,
7898 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7899 },
7900 {
7901 "bounds check after truncation of non-boundary-crossing range",
7902 .insns = {
7903 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7904 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7906 BPF_LD_MAP_FD(BPF_REG_1, 0),
7907 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7908 BPF_FUNC_map_lookup_elem),
7909 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7910 /* r1 = [0x00, 0xff] */
7911 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7912 BPF_MOV64_IMM(BPF_REG_2, 1),
7913 /* r2 = 0x10'0000'0000 */
7914 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
7915 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
7916 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
7917 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
7918 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7919 /* r1 = [0x00, 0xff] */
7920 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
7921 /* r1 = 0 */
7922 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7923 /* no-op */
7924 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7925 /* access at offset 0 */
7926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7927 /* exit */
7928 BPF_MOV64_IMM(BPF_REG_0, 0),
7929 BPF_EXIT_INSN(),
7930 },
7931 .fixup_map1 = { 3 },
7932 .result = ACCEPT
7933 },
7934 {
7935 "bounds check after truncation of boundary-crossing range (1)",
7936 .insns = {
7937 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7938 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7940 BPF_LD_MAP_FD(BPF_REG_1, 0),
7941 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7942 BPF_FUNC_map_lookup_elem),
7943 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7944 /* r1 = [0x00, 0xff] */
7945 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7946 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7947 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7948 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7949 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7950 * [0x0000'0000, 0x0000'007f]
7951 */
7952 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
7953 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7954 /* r1 = [0x00, 0xff] or
7955 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7956 */
7957 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7958 /* r1 = 0 or
7959 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7960 */
7961 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7962 /* no-op or OOB pointer computation */
7963 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7964 /* potentially OOB access */
7965 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7966 /* exit */
7967 BPF_MOV64_IMM(BPF_REG_0, 0),
7968 BPF_EXIT_INSN(),
7969 },
7970 .fixup_map1 = { 3 },
7971 /* not actually fully unbounded, but the bound is very high */
7972 .errstr = "R0 unbounded memory access",
7973 .result = REJECT
7974 },
7975 {
7976 "bounds check after truncation of boundary-crossing range (2)",
7977 .insns = {
7978 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7979 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7981 BPF_LD_MAP_FD(BPF_REG_1, 0),
7982 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7983 BPF_FUNC_map_lookup_elem),
7984 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7985 /* r1 = [0x00, 0xff] */
7986 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7987 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7988 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7989 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7990 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7991 * [0x0000'0000, 0x0000'007f]
7992 * difference to previous test: truncation via MOV32
7993 * instead of ALU32.
7994 */
7995 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
7996 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7997 /* r1 = [0x00, 0xff] or
7998 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7999 */
8000 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8001 /* r1 = 0 or
8002 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
8003 */
8004 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8005 /* no-op or OOB pointer computation */
8006 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8007 /* potentially OOB access */
8008 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8009 /* exit */
8010 BPF_MOV64_IMM(BPF_REG_0, 0),
8011 BPF_EXIT_INSN(),
8012 },
8013 .fixup_map1 = { 3 },
8014 /* not actually fully unbounded, but the bound is very high */
8015 .errstr = "R0 unbounded memory access",
8016 .result = REJECT
8017 },
8018 {
8019 "bounds check after wrapping 32-bit addition",
8020 .insns = {
8021 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8022 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8023 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8024 BPF_LD_MAP_FD(BPF_REG_1, 0),
8025 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8026 BPF_FUNC_map_lookup_elem),
8027 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
8028 /* r1 = 0x7fff'ffff */
8029 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
8030 /* r1 = 0xffff'fffe */
8031 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8032 /* r1 = 0 */
8033 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
8034 /* no-op */
8035 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8036 /* access at offset 0 */
8037 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8038 /* exit */
8039 BPF_MOV64_IMM(BPF_REG_0, 0),
8040 BPF_EXIT_INSN(),
8041 },
8042 .fixup_map1 = { 3 },
8043 .result = ACCEPT
8044 },
8045 {
8046 "bounds check after shift with oversized count operand",
8047 .insns = {
8048 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8049 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8050 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8051 BPF_LD_MAP_FD(BPF_REG_1, 0),
8052 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8053 BPF_FUNC_map_lookup_elem),
8054 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8055 BPF_MOV64_IMM(BPF_REG_2, 32),
8056 BPF_MOV64_IMM(BPF_REG_1, 1),
8057 /* r1 = (u32)1 << (u32)32 = ? */
8058 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
8059 /* r1 = [0x0000, 0xffff] */
8060 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
8061 /* computes unknown pointer, potentially OOB */
8062 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8063 /* potentially OOB access */
8064 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8065 /* exit */
8066 BPF_MOV64_IMM(BPF_REG_0, 0),
8067 BPF_EXIT_INSN(),
8068 },
8069 .fixup_map1 = { 3 },
8070 .errstr = "R0 max value is outside of the array range",
8071 .result = REJECT
8072 },
8073 {
8074 "bounds check after right shift of maybe-negative number",
8075 .insns = {
8076 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8077 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8079 BPF_LD_MAP_FD(BPF_REG_1, 0),
8080 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8081 BPF_FUNC_map_lookup_elem),
8082 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8083 /* r1 = [0x00, 0xff] */
8084 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8085 /* r1 = [-0x01, 0xfe] */
8086 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
8087 /* r1 = 0 or 0xff'ffff'ffff'ffff */
8088 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8089 /* r1 = 0 or 0xffff'ffff'ffff */
8090 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8091 /* computes unknown pointer, potentially OOB */
8092 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8093 /* potentially OOB access */
8094 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8095 /* exit */
8096 BPF_MOV64_IMM(BPF_REG_0, 0),
8097 BPF_EXIT_INSN(),
8098 },
8099 .fixup_map1 = { 3 },
8100 .errstr = "R0 unbounded memory access",
8101 .result = REJECT
8102 },
8103 {
8104 "bounds check map access with off+size signed 32bit overflow. test1",
8105 .insns = {
8106 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8107 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8108 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8109 BPF_LD_MAP_FD(BPF_REG_1, 0),
8110 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8111 BPF_FUNC_map_lookup_elem),
8112 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8113 BPF_EXIT_INSN(),
8114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
8115 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8116 BPF_JMP_A(0),
8117 BPF_EXIT_INSN(),
8118 },
8119 .fixup_map1 = { 3 },
8120 .errstr = "map_value pointer and 2147483646",
8121 .result = REJECT
8122 },
8123 {
8124 "bounds check map access with off+size signed 32bit overflow. test2",
8125 .insns = {
8126 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8127 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8128 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8129 BPF_LD_MAP_FD(BPF_REG_1, 0),
8130 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8131 BPF_FUNC_map_lookup_elem),
8132 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8133 BPF_EXIT_INSN(),
8134 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8136 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8137 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8138 BPF_JMP_A(0),
8139 BPF_EXIT_INSN(),
8140 },
8141 .fixup_map1 = { 3 },
8142 .errstr = "pointer offset 1073741822",
8143 .result = REJECT
8144 },
8145 {
8146 "bounds check map access with off+size signed 32bit overflow. test3",
8147 .insns = {
8148 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8149 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8150 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8151 BPF_LD_MAP_FD(BPF_REG_1, 0),
8152 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8153 BPF_FUNC_map_lookup_elem),
8154 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8155 BPF_EXIT_INSN(),
8156 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8157 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8158 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8159 BPF_JMP_A(0),
8160 BPF_EXIT_INSN(),
8161 },
8162 .fixup_map1 = { 3 },
8163 .errstr = "pointer offset -1073741822",
8164 .result = REJECT
8165 },
8166 {
8167 "bounds check map access with off+size signed 32bit overflow. test4",
8168 .insns = {
8169 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8170 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8171 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8172 BPF_LD_MAP_FD(BPF_REG_1, 0),
8173 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8174 BPF_FUNC_map_lookup_elem),
8175 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8176 BPF_EXIT_INSN(),
8177 BPF_MOV64_IMM(BPF_REG_1, 1000000),
8178 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
8179 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8180 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8181 BPF_JMP_A(0),
8182 BPF_EXIT_INSN(),
8183 },
8184 .fixup_map1 = { 3 },
8185 .errstr = "map_value pointer and 1000000000000",
8186 .result = REJECT
8187 },
8188 {
8189 "pointer/scalar confusion in state equality check (way 1)",
8190 .insns = {
8191 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8192 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8193 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8194 BPF_LD_MAP_FD(BPF_REG_1, 0),
8195 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8196 BPF_FUNC_map_lookup_elem),
8197 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
8198 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8199 BPF_JMP_A(1),
8200 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8201 BPF_JMP_A(0),
8202 BPF_EXIT_INSN(),
8203 },
8204 .fixup_map1 = { 3 },
8205 .result = ACCEPT,
8206 .retval = POINTER_VALUE,
8207 .result_unpriv = REJECT,
8208 .errstr_unpriv = "R0 leaks addr as return value"
8209 },
8210 {
8211 "pointer/scalar confusion in state equality check (way 2)",
8212 .insns = {
8213 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8214 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8216 BPF_LD_MAP_FD(BPF_REG_1, 0),
8217 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8218 BPF_FUNC_map_lookup_elem),
8219 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8220 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8221 BPF_JMP_A(1),
8222 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8223 BPF_EXIT_INSN(),
8224 },
8225 .fixup_map1 = { 3 },
8226 .result = ACCEPT,
8227 .retval = POINTER_VALUE,
8228 .result_unpriv = REJECT,
8229 .errstr_unpriv = "R0 leaks addr as return value"
8230 },
8231 {
8232 "variable-offset ctx access",
8233 .insns = {
8234 /* Get an unknown value */
8235 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8236 /* Make it small and 4-byte aligned */
8237 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8238 /* add it to skb. We now have either &skb->len or
8239 * &skb->pkt_type, but we don't know which
8240 */
8241 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
8242 /* dereference it */
8243 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8244 BPF_EXIT_INSN(),
8245 },
8246 .errstr = "variable ctx access var_off=(0x0; 0x4)",
8247 .result = REJECT,
8248 .prog_type = BPF_PROG_TYPE_LWT_IN,
8249 },
8250 {
8251 "variable-offset stack access",
8252 .insns = {
8253 /* Fill the top 8 bytes of the stack */
8254 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8255 /* Get an unknown value */
8256 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8257 /* Make it small and 4-byte aligned */
8258 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8259 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8260 /* add it to fp. We now have either fp-4 or fp-8, but
8261 * we don't know which
8262 */
8263 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8264 /* dereference it */
8265 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
8266 BPF_EXIT_INSN(),
8267 },
8268 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
8269 .result = REJECT,
8270 .prog_type = BPF_PROG_TYPE_LWT_IN,
8271 },
8272 {
8273 "indirect variable-offset stack access",
8274 .insns = {
8275 /* Fill the top 8 bytes of the stack */
8276 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8277 /* Get an unknown value */
8278 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8279 /* Make it small and 4-byte aligned */
8280 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8281 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8282 /* add it to fp. We now have either fp-4 or fp-8, but
8283 * we don't know which
8284 */
8285 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8286 /* dereference it indirectly */
8287 BPF_LD_MAP_FD(BPF_REG_1, 0),
8288 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8289 BPF_FUNC_map_lookup_elem),
8290 BPF_MOV64_IMM(BPF_REG_0, 0),
8291 BPF_EXIT_INSN(),
8292 },
8293 .fixup_map1 = { 5 },
8294 .errstr = "variable stack read R2",
8295 .result = REJECT,
8296 .prog_type = BPF_PROG_TYPE_LWT_IN,
8297 },
8298 {
8299 "direct stack access with 32-bit wraparound. test1",
8300 .insns = {
8301 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8304 BPF_MOV32_IMM(BPF_REG_0, 0),
8305 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8306 BPF_EXIT_INSN()
8307 },
8308 .errstr = "fp pointer and 2147483647",
8309 .result = REJECT
8310 },
8311 {
8312 "direct stack access with 32-bit wraparound. test2",
8313 .insns = {
8314 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8316 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8317 BPF_MOV32_IMM(BPF_REG_0, 0),
8318 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8319 BPF_EXIT_INSN()
8320 },
8321 .errstr = "fp pointer and 1073741823",
8322 .result = REJECT
8323 },
8324 {
8325 "direct stack access with 32-bit wraparound. test3",
8326 .insns = {
8327 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8328 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8329 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8330 BPF_MOV32_IMM(BPF_REG_0, 0),
8331 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8332 BPF_EXIT_INSN()
8333 },
8334 .errstr = "fp pointer offset 1073741822",
8335 .result = REJECT
8336 },
8337 {
8338 "liveness pruning and write screening",
8339 .insns = {
8340 /* Get an unknown value */
8341 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8342 /* branch conditions teach us nothing about R2 */
8343 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8344 BPF_MOV64_IMM(BPF_REG_0, 0),
8345 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8346 BPF_MOV64_IMM(BPF_REG_0, 0),
8347 BPF_EXIT_INSN(),
8348 },
8349 .errstr = "R0 !read_ok",
8350 .result = REJECT,
8351 .prog_type = BPF_PROG_TYPE_LWT_IN,
8352 },
8353 {
8354 "varlen_map_value_access pruning",
8355 .insns = {
8356 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8357 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8358 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8359 BPF_LD_MAP_FD(BPF_REG_1, 0),
8360 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8361 BPF_FUNC_map_lookup_elem),
8362 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8363 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
8364 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
8365 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
8366 BPF_MOV32_IMM(BPF_REG_1, 0),
8367 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
8368 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8369 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
8370 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
8371 offsetof(struct test_val, foo)),
8372 BPF_EXIT_INSN(),
8373 },
8374 .fixup_map2 = { 3 },
8375 .errstr_unpriv = "R0 leaks addr",
8376 .errstr = "R0 unbounded memory access",
8377 .result_unpriv = REJECT,
8378 .result = REJECT,
8379 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8380 },
8381 {
8382 "invalid 64-bit BPF_END",
8383 .insns = {
8384 BPF_MOV32_IMM(BPF_REG_0, 0),
8385 {
8386 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
8387 .dst_reg = BPF_REG_0,
8388 .src_reg = 0,
8389 .off = 0,
8390 .imm = 32,
8391 },
8392 BPF_EXIT_INSN(),
8393 },
8394 .errstr = "unknown opcode d7",
8395 .result = REJECT,
8396 },
8397 {
8398 "XDP, using ifindex from netdev",
8399 .insns = {
8400 BPF_MOV64_IMM(BPF_REG_0, 0),
8401 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8402 offsetof(struct xdp_md, ingress_ifindex)),
8403 BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
8404 BPF_MOV64_IMM(BPF_REG_0, 1),
8405 BPF_EXIT_INSN(),
8406 },
8407 .result = ACCEPT,
8408 .prog_type = BPF_PROG_TYPE_XDP,
8409 .retval = 1,
8410 },
8411 {
8412 "meta access, test1",
8413 .insns = {
8414 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8415 offsetof(struct xdp_md, data_meta)),
8416 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8417 offsetof(struct xdp_md, data)),
8418 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8420 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8421 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8422 BPF_MOV64_IMM(BPF_REG_0, 0),
8423 BPF_EXIT_INSN(),
8424 },
8425 .result = ACCEPT,
8426 .prog_type = BPF_PROG_TYPE_XDP,
8427 },
8428 {
8429 "meta access, test2",
8430 .insns = {
8431 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8432 offsetof(struct xdp_md, data_meta)),
8433 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8434 offsetof(struct xdp_md, data)),
8435 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8436 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
8437 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8438 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8439 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8440 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8441 BPF_MOV64_IMM(BPF_REG_0, 0),
8442 BPF_EXIT_INSN(),
8443 },
8444 .result = REJECT,
8445 .errstr = "invalid access to packet, off=-8",
8446 .prog_type = BPF_PROG_TYPE_XDP,
8447 },
8448 {
8449 "meta access, test3",
8450 .insns = {
8451 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8452 offsetof(struct xdp_md, data_meta)),
8453 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8454 offsetof(struct xdp_md, data_end)),
8455 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8457 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8458 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8459 BPF_MOV64_IMM(BPF_REG_0, 0),
8460 BPF_EXIT_INSN(),
8461 },
8462 .result = REJECT,
8463 .errstr = "invalid access to packet",
8464 .prog_type = BPF_PROG_TYPE_XDP,
8465 },
8466 {
8467 "meta access, test4",
8468 .insns = {
8469 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8470 offsetof(struct xdp_md, data_meta)),
8471 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8472 offsetof(struct xdp_md, data_end)),
8473 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8474 offsetof(struct xdp_md, data)),
8475 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
8476 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8477 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8478 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8479 BPF_MOV64_IMM(BPF_REG_0, 0),
8480 BPF_EXIT_INSN(),
8481 },
8482 .result = REJECT,
8483 .errstr = "invalid access to packet",
8484 .prog_type = BPF_PROG_TYPE_XDP,
8485 },
8486 {
8487 "meta access, test5",
8488 .insns = {
8489 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8490 offsetof(struct xdp_md, data_meta)),
8491 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8492 offsetof(struct xdp_md, data)),
8493 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8495 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
8496 BPF_MOV64_IMM(BPF_REG_2, -8),
8497 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8498 BPF_FUNC_xdp_adjust_meta),
8499 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8500 BPF_MOV64_IMM(BPF_REG_0, 0),
8501 BPF_EXIT_INSN(),
8502 },
8503 .result = REJECT,
8504 .errstr = "R3 !read_ok",
8505 .prog_type = BPF_PROG_TYPE_XDP,
8506 },
8507 {
8508 "meta access, test6",
8509 .insns = {
8510 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8511 offsetof(struct xdp_md, data_meta)),
8512 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8513 offsetof(struct xdp_md, data)),
8514 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8516 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8517 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8518 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
8519 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8520 BPF_MOV64_IMM(BPF_REG_0, 0),
8521 BPF_EXIT_INSN(),
8522 },
8523 .result = REJECT,
8524 .errstr = "invalid access to packet",
8525 .prog_type = BPF_PROG_TYPE_XDP,
8526 },
8527 {
8528 "meta access, test7",
8529 .insns = {
8530 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8531 offsetof(struct xdp_md, data_meta)),
8532 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8533 offsetof(struct xdp_md, data)),
8534 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8536 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8537 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8538 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8539 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8540 BPF_MOV64_IMM(BPF_REG_0, 0),
8541 BPF_EXIT_INSN(),
8542 },
8543 .result = ACCEPT,
8544 .prog_type = BPF_PROG_TYPE_XDP,
8545 },
8546 {
8547 "meta access, test8",
8548 .insns = {
8549 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8550 offsetof(struct xdp_md, data_meta)),
8551 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8552 offsetof(struct xdp_md, data)),
8553 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8554 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8555 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8556 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8557 BPF_MOV64_IMM(BPF_REG_0, 0),
8558 BPF_EXIT_INSN(),
8559 },
8560 .result = ACCEPT,
8561 .prog_type = BPF_PROG_TYPE_XDP,
8562 },
8563 {
8564 "meta access, test9",
8565 .insns = {
8566 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8567 offsetof(struct xdp_md, data_meta)),
8568 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8569 offsetof(struct xdp_md, data)),
8570 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8571 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
8573 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8574 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8575 BPF_MOV64_IMM(BPF_REG_0, 0),
8576 BPF_EXIT_INSN(),
8577 },
8578 .result = REJECT,
8579 .errstr = "invalid access to packet",
8580 .prog_type = BPF_PROG_TYPE_XDP,
8581 },
8582 {
8583 "meta access, test10",
8584 .insns = {
8585 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8586 offsetof(struct xdp_md, data_meta)),
8587 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8588 offsetof(struct xdp_md, data)),
8589 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8590 offsetof(struct xdp_md, data_end)),
8591 BPF_MOV64_IMM(BPF_REG_5, 42),
8592 BPF_MOV64_IMM(BPF_REG_6, 24),
8593 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8594 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8595 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8596 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8597 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
8598 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8599 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8600 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8601 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
8602 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
8603 BPF_MOV64_IMM(BPF_REG_0, 0),
8604 BPF_EXIT_INSN(),
8605 },
8606 .result = REJECT,
8607 .errstr = "invalid access to packet",
8608 .prog_type = BPF_PROG_TYPE_XDP,
8609 },
8610 {
8611 "meta access, test11",
8612 .insns = {
8613 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8614 offsetof(struct xdp_md, data_meta)),
8615 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8616 offsetof(struct xdp_md, data)),
8617 BPF_MOV64_IMM(BPF_REG_5, 42),
8618 BPF_MOV64_IMM(BPF_REG_6, 24),
8619 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8620 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8621 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8622 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8623 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
8624 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8625 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8627 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
8628 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
8629 BPF_MOV64_IMM(BPF_REG_0, 0),
8630 BPF_EXIT_INSN(),
8631 },
8632 .result = ACCEPT,
8633 .prog_type = BPF_PROG_TYPE_XDP,
8634 },
8635 {
8636 "meta access, test12",
8637 .insns = {
8638 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8639 offsetof(struct xdp_md, data_meta)),
8640 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8641 offsetof(struct xdp_md, data)),
8642 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8643 offsetof(struct xdp_md, data_end)),
8644 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8645 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8646 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
8647 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8648 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8649 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8650 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
8651 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8652 BPF_MOV64_IMM(BPF_REG_0, 0),
8653 BPF_EXIT_INSN(),
8654 },
8655 .result = ACCEPT,
8656 .prog_type = BPF_PROG_TYPE_XDP,
8657 },
8658 {
8659 "arithmetic ops make PTR_TO_CTX unusable",
8660 .insns = {
8661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
8662 offsetof(struct __sk_buff, data) -
8663 offsetof(struct __sk_buff, mark)),
8664 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8665 offsetof(struct __sk_buff, mark)),
8666 BPF_EXIT_INSN(),
8667 },
8668 .errstr = "dereference of modified ctx ptr",
8669 .result = REJECT,
8670 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8671 },
8672 {
8673 "pkt_end - pkt_start is allowed",
8674 .insns = {
8675 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8676 offsetof(struct __sk_buff, data_end)),
8677 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8678 offsetof(struct __sk_buff, data)),
8679 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
8680 BPF_EXIT_INSN(),
8681 },
8682 .result = ACCEPT,
8683 .retval = TEST_DATA_LEN,
8684 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8685 },
8686 {
8687 "XDP pkt read, pkt_end mangling, bad access 1",
8688 .insns = {
8689 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8690 offsetof(struct xdp_md, data)),
8691 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8692 offsetof(struct xdp_md, data_end)),
8693 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
8696 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8697 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8698 BPF_MOV64_IMM(BPF_REG_0, 0),
8699 BPF_EXIT_INSN(),
8700 },
8701 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
8702 .result = REJECT,
8703 .prog_type = BPF_PROG_TYPE_XDP,
8704 },
8705 {
8706 "XDP pkt read, pkt_end mangling, bad access 2",
8707 .insns = {
8708 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8709 offsetof(struct xdp_md, data)),
8710 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8711 offsetof(struct xdp_md, data_end)),
8712 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8714 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
8715 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8716 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8717 BPF_MOV64_IMM(BPF_REG_0, 0),
8718 BPF_EXIT_INSN(),
8719 },
8720 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
8721 .result = REJECT,
8722 .prog_type = BPF_PROG_TYPE_XDP,
8723 },
8724 {
8725 "XDP pkt read, pkt_data' > pkt_end, good access",
8726 .insns = {
8727 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8728 offsetof(struct xdp_md, data)),
8729 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8730 offsetof(struct xdp_md, data_end)),
8731 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8732 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8733 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8734 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8735 BPF_MOV64_IMM(BPF_REG_0, 0),
8736 BPF_EXIT_INSN(),
8737 },
8738 .result = ACCEPT,
8739 .prog_type = BPF_PROG_TYPE_XDP,
8740 },
8741 {
8742 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
8743 .insns = {
8744 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8745 offsetof(struct xdp_md, data)),
8746 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8747 offsetof(struct xdp_md, data_end)),
8748 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8749 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8750 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8751 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8752 BPF_MOV64_IMM(BPF_REG_0, 0),
8753 BPF_EXIT_INSN(),
8754 },
8755 .errstr = "R1 offset is outside of the packet",
8756 .result = REJECT,
8757 .prog_type = BPF_PROG_TYPE_XDP,
8758 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8759 },
8760 {
8761 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
8762 .insns = {
8763 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8764 offsetof(struct xdp_md, data)),
8765 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8766 offsetof(struct xdp_md, data_end)),
8767 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8768 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8769 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8770 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8771 BPF_MOV64_IMM(BPF_REG_0, 0),
8772 BPF_EXIT_INSN(),
8773 },
8774 .errstr = "R1 offset is outside of the packet",
8775 .result = REJECT,
8776 .prog_type = BPF_PROG_TYPE_XDP,
8777 },
8778 {
8779 "XDP pkt read, pkt_end > pkt_data', good access",
8780 .insns = {
8781 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8782 offsetof(struct xdp_md, data)),
8783 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8784 offsetof(struct xdp_md, data_end)),
8785 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8786 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8787 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8788 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8789 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8790 BPF_MOV64_IMM(BPF_REG_0, 0),
8791 BPF_EXIT_INSN(),
8792 },
8793 .result = ACCEPT,
8794 .prog_type = BPF_PROG_TYPE_XDP,
8795 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8796 },
8797 {
8798 "XDP pkt read, pkt_end > pkt_data', bad access 1",
8799 .insns = {
8800 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8801 offsetof(struct xdp_md, data)),
8802 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8803 offsetof(struct xdp_md, data_end)),
8804 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8805 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8806 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8807 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8808 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8809 BPF_MOV64_IMM(BPF_REG_0, 0),
8810 BPF_EXIT_INSN(),
8811 },
8812 .errstr = "R1 offset is outside of the packet",
8813 .result = REJECT,
8814 .prog_type = BPF_PROG_TYPE_XDP,
8815 },
8816 {
8817 "XDP pkt read, pkt_end > pkt_data', bad access 2",
8818 .insns = {
8819 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8820 offsetof(struct xdp_md, data)),
8821 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8822 offsetof(struct xdp_md, data_end)),
8823 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8825 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8826 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8827 BPF_MOV64_IMM(BPF_REG_0, 0),
8828 BPF_EXIT_INSN(),
8829 },
8830 .errstr = "R1 offset is outside of the packet",
8831 .result = REJECT,
8832 .prog_type = BPF_PROG_TYPE_XDP,
8833 },
8834 {
8835 "XDP pkt read, pkt_data' < pkt_end, good access",
8836 .insns = {
8837 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8838 offsetof(struct xdp_md, data)),
8839 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8840 offsetof(struct xdp_md, data_end)),
8841 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8843 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8844 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8845 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8846 BPF_MOV64_IMM(BPF_REG_0, 0),
8847 BPF_EXIT_INSN(),
8848 },
8849 .result = ACCEPT,
8850 .prog_type = BPF_PROG_TYPE_XDP,
8851 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8852 },
8853 {
8854 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
8855 .insns = {
8856 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8857 offsetof(struct xdp_md, data)),
8858 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8859 offsetof(struct xdp_md, data_end)),
8860 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8861 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8862 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8863 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8864 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8865 BPF_MOV64_IMM(BPF_REG_0, 0),
8866 BPF_EXIT_INSN(),
8867 },
8868 .errstr = "R1 offset is outside of the packet",
8869 .result = REJECT,
8870 .prog_type = BPF_PROG_TYPE_XDP,
8871 },
8872 {
8873 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
8874 .insns = {
8875 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8876 offsetof(struct xdp_md, data)),
8877 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8878 offsetof(struct xdp_md, data_end)),
8879 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8880 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8881 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8882 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8883 BPF_MOV64_IMM(BPF_REG_0, 0),
8884 BPF_EXIT_INSN(),
8885 },
8886 .errstr = "R1 offset is outside of the packet",
8887 .result = REJECT,
8888 .prog_type = BPF_PROG_TYPE_XDP,
8889 },
8890 {
8891 "XDP pkt read, pkt_end < pkt_data', good access",
8892 .insns = {
8893 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8894 offsetof(struct xdp_md, data)),
8895 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8896 offsetof(struct xdp_md, data_end)),
8897 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8898 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8899 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8900 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8901 BPF_MOV64_IMM(BPF_REG_0, 0),
8902 BPF_EXIT_INSN(),
8903 },
8904 .result = ACCEPT,
8905 .prog_type = BPF_PROG_TYPE_XDP,
8906 },
8907 {
8908 "XDP pkt read, pkt_end < pkt_data', bad access 1",
8909 .insns = {
8910 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8911 offsetof(struct xdp_md, data)),
8912 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8913 offsetof(struct xdp_md, data_end)),
8914 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8915 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8916 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8917 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8918 BPF_MOV64_IMM(BPF_REG_0, 0),
8919 BPF_EXIT_INSN(),
8920 },
8921 .errstr = "R1 offset is outside of the packet",
8922 .result = REJECT,
8923 .prog_type = BPF_PROG_TYPE_XDP,
8924 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8925 },
8926 {
8927 "XDP pkt read, pkt_end < pkt_data', bad access 2",
8928 .insns = {
8929 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8930 offsetof(struct xdp_md, data)),
8931 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8932 offsetof(struct xdp_md, data_end)),
8933 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8934 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8935 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
8936 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8937 BPF_MOV64_IMM(BPF_REG_0, 0),
8938 BPF_EXIT_INSN(),
8939 },
8940 .errstr = "R1 offset is outside of the packet",
8941 .result = REJECT,
8942 .prog_type = BPF_PROG_TYPE_XDP,
8943 },
8944 {
8945 "XDP pkt read, pkt_data' >= pkt_end, good access",
8946 .insns = {
8947 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8948 offsetof(struct xdp_md, data)),
8949 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8950 offsetof(struct xdp_md, data_end)),
8951 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8952 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8953 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8954 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8955 BPF_MOV64_IMM(BPF_REG_0, 0),
8956 BPF_EXIT_INSN(),
8957 },
8958 .result = ACCEPT,
8959 .prog_type = BPF_PROG_TYPE_XDP,
8960 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8961 },
8962 {
8963 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
8964 .insns = {
8965 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8966 offsetof(struct xdp_md, data)),
8967 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8968 offsetof(struct xdp_md, data_end)),
8969 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8970 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8971 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8972 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8973 BPF_MOV64_IMM(BPF_REG_0, 0),
8974 BPF_EXIT_INSN(),
8975 },
8976 .errstr = "R1 offset is outside of the packet",
8977 .result = REJECT,
8978 .prog_type = BPF_PROG_TYPE_XDP,
8979 },
8980 {
8981 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
8982 .insns = {
8983 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8984 offsetof(struct xdp_md, data)),
8985 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8986 offsetof(struct xdp_md, data_end)),
8987 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8988 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8989 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8990 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8991 BPF_MOV64_IMM(BPF_REG_0, 0),
8992 BPF_EXIT_INSN(),
8993 },
8994 .errstr = "R1 offset is outside of the packet",
8995 .result = REJECT,
8996 .prog_type = BPF_PROG_TYPE_XDP,
8997 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8998 },
8999 {
9000 "XDP pkt read, pkt_end >= pkt_data', good access",
9001 .insns = {
9002 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9003 offsetof(struct xdp_md, data)),
9004 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9005 offsetof(struct xdp_md, data_end)),
9006 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9008 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9009 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9010 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9011 BPF_MOV64_IMM(BPF_REG_0, 0),
9012 BPF_EXIT_INSN(),
9013 },
9014 .result = ACCEPT,
9015 .prog_type = BPF_PROG_TYPE_XDP,
9016 },
9017 {
9018 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
9019 .insns = {
9020 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9021 offsetof(struct xdp_md, data)),
9022 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9023 offsetof(struct xdp_md, data_end)),
9024 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9026 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9027 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9028 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9029 BPF_MOV64_IMM(BPF_REG_0, 0),
9030 BPF_EXIT_INSN(),
9031 },
9032 .errstr = "R1 offset is outside of the packet",
9033 .result = REJECT,
9034 .prog_type = BPF_PROG_TYPE_XDP,
9035 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9036 },
9037 {
9038 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
9039 .insns = {
9040 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9041 offsetof(struct xdp_md, data)),
9042 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9043 offsetof(struct xdp_md, data_end)),
9044 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9045 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9046 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9047 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9048 BPF_MOV64_IMM(BPF_REG_0, 0),
9049 BPF_EXIT_INSN(),
9050 },
9051 .errstr = "R1 offset is outside of the packet",
9052 .result = REJECT,
9053 .prog_type = BPF_PROG_TYPE_XDP,
9054 },
9055 {
9056 "XDP pkt read, pkt_data' <= pkt_end, good access",
9057 .insns = {
9058 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9059 offsetof(struct xdp_md, data)),
9060 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9061 offsetof(struct xdp_md, data_end)),
9062 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9063 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9064 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9065 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9066 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9067 BPF_MOV64_IMM(BPF_REG_0, 0),
9068 BPF_EXIT_INSN(),
9069 },
9070 .result = ACCEPT,
9071 .prog_type = BPF_PROG_TYPE_XDP,
9072 },
9073 {
9074 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
9075 .insns = {
9076 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9077 offsetof(struct xdp_md, data)),
9078 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9079 offsetof(struct xdp_md, data_end)),
9080 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9082 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9083 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9084 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9085 BPF_MOV64_IMM(BPF_REG_0, 0),
9086 BPF_EXIT_INSN(),
9087 },
9088 .errstr = "R1 offset is outside of the packet",
9089 .result = REJECT,
9090 .prog_type = BPF_PROG_TYPE_XDP,
9091 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9092 },
9093 {
9094 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
9095 .insns = {
9096 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9097 offsetof(struct xdp_md, data)),
9098 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9099 offsetof(struct xdp_md, data_end)),
9100 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9101 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9102 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9103 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9104 BPF_MOV64_IMM(BPF_REG_0, 0),
9105 BPF_EXIT_INSN(),
9106 },
9107 .errstr = "R1 offset is outside of the packet",
9108 .result = REJECT,
9109 .prog_type = BPF_PROG_TYPE_XDP,
9110 },
9111 {
9112 "XDP pkt read, pkt_end <= pkt_data', good access",
9113 .insns = {
9114 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9115 offsetof(struct xdp_md, data)),
9116 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9117 offsetof(struct xdp_md, data_end)),
9118 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9120 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9121 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9122 BPF_MOV64_IMM(BPF_REG_0, 0),
9123 BPF_EXIT_INSN(),
9124 },
9125 .result = ACCEPT,
9126 .prog_type = BPF_PROG_TYPE_XDP,
9127 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9128 },
9129 {
9130 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
9131 .insns = {
9132 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9133 offsetof(struct xdp_md, data)),
9134 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9135 offsetof(struct xdp_md, data_end)),
9136 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9137 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9138 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9139 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9140 BPF_MOV64_IMM(BPF_REG_0, 0),
9141 BPF_EXIT_INSN(),
9142 },
9143 .errstr = "R1 offset is outside of the packet",
9144 .result = REJECT,
9145 .prog_type = BPF_PROG_TYPE_XDP,
9146 },
9147 {
9148 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
9149 .insns = {
9150 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9151 offsetof(struct xdp_md, data)),
9152 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9153 offsetof(struct xdp_md, data_end)),
9154 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9155 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9156 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9157 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9158 BPF_MOV64_IMM(BPF_REG_0, 0),
9159 BPF_EXIT_INSN(),
9160 },
9161 .errstr = "R1 offset is outside of the packet",
9162 .result = REJECT,
9163 .prog_type = BPF_PROG_TYPE_XDP,
9164 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9165 },
9166 {
9167 "XDP pkt read, pkt_meta' > pkt_data, good access",
9168 .insns = {
9169 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9170 offsetof(struct xdp_md, data_meta)),
9171 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9172 offsetof(struct xdp_md, data)),
9173 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9175 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9176 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9177 BPF_MOV64_IMM(BPF_REG_0, 0),
9178 BPF_EXIT_INSN(),
9179 },
9180 .result = ACCEPT,
9181 .prog_type = BPF_PROG_TYPE_XDP,
9182 },
9183 {
9184 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
9185 .insns = {
9186 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9187 offsetof(struct xdp_md, data_meta)),
9188 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9189 offsetof(struct xdp_md, data)),
9190 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9191 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9192 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9193 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9194 BPF_MOV64_IMM(BPF_REG_0, 0),
9195 BPF_EXIT_INSN(),
9196 },
9197 .errstr = "R1 offset is outside of the packet",
9198 .result = REJECT,
9199 .prog_type = BPF_PROG_TYPE_XDP,
9200 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9201 },
9202 {
9203 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
9204 .insns = {
9205 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9206 offsetof(struct xdp_md, data_meta)),
9207 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9208 offsetof(struct xdp_md, data)),
9209 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9211 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
9212 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9213 BPF_MOV64_IMM(BPF_REG_0, 0),
9214 BPF_EXIT_INSN(),
9215 },
9216 .errstr = "R1 offset is outside of the packet",
9217 .result = REJECT,
9218 .prog_type = BPF_PROG_TYPE_XDP,
9219 },
9220 {
9221 "XDP pkt read, pkt_data > pkt_meta', good access",
9222 .insns = {
9223 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9224 offsetof(struct xdp_md, data_meta)),
9225 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9226 offsetof(struct xdp_md, data)),
9227 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9228 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9229 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9230 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9231 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9232 BPF_MOV64_IMM(BPF_REG_0, 0),
9233 BPF_EXIT_INSN(),
9234 },
9235 .result = ACCEPT,
9236 .prog_type = BPF_PROG_TYPE_XDP,
9237 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9238 },
9239 {
9240 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
9241 .insns = {
9242 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9243 offsetof(struct xdp_md, data_meta)),
9244 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9245 offsetof(struct xdp_md, data)),
9246 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9248 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9249 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9250 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9251 BPF_MOV64_IMM(BPF_REG_0, 0),
9252 BPF_EXIT_INSN(),
9253 },
9254 .errstr = "R1 offset is outside of the packet",
9255 .result = REJECT,
9256 .prog_type = BPF_PROG_TYPE_XDP,
9257 },
9258 {
9259 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
9260 .insns = {
9261 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9262 offsetof(struct xdp_md, data_meta)),
9263 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9264 offsetof(struct xdp_md, data)),
9265 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9266 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9267 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9268 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9269 BPF_MOV64_IMM(BPF_REG_0, 0),
9270 BPF_EXIT_INSN(),
9271 },
9272 .errstr = "R1 offset is outside of the packet",
9273 .result = REJECT,
9274 .prog_type = BPF_PROG_TYPE_XDP,
9275 },
9276 {
9277 "XDP pkt read, pkt_meta' < pkt_data, good access",
9278 .insns = {
9279 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9280 offsetof(struct xdp_md, data_meta)),
9281 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9282 offsetof(struct xdp_md, data)),
9283 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9284 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9285 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9286 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9287 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9288 BPF_MOV64_IMM(BPF_REG_0, 0),
9289 BPF_EXIT_INSN(),
9290 },
9291 .result = ACCEPT,
9292 .prog_type = BPF_PROG_TYPE_XDP,
9293 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9294 },
9295 {
9296 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
9297 .insns = {
9298 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9299 offsetof(struct xdp_md, data_meta)),
9300 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9301 offsetof(struct xdp_md, data)),
9302 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9304 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9305 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9306 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9307 BPF_MOV64_IMM(BPF_REG_0, 0),
9308 BPF_EXIT_INSN(),
9309 },
9310 .errstr = "R1 offset is outside of the packet",
9311 .result = REJECT,
9312 .prog_type = BPF_PROG_TYPE_XDP,
9313 },
9314 {
9315 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
9316 .insns = {
9317 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9318 offsetof(struct xdp_md, data_meta)),
9319 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9320 offsetof(struct xdp_md, data)),
9321 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9322 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9323 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9324 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9325 BPF_MOV64_IMM(BPF_REG_0, 0),
9326 BPF_EXIT_INSN(),
9327 },
9328 .errstr = "R1 offset is outside of the packet",
9329 .result = REJECT,
9330 .prog_type = BPF_PROG_TYPE_XDP,
9331 },
9332 {
9333 "XDP pkt read, pkt_data < pkt_meta', good access",
9334 .insns = {
9335 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9336 offsetof(struct xdp_md, data_meta)),
9337 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9338 offsetof(struct xdp_md, data)),
9339 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9340 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9341 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9342 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9343 BPF_MOV64_IMM(BPF_REG_0, 0),
9344 BPF_EXIT_INSN(),
9345 },
9346 .result = ACCEPT,
9347 .prog_type = BPF_PROG_TYPE_XDP,
9348 },
9349 {
9350 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
9351 .insns = {
9352 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9353 offsetof(struct xdp_md, data_meta)),
9354 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9355 offsetof(struct xdp_md, data)),
9356 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9357 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9358 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9359 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9360 BPF_MOV64_IMM(BPF_REG_0, 0),
9361 BPF_EXIT_INSN(),
9362 },
9363 .errstr = "R1 offset is outside of the packet",
9364 .result = REJECT,
9365 .prog_type = BPF_PROG_TYPE_XDP,
9366 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9367 },
9368 {
9369 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
9370 .insns = {
9371 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9372 offsetof(struct xdp_md, data_meta)),
9373 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9374 offsetof(struct xdp_md, data)),
9375 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9376 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9377 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9378 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9379 BPF_MOV64_IMM(BPF_REG_0, 0),
9380 BPF_EXIT_INSN(),
9381 },
9382 .errstr = "R1 offset is outside of the packet",
9383 .result = REJECT,
9384 .prog_type = BPF_PROG_TYPE_XDP,
9385 },
9386 {
9387 "XDP pkt read, pkt_meta' >= pkt_data, good access",
9388 .insns = {
9389 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9390 offsetof(struct xdp_md, data_meta)),
9391 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9392 offsetof(struct xdp_md, data)),
9393 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9395 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9396 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9397 BPF_MOV64_IMM(BPF_REG_0, 0),
9398 BPF_EXIT_INSN(),
9399 },
9400 .result = ACCEPT,
9401 .prog_type = BPF_PROG_TYPE_XDP,
9402 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9403 },
9404 {
9405 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
9406 .insns = {
9407 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9408 offsetof(struct xdp_md, data_meta)),
9409 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9410 offsetof(struct xdp_md, data)),
9411 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9413 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9414 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9415 BPF_MOV64_IMM(BPF_REG_0, 0),
9416 BPF_EXIT_INSN(),
9417 },
9418 .errstr = "R1 offset is outside of the packet",
9419 .result = REJECT,
9420 .prog_type = BPF_PROG_TYPE_XDP,
9421 },
9422 {
9423 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
9424 .insns = {
9425 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9426 offsetof(struct xdp_md, data_meta)),
9427 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9428 offsetof(struct xdp_md, data)),
9429 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9430 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9431 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9432 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9433 BPF_MOV64_IMM(BPF_REG_0, 0),
9434 BPF_EXIT_INSN(),
9435 },
9436 .errstr = "R1 offset is outside of the packet",
9437 .result = REJECT,
9438 .prog_type = BPF_PROG_TYPE_XDP,
9439 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9440 },
9441 {
9442 "XDP pkt read, pkt_data >= pkt_meta', good access",
9443 .insns = {
9444 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9445 offsetof(struct xdp_md, data_meta)),
9446 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9447 offsetof(struct xdp_md, data)),
9448 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9450 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9451 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9452 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9453 BPF_MOV64_IMM(BPF_REG_0, 0),
9454 BPF_EXIT_INSN(),
9455 },
9456 .result = ACCEPT,
9457 .prog_type = BPF_PROG_TYPE_XDP,
9458 },
9459 {
9460 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
9461 .insns = {
9462 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9463 offsetof(struct xdp_md, data_meta)),
9464 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9465 offsetof(struct xdp_md, data)),
9466 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9468 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9469 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9470 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9471 BPF_MOV64_IMM(BPF_REG_0, 0),
9472 BPF_EXIT_INSN(),
9473 },
9474 .errstr = "R1 offset is outside of the packet",
9475 .result = REJECT,
9476 .prog_type = BPF_PROG_TYPE_XDP,
9477 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9478 },
9479 {
9480 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
9481 .insns = {
9482 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9483 offsetof(struct xdp_md, data_meta)),
9484 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9485 offsetof(struct xdp_md, data)),
9486 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9487 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9488 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9489 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9490 BPF_MOV64_IMM(BPF_REG_0, 0),
9491 BPF_EXIT_INSN(),
9492 },
9493 .errstr = "R1 offset is outside of the packet",
9494 .result = REJECT,
9495 .prog_type = BPF_PROG_TYPE_XDP,
9496 },
9497 {
9498 "XDP pkt read, pkt_meta' <= pkt_data, good access",
9499 .insns = {
9500 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9501 offsetof(struct xdp_md, data_meta)),
9502 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9503 offsetof(struct xdp_md, data)),
9504 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9506 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9507 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9508 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9509 BPF_MOV64_IMM(BPF_REG_0, 0),
9510 BPF_EXIT_INSN(),
9511 },
9512 .result = ACCEPT,
9513 .prog_type = BPF_PROG_TYPE_XDP,
9514 },
9515 {
9516 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
9517 .insns = {
9518 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9519 offsetof(struct xdp_md, data_meta)),
9520 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9521 offsetof(struct xdp_md, data)),
9522 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9524 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9525 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9526 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9527 BPF_MOV64_IMM(BPF_REG_0, 0),
9528 BPF_EXIT_INSN(),
9529 },
9530 .errstr = "R1 offset is outside of the packet",
9531 .result = REJECT,
9532 .prog_type = BPF_PROG_TYPE_XDP,
9533 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9534 },
9535 {
9536 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
9537 .insns = {
9538 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9539 offsetof(struct xdp_md, data_meta)),
9540 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9541 offsetof(struct xdp_md, data)),
9542 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9543 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9544 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9545 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9546 BPF_MOV64_IMM(BPF_REG_0, 0),
9547 BPF_EXIT_INSN(),
9548 },
9549 .errstr = "R1 offset is outside of the packet",
9550 .result = REJECT,
9551 .prog_type = BPF_PROG_TYPE_XDP,
9552 },
9553 {
9554 "XDP pkt read, pkt_data <= pkt_meta', good access",
9555 .insns = {
9556 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9557 offsetof(struct xdp_md, data_meta)),
9558 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9559 offsetof(struct xdp_md, data)),
9560 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9561 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9562 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9563 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9564 BPF_MOV64_IMM(BPF_REG_0, 0),
9565 BPF_EXIT_INSN(),
9566 },
9567 .result = ACCEPT,
9568 .prog_type = BPF_PROG_TYPE_XDP,
9569 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9570 },
9571 {
9572 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
9573 .insns = {
9574 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9575 offsetof(struct xdp_md, data_meta)),
9576 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9577 offsetof(struct xdp_md, data)),
9578 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9579 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9580 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9581 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9582 BPF_MOV64_IMM(BPF_REG_0, 0),
9583 BPF_EXIT_INSN(),
9584 },
9585 .errstr = "R1 offset is outside of the packet",
9586 .result = REJECT,
9587 .prog_type = BPF_PROG_TYPE_XDP,
9588 },
9589 {
9590 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
9591 .insns = {
9592 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9593 offsetof(struct xdp_md, data_meta)),
9594 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9595 offsetof(struct xdp_md, data)),
9596 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9597 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9598 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9599 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9600 BPF_MOV64_IMM(BPF_REG_0, 0),
9601 BPF_EXIT_INSN(),
9602 },
9603 .errstr = "R1 offset is outside of the packet",
9604 .result = REJECT,
9605 .prog_type = BPF_PROG_TYPE_XDP,
9606 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9607 },
9608 {
9609 "check deducing bounds from const, 1",
9610 .insns = {
9611 BPF_MOV64_IMM(BPF_REG_0, 1),
9612 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
9613 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9614 BPF_EXIT_INSN(),
9615 },
9616 .result = REJECT,
9617 .errstr = "R0 tried to subtract pointer from scalar",
9618 },
9619 {
9620 "check deducing bounds from const, 2",
9621 .insns = {
9622 BPF_MOV64_IMM(BPF_REG_0, 1),
9623 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
9624 BPF_EXIT_INSN(),
9625 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
9626 BPF_EXIT_INSN(),
9627 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9628 BPF_EXIT_INSN(),
9629 },
9630 .result = ACCEPT,
9631 .retval = 1,
9632 },
9633 {
9634 "check deducing bounds from const, 3",
9635 .insns = {
9636 BPF_MOV64_IMM(BPF_REG_0, 0),
9637 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9638 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9639 BPF_EXIT_INSN(),
9640 },
9641 .result = REJECT,
9642 .errstr = "R0 tried to subtract pointer from scalar",
9643 },
9644 {
9645 "check deducing bounds from const, 4",
9646 .insns = {
9647 BPF_MOV64_IMM(BPF_REG_0, 0),
9648 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
9649 BPF_EXIT_INSN(),
9650 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9651 BPF_EXIT_INSN(),
9652 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9653 BPF_EXIT_INSN(),
9654 },
9655 .result = ACCEPT,
9656 },
9657 {
9658 "check deducing bounds from const, 5",
9659 .insns = {
9660 BPF_MOV64_IMM(BPF_REG_0, 0),
9661 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9662 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9663 BPF_EXIT_INSN(),
9664 },
9665 .result = REJECT,
9666 .errstr = "R0 tried to subtract pointer from scalar",
9667 },
9668 {
9669 "check deducing bounds from const, 6",
9670 .insns = {
9671 BPF_MOV64_IMM(BPF_REG_0, 0),
9672 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9673 BPF_EXIT_INSN(),
9674 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9675 BPF_EXIT_INSN(),
9676 },
9677 .result = REJECT,
9678 .errstr = "R0 tried to subtract pointer from scalar",
9679 },
9680 {
9681 "check deducing bounds from const, 7",
9682 .insns = {
9683 BPF_MOV64_IMM(BPF_REG_0, ~0),
9684 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9685 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9686 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9687 offsetof(struct __sk_buff, mark)),
9688 BPF_EXIT_INSN(),
9689 },
9690 .result = REJECT,
9691 .errstr = "dereference of modified ctx ptr",
9692 },
9693 {
9694 "check deducing bounds from const, 8",
9695 .insns = {
9696 BPF_MOV64_IMM(BPF_REG_0, ~0),
9697 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9698 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
9699 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9700 offsetof(struct __sk_buff, mark)),
9701 BPF_EXIT_INSN(),
9702 },
9703 .result = REJECT,
9704 .errstr = "dereference of modified ctx ptr",
9705 },
9706 {
9707 "check deducing bounds from const, 9",
9708 .insns = {
9709 BPF_MOV64_IMM(BPF_REG_0, 0),
9710 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9711 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9712 BPF_EXIT_INSN(),
9713 },
9714 .result = REJECT,
9715 .errstr = "R0 tried to subtract pointer from scalar",
9716 },
9717 {
9718 "check deducing bounds from const, 10",
9719 .insns = {
9720 BPF_MOV64_IMM(BPF_REG_0, 0),
9721 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9722 /* Marks reg as unknown. */
9723 BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
9724 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9725 BPF_EXIT_INSN(),
9726 },
9727 .result = REJECT,
9728 .errstr = "math between ctx pointer and register with unbounded min value is not allowed",
9729 },
9730 {
9731 "bpf_exit with invalid return code. test1",
9732 .insns = {
9733 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9734 BPF_EXIT_INSN(),
9735 },
9736 .errstr = "R0 has value (0x0; 0xffffffff)",
9737 .result = REJECT,
9738 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9739 },
9740 {
9741 "bpf_exit with invalid return code. test2",
9742 .insns = {
9743 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9744 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
9745 BPF_EXIT_INSN(),
9746 },
9747 .result = ACCEPT,
9748 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9749 },
9750 {
9751 "bpf_exit with invalid return code. test3",
9752 .insns = {
9753 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9754 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
9755 BPF_EXIT_INSN(),
9756 },
9757 .errstr = "R0 has value (0x0; 0x3)",
9758 .result = REJECT,
9759 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9760 },
9761 {
9762 "bpf_exit with invalid return code. test4",
9763 .insns = {
9764 BPF_MOV64_IMM(BPF_REG_0, 1),
9765 BPF_EXIT_INSN(),
9766 },
9767 .result = ACCEPT,
9768 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9769 },
9770 {
9771 "bpf_exit with invalid return code. test5",
9772 .insns = {
9773 BPF_MOV64_IMM(BPF_REG_0, 2),
9774 BPF_EXIT_INSN(),
9775 },
9776 .errstr = "R0 has value (0x2; 0x0)",
9777 .result = REJECT,
9778 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9779 },
9780 {
9781 "bpf_exit with invalid return code. test6",
9782 .insns = {
9783 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9784 BPF_EXIT_INSN(),
9785 },
9786 .errstr = "R0 is not a known value (ctx)",
9787 .result = REJECT,
9788 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9789 },
9790 {
9791 "bpf_exit with invalid return code. test7",
9792 .insns = {
9793 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9794 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
9795 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
9796 BPF_EXIT_INSN(),
9797 },
9798 .errstr = "R0 has unknown scalar value",
9799 .result = REJECT,
9800 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9801 },
9802 {
9803 "calls: basic sanity",
9804 .insns = {
9805 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9806 BPF_MOV64_IMM(BPF_REG_0, 1),
9807 BPF_EXIT_INSN(),
9808 BPF_MOV64_IMM(BPF_REG_0, 2),
9809 BPF_EXIT_INSN(),
9810 },
9811 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9812 .result = ACCEPT,
9813 },
9814 {
9815 "calls: not on unpriviledged",
9816 .insns = {
9817 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9818 BPF_MOV64_IMM(BPF_REG_0, 1),
9819 BPF_EXIT_INSN(),
9820 BPF_MOV64_IMM(BPF_REG_0, 2),
9821 BPF_EXIT_INSN(),
9822 },
9823 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
9824 .result_unpriv = REJECT,
9825 .result = ACCEPT,
9826 .retval = 1,
9827 },
9828 {
9829 "calls: div by 0 in subprog",
9830 .insns = {
9831 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9832 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9833 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9834 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9835 offsetof(struct __sk_buff, data_end)),
9836 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9837 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9838 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9839 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9840 BPF_MOV64_IMM(BPF_REG_0, 1),
9841 BPF_EXIT_INSN(),
9842 BPF_MOV32_IMM(BPF_REG_2, 0),
9843 BPF_MOV32_IMM(BPF_REG_3, 1),
9844 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
9845 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9846 offsetof(struct __sk_buff, data)),
9847 BPF_EXIT_INSN(),
9848 },
9849 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9850 .result = ACCEPT,
9851 .retval = 1,
9852 },
9853 {
9854 "calls: multiple ret types in subprog 1",
9855 .insns = {
9856 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9857 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9858 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9859 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9860 offsetof(struct __sk_buff, data_end)),
9861 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9863 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9864 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9865 BPF_MOV64_IMM(BPF_REG_0, 1),
9866 BPF_EXIT_INSN(),
9867 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9868 offsetof(struct __sk_buff, data)),
9869 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9870 BPF_MOV32_IMM(BPF_REG_0, 42),
9871 BPF_EXIT_INSN(),
9872 },
9873 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9874 .result = REJECT,
9875 .errstr = "R0 invalid mem access 'inv'",
9876 },
9877 {
9878 "calls: multiple ret types in subprog 2",
9879 .insns = {
9880 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9881 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9882 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9883 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9884 offsetof(struct __sk_buff, data_end)),
9885 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9886 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9887 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9888 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9889 BPF_MOV64_IMM(BPF_REG_0, 1),
9890 BPF_EXIT_INSN(),
9891 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9892 offsetof(struct __sk_buff, data)),
9893 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9894 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
9895 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9896 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9898 BPF_LD_MAP_FD(BPF_REG_1, 0),
9899 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9900 BPF_FUNC_map_lookup_elem),
9901 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9902 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
9903 offsetof(struct __sk_buff, data)),
9904 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
9905 BPF_EXIT_INSN(),
9906 },
9907 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9908 .fixup_map1 = { 16 },
9909 .result = REJECT,
9910 .errstr = "R0 min value is outside of the array range",
9911 },
9912 {
9913 "calls: overlapping caller/callee",
9914 .insns = {
9915 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
9916 BPF_MOV64_IMM(BPF_REG_0, 1),
9917 BPF_EXIT_INSN(),
9918 },
9919 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9920 .errstr = "last insn is not an exit or jmp",
9921 .result = REJECT,
9922 },
9923 {
9924 "calls: wrong recursive calls",
9925 .insns = {
9926 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9927 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9928 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9929 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9930 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9931 BPF_MOV64_IMM(BPF_REG_0, 1),
9932 BPF_EXIT_INSN(),
9933 },
9934 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9935 .errstr = "jump out of range",
9936 .result = REJECT,
9937 },
9938 {
9939 "calls: wrong src reg",
9940 .insns = {
9941 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
9942 BPF_MOV64_IMM(BPF_REG_0, 1),
9943 BPF_EXIT_INSN(),
9944 },
9945 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9946 .errstr = "BPF_CALL uses reserved fields",
9947 .result = REJECT,
9948 },
9949 {
9950 "calls: wrong off value",
9951 .insns = {
9952 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
9953 BPF_MOV64_IMM(BPF_REG_0, 1),
9954 BPF_EXIT_INSN(),
9955 BPF_MOV64_IMM(BPF_REG_0, 2),
9956 BPF_EXIT_INSN(),
9957 },
9958 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9959 .errstr = "BPF_CALL uses reserved fields",
9960 .result = REJECT,
9961 },
9962 {
9963 "calls: jump back loop",
9964 .insns = {
9965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
9966 BPF_MOV64_IMM(BPF_REG_0, 1),
9967 BPF_EXIT_INSN(),
9968 },
9969 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9970 .errstr = "back-edge from insn 0 to 0",
9971 .result = REJECT,
9972 },
9973 {
9974 "calls: conditional call",
9975 .insns = {
9976 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9977 offsetof(struct __sk_buff, mark)),
9978 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9979 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9980 BPF_MOV64_IMM(BPF_REG_0, 1),
9981 BPF_EXIT_INSN(),
9982 BPF_MOV64_IMM(BPF_REG_0, 2),
9983 BPF_EXIT_INSN(),
9984 },
9985 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9986 .errstr = "jump out of range",
9987 .result = REJECT,
9988 },
9989 {
9990 "calls: conditional call 2",
9991 .insns = {
9992 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9993 offsetof(struct __sk_buff, mark)),
9994 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9995 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9996 BPF_MOV64_IMM(BPF_REG_0, 1),
9997 BPF_EXIT_INSN(),
9998 BPF_MOV64_IMM(BPF_REG_0, 2),
9999 BPF_EXIT_INSN(),
10000 BPF_MOV64_IMM(BPF_REG_0, 3),
10001 BPF_EXIT_INSN(),
10002 },
10003 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10004 .result = ACCEPT,
10005 },
10006 {
10007 "calls: conditional call 3",
10008 .insns = {
10009 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10010 offsetof(struct __sk_buff, mark)),
10011 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10012 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10013 BPF_MOV64_IMM(BPF_REG_0, 1),
10014 BPF_EXIT_INSN(),
10015 BPF_MOV64_IMM(BPF_REG_0, 1),
10016 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10017 BPF_MOV64_IMM(BPF_REG_0, 3),
10018 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10019 },
10020 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10021 .errstr = "back-edge from insn",
10022 .result = REJECT,
10023 },
10024 {
10025 "calls: conditional call 4",
10026 .insns = {
10027 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10028 offsetof(struct __sk_buff, mark)),
10029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10030 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10031 BPF_MOV64_IMM(BPF_REG_0, 1),
10032 BPF_EXIT_INSN(),
10033 BPF_MOV64_IMM(BPF_REG_0, 1),
10034 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
10035 BPF_MOV64_IMM(BPF_REG_0, 3),
10036 BPF_EXIT_INSN(),
10037 },
10038 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10039 .result = ACCEPT,
10040 },
10041 {
10042 "calls: conditional call 5",
10043 .insns = {
10044 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10045 offsetof(struct __sk_buff, mark)),
10046 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10047 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10048 BPF_MOV64_IMM(BPF_REG_0, 1),
10049 BPF_EXIT_INSN(),
10050 BPF_MOV64_IMM(BPF_REG_0, 1),
10051 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10052 BPF_MOV64_IMM(BPF_REG_0, 3),
10053 BPF_EXIT_INSN(),
10054 },
10055 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10056 .errstr = "back-edge from insn",
10057 .result = REJECT,
10058 },
10059 {
10060 "calls: conditional call 6",
10061 .insns = {
10062 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10063 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
10064 BPF_EXIT_INSN(),
10065 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10066 offsetof(struct __sk_buff, mark)),
10067 BPF_EXIT_INSN(),
10068 },
10069 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10070 .errstr = "back-edge from insn",
10071 .result = REJECT,
10072 },
10073 {
10074 "calls: using r0 returned by callee",
10075 .insns = {
10076 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10077 BPF_EXIT_INSN(),
10078 BPF_MOV64_IMM(BPF_REG_0, 2),
10079 BPF_EXIT_INSN(),
10080 },
10081 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10082 .result = ACCEPT,
10083 },
10084 {
10085 "calls: using uninit r0 from callee",
10086 .insns = {
10087 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10088 BPF_EXIT_INSN(),
10089 BPF_EXIT_INSN(),
10090 },
10091 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10092 .errstr = "!read_ok",
10093 .result = REJECT,
10094 },
10095 {
10096 "calls: callee is using r1",
10097 .insns = {
10098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10099 BPF_EXIT_INSN(),
10100 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10101 offsetof(struct __sk_buff, len)),
10102 BPF_EXIT_INSN(),
10103 },
10104 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
10105 .result = ACCEPT,
10106 .retval = TEST_DATA_LEN,
10107 },
10108 {
10109 "calls: callee using args1",
10110 .insns = {
10111 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10112 BPF_EXIT_INSN(),
10113 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10114 BPF_EXIT_INSN(),
10115 },
10116 .errstr_unpriv = "allowed for root only",
10117 .result_unpriv = REJECT,
10118 .result = ACCEPT,
10119 .retval = POINTER_VALUE,
10120 },
10121 {
10122 "calls: callee using wrong args2",
10123 .insns = {
10124 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10125 BPF_EXIT_INSN(),
10126 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10127 BPF_EXIT_INSN(),
10128 },
10129 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10130 .errstr = "R2 !read_ok",
10131 .result = REJECT,
10132 },
10133 {
10134 "calls: callee using two args",
10135 .insns = {
10136 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10137 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
10138 offsetof(struct __sk_buff, len)),
10139 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
10140 offsetof(struct __sk_buff, len)),
10141 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10142 BPF_EXIT_INSN(),
10143 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10144 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
10145 BPF_EXIT_INSN(),
10146 },
10147 .errstr_unpriv = "allowed for root only",
10148 .result_unpriv = REJECT,
10149 .result = ACCEPT,
10150 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
10151 },
10152 {
10153 "calls: callee changing pkt pointers",
10154 .insns = {
10155 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
10156 offsetof(struct xdp_md, data)),
10157 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
10158 offsetof(struct xdp_md, data_end)),
10159 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
10160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
10161 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
10162 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10163 /* clear_all_pkt_pointers() has to walk all frames
10164 * to make sure that pkt pointers in the caller
10165 * are cleared when callee is calling a helper that
10166 * adjusts packet size
10167 */
10168 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10169 BPF_MOV32_IMM(BPF_REG_0, 0),
10170 BPF_EXIT_INSN(),
10171 BPF_MOV64_IMM(BPF_REG_2, 0),
10172 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10173 BPF_FUNC_xdp_adjust_head),
10174 BPF_EXIT_INSN(),
10175 },
10176 .result = REJECT,
10177 .errstr = "R6 invalid mem access 'inv'",
10178 .prog_type = BPF_PROG_TYPE_XDP,
10179 },
10180 {
10181 "calls: two calls with args",
10182 .insns = {
10183 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10184 BPF_EXIT_INSN(),
10185 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10186 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10187 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10188 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10190 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10191 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10192 BPF_EXIT_INSN(),
10193 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10194 offsetof(struct __sk_buff, len)),
10195 BPF_EXIT_INSN(),
10196 },
10197 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10198 .result = ACCEPT,
10199 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
10200 },
10201 {
10202 "calls: calls with stack arith",
10203 .insns = {
10204 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10205 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10206 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10207 BPF_EXIT_INSN(),
10208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10209 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10210 BPF_EXIT_INSN(),
10211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10212 BPF_MOV64_IMM(BPF_REG_0, 42),
10213 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10214 BPF_EXIT_INSN(),
10215 },
10216 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10217 .result = ACCEPT,
10218 .retval = 42,
10219 },
10220 {
10221 "calls: calls with misaligned stack access",
10222 .insns = {
10223 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10224 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10225 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10226 BPF_EXIT_INSN(),
10227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
10228 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10229 BPF_EXIT_INSN(),
10230 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10231 BPF_MOV64_IMM(BPF_REG_0, 42),
10232 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10233 BPF_EXIT_INSN(),
10234 },
10235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10236 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
10237 .errstr = "misaligned stack access",
10238 .result = REJECT,
10239 },
10240 {
10241 "calls: calls control flow, jump test",
10242 .insns = {
10243 BPF_MOV64_IMM(BPF_REG_0, 42),
10244 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10245 BPF_MOV64_IMM(BPF_REG_0, 43),
10246 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10247 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10248 BPF_EXIT_INSN(),
10249 },
10250 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10251 .result = ACCEPT,
10252 .retval = 43,
10253 },
10254 {
10255 "calls: calls control flow, jump test 2",
10256 .insns = {
10257 BPF_MOV64_IMM(BPF_REG_0, 42),
10258 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10259 BPF_MOV64_IMM(BPF_REG_0, 43),
10260 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10262 BPF_EXIT_INSN(),
10263 },
10264 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10265 .errstr = "jump out of range from insn 1 to 4",
10266 .result = REJECT,
10267 },
10268 {
10269 "calls: two calls with bad jump",
10270 .insns = {
10271 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10272 BPF_EXIT_INSN(),
10273 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10274 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10275 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10276 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10277 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10278 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10279 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10280 BPF_EXIT_INSN(),
10281 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10282 offsetof(struct __sk_buff, len)),
10283 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
10284 BPF_EXIT_INSN(),
10285 },
10286 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10287 .errstr = "jump out of range from insn 11 to 9",
10288 .result = REJECT,
10289 },
10290 {
10291 "calls: recursive call. test1",
10292 .insns = {
10293 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10294 BPF_EXIT_INSN(),
10295 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10296 BPF_EXIT_INSN(),
10297 },
10298 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10299 .errstr = "back-edge",
10300 .result = REJECT,
10301 },
10302 {
10303 "calls: recursive call. test2",
10304 .insns = {
10305 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10306 BPF_EXIT_INSN(),
10307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10308 BPF_EXIT_INSN(),
10309 },
10310 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10311 .errstr = "back-edge",
10312 .result = REJECT,
10313 },
10314 {
10315 "calls: unreachable code",
10316 .insns = {
10317 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10318 BPF_EXIT_INSN(),
10319 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10320 BPF_EXIT_INSN(),
10321 BPF_MOV64_IMM(BPF_REG_0, 0),
10322 BPF_EXIT_INSN(),
10323 BPF_MOV64_IMM(BPF_REG_0, 0),
10324 BPF_EXIT_INSN(),
10325 },
10326 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10327 .errstr = "unreachable insn 6",
10328 .result = REJECT,
10329 },
10330 {
10331 "calls: invalid call",
10332 .insns = {
10333 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10334 BPF_EXIT_INSN(),
10335 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
10336 BPF_EXIT_INSN(),
10337 },
10338 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10339 .errstr = "invalid destination",
10340 .result = REJECT,
10341 },
10342 {
10343 "calls: invalid call 2",
10344 .insns = {
10345 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10346 BPF_EXIT_INSN(),
10347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
10348 BPF_EXIT_INSN(),
10349 },
10350 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10351 .errstr = "invalid destination",
10352 .result = REJECT,
10353 },
10354 {
10355 "calls: jumping across function bodies. test1",
10356 .insns = {
10357 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10358 BPF_MOV64_IMM(BPF_REG_0, 0),
10359 BPF_EXIT_INSN(),
10360 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
10361 BPF_EXIT_INSN(),
10362 },
10363 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10364 .errstr = "jump out of range",
10365 .result = REJECT,
10366 },
10367 {
10368 "calls: jumping across function bodies. test2",
10369 .insns = {
10370 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
10371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10372 BPF_MOV64_IMM(BPF_REG_0, 0),
10373 BPF_EXIT_INSN(),
10374 BPF_EXIT_INSN(),
10375 },
10376 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10377 .errstr = "jump out of range",
10378 .result = REJECT,
10379 },
10380 {
10381 "calls: call without exit",
10382 .insns = {
10383 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10384 BPF_EXIT_INSN(),
10385 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10386 BPF_EXIT_INSN(),
10387 BPF_MOV64_IMM(BPF_REG_0, 0),
10388 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
10389 },
10390 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10391 .errstr = "not an exit",
10392 .result = REJECT,
10393 },
10394 {
10395 "calls: call into middle of ld_imm64",
10396 .insns = {
10397 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10398 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10399 BPF_MOV64_IMM(BPF_REG_0, 0),
10400 BPF_EXIT_INSN(),
10401 BPF_LD_IMM64(BPF_REG_0, 0),
10402 BPF_EXIT_INSN(),
10403 },
10404 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10405 .errstr = "last insn",
10406 .result = REJECT,
10407 },
10408 {
10409 "calls: call into middle of other call",
10410 .insns = {
10411 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10412 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10413 BPF_MOV64_IMM(BPF_REG_0, 0),
10414 BPF_EXIT_INSN(),
10415 BPF_MOV64_IMM(BPF_REG_0, 0),
10416 BPF_MOV64_IMM(BPF_REG_0, 0),
10417 BPF_EXIT_INSN(),
10418 },
10419 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10420 .errstr = "last insn",
10421 .result = REJECT,
10422 },
10423 {
10424 "calls: ld_abs with changing ctx data in callee",
10425 .insns = {
10426 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10427 BPF_LD_ABS(BPF_B, 0),
10428 BPF_LD_ABS(BPF_H, 0),
10429 BPF_LD_ABS(BPF_W, 0),
10430 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
10431 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10432 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
10433 BPF_LD_ABS(BPF_B, 0),
10434 BPF_LD_ABS(BPF_H, 0),
10435 BPF_LD_ABS(BPF_W, 0),
10436 BPF_EXIT_INSN(),
10437 BPF_MOV64_IMM(BPF_REG_2, 1),
10438 BPF_MOV64_IMM(BPF_REG_3, 2),
10439 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10440 BPF_FUNC_skb_vlan_push),
10441 BPF_EXIT_INSN(),
10442 },
10443 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10444 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
10445 .result = REJECT,
10446 },
10447 {
10448 "calls: two calls with bad fallthrough",
10449 .insns = {
10450 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10451 BPF_EXIT_INSN(),
10452 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10453 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10454 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10455 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10456 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10457 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10458 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10459 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
10460 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10461 offsetof(struct __sk_buff, len)),
10462 BPF_EXIT_INSN(),
10463 },
10464 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10465 .errstr = "not an exit",
10466 .result = REJECT,
10467 },
10468 {
10469 "calls: two calls with stack read",
10470 .insns = {
10471 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10472 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10474 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10475 BPF_EXIT_INSN(),
10476 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10477 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10478 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10479 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10481 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10482 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10483 BPF_EXIT_INSN(),
10484 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10485 BPF_EXIT_INSN(),
10486 },
10487 .prog_type = BPF_PROG_TYPE_XDP,
10488 .result = ACCEPT,
10489 },
10490 {
10491 "calls: two calls with stack write",
10492 .insns = {
10493 /* main prog */
10494 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10495 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10496 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10497 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10499 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10500 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10501 BPF_EXIT_INSN(),
10502
10503 /* subprog 1 */
10504 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10505 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10506 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
10507 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
10508 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10510 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
10511 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
10512 /* write into stack frame of main prog */
10513 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10514 BPF_EXIT_INSN(),
10515
10516 /* subprog 2 */
10517 /* read from stack frame of main prog */
10518 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10519 BPF_EXIT_INSN(),
10520 },
10521 .prog_type = BPF_PROG_TYPE_XDP,
10522 .result = ACCEPT,
10523 },
10524 {
10525 "calls: stack overflow using two frames (pre-call access)",
10526 .insns = {
10527 /* prog 1 */
10528 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10529 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
10530 BPF_EXIT_INSN(),
10531
10532 /* prog 2 */
10533 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10534 BPF_MOV64_IMM(BPF_REG_0, 0),
10535 BPF_EXIT_INSN(),
10536 },
10537 .prog_type = BPF_PROG_TYPE_XDP,
10538 .errstr = "combined stack size",
10539 .result = REJECT,
10540 },
10541 {
10542 "calls: stack overflow using two frames (post-call access)",
10543 .insns = {
10544 /* prog 1 */
10545 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
10546 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10547 BPF_EXIT_INSN(),
10548
10549 /* prog 2 */
10550 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10551 BPF_MOV64_IMM(BPF_REG_0, 0),
10552 BPF_EXIT_INSN(),
10553 },
10554 .prog_type = BPF_PROG_TYPE_XDP,
10555 .errstr = "combined stack size",
10556 .result = REJECT,
10557 },
10558 {
10559 "calls: stack depth check using three frames. test1",
10560 .insns = {
10561 /* main */
10562 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10563 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10564 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10565 BPF_MOV64_IMM(BPF_REG_0, 0),
10566 BPF_EXIT_INSN(),
10567 /* A */
10568 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10569 BPF_EXIT_INSN(),
10570 /* B */
10571 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10572 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10573 BPF_EXIT_INSN(),
10574 },
10575 .prog_type = BPF_PROG_TYPE_XDP,
10576 /* stack_main=32, stack_A=256, stack_B=64
10577 * and max(main+A, main+A+B) < 512
10578 */
10579 .result = ACCEPT,
10580 },
10581 {
10582 "calls: stack depth check using three frames. test2",
10583 .insns = {
10584 /* main */
10585 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10586 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10587 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10588 BPF_MOV64_IMM(BPF_REG_0, 0),
10589 BPF_EXIT_INSN(),
10590 /* A */
10591 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10592 BPF_EXIT_INSN(),
10593 /* B */
10594 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10595 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10596 BPF_EXIT_INSN(),
10597 },
10598 .prog_type = BPF_PROG_TYPE_XDP,
10599 /* stack_main=32, stack_A=64, stack_B=256
10600 * and max(main+A, main+A+B) < 512
10601 */
10602 .result = ACCEPT,
10603 },
10604 {
10605 "calls: stack depth check using three frames. test3",
10606 .insns = {
10607 /* main */
10608 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10609 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10610 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10611 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
10612 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
10613 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10614 BPF_MOV64_IMM(BPF_REG_0, 0),
10615 BPF_EXIT_INSN(),
10616 /* A */
10617 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
10618 BPF_EXIT_INSN(),
10619 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
10620 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10621 /* B */
10622 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
10623 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
10624 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10625 BPF_EXIT_INSN(),
10626 },
10627 .prog_type = BPF_PROG_TYPE_XDP,
10628 /* stack_main=64, stack_A=224, stack_B=256
10629 * and max(main+A, main+A+B) > 512
10630 */
10631 .errstr = "combined stack",
10632 .result = REJECT,
10633 },
10634 {
10635 "calls: stack depth check using three frames. test4",
10636 /* void main(void) {
10637 * func1(0);
10638 * func1(1);
10639 * func2(1);
10640 * }
10641 * void func1(int alloc_or_recurse) {
10642 * if (alloc_or_recurse) {
10643 * frame_pointer[-300] = 1;
10644 * } else {
10645 * func2(alloc_or_recurse);
10646 * }
10647 * }
10648 * void func2(int alloc_or_recurse) {
10649 * if (alloc_or_recurse) {
10650 * frame_pointer[-300] = 1;
10651 * }
10652 * }
10653 */
10654 .insns = {
10655 /* main */
10656 BPF_MOV64_IMM(BPF_REG_1, 0),
10657 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10658 BPF_MOV64_IMM(BPF_REG_1, 1),
10659 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10660 BPF_MOV64_IMM(BPF_REG_1, 1),
10661 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
10662 BPF_MOV64_IMM(BPF_REG_0, 0),
10663 BPF_EXIT_INSN(),
10664 /* A */
10665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
10666 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10667 BPF_EXIT_INSN(),
10668 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10669 BPF_EXIT_INSN(),
10670 /* B */
10671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10672 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10673 BPF_EXIT_INSN(),
10674 },
10675 .prog_type = BPF_PROG_TYPE_XDP,
10676 .result = REJECT,
10677 .errstr = "combined stack",
10678 },
10679 {
10680 "calls: stack depth check using three frames. test5",
10681 .insns = {
10682 /* main */
10683 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
10684 BPF_EXIT_INSN(),
10685 /* A */
10686 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10687 BPF_EXIT_INSN(),
10688 /* B */
10689 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
10690 BPF_EXIT_INSN(),
10691 /* C */
10692 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
10693 BPF_EXIT_INSN(),
10694 /* D */
10695 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
10696 BPF_EXIT_INSN(),
10697 /* E */
10698 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
10699 BPF_EXIT_INSN(),
10700 /* F */
10701 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
10702 BPF_EXIT_INSN(),
10703 /* G */
10704 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
10705 BPF_EXIT_INSN(),
10706 /* H */
10707 BPF_MOV64_IMM(BPF_REG_0, 0),
10708 BPF_EXIT_INSN(),
10709 },
10710 .prog_type = BPF_PROG_TYPE_XDP,
10711 .errstr = "call stack",
10712 .result = REJECT,
10713 },
10714 {
10715 "calls: spill into caller stack frame",
10716 .insns = {
10717 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10718 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10719 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10721 BPF_EXIT_INSN(),
10722 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
10723 BPF_MOV64_IMM(BPF_REG_0, 0),
10724 BPF_EXIT_INSN(),
10725 },
10726 .prog_type = BPF_PROG_TYPE_XDP,
10727 .errstr = "cannot spill",
10728 .result = REJECT,
10729 },
10730 {
10731 "calls: write into caller stack frame",
10732 .insns = {
10733 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10735 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10736 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10737 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10738 BPF_EXIT_INSN(),
10739 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
10740 BPF_MOV64_IMM(BPF_REG_0, 0),
10741 BPF_EXIT_INSN(),
10742 },
10743 .prog_type = BPF_PROG_TYPE_XDP,
10744 .result = ACCEPT,
10745 .retval = 42,
10746 },
10747 {
10748 "calls: write into callee stack frame",
10749 .insns = {
10750 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10751 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
10752 BPF_EXIT_INSN(),
10753 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
10754 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
10755 BPF_EXIT_INSN(),
10756 },
10757 .prog_type = BPF_PROG_TYPE_XDP,
10758 .errstr = "cannot return stack pointer",
10759 .result = REJECT,
10760 },
10761 {
10762 "calls: two calls with stack write and void return",
10763 .insns = {
10764 /* main prog */
10765 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10766 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10767 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10768 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10770 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10771 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10772 BPF_EXIT_INSN(),
10773
10774 /* subprog 1 */
10775 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10776 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10777 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10778 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10779 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10780 BPF_EXIT_INSN(),
10781
10782 /* subprog 2 */
10783 /* write into stack frame of main prog */
10784 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
10785 BPF_EXIT_INSN(), /* void return */
10786 },
10787 .prog_type = BPF_PROG_TYPE_XDP,
10788 .result = ACCEPT,
10789 },
10790 {
10791 "calls: ambiguous return value",
10792 .insns = {
10793 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10794 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10795 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10796 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10798 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10799 BPF_EXIT_INSN(),
10800 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10801 BPF_MOV64_IMM(BPF_REG_0, 0),
10802 BPF_EXIT_INSN(),
10803 },
10804 .errstr_unpriv = "allowed for root only",
10805 .result_unpriv = REJECT,
10806 .errstr = "R0 !read_ok",
10807 .result = REJECT,
10808 },
10809 {
10810 "calls: two calls that return map_value",
10811 .insns = {
10812 /* main prog */
10813 /* pass fp-16, fp-8 into a function */
10814 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10815 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10816 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10818 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10819
10820 /* fetch map_value_ptr from the stack of this function */
10821 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
10822 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10823 /* write into map value */
10824 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10825 /* fetch secound map_value_ptr from the stack */
10826 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10828 /* write into map value */
10829 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10830 BPF_MOV64_IMM(BPF_REG_0, 0),
10831 BPF_EXIT_INSN(),
10832
10833 /* subprog 1 */
10834 /* call 3rd function twice */
10835 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10836 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10837 /* first time with fp-8 */
10838 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10839 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10840 /* second time with fp-16 */
10841 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10842 BPF_EXIT_INSN(),
10843
10844 /* subprog 2 */
10845 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10846 /* lookup from map */
10847 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10848 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10850 BPF_LD_MAP_FD(BPF_REG_1, 0),
10851 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10852 BPF_FUNC_map_lookup_elem),
10853 /* write map_value_ptr into stack frame of main prog */
10854 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10855 BPF_MOV64_IMM(BPF_REG_0, 0),
10856 BPF_EXIT_INSN(), /* return 0 */
10857 },
10858 .prog_type = BPF_PROG_TYPE_XDP,
10859 .fixup_map1 = { 23 },
10860 .result = ACCEPT,
10861 },
10862 {
10863 "calls: two calls that return map_value with bool condition",
10864 .insns = {
10865 /* main prog */
10866 /* pass fp-16, fp-8 into a function */
10867 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10869 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10871 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10872 BPF_MOV64_IMM(BPF_REG_0, 0),
10873 BPF_EXIT_INSN(),
10874
10875 /* subprog 1 */
10876 /* call 3rd function twice */
10877 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10878 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10879 /* first time with fp-8 */
10880 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10881 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10882 /* fetch map_value_ptr from the stack of this function */
10883 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10884 /* write into map value */
10885 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10886 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10887 /* second time with fp-16 */
10888 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10889 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10890 /* fetch secound map_value_ptr from the stack */
10891 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10892 /* write into map value */
10893 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10894 BPF_EXIT_INSN(),
10895
10896 /* subprog 2 */
10897 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10898 /* lookup from map */
10899 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10900 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10901 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10902 BPF_LD_MAP_FD(BPF_REG_1, 0),
10903 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10904 BPF_FUNC_map_lookup_elem),
10905 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10906 BPF_MOV64_IMM(BPF_REG_0, 0),
10907 BPF_EXIT_INSN(), /* return 0 */
10908 /* write map_value_ptr into stack frame of main prog */
10909 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10910 BPF_MOV64_IMM(BPF_REG_0, 1),
10911 BPF_EXIT_INSN(), /* return 1 */
10912 },
10913 .prog_type = BPF_PROG_TYPE_XDP,
10914 .fixup_map1 = { 23 },
10915 .result = ACCEPT,
10916 },
10917 {
10918 "calls: two calls that return map_value with incorrect bool check",
10919 .insns = {
10920 /* main prog */
10921 /* pass fp-16, fp-8 into a function */
10922 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10923 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10924 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10925 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10926 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10927 BPF_MOV64_IMM(BPF_REG_0, 0),
10928 BPF_EXIT_INSN(),
10929
10930 /* subprog 1 */
10931 /* call 3rd function twice */
10932 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10933 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10934 /* first time with fp-8 */
10935 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10936 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10937 /* fetch map_value_ptr from the stack of this function */
10938 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10939 /* write into map value */
10940 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10941 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10942 /* second time with fp-16 */
10943 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10944 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10945 /* fetch secound map_value_ptr from the stack */
10946 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10947 /* write into map value */
10948 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10949 BPF_EXIT_INSN(),
10950
10951 /* subprog 2 */
10952 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10953 /* lookup from map */
10954 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10955 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10956 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10957 BPF_LD_MAP_FD(BPF_REG_1, 0),
10958 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10959 BPF_FUNC_map_lookup_elem),
10960 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10961 BPF_MOV64_IMM(BPF_REG_0, 0),
10962 BPF_EXIT_INSN(), /* return 0 */
10963 /* write map_value_ptr into stack frame of main prog */
10964 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10965 BPF_MOV64_IMM(BPF_REG_0, 1),
10966 BPF_EXIT_INSN(), /* return 1 */
10967 },
10968 .prog_type = BPF_PROG_TYPE_XDP,
10969 .fixup_map1 = { 23 },
10970 .result = REJECT,
10971 .errstr = "invalid read from stack off -16+0 size 8",
10972 },
10973 {
10974 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
10975 .insns = {
10976 /* main prog */
10977 /* pass fp-16, fp-8 into a function */
10978 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10979 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10980 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10981 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10982 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10983 BPF_MOV64_IMM(BPF_REG_0, 0),
10984 BPF_EXIT_INSN(),
10985
10986 /* subprog 1 */
10987 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10988 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10989 /* 1st lookup from map */
10990 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10991 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10992 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10993 BPF_LD_MAP_FD(BPF_REG_1, 0),
10994 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10995 BPF_FUNC_map_lookup_elem),
10996 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10997 BPF_MOV64_IMM(BPF_REG_8, 0),
10998 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10999 /* write map_value_ptr into stack frame of main prog at fp-8 */
11000 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11001 BPF_MOV64_IMM(BPF_REG_8, 1),
11002
11003 /* 2nd lookup from map */
11004 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11005 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11006 BPF_LD_MAP_FD(BPF_REG_1, 0),
11007 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11008 BPF_FUNC_map_lookup_elem),
11009 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11010 BPF_MOV64_IMM(BPF_REG_9, 0),
11011 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11012 /* write map_value_ptr into stack frame of main prog at fp-16 */
11013 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11014 BPF_MOV64_IMM(BPF_REG_9, 1),
11015
11016 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11017 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11018 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11019 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11020 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11022 BPF_EXIT_INSN(),
11023
11024 /* subprog 2 */
11025 /* if arg2 == 1 do *arg1 = 0 */
11026 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11027 /* fetch map_value_ptr from the stack of this function */
11028 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11029 /* write into map value */
11030 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11031
11032 /* if arg4 == 1 do *arg3 = 0 */
11033 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11034 /* fetch map_value_ptr from the stack of this function */
11035 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11036 /* write into map value */
11037 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11038 BPF_EXIT_INSN(),
11039 },
11040 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11041 .fixup_map1 = { 12, 22 },
11042 .result = REJECT,
11043 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11044 },
11045 {
11046 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
11047 .insns = {
11048 /* main prog */
11049 /* pass fp-16, fp-8 into a function */
11050 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11052 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11054 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11055 BPF_MOV64_IMM(BPF_REG_0, 0),
11056 BPF_EXIT_INSN(),
11057
11058 /* subprog 1 */
11059 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11060 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11061 /* 1st lookup from map */
11062 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11063 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11064 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11065 BPF_LD_MAP_FD(BPF_REG_1, 0),
11066 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11067 BPF_FUNC_map_lookup_elem),
11068 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11069 BPF_MOV64_IMM(BPF_REG_8, 0),
11070 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11071 /* write map_value_ptr into stack frame of main prog at fp-8 */
11072 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11073 BPF_MOV64_IMM(BPF_REG_8, 1),
11074
11075 /* 2nd lookup from map */
11076 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11077 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11078 BPF_LD_MAP_FD(BPF_REG_1, 0),
11079 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11080 BPF_FUNC_map_lookup_elem),
11081 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11082 BPF_MOV64_IMM(BPF_REG_9, 0),
11083 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11084 /* write map_value_ptr into stack frame of main prog at fp-16 */
11085 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11086 BPF_MOV64_IMM(BPF_REG_9, 1),
11087
11088 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11089 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11090 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11091 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11092 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11093 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11094 BPF_EXIT_INSN(),
11095
11096 /* subprog 2 */
11097 /* if arg2 == 1 do *arg1 = 0 */
11098 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11099 /* fetch map_value_ptr from the stack of this function */
11100 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11101 /* write into map value */
11102 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11103
11104 /* if arg4 == 1 do *arg3 = 0 */
11105 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11106 /* fetch map_value_ptr from the stack of this function */
11107 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11108 /* write into map value */
11109 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11110 BPF_EXIT_INSN(),
11111 },
11112 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11113 .fixup_map1 = { 12, 22 },
11114 .result = ACCEPT,
11115 },
11116 {
11117 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
11118 .insns = {
11119 /* main prog */
11120 /* pass fp-16, fp-8 into a function */
11121 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11123 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11124 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11125 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11126 BPF_MOV64_IMM(BPF_REG_0, 0),
11127 BPF_EXIT_INSN(),
11128
11129 /* subprog 1 */
11130 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11131 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11132 /* 1st lookup from map */
11133 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
11134 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11136 BPF_LD_MAP_FD(BPF_REG_1, 0),
11137 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11138 BPF_FUNC_map_lookup_elem),
11139 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11140 BPF_MOV64_IMM(BPF_REG_8, 0),
11141 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11142 /* write map_value_ptr into stack frame of main prog at fp-8 */
11143 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11144 BPF_MOV64_IMM(BPF_REG_8, 1),
11145
11146 /* 2nd lookup from map */
11147 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11148 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11149 BPF_LD_MAP_FD(BPF_REG_1, 0),
11150 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11151 BPF_FUNC_map_lookup_elem),
11152 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11153 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
11154 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11155 /* write map_value_ptr into stack frame of main prog at fp-16 */
11156 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11157 BPF_MOV64_IMM(BPF_REG_9, 1),
11158
11159 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11160 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
11161 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11162 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11163 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11164 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
11165 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
11166
11167 /* subprog 2 */
11168 /* if arg2 == 1 do *arg1 = 0 */
11169 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11170 /* fetch map_value_ptr from the stack of this function */
11171 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11172 /* write into map value */
11173 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11174
11175 /* if arg4 == 1 do *arg3 = 0 */
11176 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11177 /* fetch map_value_ptr from the stack of this function */
11178 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11179 /* write into map value */
11180 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11181 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
11182 },
11183 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11184 .fixup_map1 = { 12, 22 },
11185 .result = REJECT,
11186 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11187 },
11188 {
11189 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
11190 .insns = {
11191 /* main prog */
11192 /* pass fp-16, fp-8 into a function */
11193 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11195 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11196 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11197 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11198 BPF_MOV64_IMM(BPF_REG_0, 0),
11199 BPF_EXIT_INSN(),
11200
11201 /* subprog 1 */
11202 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11203 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11204 /* 1st lookup from map */
11205 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11206 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11208 BPF_LD_MAP_FD(BPF_REG_1, 0),
11209 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11210 BPF_FUNC_map_lookup_elem),
11211 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11212 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11213 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11214 BPF_MOV64_IMM(BPF_REG_8, 0),
11215 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11216 BPF_MOV64_IMM(BPF_REG_8, 1),
11217
11218 /* 2nd lookup from map */
11219 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11220 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11221 BPF_LD_MAP_FD(BPF_REG_1, 0),
11222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11223 BPF_FUNC_map_lookup_elem),
11224 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11225 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11226 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11227 BPF_MOV64_IMM(BPF_REG_9, 0),
11228 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11229 BPF_MOV64_IMM(BPF_REG_9, 1),
11230
11231 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11232 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11233 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11234 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11235 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11237 BPF_EXIT_INSN(),
11238
11239 /* subprog 2 */
11240 /* if arg2 == 1 do *arg1 = 0 */
11241 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11242 /* fetch map_value_ptr from the stack of this function */
11243 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11244 /* write into map value */
11245 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11246
11247 /* if arg4 == 1 do *arg3 = 0 */
11248 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11249 /* fetch map_value_ptr from the stack of this function */
11250 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11251 /* write into map value */
11252 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11253 BPF_EXIT_INSN(),
11254 },
11255 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11256 .fixup_map1 = { 12, 22 },
11257 .result = ACCEPT,
11258 },
11259 {
11260 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
11261 .insns = {
11262 /* main prog */
11263 /* pass fp-16, fp-8 into a function */
11264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11266 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11267 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11268 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11269 BPF_MOV64_IMM(BPF_REG_0, 0),
11270 BPF_EXIT_INSN(),
11271
11272 /* subprog 1 */
11273 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11274 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11275 /* 1st lookup from map */
11276 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11277 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11279 BPF_LD_MAP_FD(BPF_REG_1, 0),
11280 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11281 BPF_FUNC_map_lookup_elem),
11282 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11283 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11284 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11285 BPF_MOV64_IMM(BPF_REG_8, 0),
11286 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11287 BPF_MOV64_IMM(BPF_REG_8, 1),
11288
11289 /* 2nd lookup from map */
11290 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11291 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11292 BPF_LD_MAP_FD(BPF_REG_1, 0),
11293 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11294 BPF_FUNC_map_lookup_elem),
11295 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11296 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11297 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11298 BPF_MOV64_IMM(BPF_REG_9, 0),
11299 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11300 BPF_MOV64_IMM(BPF_REG_9, 1),
11301
11302 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11303 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11304 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11305 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11306 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11308 BPF_EXIT_INSN(),
11309
11310 /* subprog 2 */
11311 /* if arg2 == 1 do *arg1 = 0 */
11312 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11313 /* fetch map_value_ptr from the stack of this function */
11314 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11315 /* write into map value */
11316 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11317
11318 /* if arg4 == 0 do *arg3 = 0 */
11319 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
11320 /* fetch map_value_ptr from the stack of this function */
11321 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11322 /* write into map value */
11323 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11324 BPF_EXIT_INSN(),
11325 },
11326 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11327 .fixup_map1 = { 12, 22 },
11328 .result = REJECT,
11329 .errstr = "R0 invalid mem access 'inv'",
11330 },
11331 {
11332 "calls: pkt_ptr spill into caller stack",
11333 .insns = {
11334 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11335 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11336 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11337 BPF_EXIT_INSN(),
11338
11339 /* subprog 1 */
11340 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11341 offsetof(struct __sk_buff, data)),
11342 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11343 offsetof(struct __sk_buff, data_end)),
11344 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11346 /* spill unchecked pkt_ptr into stack of caller */
11347 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11348 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11349 /* now the pkt range is verified, read pkt_ptr from stack */
11350 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11351 /* write 4 bytes into packet */
11352 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11353 BPF_EXIT_INSN(),
11354 },
11355 .result = ACCEPT,
11356 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11357 .retval = POINTER_VALUE,
11358 },
11359 {
11360 "calls: pkt_ptr spill into caller stack 2",
11361 .insns = {
11362 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11364 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11365 /* Marking is still kept, but not in all cases safe. */
11366 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11367 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11368 BPF_EXIT_INSN(),
11369
11370 /* subprog 1 */
11371 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11372 offsetof(struct __sk_buff, data)),
11373 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11374 offsetof(struct __sk_buff, data_end)),
11375 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11376 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11377 /* spill unchecked pkt_ptr into stack of caller */
11378 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11379 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11380 /* now the pkt range is verified, read pkt_ptr from stack */
11381 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11382 /* write 4 bytes into packet */
11383 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11384 BPF_EXIT_INSN(),
11385 },
11386 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11387 .errstr = "invalid access to packet",
11388 .result = REJECT,
11389 },
11390 {
11391 "calls: pkt_ptr spill into caller stack 3",
11392 .insns = {
11393 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11395 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11396 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11397 /* Marking is still kept and safe here. */
11398 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11399 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11400 BPF_EXIT_INSN(),
11401
11402 /* subprog 1 */
11403 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11404 offsetof(struct __sk_buff, data)),
11405 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11406 offsetof(struct __sk_buff, data_end)),
11407 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11408 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11409 /* spill unchecked pkt_ptr into stack of caller */
11410 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11411 BPF_MOV64_IMM(BPF_REG_5, 0),
11412 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11413 BPF_MOV64_IMM(BPF_REG_5, 1),
11414 /* now the pkt range is verified, read pkt_ptr from stack */
11415 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11416 /* write 4 bytes into packet */
11417 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11418 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11419 BPF_EXIT_INSN(),
11420 },
11421 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11422 .result = ACCEPT,
11423 .retval = 1,
11424 },
11425 {
11426 "calls: pkt_ptr spill into caller stack 4",
11427 .insns = {
11428 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11429 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11430 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11431 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11432 /* Check marking propagated. */
11433 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11434 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11435 BPF_EXIT_INSN(),
11436
11437 /* subprog 1 */
11438 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11439 offsetof(struct __sk_buff, data)),
11440 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11441 offsetof(struct __sk_buff, data_end)),
11442 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11444 /* spill unchecked pkt_ptr into stack of caller */
11445 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11446 BPF_MOV64_IMM(BPF_REG_5, 0),
11447 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11448 BPF_MOV64_IMM(BPF_REG_5, 1),
11449 /* don't read back pkt_ptr from stack here */
11450 /* write 4 bytes into packet */
11451 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11452 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11453 BPF_EXIT_INSN(),
11454 },
11455 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11456 .result = ACCEPT,
11457 .retval = 1,
11458 },
11459 {
11460 "calls: pkt_ptr spill into caller stack 5",
11461 .insns = {
11462 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11463 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11464 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
11465 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11466 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11467 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11468 BPF_EXIT_INSN(),
11469
11470 /* subprog 1 */
11471 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11472 offsetof(struct __sk_buff, data)),
11473 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11474 offsetof(struct __sk_buff, data_end)),
11475 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11476 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11477 BPF_MOV64_IMM(BPF_REG_5, 0),
11478 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11479 /* spill checked pkt_ptr into stack of caller */
11480 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11481 BPF_MOV64_IMM(BPF_REG_5, 1),
11482 /* don't read back pkt_ptr from stack here */
11483 /* write 4 bytes into packet */
11484 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11485 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11486 BPF_EXIT_INSN(),
11487 },
11488 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11489 .errstr = "same insn cannot be used with different",
11490 .result = REJECT,
11491 },
11492 {
11493 "calls: pkt_ptr spill into caller stack 6",
11494 .insns = {
11495 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11496 offsetof(struct __sk_buff, data_end)),
11497 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11499 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11500 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11501 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11502 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11503 BPF_EXIT_INSN(),
11504
11505 /* subprog 1 */
11506 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11507 offsetof(struct __sk_buff, data)),
11508 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11509 offsetof(struct __sk_buff, data_end)),
11510 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11511 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11512 BPF_MOV64_IMM(BPF_REG_5, 0),
11513 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11514 /* spill checked pkt_ptr into stack of caller */
11515 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11516 BPF_MOV64_IMM(BPF_REG_5, 1),
11517 /* don't read back pkt_ptr from stack here */
11518 /* write 4 bytes into packet */
11519 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11520 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11521 BPF_EXIT_INSN(),
11522 },
11523 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11524 .errstr = "R4 invalid mem access",
11525 .result = REJECT,
11526 },
11527 {
11528 "calls: pkt_ptr spill into caller stack 7",
11529 .insns = {
11530 BPF_MOV64_IMM(BPF_REG_2, 0),
11531 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11533 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11534 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11535 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11536 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11537 BPF_EXIT_INSN(),
11538
11539 /* subprog 1 */
11540 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11541 offsetof(struct __sk_buff, data)),
11542 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11543 offsetof(struct __sk_buff, data_end)),
11544 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11546 BPF_MOV64_IMM(BPF_REG_5, 0),
11547 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11548 /* spill checked pkt_ptr into stack of caller */
11549 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11550 BPF_MOV64_IMM(BPF_REG_5, 1),
11551 /* don't read back pkt_ptr from stack here */
11552 /* write 4 bytes into packet */
11553 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11554 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11555 BPF_EXIT_INSN(),
11556 },
11557 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11558 .errstr = "R4 invalid mem access",
11559 .result = REJECT,
11560 },
11561 {
11562 "calls: pkt_ptr spill into caller stack 8",
11563 .insns = {
11564 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11565 offsetof(struct __sk_buff, data)),
11566 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11567 offsetof(struct __sk_buff, data_end)),
11568 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11569 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11570 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11571 BPF_EXIT_INSN(),
11572 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11573 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11574 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11575 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11576 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11577 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11578 BPF_EXIT_INSN(),
11579
11580 /* subprog 1 */
11581 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11582 offsetof(struct __sk_buff, data)),
11583 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11584 offsetof(struct __sk_buff, data_end)),
11585 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11587 BPF_MOV64_IMM(BPF_REG_5, 0),
11588 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11589 /* spill checked pkt_ptr into stack of caller */
11590 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11591 BPF_MOV64_IMM(BPF_REG_5, 1),
11592 /* don't read back pkt_ptr from stack here */
11593 /* write 4 bytes into packet */
11594 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11595 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11596 BPF_EXIT_INSN(),
11597 },
11598 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11599 .result = ACCEPT,
11600 },
11601 {
11602 "calls: pkt_ptr spill into caller stack 9",
11603 .insns = {
11604 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11605 offsetof(struct __sk_buff, data)),
11606 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11607 offsetof(struct __sk_buff, data_end)),
11608 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11610 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11611 BPF_EXIT_INSN(),
11612 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11613 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11614 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11615 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11616 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11617 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11618 BPF_EXIT_INSN(),
11619
11620 /* subprog 1 */
11621 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11622 offsetof(struct __sk_buff, data)),
11623 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11624 offsetof(struct __sk_buff, data_end)),
11625 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11627 BPF_MOV64_IMM(BPF_REG_5, 0),
11628 /* spill unchecked pkt_ptr into stack of caller */
11629 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11630 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11631 BPF_MOV64_IMM(BPF_REG_5, 1),
11632 /* don't read back pkt_ptr from stack here */
11633 /* write 4 bytes into packet */
11634 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11635 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11636 BPF_EXIT_INSN(),
11637 },
11638 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11639 .errstr = "invalid access to packet",
11640 .result = REJECT,
11641 },
11642 {
11643 "calls: caller stack init to zero or map_value_or_null",
11644 .insns = {
11645 BPF_MOV64_IMM(BPF_REG_0, 0),
11646 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11649 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11650 /* fetch map_value_or_null or const_zero from stack */
11651 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11653 /* store into map_value */
11654 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
11655 BPF_EXIT_INSN(),
11656
11657 /* subprog 1 */
11658 /* if (ctx == 0) return; */
11659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
11660 /* else bpf_map_lookup() and *(fp - 8) = r0 */
11661 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
11662 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11664 BPF_LD_MAP_FD(BPF_REG_1, 0),
11665 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11666 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11667 BPF_FUNC_map_lookup_elem),
11668 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11669 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11670 BPF_EXIT_INSN(),
11671 },
11672 .fixup_map1 = { 13 },
11673 .result = ACCEPT,
11674 .prog_type = BPF_PROG_TYPE_XDP,
11675 },
11676 {
11677 "calls: stack init to zero and pruning",
11678 .insns = {
11679 /* first make allocated_stack 16 byte */
11680 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
11681 /* now fork the execution such that the false branch
11682 * of JGT insn will be verified second and it skisp zero
11683 * init of fp-8 stack slot. If stack liveness marking
11684 * is missing live_read marks from call map_lookup
11685 * processing then pruning will incorrectly assume
11686 * that fp-8 stack slot was unused in the fall-through
11687 * branch and will accept the program incorrectly
11688 */
11689 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
11690 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11691 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
11692 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11694 BPF_LD_MAP_FD(BPF_REG_1, 0),
11695 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11696 BPF_FUNC_map_lookup_elem),
11697 BPF_EXIT_INSN(),
11698 },
11699 .fixup_map2 = { 6 },
11700 .errstr = "invalid indirect read from stack off -8+0 size 8",
11701 .result = REJECT,
11702 .prog_type = BPF_PROG_TYPE_XDP,
11703 },
11704 {
11705 "calls: two calls returning different map pointers for lookup (hash, array)",
11706 .insns = {
11707 /* main prog */
11708 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11709 BPF_CALL_REL(11),
11710 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11711 BPF_CALL_REL(12),
11712 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11713 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11716 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11717 BPF_FUNC_map_lookup_elem),
11718 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11719 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
11720 offsetof(struct test_val, foo)),
11721 BPF_MOV64_IMM(BPF_REG_0, 1),
11722 BPF_EXIT_INSN(),
11723 /* subprog 1 */
11724 BPF_LD_MAP_FD(BPF_REG_0, 0),
11725 BPF_EXIT_INSN(),
11726 /* subprog 2 */
11727 BPF_LD_MAP_FD(BPF_REG_0, 0),
11728 BPF_EXIT_INSN(),
11729 },
11730 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11731 .fixup_map2 = { 13 },
11732 .fixup_map4 = { 16 },
11733 .result = ACCEPT,
11734 .retval = 1,
11735 },
11736 {
11737 "calls: two calls returning different map pointers for lookup (hash, map in map)",
11738 .insns = {
11739 /* main prog */
11740 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11741 BPF_CALL_REL(11),
11742 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11743 BPF_CALL_REL(12),
11744 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11745 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11746 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11747 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11748 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11749 BPF_FUNC_map_lookup_elem),
11750 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11751 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
11752 offsetof(struct test_val, foo)),
11753 BPF_MOV64_IMM(BPF_REG_0, 1),
11754 BPF_EXIT_INSN(),
11755 /* subprog 1 */
11756 BPF_LD_MAP_FD(BPF_REG_0, 0),
11757 BPF_EXIT_INSN(),
11758 /* subprog 2 */
11759 BPF_LD_MAP_FD(BPF_REG_0, 0),
11760 BPF_EXIT_INSN(),
11761 },
11762 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11763 .fixup_map_in_map = { 16 },
11764 .fixup_map4 = { 13 },
11765 .result = REJECT,
11766 .errstr = "R0 invalid mem access 'map_ptr'",
11767 },
11768 {
11769 "cond: two branches returning different map pointers for lookup (tail, tail)",
11770 .insns = {
11771 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
11772 offsetof(struct __sk_buff, mark)),
11773 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 3),
11774 BPF_LD_MAP_FD(BPF_REG_2, 0),
11775 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11776 BPF_LD_MAP_FD(BPF_REG_2, 0),
11777 BPF_MOV64_IMM(BPF_REG_3, 7),
11778 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11779 BPF_FUNC_tail_call),
11780 BPF_MOV64_IMM(BPF_REG_0, 1),
11781 BPF_EXIT_INSN(),
11782 },
11783 .fixup_prog1 = { 5 },
11784 .fixup_prog2 = { 2 },
11785 .result_unpriv = REJECT,
11786 .errstr_unpriv = "tail_call abusing map_ptr",
11787 .result = ACCEPT,
11788 .retval = 42,
11789 },
11790 {
11791 "cond: two branches returning same map pointers for lookup (tail, tail)",
11792 .insns = {
11793 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
11794 offsetof(struct __sk_buff, mark)),
11795 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 3),
11796 BPF_LD_MAP_FD(BPF_REG_2, 0),
11797 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11798 BPF_LD_MAP_FD(BPF_REG_2, 0),
11799 BPF_MOV64_IMM(BPF_REG_3, 7),
11800 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11801 BPF_FUNC_tail_call),
11802 BPF_MOV64_IMM(BPF_REG_0, 1),
11803 BPF_EXIT_INSN(),
11804 },
11805 .fixup_prog2 = { 2, 5 },
11806 .result_unpriv = ACCEPT,
11807 .result = ACCEPT,
11808 .retval = 42,
11809 },
11810 {
11811 "search pruning: all branches should be verified (nop operation)",
11812 .insns = {
11813 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11814 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11815 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11816 BPF_LD_MAP_FD(BPF_REG_1, 0),
11817 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11818 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
11819 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11820 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11821 BPF_MOV64_IMM(BPF_REG_4, 0),
11822 BPF_JMP_A(1),
11823 BPF_MOV64_IMM(BPF_REG_4, 1),
11824 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11825 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11826 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
11828 BPF_MOV64_IMM(BPF_REG_6, 0),
11829 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
11830 BPF_EXIT_INSN(),
11831 },
11832 .fixup_map1 = { 3 },
11833 .errstr = "R6 invalid mem access 'inv'",
11834 .result = REJECT,
11835 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11836 },
11837 {
11838 "search pruning: all branches should be verified (invalid stack access)",
11839 .insns = {
11840 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11842 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11843 BPF_LD_MAP_FD(BPF_REG_1, 0),
11844 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11845 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
11846 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11847 BPF_MOV64_IMM(BPF_REG_4, 0),
11848 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11849 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11850 BPF_JMP_A(1),
11851 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
11852 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11853 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11854 BPF_EXIT_INSN(),
11855 },
11856 .fixup_map1 = { 3 },
11857 .errstr = "invalid read from stack off -16+0 size 8",
11858 .result = REJECT,
11859 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11860 },
11861 {
11862 "jit: lsh, rsh, arsh by 1",
11863 .insns = {
11864 BPF_MOV64_IMM(BPF_REG_0, 1),
11865 BPF_MOV64_IMM(BPF_REG_1, 0xff),
11866 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
11867 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
11868 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
11869 BPF_EXIT_INSN(),
11870 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
11871 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
11872 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
11873 BPF_EXIT_INSN(),
11874 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
11875 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
11876 BPF_EXIT_INSN(),
11877 BPF_MOV64_IMM(BPF_REG_0, 2),
11878 BPF_EXIT_INSN(),
11879 },
11880 .result = ACCEPT,
11881 .retval = 2,
11882 },
11883 {
11884 "jit: mov32 for ldimm64, 1",
11885 .insns = {
11886 BPF_MOV64_IMM(BPF_REG_0, 2),
11887 BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
11888 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
11889 BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
11890 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11891 BPF_MOV64_IMM(BPF_REG_0, 1),
11892 BPF_EXIT_INSN(),
11893 },
11894 .result = ACCEPT,
11895 .retval = 2,
11896 },
11897 {
11898 "jit: mov32 for ldimm64, 2",
11899 .insns = {
11900 BPF_MOV64_IMM(BPF_REG_0, 1),
11901 BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
11902 BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
11903 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11904 BPF_MOV64_IMM(BPF_REG_0, 2),
11905 BPF_EXIT_INSN(),
11906 },
11907 .result = ACCEPT,
11908 .retval = 2,
11909 },
11910 {
11911 "jit: various mul tests",
11912 .insns = {
11913 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11914 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11915 BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
11916 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11917 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11918 BPF_MOV64_IMM(BPF_REG_0, 1),
11919 BPF_EXIT_INSN(),
11920 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11921 BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11922 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11923 BPF_MOV64_IMM(BPF_REG_0, 1),
11924 BPF_EXIT_INSN(),
11925 BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
11926 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11927 BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11928 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11929 BPF_MOV64_IMM(BPF_REG_0, 1),
11930 BPF_EXIT_INSN(),
11931 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11932 BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11933 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11934 BPF_MOV64_IMM(BPF_REG_0, 1),
11935 BPF_EXIT_INSN(),
11936 BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
11937 BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
11938 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11939 BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
11940 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
11941 BPF_MOV64_IMM(BPF_REG_0, 1),
11942 BPF_EXIT_INSN(),
11943 BPF_MOV64_IMM(BPF_REG_0, 2),
11944 BPF_EXIT_INSN(),
11945 },
11946 .result = ACCEPT,
11947 .retval = 2,
11948 },
11949 {
11950 "xadd/w check unaligned stack",
11951 .insns = {
11952 BPF_MOV64_IMM(BPF_REG_0, 1),
11953 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11954 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
11955 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11956 BPF_EXIT_INSN(),
11957 },
11958 .result = REJECT,
11959 .errstr = "misaligned stack access off",
11960 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11961 },
11962 {
11963 "xadd/w check unaligned map",
11964 .insns = {
11965 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11966 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11968 BPF_LD_MAP_FD(BPF_REG_1, 0),
11969 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11970 BPF_FUNC_map_lookup_elem),
11971 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
11972 BPF_EXIT_INSN(),
11973 BPF_MOV64_IMM(BPF_REG_1, 1),
11974 BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
11975 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
11976 BPF_EXIT_INSN(),
11977 },
11978 .fixup_map1 = { 3 },
11979 .result = REJECT,
11980 .errstr = "misaligned value access off",
11981 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11982 },
11983 {
11984 "xadd/w check unaligned pkt",
11985 .insns = {
11986 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11987 offsetof(struct xdp_md, data)),
11988 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11989 offsetof(struct xdp_md, data_end)),
11990 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
11991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
11992 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
11993 BPF_MOV64_IMM(BPF_REG_0, 99),
11994 BPF_JMP_IMM(BPF_JA, 0, 0, 6),
11995 BPF_MOV64_IMM(BPF_REG_0, 1),
11996 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11997 BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
11998 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
11999 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
12000 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
12001 BPF_EXIT_INSN(),
12002 },
12003 .result = REJECT,
12004 .errstr = "BPF_XADD stores into R2 packet",
12005 .prog_type = BPF_PROG_TYPE_XDP,
12006 },
12007 {
12008 "xadd/w check whether src/dst got mangled, 1",
12009 .insns = {
12010 BPF_MOV64_IMM(BPF_REG_0, 1),
12011 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12012 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12013 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12014 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12015 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12016 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12017 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12018 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12019 BPF_EXIT_INSN(),
12020 BPF_MOV64_IMM(BPF_REG_0, 42),
12021 BPF_EXIT_INSN(),
12022 },
12023 .result = ACCEPT,
12024 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12025 .retval = 3,
12026 },
12027 {
12028 "xadd/w check whether src/dst got mangled, 2",
12029 .insns = {
12030 BPF_MOV64_IMM(BPF_REG_0, 1),
12031 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12032 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12033 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12034 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12035 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12036 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12037 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12038 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
12039 BPF_EXIT_INSN(),
12040 BPF_MOV64_IMM(BPF_REG_0, 42),
12041 BPF_EXIT_INSN(),
12042 },
12043 .result = ACCEPT,
12044 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12045 .retval = 3,
12046 },
12047 {
12048 "bpf_get_stack return R0 within range",
12049 .insns = {
12050 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12051 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12052 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12054 BPF_LD_MAP_FD(BPF_REG_1, 0),
12055 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12056 BPF_FUNC_map_lookup_elem),
12057 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
12058 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
12059 BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
12060 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12061 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12062 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
12063 BPF_MOV64_IMM(BPF_REG_4, 256),
12064 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12065 BPF_MOV64_IMM(BPF_REG_1, 0),
12066 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
12067 BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
12068 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
12069 BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
12070 BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
12071 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12072 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
12073 BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
12074 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
12075 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 32),
12076 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
12077 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
12078 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12079 BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
12080 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
12081 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
12082 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12083 BPF_MOV64_REG(BPF_REG_3, BPF_REG_9),
12084 BPF_MOV64_IMM(BPF_REG_4, 0),
12085 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12086 BPF_EXIT_INSN(),
12087 },
12088 .fixup_map2 = { 4 },
12089 .result = ACCEPT,
12090 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12091 },
12092 {
12093 "ld_abs: invalid op 1",
12094 .insns = {
12095 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12096 BPF_LD_ABS(BPF_DW, 0),
12097 BPF_EXIT_INSN(),
12098 },
12099 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12100 .result = REJECT,
12101 .errstr = "unknown opcode",
12102 },
12103 {
12104 "ld_abs: invalid op 2",
12105 .insns = {
12106 BPF_MOV32_IMM(BPF_REG_0, 256),
12107 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12108 BPF_LD_IND(BPF_DW, BPF_REG_0, 0),
12109 BPF_EXIT_INSN(),
12110 },
12111 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12112 .result = REJECT,
12113 .errstr = "unknown opcode",
12114 },
12115 {
12116 "ld_abs: nmap reduced",
12117 .insns = {
12118 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12119 BPF_LD_ABS(BPF_H, 12),
12120 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 28),
12121 BPF_LD_ABS(BPF_H, 12),
12122 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 26),
12123 BPF_MOV32_IMM(BPF_REG_0, 18),
12124 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -64),
12125 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -64),
12126 BPF_LD_IND(BPF_W, BPF_REG_7, 14),
12127 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -60),
12128 BPF_MOV32_IMM(BPF_REG_0, 280971478),
12129 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
12130 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
12131 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -60),
12132 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
12133 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 15),
12134 BPF_LD_ABS(BPF_H, 12),
12135 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 13),
12136 BPF_MOV32_IMM(BPF_REG_0, 22),
12137 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
12138 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
12139 BPF_LD_IND(BPF_H, BPF_REG_7, 14),
12140 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -52),
12141 BPF_MOV32_IMM(BPF_REG_0, 17366),
12142 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -48),
12143 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -48),
12144 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -52),
12145 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
12146 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12147 BPF_MOV32_IMM(BPF_REG_0, 256),
12148 BPF_EXIT_INSN(),
12149 BPF_MOV32_IMM(BPF_REG_0, 0),
12150 BPF_EXIT_INSN(),
12151 },
12152 .data = {
12153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0,
12154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12155 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
12156 },
12157 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12158 .result = ACCEPT,
12159 .retval = 256,
12160 },
12161 {
12162 "ld_abs: div + abs, test 1",
12163 .insns = {
12164 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12165 BPF_LD_ABS(BPF_B, 3),
12166 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12167 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12168 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12169 BPF_LD_ABS(BPF_B, 4),
12170 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12171 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12172 BPF_EXIT_INSN(),
12173 },
12174 .data = {
12175 10, 20, 30, 40, 50,
12176 },
12177 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12178 .result = ACCEPT,
12179 .retval = 10,
12180 },
12181 {
12182 "ld_abs: div + abs, test 2",
12183 .insns = {
12184 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12185 BPF_LD_ABS(BPF_B, 3),
12186 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12187 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12188 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12189 BPF_LD_ABS(BPF_B, 128),
12190 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12191 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12192 BPF_EXIT_INSN(),
12193 },
12194 .data = {
12195 10, 20, 30, 40, 50,
12196 },
12197 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12198 .result = ACCEPT,
12199 .retval = 0,
12200 },
12201 {
12202 "ld_abs: div + abs, test 3",
12203 .insns = {
12204 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12205 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12206 BPF_LD_ABS(BPF_B, 3),
12207 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12208 BPF_EXIT_INSN(),
12209 },
12210 .data = {
12211 10, 20, 30, 40, 50,
12212 },
12213 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12214 .result = ACCEPT,
12215 .retval = 0,
12216 },
12217 {
12218 "ld_abs: div + abs, test 4",
12219 .insns = {
12220 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12221 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12222 BPF_LD_ABS(BPF_B, 256),
12223 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12224 BPF_EXIT_INSN(),
12225 },
12226 .data = {
12227 10, 20, 30, 40, 50,
12228 },
12229 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12230 .result = ACCEPT,
12231 .retval = 0,
12232 },
12233 {
12234 "ld_abs: vlan + abs, test 1",
12235 .insns = { },
12236 .data = {
12237 0x34,
12238 },
12239 .fill_helper = bpf_fill_ld_abs_vlan_push_pop,
12240 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12241 .result = ACCEPT,
12242 .retval = 0xbef,
12243 },
12244 {
12245 "ld_abs: vlan + abs, test 2",
12246 .insns = {
12247 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12248 BPF_LD_ABS(BPF_B, 0),
12249 BPF_LD_ABS(BPF_H, 0),
12250 BPF_LD_ABS(BPF_W, 0),
12251 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
12252 BPF_MOV64_IMM(BPF_REG_6, 0),
12253 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12254 BPF_MOV64_IMM(BPF_REG_2, 1),
12255 BPF_MOV64_IMM(BPF_REG_3, 2),
12256 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12257 BPF_FUNC_skb_vlan_push),
12258 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
12259 BPF_LD_ABS(BPF_B, 0),
12260 BPF_LD_ABS(BPF_H, 0),
12261 BPF_LD_ABS(BPF_W, 0),
12262 BPF_MOV64_IMM(BPF_REG_0, 42),
12263 BPF_EXIT_INSN(),
12264 },
12265 .data = {
12266 0x34,
12267 },
12268 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12269 .result = ACCEPT,
12270 .retval = 42,
12271 },
12272 {
12273 "ld_abs: jump around ld_abs",
12274 .insns = { },
12275 .data = {
12276 10, 11,
12277 },
12278 .fill_helper = bpf_fill_jump_around_ld_abs,
12279 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12280 .result = ACCEPT,
12281 .retval = 10,
12282 },
12283 {
12284 "ld_dw: xor semi-random 64 bit imms, test 1",
12285 .insns = { },
12286 .data = { },
12287 .fill_helper = bpf_fill_rand_ld_dw,
12288 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12289 .result = ACCEPT,
12290 .retval = 4090,
12291 },
12292 {
12293 "ld_dw: xor semi-random 64 bit imms, test 2",
12294 .insns = { },
12295 .data = { },
12296 .fill_helper = bpf_fill_rand_ld_dw,
12297 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12298 .result = ACCEPT,
12299 .retval = 2047,
12300 },
12301 {
12302 "ld_dw: xor semi-random 64 bit imms, test 3",
12303 .insns = { },
12304 .data = { },
12305 .fill_helper = bpf_fill_rand_ld_dw,
12306 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12307 .result = ACCEPT,
12308 .retval = 511,
12309 },
12310 {
12311 "ld_dw: xor semi-random 64 bit imms, test 4",
12312 .insns = { },
12313 .data = { },
12314 .fill_helper = bpf_fill_rand_ld_dw,
12315 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12316 .result = ACCEPT,
12317 .retval = 5,
12318 },
12319 {
12320 "pass unmodified ctx pointer to helper",
12321 .insns = {
12322 BPF_MOV64_IMM(BPF_REG_2, 0),
12323 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12324 BPF_FUNC_csum_update),
12325 BPF_MOV64_IMM(BPF_REG_0, 0),
12326 BPF_EXIT_INSN(),
12327 },
12328 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12329 .result = ACCEPT,
12330 },
12331 {
12332 "pass modified ctx pointer to helper, 1",
12333 .insns = {
12334 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
12335 BPF_MOV64_IMM(BPF_REG_2, 0),
12336 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12337 BPF_FUNC_csum_update),
12338 BPF_MOV64_IMM(BPF_REG_0, 0),
12339 BPF_EXIT_INSN(),
12340 },
12341 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12342 .result = REJECT,
12343 .errstr = "dereference of modified ctx ptr",
12344 },
12345 {
12346 "pass modified ctx pointer to helper, 2",
12347 .insns = {
12348 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
12349 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12350 BPF_FUNC_get_socket_cookie),
12351 BPF_MOV64_IMM(BPF_REG_0, 0),
12352 BPF_EXIT_INSN(),
12353 },
12354 .result_unpriv = REJECT,
12355 .result = REJECT,
12356 .errstr_unpriv = "dereference of modified ctx ptr",
12357 .errstr = "dereference of modified ctx ptr",
12358 },
12359 {
12360 "pass modified ctx pointer to helper, 3",
12361 .insns = {
12362 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
12363 BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
12364 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
12365 BPF_MOV64_IMM(BPF_REG_2, 0),
12366 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12367 BPF_FUNC_csum_update),
12368 BPF_MOV64_IMM(BPF_REG_0, 0),
12369 BPF_EXIT_INSN(),
12370 },
12371 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12372 .result = REJECT,
12373 .errstr = "variable ctx access var_off=(0x0; 0x4)",
12374 },
12375 };
12376
12377 static int probe_filter_length(const struct bpf_insn *fp)
12378 {
12379 int len;
12380
12381 for (len = MAX_INSNS - 1; len > 0; --len)
12382 if (fp[len].code != 0 || fp[len].imm != 0)
12383 break;
12384 return len + 1;
12385 }
12386
12387 static int create_map(uint32_t type, uint32_t size_key,
12388 uint32_t size_value, uint32_t max_elem)
12389 {
12390 int fd;
12391
12392 fd = bpf_create_map(type, size_key, size_value, max_elem,
12393 type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0);
12394 if (fd < 0)
12395 printf("Failed to create hash map '%s'!\n", strerror(errno));
12396
12397 return fd;
12398 }
12399
12400 static int create_prog_dummy1(void)
12401 {
12402 struct bpf_insn prog[] = {
12403 BPF_MOV64_IMM(BPF_REG_0, 42),
12404 BPF_EXIT_INSN(),
12405 };
12406
12407 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12408 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12409 }
12410
12411 static int create_prog_dummy2(int mfd, int idx)
12412 {
12413 struct bpf_insn prog[] = {
12414 BPF_MOV64_IMM(BPF_REG_3, idx),
12415 BPF_LD_MAP_FD(BPF_REG_2, mfd),
12416 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12417 BPF_FUNC_tail_call),
12418 BPF_MOV64_IMM(BPF_REG_0, 41),
12419 BPF_EXIT_INSN(),
12420 };
12421
12422 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12423 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12424 }
12425
12426 static int create_prog_array(uint32_t max_elem, int p1key)
12427 {
12428 int p2key = 1;
12429 int mfd, p1fd, p2fd;
12430
12431 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
12432 sizeof(int), max_elem, 0);
12433 if (mfd < 0) {
12434 printf("Failed to create prog array '%s'!\n", strerror(errno));
12435 return -1;
12436 }
12437
12438 p1fd = create_prog_dummy1();
12439 p2fd = create_prog_dummy2(mfd, p2key);
12440 if (p1fd < 0 || p2fd < 0)
12441 goto out;
12442 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
12443 goto out;
12444 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
12445 goto out;
12446 close(p2fd);
12447 close(p1fd);
12448
12449 return mfd;
12450 out:
12451 close(p2fd);
12452 close(p1fd);
12453 close(mfd);
12454 return -1;
12455 }
12456
12457 static int create_map_in_map(void)
12458 {
12459 int inner_map_fd, outer_map_fd;
12460
12461 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12462 sizeof(int), 1, 0);
12463 if (inner_map_fd < 0) {
12464 printf("Failed to create array '%s'!\n", strerror(errno));
12465 return inner_map_fd;
12466 }
12467
12468 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
12469 sizeof(int), inner_map_fd, 1, 0);
12470 if (outer_map_fd < 0)
12471 printf("Failed to create array of maps '%s'!\n",
12472 strerror(errno));
12473
12474 close(inner_map_fd);
12475
12476 return outer_map_fd;
12477 }
12478
12479 static char bpf_vlog[UINT_MAX >> 8];
12480
12481 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12482 int *map_fds)
12483 {
12484 int *fixup_map1 = test->fixup_map1;
12485 int *fixup_map2 = test->fixup_map2;
12486 int *fixup_map3 = test->fixup_map3;
12487 int *fixup_map4 = test->fixup_map4;
12488 int *fixup_prog1 = test->fixup_prog1;
12489 int *fixup_prog2 = test->fixup_prog2;
12490 int *fixup_map_in_map = test->fixup_map_in_map;
12491
12492 if (test->fill_helper)
12493 test->fill_helper(test);
12494
12495 /* Allocating HTs with 1 elem is fine here, since we only test
12496 * for verifier and not do a runtime lookup, so the only thing
12497 * that really matters is value size in this case.
12498 */
12499 if (*fixup_map1) {
12500 map_fds[0] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12501 sizeof(long long), 1);
12502 do {
12503 prog[*fixup_map1].imm = map_fds[0];
12504 fixup_map1++;
12505 } while (*fixup_map1);
12506 }
12507
12508 if (*fixup_map2) {
12509 map_fds[1] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12510 sizeof(struct test_val), 1);
12511 do {
12512 prog[*fixup_map2].imm = map_fds[1];
12513 fixup_map2++;
12514 } while (*fixup_map2);
12515 }
12516
12517 if (*fixup_map3) {
12518 map_fds[2] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12519 sizeof(struct other_val), 1);
12520 do {
12521 prog[*fixup_map3].imm = map_fds[2];
12522 fixup_map3++;
12523 } while (*fixup_map3);
12524 }
12525
12526 if (*fixup_map4) {
12527 map_fds[3] = create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12528 sizeof(struct test_val), 1);
12529 do {
12530 prog[*fixup_map4].imm = map_fds[3];
12531 fixup_map4++;
12532 } while (*fixup_map4);
12533 }
12534
12535 if (*fixup_prog1) {
12536 map_fds[4] = create_prog_array(4, 0);
12537 do {
12538 prog[*fixup_prog1].imm = map_fds[4];
12539 fixup_prog1++;
12540 } while (*fixup_prog1);
12541 }
12542
12543 if (*fixup_prog2) {
12544 map_fds[5] = create_prog_array(8, 7);
12545 do {
12546 prog[*fixup_prog2].imm = map_fds[5];
12547 fixup_prog2++;
12548 } while (*fixup_prog2);
12549 }
12550
12551 if (*fixup_map_in_map) {
12552 map_fds[6] = create_map_in_map();
12553 do {
12554 prog[*fixup_map_in_map].imm = map_fds[6];
12555 fixup_map_in_map++;
12556 } while (*fixup_map_in_map);
12557 }
12558 }
12559
12560 static void do_test_single(struct bpf_test *test, bool unpriv,
12561 int *passes, int *errors)
12562 {
12563 int fd_prog, expected_ret, reject_from_alignment;
12564 int prog_len, prog_type = test->prog_type;
12565 struct bpf_insn *prog = test->insns;
12566 int map_fds[MAX_NR_MAPS];
12567 const char *expected_err;
12568 uint32_t retval;
12569 int i, err;
12570
12571 for (i = 0; i < MAX_NR_MAPS; i++)
12572 map_fds[i] = -1;
12573
12574 do_test_fixup(test, prog, map_fds);
12575 prog_len = probe_filter_length(prog);
12576
12577 fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
12578 prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
12579 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
12580
12581 expected_ret = unpriv && test->result_unpriv != UNDEF ?
12582 test->result_unpriv : test->result;
12583 expected_err = unpriv && test->errstr_unpriv ?
12584 test->errstr_unpriv : test->errstr;
12585
12586 reject_from_alignment = fd_prog < 0 &&
12587 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
12588 strstr(bpf_vlog, "Unknown alignment.");
12589 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
12590 if (reject_from_alignment) {
12591 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
12592 strerror(errno));
12593 goto fail_log;
12594 }
12595 #endif
12596 if (expected_ret == ACCEPT) {
12597 if (fd_prog < 0 && !reject_from_alignment) {
12598 printf("FAIL\nFailed to load prog '%s'!\n",
12599 strerror(errno));
12600 goto fail_log;
12601 }
12602 } else {
12603 if (fd_prog >= 0) {
12604 printf("FAIL\nUnexpected success to load!\n");
12605 goto fail_log;
12606 }
12607 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
12608 printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
12609 expected_err, bpf_vlog);
12610 goto fail_log;
12611 }
12612 }
12613
12614 if (fd_prog >= 0) {
12615 __u8 tmp[TEST_DATA_LEN << 2];
12616 __u32 size_tmp = sizeof(tmp);
12617
12618 err = bpf_prog_test_run(fd_prog, 1, test->data,
12619 sizeof(test->data), tmp, &size_tmp,
12620 &retval, NULL);
12621 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
12622 printf("Unexpected bpf_prog_test_run error\n");
12623 goto fail_log;
12624 }
12625 if (!err && retval != test->retval &&
12626 test->retval != POINTER_VALUE) {
12627 printf("FAIL retval %d != %d\n", retval, test->retval);
12628 goto fail_log;
12629 }
12630 }
12631 (*passes)++;
12632 printf("OK%s\n", reject_from_alignment ?
12633 " (NOTE: reject due to unknown alignment)" : "");
12634 close_fds:
12635 close(fd_prog);
12636 for (i = 0; i < MAX_NR_MAPS; i++)
12637 close(map_fds[i]);
12638 sched_yield();
12639 return;
12640 fail_log:
12641 (*errors)++;
12642 printf("%s", bpf_vlog);
12643 goto close_fds;
12644 }
12645
12646 static bool is_admin(void)
12647 {
12648 cap_t caps;
12649 cap_flag_value_t sysadmin = CAP_CLEAR;
12650 const cap_value_t cap_val = CAP_SYS_ADMIN;
12651
12652 #ifdef CAP_IS_SUPPORTED
12653 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
12654 perror("cap_get_flag");
12655 return false;
12656 }
12657 #endif
12658 caps = cap_get_proc();
12659 if (!caps) {
12660 perror("cap_get_proc");
12661 return false;
12662 }
12663 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
12664 perror("cap_get_flag");
12665 if (cap_free(caps))
12666 perror("cap_free");
12667 return (sysadmin == CAP_SET);
12668 }
12669
12670 static int set_admin(bool admin)
12671 {
12672 cap_t caps;
12673 const cap_value_t cap_val = CAP_SYS_ADMIN;
12674 int ret = -1;
12675
12676 caps = cap_get_proc();
12677 if (!caps) {
12678 perror("cap_get_proc");
12679 return -1;
12680 }
12681 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
12682 admin ? CAP_SET : CAP_CLEAR)) {
12683 perror("cap_set_flag");
12684 goto out;
12685 }
12686 if (cap_set_proc(caps)) {
12687 perror("cap_set_proc");
12688 goto out;
12689 }
12690 ret = 0;
12691 out:
12692 if (cap_free(caps))
12693 perror("cap_free");
12694 return ret;
12695 }
12696
12697 static void get_unpriv_disabled()
12698 {
12699 char buf[2];
12700 FILE *fd;
12701
12702 fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
12703 if (!fd) {
12704 perror("fopen /proc/sys/"UNPRIV_SYSCTL);
12705 unpriv_disabled = true;
12706 return;
12707 }
12708 if (fgets(buf, 2, fd) == buf && atoi(buf))
12709 unpriv_disabled = true;
12710 fclose(fd);
12711 }
12712
12713 static int do_test(bool unpriv, unsigned int from, unsigned int to)
12714 {
12715 int i, passes = 0, errors = 0, skips = 0;
12716
12717 for (i = from; i < to; i++) {
12718 struct bpf_test *test = &tests[i];
12719
12720 /* Program types that are not supported by non-root we
12721 * skip right away.
12722 */
12723 if (!test->prog_type && unpriv_disabled) {
12724 printf("#%d/u %s SKIP\n", i, test->descr);
12725 skips++;
12726 } else if (!test->prog_type) {
12727 if (!unpriv)
12728 set_admin(false);
12729 printf("#%d/u %s ", i, test->descr);
12730 do_test_single(test, true, &passes, &errors);
12731 if (!unpriv)
12732 set_admin(true);
12733 }
12734
12735 if (unpriv) {
12736 printf("#%d/p %s SKIP\n", i, test->descr);
12737 skips++;
12738 } else {
12739 printf("#%d/p %s ", i, test->descr);
12740 do_test_single(test, false, &passes, &errors);
12741 }
12742 }
12743
12744 printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
12745 skips, errors);
12746 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
12747 }
12748
12749 int main(int argc, char **argv)
12750 {
12751 unsigned int from = 0, to = ARRAY_SIZE(tests);
12752 bool unpriv = !is_admin();
12753
12754 if (argc == 3) {
12755 unsigned int l = atoi(argv[argc - 2]);
12756 unsigned int u = atoi(argv[argc - 1]);
12757
12758 if (l < to && u < to) {
12759 from = l;
12760 to = u + 1;
12761 }
12762 } else if (argc == 2) {
12763 unsigned int t = atoi(argv[argc - 1]);
12764
12765 if (t < to) {
12766 from = t;
12767 to = t + 1;
12768 }
12769 }
12770
12771 get_unpriv_disabled();
12772 if (unpriv && unpriv_disabled) {
12773 printf("Cannot run as unprivileged user with sysctl %s.\n",
12774 UNPRIV_SYSCTL);
12775 return EXIT_FAILURE;
12776 }
12777
12778 bpf_semi_rand_init();
12779 return do_test(unpriv, from, to);
12780 }