]> git.ipfire.org Git - thirdparty/linux.git/blob - tools/testing/selftests/bpf/test_verifier.c
drm/i915: Flush GPU relocs harder for gen3
[thirdparty/linux.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 * Copyright (c) 2018 Covalent IO, Inc. http://covalent.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
11 */
12
13 #include <endian.h>
14 #include <asm/types.h>
15 #include <linux/types.h>
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <stddef.h>
23 #include <stdbool.h>
24 #include <sched.h>
25 #include <limits.h>
26
27 #include <sys/capability.h>
28
29 #include <linux/unistd.h>
30 #include <linux/filter.h>
31 #include <linux/bpf_perf_event.h>
32 #include <linux/bpf.h>
33 #include <linux/if_ether.h>
34
35 #include <bpf/bpf.h>
36
37 #ifdef HAVE_GENHDR
38 # include "autoconf.h"
39 #else
40 # if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
41 # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
42 # endif
43 #endif
44 #include "bpf_rlimit.h"
45 #include "bpf_rand.h"
46 #include "bpf_util.h"
47 #include "../../../include/linux/filter.h"
48
49 #define MAX_INSNS BPF_MAXINSNS
50 #define MAX_FIXUPS 8
51 #define MAX_NR_MAPS 13
52 #define POINTER_VALUE 0xcafe4all
53 #define TEST_DATA_LEN 64
54
55 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
56 #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
57
58 #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
59 static bool unpriv_disabled = false;
60
61 struct bpf_test {
62 const char *descr;
63 struct bpf_insn insns[MAX_INSNS];
64 int fixup_map_hash_8b[MAX_FIXUPS];
65 int fixup_map_hash_48b[MAX_FIXUPS];
66 int fixup_map_hash_16b[MAX_FIXUPS];
67 int fixup_map_array_48b[MAX_FIXUPS];
68 int fixup_map_sockmap[MAX_FIXUPS];
69 int fixup_map_sockhash[MAX_FIXUPS];
70 int fixup_map_xskmap[MAX_FIXUPS];
71 int fixup_map_stacktrace[MAX_FIXUPS];
72 int fixup_prog1[MAX_FIXUPS];
73 int fixup_prog2[MAX_FIXUPS];
74 int fixup_map_in_map[MAX_FIXUPS];
75 int fixup_cgroup_storage[MAX_FIXUPS];
76 int fixup_percpu_cgroup_storage[MAX_FIXUPS];
77 const char *errstr;
78 const char *errstr_unpriv;
79 uint32_t retval, retval_unpriv;
80 enum {
81 UNDEF,
82 ACCEPT,
83 REJECT
84 } result, result_unpriv;
85 enum bpf_prog_type prog_type;
86 uint8_t flags;
87 __u8 data[TEST_DATA_LEN];
88 void (*fill_helper)(struct bpf_test *self);
89 };
90
91 /* Note we want this to be 64 bit aligned so that the end of our array is
92 * actually the end of the structure.
93 */
94 #define MAX_ENTRIES 11
95
96 struct test_val {
97 unsigned int index;
98 int foo[MAX_ENTRIES];
99 };
100
101 struct other_val {
102 long long foo;
103 long long bar;
104 };
105
106 static void bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
107 {
108 /* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
109 #define PUSH_CNT 51
110 unsigned int len = BPF_MAXINSNS;
111 struct bpf_insn *insn = self->insns;
112 int i = 0, j, k = 0;
113
114 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
115 loop:
116 for (j = 0; j < PUSH_CNT; j++) {
117 insn[i++] = BPF_LD_ABS(BPF_B, 0);
118 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
119 i++;
120 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
121 insn[i++] = BPF_MOV64_IMM(BPF_REG_2, 1);
122 insn[i++] = BPF_MOV64_IMM(BPF_REG_3, 2);
123 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
124 BPF_FUNC_skb_vlan_push),
125 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
126 i++;
127 }
128
129 for (j = 0; j < PUSH_CNT; j++) {
130 insn[i++] = BPF_LD_ABS(BPF_B, 0);
131 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
132 i++;
133 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
134 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
135 BPF_FUNC_skb_vlan_pop),
136 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
137 i++;
138 }
139 if (++k < 5)
140 goto loop;
141
142 for (; i < len - 1; i++)
143 insn[i] = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, 0xbef);
144 insn[len - 1] = BPF_EXIT_INSN();
145 }
146
147 static void bpf_fill_jump_around_ld_abs(struct bpf_test *self)
148 {
149 struct bpf_insn *insn = self->insns;
150 unsigned int len = BPF_MAXINSNS;
151 int i = 0;
152
153 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
154 insn[i++] = BPF_LD_ABS(BPF_B, 0);
155 insn[i] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 10, len - i - 2);
156 i++;
157 while (i < len - 1)
158 insn[i++] = BPF_LD_ABS(BPF_B, 1);
159 insn[i] = BPF_EXIT_INSN();
160 }
161
162 static void bpf_fill_rand_ld_dw(struct bpf_test *self)
163 {
164 struct bpf_insn *insn = self->insns;
165 uint64_t res = 0;
166 int i = 0;
167
168 insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0);
169 while (i < self->retval) {
170 uint64_t val = bpf_semi_rand_get();
171 struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) };
172
173 res ^= val;
174 insn[i++] = tmp[0];
175 insn[i++] = tmp[1];
176 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
177 }
178 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
179 insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32);
180 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
181 insn[i] = BPF_EXIT_INSN();
182 res ^= (res >> 32);
183 self->retval = (uint32_t)res;
184 }
185
186 /* BPF_SK_LOOKUP contains 13 instructions, if you need to fix up maps */
187 #define BPF_SK_LOOKUP \
188 /* struct bpf_sock_tuple tuple = {} */ \
189 BPF_MOV64_IMM(BPF_REG_2, 0), \
190 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8), \
191 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -16), \
192 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -24), \
193 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -32), \
194 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -40), \
195 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -48), \
196 /* sk = sk_lookup_tcp(ctx, &tuple, sizeof tuple, 0, 0) */ \
197 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), \
198 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48), \
199 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct bpf_sock_tuple)), \
200 BPF_MOV64_IMM(BPF_REG_4, 0), \
201 BPF_MOV64_IMM(BPF_REG_5, 0), \
202 BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp)
203
204 static struct bpf_test tests[] = {
205 {
206 "add+sub+mul",
207 .insns = {
208 BPF_MOV64_IMM(BPF_REG_1, 1),
209 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
210 BPF_MOV64_IMM(BPF_REG_2, 3),
211 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
213 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
214 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
215 BPF_EXIT_INSN(),
216 },
217 .result = ACCEPT,
218 .retval = -3,
219 },
220 {
221 "DIV32 by 0, zero check 1",
222 .insns = {
223 BPF_MOV32_IMM(BPF_REG_0, 42),
224 BPF_MOV32_IMM(BPF_REG_1, 0),
225 BPF_MOV32_IMM(BPF_REG_2, 1),
226 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
227 BPF_EXIT_INSN(),
228 },
229 .result = ACCEPT,
230 .retval = 42,
231 },
232 {
233 "DIV32 by 0, zero check 2",
234 .insns = {
235 BPF_MOV32_IMM(BPF_REG_0, 42),
236 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
237 BPF_MOV32_IMM(BPF_REG_2, 1),
238 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
239 BPF_EXIT_INSN(),
240 },
241 .result = ACCEPT,
242 .retval = 42,
243 },
244 {
245 "DIV64 by 0, zero check",
246 .insns = {
247 BPF_MOV32_IMM(BPF_REG_0, 42),
248 BPF_MOV32_IMM(BPF_REG_1, 0),
249 BPF_MOV32_IMM(BPF_REG_2, 1),
250 BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
251 BPF_EXIT_INSN(),
252 },
253 .result = ACCEPT,
254 .retval = 42,
255 },
256 {
257 "MOD32 by 0, zero check 1",
258 .insns = {
259 BPF_MOV32_IMM(BPF_REG_0, 42),
260 BPF_MOV32_IMM(BPF_REG_1, 0),
261 BPF_MOV32_IMM(BPF_REG_2, 1),
262 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
263 BPF_EXIT_INSN(),
264 },
265 .result = ACCEPT,
266 .retval = 42,
267 },
268 {
269 "MOD32 by 0, zero check 2",
270 .insns = {
271 BPF_MOV32_IMM(BPF_REG_0, 42),
272 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
273 BPF_MOV32_IMM(BPF_REG_2, 1),
274 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
275 BPF_EXIT_INSN(),
276 },
277 .result = ACCEPT,
278 .retval = 42,
279 },
280 {
281 "MOD64 by 0, zero check",
282 .insns = {
283 BPF_MOV32_IMM(BPF_REG_0, 42),
284 BPF_MOV32_IMM(BPF_REG_1, 0),
285 BPF_MOV32_IMM(BPF_REG_2, 1),
286 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
287 BPF_EXIT_INSN(),
288 },
289 .result = ACCEPT,
290 .retval = 42,
291 },
292 {
293 "DIV32 by 0, zero check ok, cls",
294 .insns = {
295 BPF_MOV32_IMM(BPF_REG_0, 42),
296 BPF_MOV32_IMM(BPF_REG_1, 2),
297 BPF_MOV32_IMM(BPF_REG_2, 16),
298 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
299 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
300 BPF_EXIT_INSN(),
301 },
302 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
303 .result = ACCEPT,
304 .retval = 8,
305 },
306 {
307 "DIV32 by 0, zero check 1, cls",
308 .insns = {
309 BPF_MOV32_IMM(BPF_REG_1, 0),
310 BPF_MOV32_IMM(BPF_REG_0, 1),
311 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
312 BPF_EXIT_INSN(),
313 },
314 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
315 .result = ACCEPT,
316 .retval = 0,
317 },
318 {
319 "DIV32 by 0, zero check 2, cls",
320 .insns = {
321 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
322 BPF_MOV32_IMM(BPF_REG_0, 1),
323 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
324 BPF_EXIT_INSN(),
325 },
326 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
327 .result = ACCEPT,
328 .retval = 0,
329 },
330 {
331 "DIV64 by 0, zero check, cls",
332 .insns = {
333 BPF_MOV32_IMM(BPF_REG_1, 0),
334 BPF_MOV32_IMM(BPF_REG_0, 1),
335 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
336 BPF_EXIT_INSN(),
337 },
338 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
339 .result = ACCEPT,
340 .retval = 0,
341 },
342 {
343 "MOD32 by 0, zero check ok, cls",
344 .insns = {
345 BPF_MOV32_IMM(BPF_REG_0, 42),
346 BPF_MOV32_IMM(BPF_REG_1, 3),
347 BPF_MOV32_IMM(BPF_REG_2, 5),
348 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
349 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
350 BPF_EXIT_INSN(),
351 },
352 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
353 .result = ACCEPT,
354 .retval = 2,
355 },
356 {
357 "MOD32 by 0, zero check 1, cls",
358 .insns = {
359 BPF_MOV32_IMM(BPF_REG_1, 0),
360 BPF_MOV32_IMM(BPF_REG_0, 1),
361 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
362 BPF_EXIT_INSN(),
363 },
364 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
365 .result = ACCEPT,
366 .retval = 1,
367 },
368 {
369 "MOD32 by 0, zero check 2, cls",
370 .insns = {
371 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
372 BPF_MOV32_IMM(BPF_REG_0, 1),
373 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
374 BPF_EXIT_INSN(),
375 },
376 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
377 .result = ACCEPT,
378 .retval = 1,
379 },
380 {
381 "MOD64 by 0, zero check 1, cls",
382 .insns = {
383 BPF_MOV32_IMM(BPF_REG_1, 0),
384 BPF_MOV32_IMM(BPF_REG_0, 2),
385 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
386 BPF_EXIT_INSN(),
387 },
388 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
389 .result = ACCEPT,
390 .retval = 2,
391 },
392 {
393 "MOD64 by 0, zero check 2, cls",
394 .insns = {
395 BPF_MOV32_IMM(BPF_REG_1, 0),
396 BPF_MOV32_IMM(BPF_REG_0, -1),
397 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
398 BPF_EXIT_INSN(),
399 },
400 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
401 .result = ACCEPT,
402 .retval = -1,
403 },
404 /* Just make sure that JITs used udiv/umod as otherwise we get
405 * an exception from INT_MIN/-1 overflow similarly as with div
406 * by zero.
407 */
408 {
409 "DIV32 overflow, check 1",
410 .insns = {
411 BPF_MOV32_IMM(BPF_REG_1, -1),
412 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
413 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
414 BPF_EXIT_INSN(),
415 },
416 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
417 .result = ACCEPT,
418 .retval = 0,
419 },
420 {
421 "DIV32 overflow, check 2",
422 .insns = {
423 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
424 BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
425 BPF_EXIT_INSN(),
426 },
427 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
428 .result = ACCEPT,
429 .retval = 0,
430 },
431 {
432 "DIV64 overflow, check 1",
433 .insns = {
434 BPF_MOV64_IMM(BPF_REG_1, -1),
435 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
436 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
437 BPF_EXIT_INSN(),
438 },
439 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
440 .result = ACCEPT,
441 .retval = 0,
442 },
443 {
444 "DIV64 overflow, check 2",
445 .insns = {
446 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
447 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
448 BPF_EXIT_INSN(),
449 },
450 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
451 .result = ACCEPT,
452 .retval = 0,
453 },
454 {
455 "MOD32 overflow, check 1",
456 .insns = {
457 BPF_MOV32_IMM(BPF_REG_1, -1),
458 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
459 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
460 BPF_EXIT_INSN(),
461 },
462 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
463 .result = ACCEPT,
464 .retval = INT_MIN,
465 },
466 {
467 "MOD32 overflow, check 2",
468 .insns = {
469 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
470 BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
471 BPF_EXIT_INSN(),
472 },
473 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
474 .result = ACCEPT,
475 .retval = INT_MIN,
476 },
477 {
478 "MOD64 overflow, check 1",
479 .insns = {
480 BPF_MOV64_IMM(BPF_REG_1, -1),
481 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
482 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
483 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
484 BPF_MOV32_IMM(BPF_REG_0, 0),
485 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
486 BPF_MOV32_IMM(BPF_REG_0, 1),
487 BPF_EXIT_INSN(),
488 },
489 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
490 .result = ACCEPT,
491 .retval = 1,
492 },
493 {
494 "MOD64 overflow, check 2",
495 .insns = {
496 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
497 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
498 BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
499 BPF_MOV32_IMM(BPF_REG_0, 0),
500 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
501 BPF_MOV32_IMM(BPF_REG_0, 1),
502 BPF_EXIT_INSN(),
503 },
504 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
505 .result = ACCEPT,
506 .retval = 1,
507 },
508 {
509 "xor32 zero extend check",
510 .insns = {
511 BPF_MOV32_IMM(BPF_REG_2, -1),
512 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
513 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
514 BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
515 BPF_MOV32_IMM(BPF_REG_0, 2),
516 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
517 BPF_MOV32_IMM(BPF_REG_0, 1),
518 BPF_EXIT_INSN(),
519 },
520 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
521 .result = ACCEPT,
522 .retval = 1,
523 },
524 {
525 "empty prog",
526 .insns = {
527 },
528 .errstr = "unknown opcode 00",
529 .result = REJECT,
530 },
531 {
532 "only exit insn",
533 .insns = {
534 BPF_EXIT_INSN(),
535 },
536 .errstr = "R0 !read_ok",
537 .result = REJECT,
538 },
539 {
540 "unreachable",
541 .insns = {
542 BPF_EXIT_INSN(),
543 BPF_EXIT_INSN(),
544 },
545 .errstr = "unreachable",
546 .result = REJECT,
547 },
548 {
549 "unreachable2",
550 .insns = {
551 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
552 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
553 BPF_EXIT_INSN(),
554 },
555 .errstr = "unreachable",
556 .result = REJECT,
557 },
558 {
559 "out of range jump",
560 .insns = {
561 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
562 BPF_EXIT_INSN(),
563 },
564 .errstr = "jump out of range",
565 .result = REJECT,
566 },
567 {
568 "out of range jump2",
569 .insns = {
570 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
571 BPF_EXIT_INSN(),
572 },
573 .errstr = "jump out of range",
574 .result = REJECT,
575 },
576 {
577 "test1 ld_imm64",
578 .insns = {
579 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
580 BPF_LD_IMM64(BPF_REG_0, 0),
581 BPF_LD_IMM64(BPF_REG_0, 0),
582 BPF_LD_IMM64(BPF_REG_0, 1),
583 BPF_LD_IMM64(BPF_REG_0, 1),
584 BPF_MOV64_IMM(BPF_REG_0, 2),
585 BPF_EXIT_INSN(),
586 },
587 .errstr = "invalid BPF_LD_IMM insn",
588 .errstr_unpriv = "R1 pointer comparison",
589 .result = REJECT,
590 },
591 {
592 "test2 ld_imm64",
593 .insns = {
594 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
595 BPF_LD_IMM64(BPF_REG_0, 0),
596 BPF_LD_IMM64(BPF_REG_0, 0),
597 BPF_LD_IMM64(BPF_REG_0, 1),
598 BPF_LD_IMM64(BPF_REG_0, 1),
599 BPF_EXIT_INSN(),
600 },
601 .errstr = "invalid BPF_LD_IMM insn",
602 .errstr_unpriv = "R1 pointer comparison",
603 .result = REJECT,
604 },
605 {
606 "test3 ld_imm64",
607 .insns = {
608 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
609 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
610 BPF_LD_IMM64(BPF_REG_0, 0),
611 BPF_LD_IMM64(BPF_REG_0, 0),
612 BPF_LD_IMM64(BPF_REG_0, 1),
613 BPF_LD_IMM64(BPF_REG_0, 1),
614 BPF_EXIT_INSN(),
615 },
616 .errstr = "invalid bpf_ld_imm64 insn",
617 .result = REJECT,
618 },
619 {
620 "test4 ld_imm64",
621 .insns = {
622 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
623 BPF_EXIT_INSN(),
624 },
625 .errstr = "invalid bpf_ld_imm64 insn",
626 .result = REJECT,
627 },
628 {
629 "test5 ld_imm64",
630 .insns = {
631 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
632 },
633 .errstr = "invalid bpf_ld_imm64 insn",
634 .result = REJECT,
635 },
636 {
637 "test6 ld_imm64",
638 .insns = {
639 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
640 BPF_RAW_INSN(0, 0, 0, 0, 0),
641 BPF_EXIT_INSN(),
642 },
643 .result = ACCEPT,
644 },
645 {
646 "test7 ld_imm64",
647 .insns = {
648 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
649 BPF_RAW_INSN(0, 0, 0, 0, 1),
650 BPF_EXIT_INSN(),
651 },
652 .result = ACCEPT,
653 .retval = 1,
654 },
655 {
656 "test8 ld_imm64",
657 .insns = {
658 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
659 BPF_RAW_INSN(0, 0, 0, 0, 1),
660 BPF_EXIT_INSN(),
661 },
662 .errstr = "uses reserved fields",
663 .result = REJECT,
664 },
665 {
666 "test9 ld_imm64",
667 .insns = {
668 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
669 BPF_RAW_INSN(0, 0, 0, 1, 1),
670 BPF_EXIT_INSN(),
671 },
672 .errstr = "invalid bpf_ld_imm64 insn",
673 .result = REJECT,
674 },
675 {
676 "test10 ld_imm64",
677 .insns = {
678 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
679 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
680 BPF_EXIT_INSN(),
681 },
682 .errstr = "invalid bpf_ld_imm64 insn",
683 .result = REJECT,
684 },
685 {
686 "test11 ld_imm64",
687 .insns = {
688 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 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 "test12 ld_imm64",
697 .insns = {
698 BPF_MOV64_IMM(BPF_REG_1, 0),
699 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
700 BPF_RAW_INSN(0, 0, 0, 0, 1),
701 BPF_EXIT_INSN(),
702 },
703 .errstr = "not pointing to valid bpf_map",
704 .result = REJECT,
705 },
706 {
707 "test13 ld_imm64",
708 .insns = {
709 BPF_MOV64_IMM(BPF_REG_1, 0),
710 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
711 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
712 BPF_EXIT_INSN(),
713 },
714 .errstr = "invalid bpf_ld_imm64 insn",
715 .result = REJECT,
716 },
717 {
718 "arsh32 on imm",
719 .insns = {
720 BPF_MOV64_IMM(BPF_REG_0, 1),
721 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
722 BPF_EXIT_INSN(),
723 },
724 .result = REJECT,
725 .errstr = "unknown opcode c4",
726 },
727 {
728 "arsh32 on reg",
729 .insns = {
730 BPF_MOV64_IMM(BPF_REG_0, 1),
731 BPF_MOV64_IMM(BPF_REG_1, 5),
732 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
733 BPF_EXIT_INSN(),
734 },
735 .result = REJECT,
736 .errstr = "unknown opcode cc",
737 },
738 {
739 "arsh64 on imm",
740 .insns = {
741 BPF_MOV64_IMM(BPF_REG_0, 1),
742 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
743 BPF_EXIT_INSN(),
744 },
745 .result = ACCEPT,
746 },
747 {
748 "arsh64 on reg",
749 .insns = {
750 BPF_MOV64_IMM(BPF_REG_0, 1),
751 BPF_MOV64_IMM(BPF_REG_1, 5),
752 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
753 BPF_EXIT_INSN(),
754 },
755 .result = ACCEPT,
756 },
757 {
758 "no bpf_exit",
759 .insns = {
760 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
761 },
762 .errstr = "not an exit",
763 .result = REJECT,
764 },
765 {
766 "loop (back-edge)",
767 .insns = {
768 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
769 BPF_EXIT_INSN(),
770 },
771 .errstr = "back-edge",
772 .result = REJECT,
773 },
774 {
775 "loop2 (back-edge)",
776 .insns = {
777 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
778 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
779 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
780 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
781 BPF_EXIT_INSN(),
782 },
783 .errstr = "back-edge",
784 .result = REJECT,
785 },
786 {
787 "conditional loop",
788 .insns = {
789 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
790 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
791 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
792 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
793 BPF_EXIT_INSN(),
794 },
795 .errstr = "back-edge",
796 .result = REJECT,
797 },
798 {
799 "read uninitialized register",
800 .insns = {
801 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
802 BPF_EXIT_INSN(),
803 },
804 .errstr = "R2 !read_ok",
805 .result = REJECT,
806 },
807 {
808 "read invalid register",
809 .insns = {
810 BPF_MOV64_REG(BPF_REG_0, -1),
811 BPF_EXIT_INSN(),
812 },
813 .errstr = "R15 is invalid",
814 .result = REJECT,
815 },
816 {
817 "program doesn't init R0 before exit",
818 .insns = {
819 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
820 BPF_EXIT_INSN(),
821 },
822 .errstr = "R0 !read_ok",
823 .result = REJECT,
824 },
825 {
826 "program doesn't init R0 before exit in all branches",
827 .insns = {
828 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
829 BPF_MOV64_IMM(BPF_REG_0, 1),
830 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
831 BPF_EXIT_INSN(),
832 },
833 .errstr = "R0 !read_ok",
834 .errstr_unpriv = "R1 pointer comparison",
835 .result = REJECT,
836 },
837 {
838 "stack out of bounds",
839 .insns = {
840 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
841 BPF_EXIT_INSN(),
842 },
843 .errstr = "invalid stack",
844 .result = REJECT,
845 },
846 {
847 "invalid call insn1",
848 .insns = {
849 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
850 BPF_EXIT_INSN(),
851 },
852 .errstr = "unknown opcode 8d",
853 .result = REJECT,
854 },
855 {
856 "invalid call insn2",
857 .insns = {
858 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
859 BPF_EXIT_INSN(),
860 },
861 .errstr = "BPF_CALL uses reserved",
862 .result = REJECT,
863 },
864 {
865 "invalid function call",
866 .insns = {
867 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
868 BPF_EXIT_INSN(),
869 },
870 .errstr = "invalid func unknown#1234567",
871 .result = REJECT,
872 },
873 {
874 "uninitialized stack1",
875 .insns = {
876 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
878 BPF_LD_MAP_FD(BPF_REG_1, 0),
879 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
880 BPF_FUNC_map_lookup_elem),
881 BPF_EXIT_INSN(),
882 },
883 .fixup_map_hash_8b = { 2 },
884 .errstr = "invalid indirect read from stack",
885 .result = REJECT,
886 },
887 {
888 "uninitialized stack2",
889 .insns = {
890 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
891 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
892 BPF_EXIT_INSN(),
893 },
894 .errstr = "invalid read from stack",
895 .result = REJECT,
896 },
897 {
898 "invalid fp arithmetic",
899 /* If this gets ever changed, make sure JITs can deal with it. */
900 .insns = {
901 BPF_MOV64_IMM(BPF_REG_0, 0),
902 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
903 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
904 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
905 BPF_EXIT_INSN(),
906 },
907 .errstr = "R1 subtraction from stack pointer",
908 .result = REJECT,
909 },
910 {
911 "non-invalid fp arithmetic",
912 .insns = {
913 BPF_MOV64_IMM(BPF_REG_0, 0),
914 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
915 BPF_EXIT_INSN(),
916 },
917 .result = ACCEPT,
918 },
919 {
920 "invalid argument register",
921 .insns = {
922 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
923 BPF_FUNC_get_cgroup_classid),
924 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
925 BPF_FUNC_get_cgroup_classid),
926 BPF_EXIT_INSN(),
927 },
928 .errstr = "R1 !read_ok",
929 .result = REJECT,
930 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
931 },
932 {
933 "non-invalid argument register",
934 .insns = {
935 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
936 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
937 BPF_FUNC_get_cgroup_classid),
938 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
939 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
940 BPF_FUNC_get_cgroup_classid),
941 BPF_EXIT_INSN(),
942 },
943 .result = ACCEPT,
944 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
945 },
946 {
947 "check valid spill/fill",
948 .insns = {
949 /* spill R1(ctx) into stack */
950 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
951 /* fill it back into R2 */
952 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
953 /* should be able to access R0 = *(R2 + 8) */
954 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
955 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
956 BPF_EXIT_INSN(),
957 },
958 .errstr_unpriv = "R0 leaks addr",
959 .result = ACCEPT,
960 .result_unpriv = REJECT,
961 .retval = POINTER_VALUE,
962 },
963 {
964 "check valid spill/fill, skb mark",
965 .insns = {
966 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
967 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
968 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
969 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
970 offsetof(struct __sk_buff, mark)),
971 BPF_EXIT_INSN(),
972 },
973 .result = ACCEPT,
974 .result_unpriv = ACCEPT,
975 },
976 {
977 "check corrupted spill/fill",
978 .insns = {
979 /* spill R1(ctx) into stack */
980 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
981 /* mess up with R1 pointer on stack */
982 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
983 /* fill back into R0 should fail */
984 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
985 BPF_EXIT_INSN(),
986 },
987 .errstr_unpriv = "attempt to corrupt spilled",
988 .errstr = "corrupted spill",
989 .result = REJECT,
990 },
991 {
992 "invalid src register in STX",
993 .insns = {
994 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
995 BPF_EXIT_INSN(),
996 },
997 .errstr = "R15 is invalid",
998 .result = REJECT,
999 },
1000 {
1001 "invalid dst register in STX",
1002 .insns = {
1003 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
1004 BPF_EXIT_INSN(),
1005 },
1006 .errstr = "R14 is invalid",
1007 .result = REJECT,
1008 },
1009 {
1010 "invalid dst register in ST",
1011 .insns = {
1012 BPF_ST_MEM(BPF_B, 14, -1, -1),
1013 BPF_EXIT_INSN(),
1014 },
1015 .errstr = "R14 is invalid",
1016 .result = REJECT,
1017 },
1018 {
1019 "invalid src register in LDX",
1020 .insns = {
1021 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
1022 BPF_EXIT_INSN(),
1023 },
1024 .errstr = "R12 is invalid",
1025 .result = REJECT,
1026 },
1027 {
1028 "invalid dst register in LDX",
1029 .insns = {
1030 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
1031 BPF_EXIT_INSN(),
1032 },
1033 .errstr = "R11 is invalid",
1034 .result = REJECT,
1035 },
1036 {
1037 "junk insn",
1038 .insns = {
1039 BPF_RAW_INSN(0, 0, 0, 0, 0),
1040 BPF_EXIT_INSN(),
1041 },
1042 .errstr = "unknown opcode 00",
1043 .result = REJECT,
1044 },
1045 {
1046 "junk insn2",
1047 .insns = {
1048 BPF_RAW_INSN(1, 0, 0, 0, 0),
1049 BPF_EXIT_INSN(),
1050 },
1051 .errstr = "BPF_LDX uses reserved fields",
1052 .result = REJECT,
1053 },
1054 {
1055 "junk insn3",
1056 .insns = {
1057 BPF_RAW_INSN(-1, 0, 0, 0, 0),
1058 BPF_EXIT_INSN(),
1059 },
1060 .errstr = "unknown opcode ff",
1061 .result = REJECT,
1062 },
1063 {
1064 "junk insn4",
1065 .insns = {
1066 BPF_RAW_INSN(-1, -1, -1, -1, -1),
1067 BPF_EXIT_INSN(),
1068 },
1069 .errstr = "unknown opcode ff",
1070 .result = REJECT,
1071 },
1072 {
1073 "junk insn5",
1074 .insns = {
1075 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
1076 BPF_EXIT_INSN(),
1077 },
1078 .errstr = "BPF_ALU uses reserved fields",
1079 .result = REJECT,
1080 },
1081 {
1082 "misaligned read from stack",
1083 .insns = {
1084 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1085 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
1086 BPF_EXIT_INSN(),
1087 },
1088 .errstr = "misaligned stack access",
1089 .result = REJECT,
1090 },
1091 {
1092 "invalid map_fd for function call",
1093 .insns = {
1094 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1095 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
1096 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1097 BPF_LD_MAP_FD(BPF_REG_1, 0),
1098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1099 BPF_FUNC_map_delete_elem),
1100 BPF_EXIT_INSN(),
1101 },
1102 .errstr = "fd 0 is not pointing to valid bpf_map",
1103 .result = REJECT,
1104 },
1105 {
1106 "don't check return value before access",
1107 .insns = {
1108 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1109 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1110 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1111 BPF_LD_MAP_FD(BPF_REG_1, 0),
1112 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1113 BPF_FUNC_map_lookup_elem),
1114 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1115 BPF_EXIT_INSN(),
1116 },
1117 .fixup_map_hash_8b = { 3 },
1118 .errstr = "R0 invalid mem access 'map_value_or_null'",
1119 .result = REJECT,
1120 },
1121 {
1122 "access memory with incorrect alignment",
1123 .insns = {
1124 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1125 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1126 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1127 BPF_LD_MAP_FD(BPF_REG_1, 0),
1128 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1129 BPF_FUNC_map_lookup_elem),
1130 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1131 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
1132 BPF_EXIT_INSN(),
1133 },
1134 .fixup_map_hash_8b = { 3 },
1135 .errstr = "misaligned value access",
1136 .result = REJECT,
1137 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1138 },
1139 {
1140 "sometimes access memory with incorrect alignment",
1141 .insns = {
1142 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1143 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1144 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1145 BPF_LD_MAP_FD(BPF_REG_1, 0),
1146 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1147 BPF_FUNC_map_lookup_elem),
1148 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1149 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1150 BPF_EXIT_INSN(),
1151 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
1152 BPF_EXIT_INSN(),
1153 },
1154 .fixup_map_hash_8b = { 3 },
1155 .errstr = "R0 invalid mem access",
1156 .errstr_unpriv = "R0 leaks addr",
1157 .result = REJECT,
1158 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1159 },
1160 {
1161 "jump test 1",
1162 .insns = {
1163 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1164 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
1165 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1166 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1167 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
1168 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
1169 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
1170 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
1171 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
1172 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
1173 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
1174 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
1175 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1176 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
1177 BPF_MOV64_IMM(BPF_REG_0, 0),
1178 BPF_EXIT_INSN(),
1179 },
1180 .errstr_unpriv = "R1 pointer comparison",
1181 .result_unpriv = REJECT,
1182 .result = ACCEPT,
1183 },
1184 {
1185 "jump test 2",
1186 .insns = {
1187 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1188 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
1189 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1190 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
1191 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
1192 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1193 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1194 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
1195 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1196 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
1197 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
1198 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1199 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
1200 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
1201 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1202 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1203 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1204 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1205 BPF_MOV64_IMM(BPF_REG_0, 0),
1206 BPF_EXIT_INSN(),
1207 },
1208 .errstr_unpriv = "R1 pointer comparison",
1209 .result_unpriv = REJECT,
1210 .result = ACCEPT,
1211 },
1212 {
1213 "jump test 3",
1214 .insns = {
1215 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1216 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1217 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1219 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
1220 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
1221 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1223 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
1224 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
1225 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1226 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
1227 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1228 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
1229 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1230 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
1231 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
1232 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
1233 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
1235 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1236 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
1237 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
1239 BPF_LD_MAP_FD(BPF_REG_1, 0),
1240 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1241 BPF_FUNC_map_delete_elem),
1242 BPF_EXIT_INSN(),
1243 },
1244 .fixup_map_hash_8b = { 24 },
1245 .errstr_unpriv = "R1 pointer comparison",
1246 .result_unpriv = REJECT,
1247 .result = ACCEPT,
1248 .retval = -ENOENT,
1249 },
1250 {
1251 "jump test 4",
1252 .insns = {
1253 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1254 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1255 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1257 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1260 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1261 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1262 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1264 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1265 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1266 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1268 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1269 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1270 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1271 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1272 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1273 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1274 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1275 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1276 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1277 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1278 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1279 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1280 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1281 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1282 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1283 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1284 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1285 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1286 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1287 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1288 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1289 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1290 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1291 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1292 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1293 BPF_MOV64_IMM(BPF_REG_0, 0),
1294 BPF_EXIT_INSN(),
1295 },
1296 .errstr_unpriv = "R1 pointer comparison",
1297 .result_unpriv = REJECT,
1298 .result = ACCEPT,
1299 },
1300 {
1301 "jump test 5",
1302 .insns = {
1303 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1304 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1305 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1306 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1307 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1308 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1309 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1310 BPF_MOV64_IMM(BPF_REG_0, 0),
1311 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1312 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1313 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1314 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1315 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1316 BPF_MOV64_IMM(BPF_REG_0, 0),
1317 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1318 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1319 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1320 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1321 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1322 BPF_MOV64_IMM(BPF_REG_0, 0),
1323 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1324 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1325 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1326 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1327 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1328 BPF_MOV64_IMM(BPF_REG_0, 0),
1329 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1330 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1331 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1332 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1333 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1334 BPF_MOV64_IMM(BPF_REG_0, 0),
1335 BPF_EXIT_INSN(),
1336 },
1337 .errstr_unpriv = "R1 pointer comparison",
1338 .result_unpriv = REJECT,
1339 .result = ACCEPT,
1340 },
1341 {
1342 "access skb fields ok",
1343 .insns = {
1344 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1345 offsetof(struct __sk_buff, len)),
1346 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1347 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1348 offsetof(struct __sk_buff, mark)),
1349 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1350 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1351 offsetof(struct __sk_buff, pkt_type)),
1352 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1353 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1354 offsetof(struct __sk_buff, queue_mapping)),
1355 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1356 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1357 offsetof(struct __sk_buff, protocol)),
1358 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1359 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1360 offsetof(struct __sk_buff, vlan_present)),
1361 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1362 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1363 offsetof(struct __sk_buff, vlan_tci)),
1364 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1365 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1366 offsetof(struct __sk_buff, napi_id)),
1367 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1368 BPF_EXIT_INSN(),
1369 },
1370 .result = ACCEPT,
1371 },
1372 {
1373 "access skb fields bad1",
1374 .insns = {
1375 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
1376 BPF_EXIT_INSN(),
1377 },
1378 .errstr = "invalid bpf_context access",
1379 .result = REJECT,
1380 },
1381 {
1382 "access skb fields bad2",
1383 .insns = {
1384 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
1385 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1386 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1387 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1388 BPF_LD_MAP_FD(BPF_REG_1, 0),
1389 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1390 BPF_FUNC_map_lookup_elem),
1391 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1392 BPF_EXIT_INSN(),
1393 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1394 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1395 offsetof(struct __sk_buff, pkt_type)),
1396 BPF_EXIT_INSN(),
1397 },
1398 .fixup_map_hash_8b = { 4 },
1399 .errstr = "different pointers",
1400 .errstr_unpriv = "R1 pointer comparison",
1401 .result = REJECT,
1402 },
1403 {
1404 "access skb fields bad3",
1405 .insns = {
1406 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1407 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1408 offsetof(struct __sk_buff, pkt_type)),
1409 BPF_EXIT_INSN(),
1410 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1411 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1413 BPF_LD_MAP_FD(BPF_REG_1, 0),
1414 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1415 BPF_FUNC_map_lookup_elem),
1416 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1417 BPF_EXIT_INSN(),
1418 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1419 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
1420 },
1421 .fixup_map_hash_8b = { 6 },
1422 .errstr = "different pointers",
1423 .errstr_unpriv = "R1 pointer comparison",
1424 .result = REJECT,
1425 },
1426 {
1427 "access skb fields bad4",
1428 .insns = {
1429 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
1430 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1431 offsetof(struct __sk_buff, len)),
1432 BPF_MOV64_IMM(BPF_REG_0, 0),
1433 BPF_EXIT_INSN(),
1434 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1435 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1437 BPF_LD_MAP_FD(BPF_REG_1, 0),
1438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1439 BPF_FUNC_map_lookup_elem),
1440 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1441 BPF_EXIT_INSN(),
1442 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1443 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1444 },
1445 .fixup_map_hash_8b = { 7 },
1446 .errstr = "different pointers",
1447 .errstr_unpriv = "R1 pointer comparison",
1448 .result = REJECT,
1449 },
1450 {
1451 "invalid access __sk_buff family",
1452 .insns = {
1453 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1454 offsetof(struct __sk_buff, family)),
1455 BPF_EXIT_INSN(),
1456 },
1457 .errstr = "invalid bpf_context access",
1458 .result = REJECT,
1459 },
1460 {
1461 "invalid access __sk_buff remote_ip4",
1462 .insns = {
1463 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1464 offsetof(struct __sk_buff, remote_ip4)),
1465 BPF_EXIT_INSN(),
1466 },
1467 .errstr = "invalid bpf_context access",
1468 .result = REJECT,
1469 },
1470 {
1471 "invalid access __sk_buff local_ip4",
1472 .insns = {
1473 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1474 offsetof(struct __sk_buff, local_ip4)),
1475 BPF_EXIT_INSN(),
1476 },
1477 .errstr = "invalid bpf_context access",
1478 .result = REJECT,
1479 },
1480 {
1481 "invalid access __sk_buff remote_ip6",
1482 .insns = {
1483 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1484 offsetof(struct __sk_buff, remote_ip6)),
1485 BPF_EXIT_INSN(),
1486 },
1487 .errstr = "invalid bpf_context access",
1488 .result = REJECT,
1489 },
1490 {
1491 "invalid access __sk_buff local_ip6",
1492 .insns = {
1493 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1494 offsetof(struct __sk_buff, local_ip6)),
1495 BPF_EXIT_INSN(),
1496 },
1497 .errstr = "invalid bpf_context access",
1498 .result = REJECT,
1499 },
1500 {
1501 "invalid access __sk_buff remote_port",
1502 .insns = {
1503 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1504 offsetof(struct __sk_buff, remote_port)),
1505 BPF_EXIT_INSN(),
1506 },
1507 .errstr = "invalid bpf_context access",
1508 .result = REJECT,
1509 },
1510 {
1511 "invalid access __sk_buff remote_port",
1512 .insns = {
1513 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1514 offsetof(struct __sk_buff, local_port)),
1515 BPF_EXIT_INSN(),
1516 },
1517 .errstr = "invalid bpf_context access",
1518 .result = REJECT,
1519 },
1520 {
1521 "valid access __sk_buff family",
1522 .insns = {
1523 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1524 offsetof(struct __sk_buff, family)),
1525 BPF_EXIT_INSN(),
1526 },
1527 .result = ACCEPT,
1528 .prog_type = BPF_PROG_TYPE_SK_SKB,
1529 },
1530 {
1531 "valid access __sk_buff remote_ip4",
1532 .insns = {
1533 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1534 offsetof(struct __sk_buff, remote_ip4)),
1535 BPF_EXIT_INSN(),
1536 },
1537 .result = ACCEPT,
1538 .prog_type = BPF_PROG_TYPE_SK_SKB,
1539 },
1540 {
1541 "valid access __sk_buff local_ip4",
1542 .insns = {
1543 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1544 offsetof(struct __sk_buff, local_ip4)),
1545 BPF_EXIT_INSN(),
1546 },
1547 .result = ACCEPT,
1548 .prog_type = BPF_PROG_TYPE_SK_SKB,
1549 },
1550 {
1551 "valid access __sk_buff remote_ip6",
1552 .insns = {
1553 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1554 offsetof(struct __sk_buff, remote_ip6[0])),
1555 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1556 offsetof(struct __sk_buff, remote_ip6[1])),
1557 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1558 offsetof(struct __sk_buff, remote_ip6[2])),
1559 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1560 offsetof(struct __sk_buff, remote_ip6[3])),
1561 BPF_EXIT_INSN(),
1562 },
1563 .result = ACCEPT,
1564 .prog_type = BPF_PROG_TYPE_SK_SKB,
1565 },
1566 {
1567 "valid access __sk_buff local_ip6",
1568 .insns = {
1569 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1570 offsetof(struct __sk_buff, local_ip6[0])),
1571 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1572 offsetof(struct __sk_buff, local_ip6[1])),
1573 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1574 offsetof(struct __sk_buff, local_ip6[2])),
1575 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1576 offsetof(struct __sk_buff, local_ip6[3])),
1577 BPF_EXIT_INSN(),
1578 },
1579 .result = ACCEPT,
1580 .prog_type = BPF_PROG_TYPE_SK_SKB,
1581 },
1582 {
1583 "valid access __sk_buff remote_port",
1584 .insns = {
1585 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1586 offsetof(struct __sk_buff, remote_port)),
1587 BPF_EXIT_INSN(),
1588 },
1589 .result = ACCEPT,
1590 .prog_type = BPF_PROG_TYPE_SK_SKB,
1591 },
1592 {
1593 "valid access __sk_buff remote_port",
1594 .insns = {
1595 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1596 offsetof(struct __sk_buff, local_port)),
1597 BPF_EXIT_INSN(),
1598 },
1599 .result = ACCEPT,
1600 .prog_type = BPF_PROG_TYPE_SK_SKB,
1601 },
1602 {
1603 "invalid access of tc_classid for SK_SKB",
1604 .insns = {
1605 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1606 offsetof(struct __sk_buff, tc_classid)),
1607 BPF_EXIT_INSN(),
1608 },
1609 .result = REJECT,
1610 .prog_type = BPF_PROG_TYPE_SK_SKB,
1611 .errstr = "invalid bpf_context access",
1612 },
1613 {
1614 "invalid access of skb->mark for SK_SKB",
1615 .insns = {
1616 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1617 offsetof(struct __sk_buff, mark)),
1618 BPF_EXIT_INSN(),
1619 },
1620 .result = REJECT,
1621 .prog_type = BPF_PROG_TYPE_SK_SKB,
1622 .errstr = "invalid bpf_context access",
1623 },
1624 {
1625 "check skb->mark is not writeable by SK_SKB",
1626 .insns = {
1627 BPF_MOV64_IMM(BPF_REG_0, 0),
1628 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1629 offsetof(struct __sk_buff, mark)),
1630 BPF_EXIT_INSN(),
1631 },
1632 .result = REJECT,
1633 .prog_type = BPF_PROG_TYPE_SK_SKB,
1634 .errstr = "invalid bpf_context access",
1635 },
1636 {
1637 "check skb->tc_index is writeable by SK_SKB",
1638 .insns = {
1639 BPF_MOV64_IMM(BPF_REG_0, 0),
1640 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1641 offsetof(struct __sk_buff, tc_index)),
1642 BPF_EXIT_INSN(),
1643 },
1644 .result = ACCEPT,
1645 .prog_type = BPF_PROG_TYPE_SK_SKB,
1646 },
1647 {
1648 "check skb->priority is writeable by SK_SKB",
1649 .insns = {
1650 BPF_MOV64_IMM(BPF_REG_0, 0),
1651 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1652 offsetof(struct __sk_buff, priority)),
1653 BPF_EXIT_INSN(),
1654 },
1655 .result = ACCEPT,
1656 .prog_type = BPF_PROG_TYPE_SK_SKB,
1657 },
1658 {
1659 "direct packet read for SK_SKB",
1660 .insns = {
1661 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1662 offsetof(struct __sk_buff, data)),
1663 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1664 offsetof(struct __sk_buff, data_end)),
1665 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1666 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1667 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1668 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1669 BPF_MOV64_IMM(BPF_REG_0, 0),
1670 BPF_EXIT_INSN(),
1671 },
1672 .result = ACCEPT,
1673 .prog_type = BPF_PROG_TYPE_SK_SKB,
1674 },
1675 {
1676 "direct packet write for SK_SKB",
1677 .insns = {
1678 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1679 offsetof(struct __sk_buff, data)),
1680 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1681 offsetof(struct __sk_buff, data_end)),
1682 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1683 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1684 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1685 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1686 BPF_MOV64_IMM(BPF_REG_0, 0),
1687 BPF_EXIT_INSN(),
1688 },
1689 .result = ACCEPT,
1690 .prog_type = BPF_PROG_TYPE_SK_SKB,
1691 },
1692 {
1693 "overlapping checks for direct packet access SK_SKB",
1694 .insns = {
1695 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1696 offsetof(struct __sk_buff, data)),
1697 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1698 offsetof(struct __sk_buff, data_end)),
1699 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1700 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1701 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1702 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1703 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1704 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1705 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1706 BPF_MOV64_IMM(BPF_REG_0, 0),
1707 BPF_EXIT_INSN(),
1708 },
1709 .result = ACCEPT,
1710 .prog_type = BPF_PROG_TYPE_SK_SKB,
1711 },
1712 {
1713 "valid access family in SK_MSG",
1714 .insns = {
1715 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1716 offsetof(struct sk_msg_md, family)),
1717 BPF_EXIT_INSN(),
1718 },
1719 .result = ACCEPT,
1720 .prog_type = BPF_PROG_TYPE_SK_MSG,
1721 },
1722 {
1723 "valid access remote_ip4 in SK_MSG",
1724 .insns = {
1725 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1726 offsetof(struct sk_msg_md, remote_ip4)),
1727 BPF_EXIT_INSN(),
1728 },
1729 .result = ACCEPT,
1730 .prog_type = BPF_PROG_TYPE_SK_MSG,
1731 },
1732 {
1733 "valid access local_ip4 in SK_MSG",
1734 .insns = {
1735 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1736 offsetof(struct sk_msg_md, local_ip4)),
1737 BPF_EXIT_INSN(),
1738 },
1739 .result = ACCEPT,
1740 .prog_type = BPF_PROG_TYPE_SK_MSG,
1741 },
1742 {
1743 "valid access remote_port in SK_MSG",
1744 .insns = {
1745 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1746 offsetof(struct sk_msg_md, remote_port)),
1747 BPF_EXIT_INSN(),
1748 },
1749 .result = ACCEPT,
1750 .prog_type = BPF_PROG_TYPE_SK_MSG,
1751 },
1752 {
1753 "valid access local_port in SK_MSG",
1754 .insns = {
1755 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1756 offsetof(struct sk_msg_md, local_port)),
1757 BPF_EXIT_INSN(),
1758 },
1759 .result = ACCEPT,
1760 .prog_type = BPF_PROG_TYPE_SK_MSG,
1761 },
1762 {
1763 "valid access remote_ip6 in SK_MSG",
1764 .insns = {
1765 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1766 offsetof(struct sk_msg_md, remote_ip6[0])),
1767 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1768 offsetof(struct sk_msg_md, remote_ip6[1])),
1769 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1770 offsetof(struct sk_msg_md, remote_ip6[2])),
1771 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1772 offsetof(struct sk_msg_md, remote_ip6[3])),
1773 BPF_EXIT_INSN(),
1774 },
1775 .result = ACCEPT,
1776 .prog_type = BPF_PROG_TYPE_SK_SKB,
1777 },
1778 {
1779 "valid access local_ip6 in SK_MSG",
1780 .insns = {
1781 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1782 offsetof(struct sk_msg_md, local_ip6[0])),
1783 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1784 offsetof(struct sk_msg_md, local_ip6[1])),
1785 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1786 offsetof(struct sk_msg_md, local_ip6[2])),
1787 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1788 offsetof(struct sk_msg_md, local_ip6[3])),
1789 BPF_EXIT_INSN(),
1790 },
1791 .result = ACCEPT,
1792 .prog_type = BPF_PROG_TYPE_SK_SKB,
1793 },
1794 {
1795 "invalid 64B read of family in SK_MSG",
1796 .insns = {
1797 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1798 offsetof(struct sk_msg_md, family)),
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 "invalid read past end of SK_MSG",
1807 .insns = {
1808 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1809 offsetof(struct sk_msg_md, local_port) + 4),
1810 BPF_EXIT_INSN(),
1811 },
1812 .errstr = "R0 !read_ok",
1813 .result = REJECT,
1814 .prog_type = BPF_PROG_TYPE_SK_MSG,
1815 },
1816 {
1817 "invalid read offset in SK_MSG",
1818 .insns = {
1819 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1820 offsetof(struct sk_msg_md, family) + 1),
1821 BPF_EXIT_INSN(),
1822 },
1823 .errstr = "invalid bpf_context access",
1824 .result = REJECT,
1825 .prog_type = BPF_PROG_TYPE_SK_MSG,
1826 },
1827 {
1828 "direct packet read for SK_MSG",
1829 .insns = {
1830 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1831 offsetof(struct sk_msg_md, data)),
1832 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1833 offsetof(struct sk_msg_md, data_end)),
1834 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1835 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1836 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1837 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1838 BPF_MOV64_IMM(BPF_REG_0, 0),
1839 BPF_EXIT_INSN(),
1840 },
1841 .result = ACCEPT,
1842 .prog_type = BPF_PROG_TYPE_SK_MSG,
1843 },
1844 {
1845 "direct packet write for SK_MSG",
1846 .insns = {
1847 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1848 offsetof(struct sk_msg_md, data)),
1849 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1850 offsetof(struct sk_msg_md, data_end)),
1851 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1853 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1854 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1855 BPF_MOV64_IMM(BPF_REG_0, 0),
1856 BPF_EXIT_INSN(),
1857 },
1858 .result = ACCEPT,
1859 .prog_type = BPF_PROG_TYPE_SK_MSG,
1860 },
1861 {
1862 "overlapping checks for direct packet access SK_MSG",
1863 .insns = {
1864 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1865 offsetof(struct sk_msg_md, data)),
1866 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1867 offsetof(struct sk_msg_md, data_end)),
1868 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1869 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1870 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1871 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1872 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1873 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1874 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1875 BPF_MOV64_IMM(BPF_REG_0, 0),
1876 BPF_EXIT_INSN(),
1877 },
1878 .result = ACCEPT,
1879 .prog_type = BPF_PROG_TYPE_SK_MSG,
1880 },
1881 {
1882 "check skb->mark is not writeable by sockets",
1883 .insns = {
1884 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1885 offsetof(struct __sk_buff, mark)),
1886 BPF_EXIT_INSN(),
1887 },
1888 .errstr = "invalid bpf_context access",
1889 .errstr_unpriv = "R1 leaks addr",
1890 .result = REJECT,
1891 },
1892 {
1893 "check skb->tc_index is not writeable by sockets",
1894 .insns = {
1895 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1896 offsetof(struct __sk_buff, tc_index)),
1897 BPF_EXIT_INSN(),
1898 },
1899 .errstr = "invalid bpf_context access",
1900 .errstr_unpriv = "R1 leaks addr",
1901 .result = REJECT,
1902 },
1903 {
1904 "check cb access: byte",
1905 .insns = {
1906 BPF_MOV64_IMM(BPF_REG_0, 0),
1907 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1908 offsetof(struct __sk_buff, cb[0])),
1909 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1910 offsetof(struct __sk_buff, cb[0]) + 1),
1911 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1912 offsetof(struct __sk_buff, cb[0]) + 2),
1913 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1914 offsetof(struct __sk_buff, cb[0]) + 3),
1915 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1916 offsetof(struct __sk_buff, cb[1])),
1917 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1918 offsetof(struct __sk_buff, cb[1]) + 1),
1919 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1920 offsetof(struct __sk_buff, cb[1]) + 2),
1921 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1922 offsetof(struct __sk_buff, cb[1]) + 3),
1923 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1924 offsetof(struct __sk_buff, cb[2])),
1925 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1926 offsetof(struct __sk_buff, cb[2]) + 1),
1927 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1928 offsetof(struct __sk_buff, cb[2]) + 2),
1929 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1930 offsetof(struct __sk_buff, cb[2]) + 3),
1931 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1932 offsetof(struct __sk_buff, cb[3])),
1933 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1934 offsetof(struct __sk_buff, cb[3]) + 1),
1935 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1936 offsetof(struct __sk_buff, cb[3]) + 2),
1937 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1938 offsetof(struct __sk_buff, cb[3]) + 3),
1939 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1940 offsetof(struct __sk_buff, cb[4])),
1941 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1942 offsetof(struct __sk_buff, cb[4]) + 1),
1943 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1944 offsetof(struct __sk_buff, cb[4]) + 2),
1945 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1946 offsetof(struct __sk_buff, cb[4]) + 3),
1947 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1948 offsetof(struct __sk_buff, cb[0])),
1949 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1950 offsetof(struct __sk_buff, cb[0]) + 1),
1951 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1952 offsetof(struct __sk_buff, cb[0]) + 2),
1953 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1954 offsetof(struct __sk_buff, cb[0]) + 3),
1955 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1956 offsetof(struct __sk_buff, cb[1])),
1957 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1958 offsetof(struct __sk_buff, cb[1]) + 1),
1959 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1960 offsetof(struct __sk_buff, cb[1]) + 2),
1961 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1962 offsetof(struct __sk_buff, cb[1]) + 3),
1963 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1964 offsetof(struct __sk_buff, cb[2])),
1965 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1966 offsetof(struct __sk_buff, cb[2]) + 1),
1967 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1968 offsetof(struct __sk_buff, cb[2]) + 2),
1969 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1970 offsetof(struct __sk_buff, cb[2]) + 3),
1971 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1972 offsetof(struct __sk_buff, cb[3])),
1973 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1974 offsetof(struct __sk_buff, cb[3]) + 1),
1975 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1976 offsetof(struct __sk_buff, cb[3]) + 2),
1977 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1978 offsetof(struct __sk_buff, cb[3]) + 3),
1979 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1980 offsetof(struct __sk_buff, cb[4])),
1981 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1982 offsetof(struct __sk_buff, cb[4]) + 1),
1983 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1984 offsetof(struct __sk_buff, cb[4]) + 2),
1985 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1986 offsetof(struct __sk_buff, cb[4]) + 3),
1987 BPF_EXIT_INSN(),
1988 },
1989 .result = ACCEPT,
1990 },
1991 {
1992 "__sk_buff->hash, offset 0, byte store not permitted",
1993 .insns = {
1994 BPF_MOV64_IMM(BPF_REG_0, 0),
1995 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1996 offsetof(struct __sk_buff, hash)),
1997 BPF_EXIT_INSN(),
1998 },
1999 .errstr = "invalid bpf_context access",
2000 .result = REJECT,
2001 },
2002 {
2003 "__sk_buff->tc_index, offset 3, byte store not permitted",
2004 .insns = {
2005 BPF_MOV64_IMM(BPF_REG_0, 0),
2006 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
2007 offsetof(struct __sk_buff, tc_index) + 3),
2008 BPF_EXIT_INSN(),
2009 },
2010 .errstr = "invalid bpf_context access",
2011 .result = REJECT,
2012 },
2013 {
2014 "check skb->hash byte load permitted",
2015 .insns = {
2016 BPF_MOV64_IMM(BPF_REG_0, 0),
2017 #if __BYTE_ORDER == __LITTLE_ENDIAN
2018 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2019 offsetof(struct __sk_buff, hash)),
2020 #else
2021 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2022 offsetof(struct __sk_buff, hash) + 3),
2023 #endif
2024 BPF_EXIT_INSN(),
2025 },
2026 .result = ACCEPT,
2027 },
2028 {
2029 "check skb->hash byte load not permitted 1",
2030 .insns = {
2031 BPF_MOV64_IMM(BPF_REG_0, 0),
2032 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2033 offsetof(struct __sk_buff, hash) + 1),
2034 BPF_EXIT_INSN(),
2035 },
2036 .errstr = "invalid bpf_context access",
2037 .result = REJECT,
2038 },
2039 {
2040 "check skb->hash byte load not permitted 2",
2041 .insns = {
2042 BPF_MOV64_IMM(BPF_REG_0, 0),
2043 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2044 offsetof(struct __sk_buff, hash) + 2),
2045 BPF_EXIT_INSN(),
2046 },
2047 .errstr = "invalid bpf_context access",
2048 .result = REJECT,
2049 },
2050 {
2051 "check skb->hash byte load not permitted 3",
2052 .insns = {
2053 BPF_MOV64_IMM(BPF_REG_0, 0),
2054 #if __BYTE_ORDER == __LITTLE_ENDIAN
2055 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2056 offsetof(struct __sk_buff, hash) + 3),
2057 #else
2058 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2059 offsetof(struct __sk_buff, hash)),
2060 #endif
2061 BPF_EXIT_INSN(),
2062 },
2063 .errstr = "invalid bpf_context access",
2064 .result = REJECT,
2065 },
2066 {
2067 "check cb access: byte, wrong type",
2068 .insns = {
2069 BPF_MOV64_IMM(BPF_REG_0, 0),
2070 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
2071 offsetof(struct __sk_buff, cb[0])),
2072 BPF_EXIT_INSN(),
2073 },
2074 .errstr = "invalid bpf_context access",
2075 .result = REJECT,
2076 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2077 },
2078 {
2079 "check cb access: half",
2080 .insns = {
2081 BPF_MOV64_IMM(BPF_REG_0, 0),
2082 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2083 offsetof(struct __sk_buff, cb[0])),
2084 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2085 offsetof(struct __sk_buff, cb[0]) + 2),
2086 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2087 offsetof(struct __sk_buff, cb[1])),
2088 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2089 offsetof(struct __sk_buff, cb[1]) + 2),
2090 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2091 offsetof(struct __sk_buff, cb[2])),
2092 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2093 offsetof(struct __sk_buff, cb[2]) + 2),
2094 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2095 offsetof(struct __sk_buff, cb[3])),
2096 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2097 offsetof(struct __sk_buff, cb[3]) + 2),
2098 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2099 offsetof(struct __sk_buff, cb[4])),
2100 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2101 offsetof(struct __sk_buff, cb[4]) + 2),
2102 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2103 offsetof(struct __sk_buff, cb[0])),
2104 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2105 offsetof(struct __sk_buff, cb[0]) + 2),
2106 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2107 offsetof(struct __sk_buff, cb[1])),
2108 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2109 offsetof(struct __sk_buff, cb[1]) + 2),
2110 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2111 offsetof(struct __sk_buff, cb[2])),
2112 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2113 offsetof(struct __sk_buff, cb[2]) + 2),
2114 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2115 offsetof(struct __sk_buff, cb[3])),
2116 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2117 offsetof(struct __sk_buff, cb[3]) + 2),
2118 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2119 offsetof(struct __sk_buff, cb[4])),
2120 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2121 offsetof(struct __sk_buff, cb[4]) + 2),
2122 BPF_EXIT_INSN(),
2123 },
2124 .result = ACCEPT,
2125 },
2126 {
2127 "check cb access: half, unaligned",
2128 .insns = {
2129 BPF_MOV64_IMM(BPF_REG_0, 0),
2130 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2131 offsetof(struct __sk_buff, cb[0]) + 1),
2132 BPF_EXIT_INSN(),
2133 },
2134 .errstr = "misaligned context access",
2135 .result = REJECT,
2136 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2137 },
2138 {
2139 "check __sk_buff->hash, offset 0, half store not permitted",
2140 .insns = {
2141 BPF_MOV64_IMM(BPF_REG_0, 0),
2142 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2143 offsetof(struct __sk_buff, hash)),
2144 BPF_EXIT_INSN(),
2145 },
2146 .errstr = "invalid bpf_context access",
2147 .result = REJECT,
2148 },
2149 {
2150 "check __sk_buff->tc_index, offset 2, half store not permitted",
2151 .insns = {
2152 BPF_MOV64_IMM(BPF_REG_0, 0),
2153 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2154 offsetof(struct __sk_buff, tc_index) + 2),
2155 BPF_EXIT_INSN(),
2156 },
2157 .errstr = "invalid bpf_context access",
2158 .result = REJECT,
2159 },
2160 {
2161 "check skb->hash half load permitted",
2162 .insns = {
2163 BPF_MOV64_IMM(BPF_REG_0, 0),
2164 #if __BYTE_ORDER == __LITTLE_ENDIAN
2165 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2166 offsetof(struct __sk_buff, hash)),
2167 #else
2168 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2169 offsetof(struct __sk_buff, hash) + 2),
2170 #endif
2171 BPF_EXIT_INSN(),
2172 },
2173 .result = ACCEPT,
2174 },
2175 {
2176 "check skb->hash half load not permitted",
2177 .insns = {
2178 BPF_MOV64_IMM(BPF_REG_0, 0),
2179 #if __BYTE_ORDER == __LITTLE_ENDIAN
2180 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2181 offsetof(struct __sk_buff, hash) + 2),
2182 #else
2183 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2184 offsetof(struct __sk_buff, hash)),
2185 #endif
2186 BPF_EXIT_INSN(),
2187 },
2188 .errstr = "invalid bpf_context access",
2189 .result = REJECT,
2190 },
2191 {
2192 "check cb access: half, wrong type",
2193 .insns = {
2194 BPF_MOV64_IMM(BPF_REG_0, 0),
2195 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2196 offsetof(struct __sk_buff, cb[0])),
2197 BPF_EXIT_INSN(),
2198 },
2199 .errstr = "invalid bpf_context access",
2200 .result = REJECT,
2201 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2202 },
2203 {
2204 "check cb access: word",
2205 .insns = {
2206 BPF_MOV64_IMM(BPF_REG_0, 0),
2207 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2208 offsetof(struct __sk_buff, cb[0])),
2209 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2210 offsetof(struct __sk_buff, cb[1])),
2211 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2212 offsetof(struct __sk_buff, cb[2])),
2213 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2214 offsetof(struct __sk_buff, cb[3])),
2215 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2216 offsetof(struct __sk_buff, cb[4])),
2217 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2218 offsetof(struct __sk_buff, cb[0])),
2219 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2220 offsetof(struct __sk_buff, cb[1])),
2221 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2222 offsetof(struct __sk_buff, cb[2])),
2223 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2224 offsetof(struct __sk_buff, cb[3])),
2225 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2226 offsetof(struct __sk_buff, cb[4])),
2227 BPF_EXIT_INSN(),
2228 },
2229 .result = ACCEPT,
2230 },
2231 {
2232 "check cb access: word, unaligned 1",
2233 .insns = {
2234 BPF_MOV64_IMM(BPF_REG_0, 0),
2235 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2236 offsetof(struct __sk_buff, cb[0]) + 2),
2237 BPF_EXIT_INSN(),
2238 },
2239 .errstr = "misaligned context access",
2240 .result = REJECT,
2241 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2242 },
2243 {
2244 "check cb access: word, unaligned 2",
2245 .insns = {
2246 BPF_MOV64_IMM(BPF_REG_0, 0),
2247 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2248 offsetof(struct __sk_buff, cb[4]) + 1),
2249 BPF_EXIT_INSN(),
2250 },
2251 .errstr = "misaligned context access",
2252 .result = REJECT,
2253 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2254 },
2255 {
2256 "check cb access: word, unaligned 3",
2257 .insns = {
2258 BPF_MOV64_IMM(BPF_REG_0, 0),
2259 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2260 offsetof(struct __sk_buff, cb[4]) + 2),
2261 BPF_EXIT_INSN(),
2262 },
2263 .errstr = "misaligned context access",
2264 .result = REJECT,
2265 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2266 },
2267 {
2268 "check cb access: word, unaligned 4",
2269 .insns = {
2270 BPF_MOV64_IMM(BPF_REG_0, 0),
2271 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2272 offsetof(struct __sk_buff, cb[4]) + 3),
2273 BPF_EXIT_INSN(),
2274 },
2275 .errstr = "misaligned context access",
2276 .result = REJECT,
2277 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2278 },
2279 {
2280 "check cb access: double",
2281 .insns = {
2282 BPF_MOV64_IMM(BPF_REG_0, 0),
2283 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2284 offsetof(struct __sk_buff, cb[0])),
2285 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2286 offsetof(struct __sk_buff, cb[2])),
2287 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2288 offsetof(struct __sk_buff, cb[0])),
2289 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2290 offsetof(struct __sk_buff, cb[2])),
2291 BPF_EXIT_INSN(),
2292 },
2293 .result = ACCEPT,
2294 },
2295 {
2296 "check cb access: double, unaligned 1",
2297 .insns = {
2298 BPF_MOV64_IMM(BPF_REG_0, 0),
2299 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2300 offsetof(struct __sk_buff, cb[1])),
2301 BPF_EXIT_INSN(),
2302 },
2303 .errstr = "misaligned context access",
2304 .result = REJECT,
2305 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2306 },
2307 {
2308 "check cb access: double, unaligned 2",
2309 .insns = {
2310 BPF_MOV64_IMM(BPF_REG_0, 0),
2311 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2312 offsetof(struct __sk_buff, cb[3])),
2313 BPF_EXIT_INSN(),
2314 },
2315 .errstr = "misaligned context access",
2316 .result = REJECT,
2317 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2318 },
2319 {
2320 "check cb access: double, oob 1",
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, cb[4])),
2325 BPF_EXIT_INSN(),
2326 },
2327 .errstr = "invalid bpf_context access",
2328 .result = REJECT,
2329 },
2330 {
2331 "check cb access: double, oob 2",
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, cb[4])),
2336 BPF_EXIT_INSN(),
2337 },
2338 .errstr = "invalid bpf_context access",
2339 .result = REJECT,
2340 },
2341 {
2342 "check __sk_buff->ifindex dw store not permitted",
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, ifindex)),
2347 BPF_EXIT_INSN(),
2348 },
2349 .errstr = "invalid bpf_context access",
2350 .result = REJECT,
2351 },
2352 {
2353 "check __sk_buff->ifindex dw load not permitted",
2354 .insns = {
2355 BPF_MOV64_IMM(BPF_REG_0, 0),
2356 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2357 offsetof(struct __sk_buff, ifindex)),
2358 BPF_EXIT_INSN(),
2359 },
2360 .errstr = "invalid bpf_context access",
2361 .result = REJECT,
2362 },
2363 {
2364 "check cb access: double, wrong type",
2365 .insns = {
2366 BPF_MOV64_IMM(BPF_REG_0, 0),
2367 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2368 offsetof(struct __sk_buff, cb[0])),
2369 BPF_EXIT_INSN(),
2370 },
2371 .errstr = "invalid bpf_context access",
2372 .result = REJECT,
2373 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2374 },
2375 {
2376 "check out of range skb->cb access",
2377 .insns = {
2378 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2379 offsetof(struct __sk_buff, cb[0]) + 256),
2380 BPF_EXIT_INSN(),
2381 },
2382 .errstr = "invalid bpf_context access",
2383 .errstr_unpriv = "",
2384 .result = REJECT,
2385 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
2386 },
2387 {
2388 "write skb fields from socket prog",
2389 .insns = {
2390 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2391 offsetof(struct __sk_buff, cb[4])),
2392 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2393 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2394 offsetof(struct __sk_buff, mark)),
2395 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2396 offsetof(struct __sk_buff, tc_index)),
2397 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2398 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2399 offsetof(struct __sk_buff, cb[0])),
2400 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2401 offsetof(struct __sk_buff, cb[2])),
2402 BPF_EXIT_INSN(),
2403 },
2404 .result = ACCEPT,
2405 .errstr_unpriv = "R1 leaks addr",
2406 .result_unpriv = REJECT,
2407 },
2408 {
2409 "write skb fields from tc_cls_act prog",
2410 .insns = {
2411 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2412 offsetof(struct __sk_buff, cb[0])),
2413 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2414 offsetof(struct __sk_buff, mark)),
2415 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2416 offsetof(struct __sk_buff, tc_index)),
2417 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2418 offsetof(struct __sk_buff, tc_index)),
2419 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2420 offsetof(struct __sk_buff, cb[3])),
2421 BPF_EXIT_INSN(),
2422 },
2423 .errstr_unpriv = "",
2424 .result_unpriv = REJECT,
2425 .result = ACCEPT,
2426 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2427 },
2428 {
2429 "PTR_TO_STACK store/load",
2430 .insns = {
2431 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2433 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2434 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2435 BPF_EXIT_INSN(),
2436 },
2437 .result = ACCEPT,
2438 .retval = 0xfaceb00c,
2439 },
2440 {
2441 "PTR_TO_STACK store/load - bad alignment on off",
2442 .insns = {
2443 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2445 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2446 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2447 BPF_EXIT_INSN(),
2448 },
2449 .result = REJECT,
2450 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
2451 },
2452 {
2453 "PTR_TO_STACK store/load - bad alignment on reg",
2454 .insns = {
2455 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2457 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2458 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2459 BPF_EXIT_INSN(),
2460 },
2461 .result = REJECT,
2462 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
2463 },
2464 {
2465 "PTR_TO_STACK store/load - out of bounds low",
2466 .insns = {
2467 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2468 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
2469 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2470 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2471 BPF_EXIT_INSN(),
2472 },
2473 .result = REJECT,
2474 .errstr = "invalid stack off=-79992 size=8",
2475 },
2476 {
2477 "PTR_TO_STACK store/load - out of bounds high",
2478 .insns = {
2479 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2481 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2482 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2483 BPF_EXIT_INSN(),
2484 },
2485 .result = REJECT,
2486 .errstr = "invalid stack off=0 size=8",
2487 },
2488 {
2489 "unpriv: return pointer",
2490 .insns = {
2491 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
2492 BPF_EXIT_INSN(),
2493 },
2494 .result = ACCEPT,
2495 .result_unpriv = REJECT,
2496 .errstr_unpriv = "R0 leaks addr",
2497 .retval = POINTER_VALUE,
2498 },
2499 {
2500 "unpriv: add const to pointer",
2501 .insns = {
2502 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2503 BPF_MOV64_IMM(BPF_REG_0, 0),
2504 BPF_EXIT_INSN(),
2505 },
2506 .result = ACCEPT,
2507 },
2508 {
2509 "unpriv: add pointer to pointer",
2510 .insns = {
2511 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2512 BPF_MOV64_IMM(BPF_REG_0, 0),
2513 BPF_EXIT_INSN(),
2514 },
2515 .result = REJECT,
2516 .errstr = "R1 pointer += pointer",
2517 },
2518 {
2519 "unpriv: neg pointer",
2520 .insns = {
2521 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
2522 BPF_MOV64_IMM(BPF_REG_0, 0),
2523 BPF_EXIT_INSN(),
2524 },
2525 .result = ACCEPT,
2526 .result_unpriv = REJECT,
2527 .errstr_unpriv = "R1 pointer arithmetic",
2528 },
2529 {
2530 "unpriv: cmp pointer with const",
2531 .insns = {
2532 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2533 BPF_MOV64_IMM(BPF_REG_0, 0),
2534 BPF_EXIT_INSN(),
2535 },
2536 .result = ACCEPT,
2537 .result_unpriv = REJECT,
2538 .errstr_unpriv = "R1 pointer comparison",
2539 },
2540 {
2541 "unpriv: cmp pointer with pointer",
2542 .insns = {
2543 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
2544 BPF_MOV64_IMM(BPF_REG_0, 0),
2545 BPF_EXIT_INSN(),
2546 },
2547 .result = ACCEPT,
2548 .result_unpriv = REJECT,
2549 .errstr_unpriv = "R10 pointer comparison",
2550 },
2551 {
2552 "unpriv: check that printk is disallowed",
2553 .insns = {
2554 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2555 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2557 BPF_MOV64_IMM(BPF_REG_2, 8),
2558 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2559 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2560 BPF_FUNC_trace_printk),
2561 BPF_MOV64_IMM(BPF_REG_0, 0),
2562 BPF_EXIT_INSN(),
2563 },
2564 .errstr_unpriv = "unknown func bpf_trace_printk#6",
2565 .result_unpriv = REJECT,
2566 .result = ACCEPT,
2567 },
2568 {
2569 "unpriv: pass pointer to helper function",
2570 .insns = {
2571 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2572 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2573 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2574 BPF_LD_MAP_FD(BPF_REG_1, 0),
2575 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2576 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2577 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2578 BPF_FUNC_map_update_elem),
2579 BPF_MOV64_IMM(BPF_REG_0, 0),
2580 BPF_EXIT_INSN(),
2581 },
2582 .fixup_map_hash_8b = { 3 },
2583 .errstr_unpriv = "R4 leaks addr",
2584 .result_unpriv = REJECT,
2585 .result = ACCEPT,
2586 },
2587 {
2588 "unpriv: indirectly pass pointer on stack to helper function",
2589 .insns = {
2590 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2591 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2593 BPF_LD_MAP_FD(BPF_REG_1, 0),
2594 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2595 BPF_FUNC_map_lookup_elem),
2596 BPF_MOV64_IMM(BPF_REG_0, 0),
2597 BPF_EXIT_INSN(),
2598 },
2599 .fixup_map_hash_8b = { 3 },
2600 .errstr = "invalid indirect read from stack off -8+0 size 8",
2601 .result = REJECT,
2602 },
2603 {
2604 "unpriv: mangle pointer on stack 1",
2605 .insns = {
2606 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2607 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
2608 BPF_MOV64_IMM(BPF_REG_0, 0),
2609 BPF_EXIT_INSN(),
2610 },
2611 .errstr_unpriv = "attempt to corrupt spilled",
2612 .result_unpriv = REJECT,
2613 .result = ACCEPT,
2614 },
2615 {
2616 "unpriv: mangle pointer on stack 2",
2617 .insns = {
2618 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2619 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2620 BPF_MOV64_IMM(BPF_REG_0, 0),
2621 BPF_EXIT_INSN(),
2622 },
2623 .errstr_unpriv = "attempt to corrupt spilled",
2624 .result_unpriv = REJECT,
2625 .result = ACCEPT,
2626 },
2627 {
2628 "unpriv: read pointer from stack in small chunks",
2629 .insns = {
2630 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2631 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2632 BPF_MOV64_IMM(BPF_REG_0, 0),
2633 BPF_EXIT_INSN(),
2634 },
2635 .errstr = "invalid size",
2636 .result = REJECT,
2637 },
2638 {
2639 "unpriv: write pointer into ctx",
2640 .insns = {
2641 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2642 BPF_MOV64_IMM(BPF_REG_0, 0),
2643 BPF_EXIT_INSN(),
2644 },
2645 .errstr_unpriv = "R1 leaks addr",
2646 .result_unpriv = REJECT,
2647 .errstr = "invalid bpf_context access",
2648 .result = REJECT,
2649 },
2650 {
2651 "unpriv: spill/fill of ctx",
2652 .insns = {
2653 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2655 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2656 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2657 BPF_MOV64_IMM(BPF_REG_0, 0),
2658 BPF_EXIT_INSN(),
2659 },
2660 .result = ACCEPT,
2661 },
2662 {
2663 "unpriv: spill/fill of ctx 2",
2664 .insns = {
2665 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2666 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2667 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2668 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2669 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2670 BPF_FUNC_get_hash_recalc),
2671 BPF_MOV64_IMM(BPF_REG_0, 0),
2672 BPF_EXIT_INSN(),
2673 },
2674 .result = ACCEPT,
2675 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2676 },
2677 {
2678 "unpriv: spill/fill of ctx 3",
2679 .insns = {
2680 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2681 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2682 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2683 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2684 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2685 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2686 BPF_FUNC_get_hash_recalc),
2687 BPF_EXIT_INSN(),
2688 },
2689 .result = REJECT,
2690 .errstr = "R1 type=fp expected=ctx",
2691 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2692 },
2693 {
2694 "unpriv: spill/fill of ctx 4",
2695 .insns = {
2696 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2697 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2698 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2699 BPF_MOV64_IMM(BPF_REG_0, 1),
2700 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2701 BPF_REG_0, -8, 0),
2702 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2704 BPF_FUNC_get_hash_recalc),
2705 BPF_EXIT_INSN(),
2706 },
2707 .result = REJECT,
2708 .errstr = "R1 type=inv expected=ctx",
2709 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2710 },
2711 {
2712 "unpriv: spill/fill of different pointers stx",
2713 .insns = {
2714 BPF_MOV64_IMM(BPF_REG_3, 42),
2715 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2716 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2717 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2718 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2719 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2720 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2721 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2722 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2723 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2724 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2725 offsetof(struct __sk_buff, mark)),
2726 BPF_MOV64_IMM(BPF_REG_0, 0),
2727 BPF_EXIT_INSN(),
2728 },
2729 .result = REJECT,
2730 .errstr = "same insn cannot be used with different pointers",
2731 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2732 },
2733 {
2734 "unpriv: spill/fill of different pointers stx - ctx and sock",
2735 .insns = {
2736 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2737 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
2738 BPF_SK_LOOKUP,
2739 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
2740 /* u64 foo; */
2741 /* void *target = &foo; */
2742 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2743 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2744 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2745 /* if (skb == NULL) *target = sock; */
2746 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
2747 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2748 /* else *target = skb; */
2749 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2750 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2751 /* struct __sk_buff *skb = *target; */
2752 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2753 /* skb->mark = 42; */
2754 BPF_MOV64_IMM(BPF_REG_3, 42),
2755 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2756 offsetof(struct __sk_buff, mark)),
2757 /* if (sk) bpf_sk_release(sk) */
2758 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
2759 BPF_EMIT_CALL(BPF_FUNC_sk_release),
2760 BPF_MOV64_IMM(BPF_REG_0, 0),
2761 BPF_EXIT_INSN(),
2762 },
2763 .result = REJECT,
2764 .errstr = "type=ctx expected=sock",
2765 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2766 },
2767 {
2768 "unpriv: spill/fill of different pointers stx - leak sock",
2769 .insns = {
2770 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2771 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
2772 BPF_SK_LOOKUP,
2773 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
2774 /* u64 foo; */
2775 /* void *target = &foo; */
2776 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2777 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2778 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2779 /* if (skb == NULL) *target = sock; */
2780 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
2781 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2782 /* else *target = skb; */
2783 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2784 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2785 /* struct __sk_buff *skb = *target; */
2786 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2787 /* skb->mark = 42; */
2788 BPF_MOV64_IMM(BPF_REG_3, 42),
2789 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2790 offsetof(struct __sk_buff, mark)),
2791 BPF_EXIT_INSN(),
2792 },
2793 .result = REJECT,
2794 //.errstr = "same insn cannot be used with different pointers",
2795 .errstr = "Unreleased reference",
2796 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2797 },
2798 {
2799 "unpriv: spill/fill of different pointers stx - sock and ctx (read)",
2800 .insns = {
2801 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2802 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
2803 BPF_SK_LOOKUP,
2804 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
2805 /* u64 foo; */
2806 /* void *target = &foo; */
2807 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2809 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2810 /* if (skb) *target = skb */
2811 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
2812 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2813 /* else *target = sock */
2814 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2815 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2816 /* struct bpf_sock *sk = *target; */
2817 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2818 /* if (sk) u32 foo = sk->mark; bpf_sk_release(sk); */
2819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
2820 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2821 offsetof(struct bpf_sock, mark)),
2822 BPF_EMIT_CALL(BPF_FUNC_sk_release),
2823 BPF_MOV64_IMM(BPF_REG_0, 0),
2824 BPF_EXIT_INSN(),
2825 },
2826 .result = REJECT,
2827 .errstr = "same insn cannot be used with different pointers",
2828 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2829 },
2830 {
2831 "unpriv: spill/fill of different pointers stx - sock and ctx (write)",
2832 .insns = {
2833 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
2834 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
2835 BPF_SK_LOOKUP,
2836 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
2837 /* u64 foo; */
2838 /* void *target = &foo; */
2839 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2840 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2841 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2842 /* if (skb) *target = skb */
2843 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
2844 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2845 /* else *target = sock */
2846 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2847 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2848 /* struct bpf_sock *sk = *target; */
2849 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2850 /* if (sk) sk->mark = 42; bpf_sk_release(sk); */
2851 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2852 BPF_MOV64_IMM(BPF_REG_3, 42),
2853 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2854 offsetof(struct bpf_sock, mark)),
2855 BPF_EMIT_CALL(BPF_FUNC_sk_release),
2856 BPF_MOV64_IMM(BPF_REG_0, 0),
2857 BPF_EXIT_INSN(),
2858 },
2859 .result = REJECT,
2860 //.errstr = "same insn cannot be used with different pointers",
2861 .errstr = "cannot write into socket",
2862 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2863 },
2864 {
2865 "unpriv: spill/fill of different pointers ldx",
2866 .insns = {
2867 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2869 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2870 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2871 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2872 -(__s32)offsetof(struct bpf_perf_event_data,
2873 sample_period) - 8),
2874 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2875 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2876 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2877 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2878 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2879 offsetof(struct bpf_perf_event_data,
2880 sample_period)),
2881 BPF_MOV64_IMM(BPF_REG_0, 0),
2882 BPF_EXIT_INSN(),
2883 },
2884 .result = REJECT,
2885 .errstr = "same insn cannot be used with different pointers",
2886 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2887 },
2888 {
2889 "unpriv: write pointer into map elem value",
2890 .insns = {
2891 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2892 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2893 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2894 BPF_LD_MAP_FD(BPF_REG_1, 0),
2895 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2896 BPF_FUNC_map_lookup_elem),
2897 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2898 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2899 BPF_EXIT_INSN(),
2900 },
2901 .fixup_map_hash_8b = { 3 },
2902 .errstr_unpriv = "R0 leaks addr",
2903 .result_unpriv = REJECT,
2904 .result = ACCEPT,
2905 },
2906 {
2907 "unpriv: partial copy of pointer",
2908 .insns = {
2909 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2910 BPF_MOV64_IMM(BPF_REG_0, 0),
2911 BPF_EXIT_INSN(),
2912 },
2913 .errstr_unpriv = "R10 partial copy",
2914 .result_unpriv = REJECT,
2915 .result = ACCEPT,
2916 },
2917 {
2918 "unpriv: pass pointer to tail_call",
2919 .insns = {
2920 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2921 BPF_LD_MAP_FD(BPF_REG_2, 0),
2922 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2923 BPF_FUNC_tail_call),
2924 BPF_MOV64_IMM(BPF_REG_0, 0),
2925 BPF_EXIT_INSN(),
2926 },
2927 .fixup_prog1 = { 1 },
2928 .errstr_unpriv = "R3 leaks addr into helper",
2929 .result_unpriv = REJECT,
2930 .result = ACCEPT,
2931 },
2932 {
2933 "unpriv: cmp map pointer with zero",
2934 .insns = {
2935 BPF_MOV64_IMM(BPF_REG_1, 0),
2936 BPF_LD_MAP_FD(BPF_REG_1, 0),
2937 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2938 BPF_MOV64_IMM(BPF_REG_0, 0),
2939 BPF_EXIT_INSN(),
2940 },
2941 .fixup_map_hash_8b = { 1 },
2942 .errstr_unpriv = "R1 pointer comparison",
2943 .result_unpriv = REJECT,
2944 .result = ACCEPT,
2945 },
2946 {
2947 "unpriv: write into frame pointer",
2948 .insns = {
2949 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2950 BPF_MOV64_IMM(BPF_REG_0, 0),
2951 BPF_EXIT_INSN(),
2952 },
2953 .errstr = "frame pointer is read only",
2954 .result = REJECT,
2955 },
2956 {
2957 "unpriv: spill/fill frame pointer",
2958 .insns = {
2959 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2960 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2961 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2962 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2963 BPF_MOV64_IMM(BPF_REG_0, 0),
2964 BPF_EXIT_INSN(),
2965 },
2966 .errstr = "frame pointer is read only",
2967 .result = REJECT,
2968 },
2969 {
2970 "unpriv: cmp of frame pointer",
2971 .insns = {
2972 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2973 BPF_MOV64_IMM(BPF_REG_0, 0),
2974 BPF_EXIT_INSN(),
2975 },
2976 .errstr_unpriv = "R10 pointer comparison",
2977 .result_unpriv = REJECT,
2978 .result = ACCEPT,
2979 },
2980 {
2981 "unpriv: adding of fp",
2982 .insns = {
2983 BPF_MOV64_IMM(BPF_REG_0, 0),
2984 BPF_MOV64_IMM(BPF_REG_1, 0),
2985 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2986 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2987 BPF_EXIT_INSN(),
2988 },
2989 .result = ACCEPT,
2990 },
2991 {
2992 "unpriv: cmp of stack pointer",
2993 .insns = {
2994 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2995 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2996 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2997 BPF_MOV64_IMM(BPF_REG_0, 0),
2998 BPF_EXIT_INSN(),
2999 },
3000 .errstr_unpriv = "R2 pointer comparison",
3001 .result_unpriv = REJECT,
3002 .result = ACCEPT,
3003 },
3004 {
3005 "runtime/jit: tail_call within bounds, prog once",
3006 .insns = {
3007 BPF_MOV64_IMM(BPF_REG_3, 0),
3008 BPF_LD_MAP_FD(BPF_REG_2, 0),
3009 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3010 BPF_FUNC_tail_call),
3011 BPF_MOV64_IMM(BPF_REG_0, 1),
3012 BPF_EXIT_INSN(),
3013 },
3014 .fixup_prog1 = { 1 },
3015 .result = ACCEPT,
3016 .retval = 42,
3017 },
3018 {
3019 "runtime/jit: tail_call within bounds, prog loop",
3020 .insns = {
3021 BPF_MOV64_IMM(BPF_REG_3, 1),
3022 BPF_LD_MAP_FD(BPF_REG_2, 0),
3023 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3024 BPF_FUNC_tail_call),
3025 BPF_MOV64_IMM(BPF_REG_0, 1),
3026 BPF_EXIT_INSN(),
3027 },
3028 .fixup_prog1 = { 1 },
3029 .result = ACCEPT,
3030 .retval = 41,
3031 },
3032 {
3033 "runtime/jit: tail_call within bounds, no prog",
3034 .insns = {
3035 BPF_MOV64_IMM(BPF_REG_3, 2),
3036 BPF_LD_MAP_FD(BPF_REG_2, 0),
3037 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3038 BPF_FUNC_tail_call),
3039 BPF_MOV64_IMM(BPF_REG_0, 1),
3040 BPF_EXIT_INSN(),
3041 },
3042 .fixup_prog1 = { 1 },
3043 .result = ACCEPT,
3044 .retval = 1,
3045 },
3046 {
3047 "runtime/jit: tail_call out of bounds",
3048 .insns = {
3049 BPF_MOV64_IMM(BPF_REG_3, 256),
3050 BPF_LD_MAP_FD(BPF_REG_2, 0),
3051 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3052 BPF_FUNC_tail_call),
3053 BPF_MOV64_IMM(BPF_REG_0, 2),
3054 BPF_EXIT_INSN(),
3055 },
3056 .fixup_prog1 = { 1 },
3057 .result = ACCEPT,
3058 .retval = 2,
3059 },
3060 {
3061 "runtime/jit: pass negative index to tail_call",
3062 .insns = {
3063 BPF_MOV64_IMM(BPF_REG_3, -1),
3064 BPF_LD_MAP_FD(BPF_REG_2, 0),
3065 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3066 BPF_FUNC_tail_call),
3067 BPF_MOV64_IMM(BPF_REG_0, 2),
3068 BPF_EXIT_INSN(),
3069 },
3070 .fixup_prog1 = { 1 },
3071 .result = ACCEPT,
3072 .retval = 2,
3073 },
3074 {
3075 "runtime/jit: pass > 32bit index to tail_call",
3076 .insns = {
3077 BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
3078 BPF_LD_MAP_FD(BPF_REG_2, 0),
3079 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3080 BPF_FUNC_tail_call),
3081 BPF_MOV64_IMM(BPF_REG_0, 2),
3082 BPF_EXIT_INSN(),
3083 },
3084 .fixup_prog1 = { 2 },
3085 .result = ACCEPT,
3086 .retval = 42,
3087 /* Verifier rewrite for unpriv skips tail call here. */
3088 .retval_unpriv = 2,
3089 },
3090 {
3091 "stack pointer arithmetic",
3092 .insns = {
3093 BPF_MOV64_IMM(BPF_REG_1, 4),
3094 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
3095 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
3096 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
3097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
3098 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3099 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
3100 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
3101 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
3103 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
3104 BPF_MOV64_IMM(BPF_REG_0, 0),
3105 BPF_EXIT_INSN(),
3106 },
3107 .result = ACCEPT,
3108 },
3109 {
3110 "raw_stack: no skb_load_bytes",
3111 .insns = {
3112 BPF_MOV64_IMM(BPF_REG_2, 4),
3113 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3115 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3116 BPF_MOV64_IMM(BPF_REG_4, 8),
3117 /* Call to skb_load_bytes() omitted. */
3118 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3119 BPF_EXIT_INSN(),
3120 },
3121 .result = REJECT,
3122 .errstr = "invalid read from stack off -8+0 size 8",
3123 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3124 },
3125 {
3126 "raw_stack: skb_load_bytes, negative len",
3127 .insns = {
3128 BPF_MOV64_IMM(BPF_REG_2, 4),
3129 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3131 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3132 BPF_MOV64_IMM(BPF_REG_4, -8),
3133 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3134 BPF_FUNC_skb_load_bytes),
3135 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3136 BPF_EXIT_INSN(),
3137 },
3138 .result = REJECT,
3139 .errstr = "R4 min value is negative",
3140 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3141 },
3142 {
3143 "raw_stack: skb_load_bytes, negative len 2",
3144 .insns = {
3145 BPF_MOV64_IMM(BPF_REG_2, 4),
3146 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3147 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3148 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3149 BPF_MOV64_IMM(BPF_REG_4, ~0),
3150 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3151 BPF_FUNC_skb_load_bytes),
3152 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3153 BPF_EXIT_INSN(),
3154 },
3155 .result = REJECT,
3156 .errstr = "R4 min value is negative",
3157 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3158 },
3159 {
3160 "raw_stack: skb_load_bytes, zero len",
3161 .insns = {
3162 BPF_MOV64_IMM(BPF_REG_2, 4),
3163 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3165 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3166 BPF_MOV64_IMM(BPF_REG_4, 0),
3167 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3168 BPF_FUNC_skb_load_bytes),
3169 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3170 BPF_EXIT_INSN(),
3171 },
3172 .result = REJECT,
3173 .errstr = "invalid stack type R3",
3174 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3175 },
3176 {
3177 "raw_stack: skb_load_bytes, no init",
3178 .insns = {
3179 BPF_MOV64_IMM(BPF_REG_2, 4),
3180 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3182 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3183 BPF_MOV64_IMM(BPF_REG_4, 8),
3184 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3185 BPF_FUNC_skb_load_bytes),
3186 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3187 BPF_EXIT_INSN(),
3188 },
3189 .result = ACCEPT,
3190 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3191 },
3192 {
3193 "raw_stack: skb_load_bytes, init",
3194 .insns = {
3195 BPF_MOV64_IMM(BPF_REG_2, 4),
3196 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3198 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
3199 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3200 BPF_MOV64_IMM(BPF_REG_4, 8),
3201 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3202 BPF_FUNC_skb_load_bytes),
3203 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3204 BPF_EXIT_INSN(),
3205 },
3206 .result = ACCEPT,
3207 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3208 },
3209 {
3210 "raw_stack: skb_load_bytes, spilled regs around bounds",
3211 .insns = {
3212 BPF_MOV64_IMM(BPF_REG_2, 4),
3213 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3215 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3216 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3217 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3218 BPF_MOV64_IMM(BPF_REG_4, 8),
3219 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3220 BPF_FUNC_skb_load_bytes),
3221 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3222 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3223 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3224 offsetof(struct __sk_buff, mark)),
3225 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3226 offsetof(struct __sk_buff, priority)),
3227 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3228 BPF_EXIT_INSN(),
3229 },
3230 .result = ACCEPT,
3231 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3232 },
3233 {
3234 "raw_stack: skb_load_bytes, spilled regs corruption",
3235 .insns = {
3236 BPF_MOV64_IMM(BPF_REG_2, 4),
3237 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3239 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3240 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3241 BPF_MOV64_IMM(BPF_REG_4, 8),
3242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3243 BPF_FUNC_skb_load_bytes),
3244 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3245 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3246 offsetof(struct __sk_buff, mark)),
3247 BPF_EXIT_INSN(),
3248 },
3249 .result = REJECT,
3250 .errstr = "R0 invalid mem access 'inv'",
3251 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3252 },
3253 {
3254 "raw_stack: skb_load_bytes, spilled regs corruption 2",
3255 .insns = {
3256 BPF_MOV64_IMM(BPF_REG_2, 4),
3257 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3258 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3259 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3260 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3261 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3262 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3263 BPF_MOV64_IMM(BPF_REG_4, 8),
3264 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3265 BPF_FUNC_skb_load_bytes),
3266 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3267 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3268 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
3269 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3270 offsetof(struct __sk_buff, mark)),
3271 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3272 offsetof(struct __sk_buff, priority)),
3273 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3274 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
3275 offsetof(struct __sk_buff, pkt_type)),
3276 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3277 BPF_EXIT_INSN(),
3278 },
3279 .result = REJECT,
3280 .errstr = "R3 invalid mem access 'inv'",
3281 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3282 },
3283 {
3284 "raw_stack: skb_load_bytes, spilled regs + data",
3285 .insns = {
3286 BPF_MOV64_IMM(BPF_REG_2, 4),
3287 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3288 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
3289 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3290 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3291 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
3292 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3293 BPF_MOV64_IMM(BPF_REG_4, 8),
3294 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3295 BPF_FUNC_skb_load_bytes),
3296 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3297 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3298 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
3299 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3300 offsetof(struct __sk_buff, mark)),
3301 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3302 offsetof(struct __sk_buff, priority)),
3303 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3304 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3305 BPF_EXIT_INSN(),
3306 },
3307 .result = ACCEPT,
3308 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3309 },
3310 {
3311 "raw_stack: skb_load_bytes, invalid access 1",
3312 .insns = {
3313 BPF_MOV64_IMM(BPF_REG_2, 4),
3314 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
3316 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3317 BPF_MOV64_IMM(BPF_REG_4, 8),
3318 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3319 BPF_FUNC_skb_load_bytes),
3320 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3321 BPF_EXIT_INSN(),
3322 },
3323 .result = REJECT,
3324 .errstr = "invalid stack type R3 off=-513 access_size=8",
3325 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3326 },
3327 {
3328 "raw_stack: skb_load_bytes, invalid access 2",
3329 .insns = {
3330 BPF_MOV64_IMM(BPF_REG_2, 4),
3331 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3332 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3333 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3334 BPF_MOV64_IMM(BPF_REG_4, 8),
3335 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3336 BPF_FUNC_skb_load_bytes),
3337 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3338 BPF_EXIT_INSN(),
3339 },
3340 .result = REJECT,
3341 .errstr = "invalid stack type R3 off=-1 access_size=8",
3342 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3343 },
3344 {
3345 "raw_stack: skb_load_bytes, invalid access 3",
3346 .insns = {
3347 BPF_MOV64_IMM(BPF_REG_2, 4),
3348 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3349 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
3350 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3351 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3352 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3353 BPF_FUNC_skb_load_bytes),
3354 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3355 BPF_EXIT_INSN(),
3356 },
3357 .result = REJECT,
3358 .errstr = "R4 min value is negative",
3359 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3360 },
3361 {
3362 "raw_stack: skb_load_bytes, invalid access 4",
3363 .insns = {
3364 BPF_MOV64_IMM(BPF_REG_2, 4),
3365 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3367 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3368 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
3369 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3370 BPF_FUNC_skb_load_bytes),
3371 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3372 BPF_EXIT_INSN(),
3373 },
3374 .result = REJECT,
3375 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
3376 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3377 },
3378 {
3379 "raw_stack: skb_load_bytes, invalid access 5",
3380 .insns = {
3381 BPF_MOV64_IMM(BPF_REG_2, 4),
3382 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3384 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3385 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
3386 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3387 BPF_FUNC_skb_load_bytes),
3388 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3389 BPF_EXIT_INSN(),
3390 },
3391 .result = REJECT,
3392 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
3393 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3394 },
3395 {
3396 "raw_stack: skb_load_bytes, invalid access 6",
3397 .insns = {
3398 BPF_MOV64_IMM(BPF_REG_2, 4),
3399 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3400 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3401 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3402 BPF_MOV64_IMM(BPF_REG_4, 0),
3403 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3404 BPF_FUNC_skb_load_bytes),
3405 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3406 BPF_EXIT_INSN(),
3407 },
3408 .result = REJECT,
3409 .errstr = "invalid stack type R3 off=-512 access_size=0",
3410 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3411 },
3412 {
3413 "raw_stack: skb_load_bytes, large access",
3414 .insns = {
3415 BPF_MOV64_IMM(BPF_REG_2, 4),
3416 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3417 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3418 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3419 BPF_MOV64_IMM(BPF_REG_4, 512),
3420 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3421 BPF_FUNC_skb_load_bytes),
3422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3423 BPF_EXIT_INSN(),
3424 },
3425 .result = ACCEPT,
3426 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3427 },
3428 {
3429 "context stores via ST",
3430 .insns = {
3431 BPF_MOV64_IMM(BPF_REG_0, 0),
3432 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
3433 BPF_EXIT_INSN(),
3434 },
3435 .errstr = "BPF_ST stores into R1 ctx is not allowed",
3436 .result = REJECT,
3437 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3438 },
3439 {
3440 "context stores via XADD",
3441 .insns = {
3442 BPF_MOV64_IMM(BPF_REG_0, 0),
3443 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
3444 BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
3445 BPF_EXIT_INSN(),
3446 },
3447 .errstr = "BPF_XADD stores into R1 ctx is not allowed",
3448 .result = REJECT,
3449 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3450 },
3451 {
3452 "direct packet access: test1",
3453 .insns = {
3454 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3455 offsetof(struct __sk_buff, data)),
3456 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3457 offsetof(struct __sk_buff, data_end)),
3458 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3459 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3460 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3461 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3462 BPF_MOV64_IMM(BPF_REG_0, 0),
3463 BPF_EXIT_INSN(),
3464 },
3465 .result = ACCEPT,
3466 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3467 },
3468 {
3469 "direct packet access: test2",
3470 .insns = {
3471 BPF_MOV64_IMM(BPF_REG_0, 1),
3472 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
3473 offsetof(struct __sk_buff, data_end)),
3474 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3475 offsetof(struct __sk_buff, data)),
3476 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
3478 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
3479 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
3480 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
3481 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
3482 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3483 offsetof(struct __sk_buff, data)),
3484 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
3485 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3486 offsetof(struct __sk_buff, len)),
3487 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
3488 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
3489 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
3490 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
3491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
3492 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
3493 offsetof(struct __sk_buff, data_end)),
3494 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3495 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
3496 BPF_MOV64_IMM(BPF_REG_0, 0),
3497 BPF_EXIT_INSN(),
3498 },
3499 .result = ACCEPT,
3500 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3501 },
3502 {
3503 "direct packet access: test3",
3504 .insns = {
3505 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3506 offsetof(struct __sk_buff, data)),
3507 BPF_MOV64_IMM(BPF_REG_0, 0),
3508 BPF_EXIT_INSN(),
3509 },
3510 .errstr = "invalid bpf_context access off=76",
3511 .result = REJECT,
3512 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
3513 },
3514 {
3515 "direct packet access: test4 (write)",
3516 .insns = {
3517 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3518 offsetof(struct __sk_buff, data)),
3519 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3520 offsetof(struct __sk_buff, data_end)),
3521 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3523 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3524 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3525 BPF_MOV64_IMM(BPF_REG_0, 0),
3526 BPF_EXIT_INSN(),
3527 },
3528 .result = ACCEPT,
3529 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3530 },
3531 {
3532 "direct packet access: test5 (pkt_end >= reg, good access)",
3533 .insns = {
3534 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3535 offsetof(struct __sk_buff, data)),
3536 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3537 offsetof(struct __sk_buff, data_end)),
3538 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3539 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3540 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3541 BPF_MOV64_IMM(BPF_REG_0, 1),
3542 BPF_EXIT_INSN(),
3543 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3544 BPF_MOV64_IMM(BPF_REG_0, 0),
3545 BPF_EXIT_INSN(),
3546 },
3547 .result = ACCEPT,
3548 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3549 },
3550 {
3551 "direct packet access: test6 (pkt_end >= reg, bad access)",
3552 .insns = {
3553 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3554 offsetof(struct __sk_buff, data)),
3555 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3556 offsetof(struct __sk_buff, data_end)),
3557 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3559 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3560 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3561 BPF_MOV64_IMM(BPF_REG_0, 1),
3562 BPF_EXIT_INSN(),
3563 BPF_MOV64_IMM(BPF_REG_0, 0),
3564 BPF_EXIT_INSN(),
3565 },
3566 .errstr = "invalid access to packet",
3567 .result = REJECT,
3568 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3569 },
3570 {
3571 "direct packet access: test7 (pkt_end >= reg, both accesses)",
3572 .insns = {
3573 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3574 offsetof(struct __sk_buff, data)),
3575 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3576 offsetof(struct __sk_buff, data_end)),
3577 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3578 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3579 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3580 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3581 BPF_MOV64_IMM(BPF_REG_0, 1),
3582 BPF_EXIT_INSN(),
3583 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3584 BPF_MOV64_IMM(BPF_REG_0, 0),
3585 BPF_EXIT_INSN(),
3586 },
3587 .errstr = "invalid access to packet",
3588 .result = REJECT,
3589 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3590 },
3591 {
3592 "direct packet access: test8 (double test, variant 1)",
3593 .insns = {
3594 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3595 offsetof(struct __sk_buff, data)),
3596 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3597 offsetof(struct __sk_buff, data_end)),
3598 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3599 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3600 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
3601 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3602 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3603 BPF_MOV64_IMM(BPF_REG_0, 1),
3604 BPF_EXIT_INSN(),
3605 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3606 BPF_MOV64_IMM(BPF_REG_0, 0),
3607 BPF_EXIT_INSN(),
3608 },
3609 .result = ACCEPT,
3610 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3611 },
3612 {
3613 "direct packet access: test9 (double test, variant 2)",
3614 .insns = {
3615 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3616 offsetof(struct __sk_buff, data)),
3617 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3618 offsetof(struct __sk_buff, data_end)),
3619 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3620 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3621 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3622 BPF_MOV64_IMM(BPF_REG_0, 1),
3623 BPF_EXIT_INSN(),
3624 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3625 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3626 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3627 BPF_MOV64_IMM(BPF_REG_0, 0),
3628 BPF_EXIT_INSN(),
3629 },
3630 .result = ACCEPT,
3631 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3632 },
3633 {
3634 "direct packet access: test10 (write invalid)",
3635 .insns = {
3636 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3637 offsetof(struct __sk_buff, data)),
3638 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3639 offsetof(struct __sk_buff, data_end)),
3640 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3641 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3642 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3643 BPF_MOV64_IMM(BPF_REG_0, 0),
3644 BPF_EXIT_INSN(),
3645 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3646 BPF_MOV64_IMM(BPF_REG_0, 0),
3647 BPF_EXIT_INSN(),
3648 },
3649 .errstr = "invalid access to packet",
3650 .result = REJECT,
3651 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3652 },
3653 {
3654 "direct packet access: test11 (shift, good access)",
3655 .insns = {
3656 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3657 offsetof(struct __sk_buff, data)),
3658 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3659 offsetof(struct __sk_buff, data_end)),
3660 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3662 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3663 BPF_MOV64_IMM(BPF_REG_3, 144),
3664 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3665 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3666 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
3667 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3668 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3669 BPF_MOV64_IMM(BPF_REG_0, 1),
3670 BPF_EXIT_INSN(),
3671 BPF_MOV64_IMM(BPF_REG_0, 0),
3672 BPF_EXIT_INSN(),
3673 },
3674 .result = ACCEPT,
3675 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3676 .retval = 1,
3677 },
3678 {
3679 "direct packet access: test12 (and, good access)",
3680 .insns = {
3681 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3682 offsetof(struct __sk_buff, data)),
3683 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3684 offsetof(struct __sk_buff, data_end)),
3685 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3686 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3687 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3688 BPF_MOV64_IMM(BPF_REG_3, 144),
3689 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3690 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3691 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3692 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3693 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3694 BPF_MOV64_IMM(BPF_REG_0, 1),
3695 BPF_EXIT_INSN(),
3696 BPF_MOV64_IMM(BPF_REG_0, 0),
3697 BPF_EXIT_INSN(),
3698 },
3699 .result = ACCEPT,
3700 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3701 .retval = 1,
3702 },
3703 {
3704 "direct packet access: test13 (branches, good access)",
3705 .insns = {
3706 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3707 offsetof(struct __sk_buff, data)),
3708 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3709 offsetof(struct __sk_buff, data_end)),
3710 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3711 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3712 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
3713 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3714 offsetof(struct __sk_buff, mark)),
3715 BPF_MOV64_IMM(BPF_REG_4, 1),
3716 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
3717 BPF_MOV64_IMM(BPF_REG_3, 14),
3718 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
3719 BPF_MOV64_IMM(BPF_REG_3, 24),
3720 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3721 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3722 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3723 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3724 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3725 BPF_MOV64_IMM(BPF_REG_0, 1),
3726 BPF_EXIT_INSN(),
3727 BPF_MOV64_IMM(BPF_REG_0, 0),
3728 BPF_EXIT_INSN(),
3729 },
3730 .result = ACCEPT,
3731 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3732 .retval = 1,
3733 },
3734 {
3735 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
3736 .insns = {
3737 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3738 offsetof(struct __sk_buff, data)),
3739 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3740 offsetof(struct __sk_buff, data_end)),
3741 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3742 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3743 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
3744 BPF_MOV64_IMM(BPF_REG_5, 12),
3745 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
3746 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3747 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3748 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
3749 BPF_MOV64_IMM(BPF_REG_0, 1),
3750 BPF_EXIT_INSN(),
3751 BPF_MOV64_IMM(BPF_REG_0, 0),
3752 BPF_EXIT_INSN(),
3753 },
3754 .result = ACCEPT,
3755 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3756 .retval = 1,
3757 },
3758 {
3759 "direct packet access: test15 (spill with xadd)",
3760 .insns = {
3761 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3762 offsetof(struct __sk_buff, data)),
3763 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3764 offsetof(struct __sk_buff, data_end)),
3765 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3766 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3767 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3768 BPF_MOV64_IMM(BPF_REG_5, 4096),
3769 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
3770 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
3771 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
3772 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
3773 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
3774 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
3775 BPF_MOV64_IMM(BPF_REG_0, 0),
3776 BPF_EXIT_INSN(),
3777 },
3778 .errstr = "R2 invalid mem access 'inv'",
3779 .result = REJECT,
3780 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3781 },
3782 {
3783 "direct packet access: test16 (arith on data_end)",
3784 .insns = {
3785 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3786 offsetof(struct __sk_buff, data)),
3787 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3788 offsetof(struct __sk_buff, data_end)),
3789 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3791 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
3792 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3793 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3794 BPF_MOV64_IMM(BPF_REG_0, 0),
3795 BPF_EXIT_INSN(),
3796 },
3797 .errstr = "R3 pointer arithmetic on pkt_end",
3798 .result = REJECT,
3799 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3800 },
3801 {
3802 "direct packet access: test17 (pruning, alignment)",
3803 .insns = {
3804 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3805 offsetof(struct __sk_buff, data)),
3806 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3807 offsetof(struct __sk_buff, data_end)),
3808 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3809 offsetof(struct __sk_buff, mark)),
3810 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
3812 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
3813 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3814 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
3815 BPF_MOV64_IMM(BPF_REG_0, 0),
3816 BPF_EXIT_INSN(),
3817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3818 BPF_JMP_A(-6),
3819 },
3820 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
3821 .result = REJECT,
3822 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3823 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
3824 },
3825 {
3826 "direct packet access: test18 (imm += pkt_ptr, 1)",
3827 .insns = {
3828 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3829 offsetof(struct __sk_buff, data)),
3830 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3831 offsetof(struct __sk_buff, data_end)),
3832 BPF_MOV64_IMM(BPF_REG_0, 8),
3833 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3834 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3835 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3836 BPF_MOV64_IMM(BPF_REG_0, 0),
3837 BPF_EXIT_INSN(),
3838 },
3839 .result = ACCEPT,
3840 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3841 },
3842 {
3843 "direct packet access: test19 (imm += pkt_ptr, 2)",
3844 .insns = {
3845 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3846 offsetof(struct __sk_buff, data)),
3847 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3848 offsetof(struct __sk_buff, data_end)),
3849 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3851 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
3852 BPF_MOV64_IMM(BPF_REG_4, 4),
3853 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3854 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
3855 BPF_MOV64_IMM(BPF_REG_0, 0),
3856 BPF_EXIT_INSN(),
3857 },
3858 .result = ACCEPT,
3859 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3860 },
3861 {
3862 "direct packet access: test20 (x += pkt_ptr, 1)",
3863 .insns = {
3864 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3865 offsetof(struct __sk_buff, data)),
3866 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3867 offsetof(struct __sk_buff, data_end)),
3868 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3869 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3870 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3871 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
3872 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3873 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3874 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3875 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3876 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3877 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3878 BPF_MOV64_IMM(BPF_REG_0, 0),
3879 BPF_EXIT_INSN(),
3880 },
3881 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3882 .result = ACCEPT,
3883 },
3884 {
3885 "direct packet access: test21 (x += pkt_ptr, 2)",
3886 .insns = {
3887 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3888 offsetof(struct __sk_buff, data)),
3889 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3890 offsetof(struct __sk_buff, data_end)),
3891 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3892 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3893 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3894 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3895 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3896 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3897 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
3898 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3899 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3900 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
3901 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3902 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3903 BPF_MOV64_IMM(BPF_REG_0, 0),
3904 BPF_EXIT_INSN(),
3905 },
3906 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3907 .result = ACCEPT,
3908 },
3909 {
3910 "direct packet access: test22 (x += pkt_ptr, 3)",
3911 .insns = {
3912 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3913 offsetof(struct __sk_buff, data)),
3914 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3915 offsetof(struct __sk_buff, data_end)),
3916 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3917 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3918 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3919 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3920 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3921 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3922 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3923 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3924 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3925 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
3926 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
3927 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3928 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3930 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3931 BPF_MOV64_IMM(BPF_REG_2, 1),
3932 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3933 BPF_MOV64_IMM(BPF_REG_0, 0),
3934 BPF_EXIT_INSN(),
3935 },
3936 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3937 .result = ACCEPT,
3938 },
3939 {
3940 "direct packet access: test23 (x += pkt_ptr, 4)",
3941 .insns = {
3942 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3943 offsetof(struct __sk_buff, data)),
3944 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3945 offsetof(struct __sk_buff, data_end)),
3946 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3947 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3948 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3949 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3950 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3951 BPF_MOV64_IMM(BPF_REG_0, 31),
3952 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3953 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3954 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3955 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3956 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3957 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3958 BPF_MOV64_IMM(BPF_REG_0, 0),
3959 BPF_EXIT_INSN(),
3960 },
3961 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3962 .result = REJECT,
3963 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
3964 },
3965 {
3966 "direct packet access: test24 (x += pkt_ptr, 5)",
3967 .insns = {
3968 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3969 offsetof(struct __sk_buff, data)),
3970 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3971 offsetof(struct __sk_buff, data_end)),
3972 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3973 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3974 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3975 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3976 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3977 BPF_MOV64_IMM(BPF_REG_0, 64),
3978 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3979 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3980 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3981 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
3982 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3983 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3984 BPF_MOV64_IMM(BPF_REG_0, 0),
3985 BPF_EXIT_INSN(),
3986 },
3987 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3988 .result = ACCEPT,
3989 },
3990 {
3991 "direct packet access: test25 (marking on <, good access)",
3992 .insns = {
3993 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3994 offsetof(struct __sk_buff, data)),
3995 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3996 offsetof(struct __sk_buff, data_end)),
3997 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3999 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
4000 BPF_MOV64_IMM(BPF_REG_0, 0),
4001 BPF_EXIT_INSN(),
4002 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4003 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
4004 },
4005 .result = ACCEPT,
4006 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4007 },
4008 {
4009 "direct packet access: test26 (marking on <, bad access)",
4010 .insns = {
4011 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4012 offsetof(struct __sk_buff, data)),
4013 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4014 offsetof(struct __sk_buff, data_end)),
4015 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4016 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4017 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
4018 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4019 BPF_MOV64_IMM(BPF_REG_0, 0),
4020 BPF_EXIT_INSN(),
4021 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
4022 },
4023 .result = REJECT,
4024 .errstr = "invalid access to packet",
4025 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4026 },
4027 {
4028 "direct packet access: test27 (marking on <=, good access)",
4029 .insns = {
4030 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4031 offsetof(struct __sk_buff, data)),
4032 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4033 offsetof(struct __sk_buff, data_end)),
4034 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4035 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4036 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
4037 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4038 BPF_MOV64_IMM(BPF_REG_0, 1),
4039 BPF_EXIT_INSN(),
4040 },
4041 .result = ACCEPT,
4042 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4043 .retval = 1,
4044 },
4045 {
4046 "direct packet access: test28 (marking on <=, bad access)",
4047 .insns = {
4048 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4049 offsetof(struct __sk_buff, data)),
4050 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4051 offsetof(struct __sk_buff, data_end)),
4052 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4054 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
4055 BPF_MOV64_IMM(BPF_REG_0, 1),
4056 BPF_EXIT_INSN(),
4057 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4058 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
4059 },
4060 .result = REJECT,
4061 .errstr = "invalid access to packet",
4062 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4063 },
4064 {
4065 "helper access to packet: test1, valid packet_ptr range",
4066 .insns = {
4067 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4068 offsetof(struct xdp_md, data)),
4069 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4070 offsetof(struct xdp_md, data_end)),
4071 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4073 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
4074 BPF_LD_MAP_FD(BPF_REG_1, 0),
4075 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
4076 BPF_MOV64_IMM(BPF_REG_4, 0),
4077 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4078 BPF_FUNC_map_update_elem),
4079 BPF_MOV64_IMM(BPF_REG_0, 0),
4080 BPF_EXIT_INSN(),
4081 },
4082 .fixup_map_hash_8b = { 5 },
4083 .result_unpriv = ACCEPT,
4084 .result = ACCEPT,
4085 .prog_type = BPF_PROG_TYPE_XDP,
4086 },
4087 {
4088 "helper access to packet: test2, unchecked packet_ptr",
4089 .insns = {
4090 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4091 offsetof(struct xdp_md, data)),
4092 BPF_LD_MAP_FD(BPF_REG_1, 0),
4093 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4094 BPF_FUNC_map_lookup_elem),
4095 BPF_MOV64_IMM(BPF_REG_0, 0),
4096 BPF_EXIT_INSN(),
4097 },
4098 .fixup_map_hash_8b = { 1 },
4099 .result = REJECT,
4100 .errstr = "invalid access to packet",
4101 .prog_type = BPF_PROG_TYPE_XDP,
4102 },
4103 {
4104 "helper access to packet: test3, variable add",
4105 .insns = {
4106 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4107 offsetof(struct xdp_md, data)),
4108 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4109 offsetof(struct xdp_md, data_end)),
4110 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
4112 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
4113 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
4114 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4115 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
4116 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
4117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
4118 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
4119 BPF_LD_MAP_FD(BPF_REG_1, 0),
4120 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
4121 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4122 BPF_FUNC_map_lookup_elem),
4123 BPF_MOV64_IMM(BPF_REG_0, 0),
4124 BPF_EXIT_INSN(),
4125 },
4126 .fixup_map_hash_8b = { 11 },
4127 .result = ACCEPT,
4128 .prog_type = BPF_PROG_TYPE_XDP,
4129 },
4130 {
4131 "helper access to packet: test4, packet_ptr with bad range",
4132 .insns = {
4133 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4134 offsetof(struct xdp_md, data)),
4135 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4136 offsetof(struct xdp_md, data_end)),
4137 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4138 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
4139 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
4140 BPF_MOV64_IMM(BPF_REG_0, 0),
4141 BPF_EXIT_INSN(),
4142 BPF_LD_MAP_FD(BPF_REG_1, 0),
4143 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4144 BPF_FUNC_map_lookup_elem),
4145 BPF_MOV64_IMM(BPF_REG_0, 0),
4146 BPF_EXIT_INSN(),
4147 },
4148 .fixup_map_hash_8b = { 7 },
4149 .result = REJECT,
4150 .errstr = "invalid access to packet",
4151 .prog_type = BPF_PROG_TYPE_XDP,
4152 },
4153 {
4154 "helper access to packet: test5, packet_ptr with too short range",
4155 .insns = {
4156 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4157 offsetof(struct xdp_md, data)),
4158 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4159 offsetof(struct xdp_md, data_end)),
4160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4161 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4162 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4163 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4164 BPF_LD_MAP_FD(BPF_REG_1, 0),
4165 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4166 BPF_FUNC_map_lookup_elem),
4167 BPF_MOV64_IMM(BPF_REG_0, 0),
4168 BPF_EXIT_INSN(),
4169 },
4170 .fixup_map_hash_8b = { 6 },
4171 .result = REJECT,
4172 .errstr = "invalid access to packet",
4173 .prog_type = BPF_PROG_TYPE_XDP,
4174 },
4175 {
4176 "helper access to packet: test6, cls valid packet_ptr range",
4177 .insns = {
4178 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4179 offsetof(struct __sk_buff, data)),
4180 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4181 offsetof(struct __sk_buff, data_end)),
4182 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4184 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
4185 BPF_LD_MAP_FD(BPF_REG_1, 0),
4186 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
4187 BPF_MOV64_IMM(BPF_REG_4, 0),
4188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4189 BPF_FUNC_map_update_elem),
4190 BPF_MOV64_IMM(BPF_REG_0, 0),
4191 BPF_EXIT_INSN(),
4192 },
4193 .fixup_map_hash_8b = { 5 },
4194 .result = ACCEPT,
4195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4196 },
4197 {
4198 "helper access to packet: test7, cls unchecked packet_ptr",
4199 .insns = {
4200 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4201 offsetof(struct __sk_buff, data)),
4202 BPF_LD_MAP_FD(BPF_REG_1, 0),
4203 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4204 BPF_FUNC_map_lookup_elem),
4205 BPF_MOV64_IMM(BPF_REG_0, 0),
4206 BPF_EXIT_INSN(),
4207 },
4208 .fixup_map_hash_8b = { 1 },
4209 .result = REJECT,
4210 .errstr = "invalid access to packet",
4211 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4212 },
4213 {
4214 "helper access to packet: test8, cls variable add",
4215 .insns = {
4216 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4217 offsetof(struct __sk_buff, data)),
4218 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4219 offsetof(struct __sk_buff, data_end)),
4220 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4221 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
4222 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
4223 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
4224 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4225 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
4226 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
4227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
4228 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
4229 BPF_LD_MAP_FD(BPF_REG_1, 0),
4230 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
4231 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4232 BPF_FUNC_map_lookup_elem),
4233 BPF_MOV64_IMM(BPF_REG_0, 0),
4234 BPF_EXIT_INSN(),
4235 },
4236 .fixup_map_hash_8b = { 11 },
4237 .result = ACCEPT,
4238 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4239 },
4240 {
4241 "helper access to packet: test9, cls packet_ptr with bad range",
4242 .insns = {
4243 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4244 offsetof(struct __sk_buff, data)),
4245 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4246 offsetof(struct __sk_buff, data_end)),
4247 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4248 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
4249 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
4250 BPF_MOV64_IMM(BPF_REG_0, 0),
4251 BPF_EXIT_INSN(),
4252 BPF_LD_MAP_FD(BPF_REG_1, 0),
4253 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4254 BPF_FUNC_map_lookup_elem),
4255 BPF_MOV64_IMM(BPF_REG_0, 0),
4256 BPF_EXIT_INSN(),
4257 },
4258 .fixup_map_hash_8b = { 7 },
4259 .result = REJECT,
4260 .errstr = "invalid access to packet",
4261 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4262 },
4263 {
4264 "helper access to packet: test10, cls packet_ptr with too short range",
4265 .insns = {
4266 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4267 offsetof(struct __sk_buff, data)),
4268 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4269 offsetof(struct __sk_buff, data_end)),
4270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4271 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4272 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4273 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4274 BPF_LD_MAP_FD(BPF_REG_1, 0),
4275 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4276 BPF_FUNC_map_lookup_elem),
4277 BPF_MOV64_IMM(BPF_REG_0, 0),
4278 BPF_EXIT_INSN(),
4279 },
4280 .fixup_map_hash_8b = { 6 },
4281 .result = REJECT,
4282 .errstr = "invalid access to packet",
4283 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4284 },
4285 {
4286 "helper access to packet: test11, cls unsuitable helper 1",
4287 .insns = {
4288 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4289 offsetof(struct __sk_buff, data)),
4290 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4291 offsetof(struct __sk_buff, data_end)),
4292 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4293 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4294 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
4295 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
4296 BPF_MOV64_IMM(BPF_REG_2, 0),
4297 BPF_MOV64_IMM(BPF_REG_4, 42),
4298 BPF_MOV64_IMM(BPF_REG_5, 0),
4299 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4300 BPF_FUNC_skb_store_bytes),
4301 BPF_MOV64_IMM(BPF_REG_0, 0),
4302 BPF_EXIT_INSN(),
4303 },
4304 .result = REJECT,
4305 .errstr = "helper access to the packet",
4306 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4307 },
4308 {
4309 "helper access to packet: test12, cls unsuitable helper 2",
4310 .insns = {
4311 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4312 offsetof(struct __sk_buff, data)),
4313 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4314 offsetof(struct __sk_buff, data_end)),
4315 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4316 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
4317 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
4318 BPF_MOV64_IMM(BPF_REG_2, 0),
4319 BPF_MOV64_IMM(BPF_REG_4, 4),
4320 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4321 BPF_FUNC_skb_load_bytes),
4322 BPF_MOV64_IMM(BPF_REG_0, 0),
4323 BPF_EXIT_INSN(),
4324 },
4325 .result = REJECT,
4326 .errstr = "helper access to the packet",
4327 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4328 },
4329 {
4330 "helper access to packet: test13, cls helper ok",
4331 .insns = {
4332 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4333 offsetof(struct __sk_buff, data)),
4334 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4335 offsetof(struct __sk_buff, data_end)),
4336 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4337 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4339 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4340 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4341 BPF_MOV64_IMM(BPF_REG_2, 4),
4342 BPF_MOV64_IMM(BPF_REG_3, 0),
4343 BPF_MOV64_IMM(BPF_REG_4, 0),
4344 BPF_MOV64_IMM(BPF_REG_5, 0),
4345 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4346 BPF_FUNC_csum_diff),
4347 BPF_MOV64_IMM(BPF_REG_0, 0),
4348 BPF_EXIT_INSN(),
4349 },
4350 .result = ACCEPT,
4351 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4352 },
4353 {
4354 "helper access to packet: test14, cls helper ok sub",
4355 .insns = {
4356 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4357 offsetof(struct __sk_buff, data)),
4358 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4359 offsetof(struct __sk_buff, data_end)),
4360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4361 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4362 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4363 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4364 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
4365 BPF_MOV64_IMM(BPF_REG_2, 4),
4366 BPF_MOV64_IMM(BPF_REG_3, 0),
4367 BPF_MOV64_IMM(BPF_REG_4, 0),
4368 BPF_MOV64_IMM(BPF_REG_5, 0),
4369 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4370 BPF_FUNC_csum_diff),
4371 BPF_MOV64_IMM(BPF_REG_0, 0),
4372 BPF_EXIT_INSN(),
4373 },
4374 .result = ACCEPT,
4375 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4376 },
4377 {
4378 "helper access to packet: test15, cls helper fail sub",
4379 .insns = {
4380 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4381 offsetof(struct __sk_buff, data)),
4382 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4383 offsetof(struct __sk_buff, data_end)),
4384 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4385 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4387 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4388 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
4389 BPF_MOV64_IMM(BPF_REG_2, 4),
4390 BPF_MOV64_IMM(BPF_REG_3, 0),
4391 BPF_MOV64_IMM(BPF_REG_4, 0),
4392 BPF_MOV64_IMM(BPF_REG_5, 0),
4393 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4394 BPF_FUNC_csum_diff),
4395 BPF_MOV64_IMM(BPF_REG_0, 0),
4396 BPF_EXIT_INSN(),
4397 },
4398 .result = REJECT,
4399 .errstr = "invalid access to packet",
4400 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4401 },
4402 {
4403 "helper access to packet: test16, cls helper fail range 1",
4404 .insns = {
4405 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4406 offsetof(struct __sk_buff, data)),
4407 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4408 offsetof(struct __sk_buff, data_end)),
4409 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4410 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4411 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4412 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4413 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4414 BPF_MOV64_IMM(BPF_REG_2, 8),
4415 BPF_MOV64_IMM(BPF_REG_3, 0),
4416 BPF_MOV64_IMM(BPF_REG_4, 0),
4417 BPF_MOV64_IMM(BPF_REG_5, 0),
4418 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4419 BPF_FUNC_csum_diff),
4420 BPF_MOV64_IMM(BPF_REG_0, 0),
4421 BPF_EXIT_INSN(),
4422 },
4423 .result = REJECT,
4424 .errstr = "invalid access to packet",
4425 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4426 },
4427 {
4428 "helper access to packet: test17, cls helper fail range 2",
4429 .insns = {
4430 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4431 offsetof(struct __sk_buff, data)),
4432 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4433 offsetof(struct __sk_buff, data_end)),
4434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4435 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4437 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4438 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4439 BPF_MOV64_IMM(BPF_REG_2, -9),
4440 BPF_MOV64_IMM(BPF_REG_3, 0),
4441 BPF_MOV64_IMM(BPF_REG_4, 0),
4442 BPF_MOV64_IMM(BPF_REG_5, 0),
4443 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4444 BPF_FUNC_csum_diff),
4445 BPF_MOV64_IMM(BPF_REG_0, 0),
4446 BPF_EXIT_INSN(),
4447 },
4448 .result = REJECT,
4449 .errstr = "R2 min value is negative",
4450 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4451 },
4452 {
4453 "helper access to packet: test18, cls helper fail range 3",
4454 .insns = {
4455 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4456 offsetof(struct __sk_buff, data)),
4457 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4458 offsetof(struct __sk_buff, data_end)),
4459 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4460 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4462 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4463 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4464 BPF_MOV64_IMM(BPF_REG_2, ~0),
4465 BPF_MOV64_IMM(BPF_REG_3, 0),
4466 BPF_MOV64_IMM(BPF_REG_4, 0),
4467 BPF_MOV64_IMM(BPF_REG_5, 0),
4468 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4469 BPF_FUNC_csum_diff),
4470 BPF_MOV64_IMM(BPF_REG_0, 0),
4471 BPF_EXIT_INSN(),
4472 },
4473 .result = REJECT,
4474 .errstr = "R2 min value is negative",
4475 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4476 },
4477 {
4478 "helper access to packet: test19, cls helper range zero",
4479 .insns = {
4480 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4481 offsetof(struct __sk_buff, data)),
4482 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4483 offsetof(struct __sk_buff, data_end)),
4484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4485 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4486 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4487 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4488 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4489 BPF_MOV64_IMM(BPF_REG_2, 0),
4490 BPF_MOV64_IMM(BPF_REG_3, 0),
4491 BPF_MOV64_IMM(BPF_REG_4, 0),
4492 BPF_MOV64_IMM(BPF_REG_5, 0),
4493 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4494 BPF_FUNC_csum_diff),
4495 BPF_MOV64_IMM(BPF_REG_0, 0),
4496 BPF_EXIT_INSN(),
4497 },
4498 .result = ACCEPT,
4499 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4500 },
4501 {
4502 "helper access to packet: test20, pkt end as input",
4503 .insns = {
4504 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4505 offsetof(struct __sk_buff, data)),
4506 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4507 offsetof(struct __sk_buff, data_end)),
4508 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4509 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4511 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4512 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
4513 BPF_MOV64_IMM(BPF_REG_2, 4),
4514 BPF_MOV64_IMM(BPF_REG_3, 0),
4515 BPF_MOV64_IMM(BPF_REG_4, 0),
4516 BPF_MOV64_IMM(BPF_REG_5, 0),
4517 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4518 BPF_FUNC_csum_diff),
4519 BPF_MOV64_IMM(BPF_REG_0, 0),
4520 BPF_EXIT_INSN(),
4521 },
4522 .result = REJECT,
4523 .errstr = "R1 type=pkt_end expected=fp",
4524 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4525 },
4526 {
4527 "helper access to packet: test21, wrong reg",
4528 .insns = {
4529 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4530 offsetof(struct __sk_buff, data)),
4531 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4532 offsetof(struct __sk_buff, data_end)),
4533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4534 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4536 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4537 BPF_MOV64_IMM(BPF_REG_2, 4),
4538 BPF_MOV64_IMM(BPF_REG_3, 0),
4539 BPF_MOV64_IMM(BPF_REG_4, 0),
4540 BPF_MOV64_IMM(BPF_REG_5, 0),
4541 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4542 BPF_FUNC_csum_diff),
4543 BPF_MOV64_IMM(BPF_REG_0, 0),
4544 BPF_EXIT_INSN(),
4545 },
4546 .result = REJECT,
4547 .errstr = "invalid access to packet",
4548 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4549 },
4550 {
4551 "prevent map lookup in sockmap",
4552 .insns = {
4553 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4554 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4556 BPF_LD_MAP_FD(BPF_REG_1, 0),
4557 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4558 BPF_FUNC_map_lookup_elem),
4559 BPF_EXIT_INSN(),
4560 },
4561 .fixup_map_sockmap = { 3 },
4562 .result = REJECT,
4563 .errstr = "cannot pass map_type 15 into func bpf_map_lookup_elem",
4564 .prog_type = BPF_PROG_TYPE_SOCK_OPS,
4565 },
4566 {
4567 "prevent map lookup in sockhash",
4568 .insns = {
4569 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4570 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4571 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4572 BPF_LD_MAP_FD(BPF_REG_1, 0),
4573 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4574 BPF_FUNC_map_lookup_elem),
4575 BPF_EXIT_INSN(),
4576 },
4577 .fixup_map_sockhash = { 3 },
4578 .result = REJECT,
4579 .errstr = "cannot pass map_type 18 into func bpf_map_lookup_elem",
4580 .prog_type = BPF_PROG_TYPE_SOCK_OPS,
4581 },
4582 {
4583 "prevent map lookup in xskmap",
4584 .insns = {
4585 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4586 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4588 BPF_LD_MAP_FD(BPF_REG_1, 0),
4589 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4590 BPF_FUNC_map_lookup_elem),
4591 BPF_EXIT_INSN(),
4592 },
4593 .fixup_map_xskmap = { 3 },
4594 .result = REJECT,
4595 .errstr = "cannot pass map_type 17 into func bpf_map_lookup_elem",
4596 .prog_type = BPF_PROG_TYPE_XDP,
4597 },
4598 {
4599 "prevent map lookup in stack trace",
4600 .insns = {
4601 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4602 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4603 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4604 BPF_LD_MAP_FD(BPF_REG_1, 0),
4605 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4606 BPF_FUNC_map_lookup_elem),
4607 BPF_EXIT_INSN(),
4608 },
4609 .fixup_map_stacktrace = { 3 },
4610 .result = REJECT,
4611 .errstr = "cannot pass map_type 7 into func bpf_map_lookup_elem",
4612 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
4613 },
4614 {
4615 "prevent map lookup in prog array",
4616 .insns = {
4617 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4618 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4619 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4620 BPF_LD_MAP_FD(BPF_REG_1, 0),
4621 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4622 BPF_FUNC_map_lookup_elem),
4623 BPF_EXIT_INSN(),
4624 },
4625 .fixup_prog2 = { 3 },
4626 .result = REJECT,
4627 .errstr = "cannot pass map_type 3 into func bpf_map_lookup_elem",
4628 },
4629 {
4630 "valid map access into an array with a constant",
4631 .insns = {
4632 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4633 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4635 BPF_LD_MAP_FD(BPF_REG_1, 0),
4636 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4637 BPF_FUNC_map_lookup_elem),
4638 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4639 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4640 offsetof(struct test_val, foo)),
4641 BPF_EXIT_INSN(),
4642 },
4643 .fixup_map_hash_48b = { 3 },
4644 .errstr_unpriv = "R0 leaks addr",
4645 .result_unpriv = REJECT,
4646 .result = ACCEPT,
4647 },
4648 {
4649 "valid map access into an array with a register",
4650 .insns = {
4651 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4652 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4653 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4654 BPF_LD_MAP_FD(BPF_REG_1, 0),
4655 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4656 BPF_FUNC_map_lookup_elem),
4657 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4658 BPF_MOV64_IMM(BPF_REG_1, 4),
4659 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4660 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4661 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4662 offsetof(struct test_val, foo)),
4663 BPF_EXIT_INSN(),
4664 },
4665 .fixup_map_hash_48b = { 3 },
4666 .errstr_unpriv = "R0 leaks addr",
4667 .result_unpriv = REJECT,
4668 .result = ACCEPT,
4669 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4670 },
4671 {
4672 "valid map access into an array with a variable",
4673 .insns = {
4674 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4675 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4676 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4677 BPF_LD_MAP_FD(BPF_REG_1, 0),
4678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4679 BPF_FUNC_map_lookup_elem),
4680 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4681 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4682 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
4683 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4684 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4685 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4686 offsetof(struct test_val, foo)),
4687 BPF_EXIT_INSN(),
4688 },
4689 .fixup_map_hash_48b = { 3 },
4690 .errstr_unpriv = "R0 leaks addr",
4691 .result_unpriv = REJECT,
4692 .result = ACCEPT,
4693 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4694 },
4695 {
4696 "valid map access into an array with a signed variable",
4697 .insns = {
4698 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4699 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4700 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4701 BPF_LD_MAP_FD(BPF_REG_1, 0),
4702 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4703 BPF_FUNC_map_lookup_elem),
4704 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
4705 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4706 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
4707 BPF_MOV32_IMM(BPF_REG_1, 0),
4708 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4709 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4710 BPF_MOV32_IMM(BPF_REG_1, 0),
4711 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4712 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4713 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4714 offsetof(struct test_val, foo)),
4715 BPF_EXIT_INSN(),
4716 },
4717 .fixup_map_hash_48b = { 3 },
4718 .errstr_unpriv = "R0 leaks addr",
4719 .result_unpriv = REJECT,
4720 .result = ACCEPT,
4721 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4722 },
4723 {
4724 "invalid map access into an array with a constant",
4725 .insns = {
4726 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4727 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4728 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4729 BPF_LD_MAP_FD(BPF_REG_1, 0),
4730 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4731 BPF_FUNC_map_lookup_elem),
4732 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4733 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
4734 offsetof(struct test_val, foo)),
4735 BPF_EXIT_INSN(),
4736 },
4737 .fixup_map_hash_48b = { 3 },
4738 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
4739 .result = REJECT,
4740 },
4741 {
4742 "invalid map access into an array with a register",
4743 .insns = {
4744 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4745 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4747 BPF_LD_MAP_FD(BPF_REG_1, 0),
4748 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4749 BPF_FUNC_map_lookup_elem),
4750 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4751 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
4752 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4753 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4754 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4755 offsetof(struct test_val, foo)),
4756 BPF_EXIT_INSN(),
4757 },
4758 .fixup_map_hash_48b = { 3 },
4759 .errstr = "R0 min value is outside of the array range",
4760 .result = REJECT,
4761 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4762 },
4763 {
4764 "invalid map access into an array with a variable",
4765 .insns = {
4766 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4767 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4768 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4769 BPF_LD_MAP_FD(BPF_REG_1, 0),
4770 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4771 BPF_FUNC_map_lookup_elem),
4772 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4773 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4774 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4775 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4776 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4777 offsetof(struct test_val, foo)),
4778 BPF_EXIT_INSN(),
4779 },
4780 .fixup_map_hash_48b = { 3 },
4781 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
4782 .result = REJECT,
4783 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4784 },
4785 {
4786 "invalid map access into an array with no floor check",
4787 .insns = {
4788 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4789 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4791 BPF_LD_MAP_FD(BPF_REG_1, 0),
4792 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4793 BPF_FUNC_map_lookup_elem),
4794 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4795 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4796 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4797 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4798 BPF_MOV32_IMM(BPF_REG_1, 0),
4799 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4800 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4801 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4802 offsetof(struct test_val, foo)),
4803 BPF_EXIT_INSN(),
4804 },
4805 .fixup_map_hash_48b = { 3 },
4806 .errstr_unpriv = "R0 leaks addr",
4807 .errstr = "R0 unbounded memory access",
4808 .result_unpriv = REJECT,
4809 .result = REJECT,
4810 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4811 },
4812 {
4813 "invalid map access into an array with a invalid max check",
4814 .insns = {
4815 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4816 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4818 BPF_LD_MAP_FD(BPF_REG_1, 0),
4819 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4820 BPF_FUNC_map_lookup_elem),
4821 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4822 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4823 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
4824 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
4825 BPF_MOV32_IMM(BPF_REG_1, 0),
4826 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4827 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4828 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4829 offsetof(struct test_val, foo)),
4830 BPF_EXIT_INSN(),
4831 },
4832 .fixup_map_hash_48b = { 3 },
4833 .errstr_unpriv = "R0 leaks addr",
4834 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
4835 .result_unpriv = REJECT,
4836 .result = REJECT,
4837 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4838 },
4839 {
4840 "invalid map access into an array with a invalid max check",
4841 .insns = {
4842 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4843 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4844 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4845 BPF_LD_MAP_FD(BPF_REG_1, 0),
4846 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4847 BPF_FUNC_map_lookup_elem),
4848 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4849 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4850 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4851 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4853 BPF_LD_MAP_FD(BPF_REG_1, 0),
4854 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4855 BPF_FUNC_map_lookup_elem),
4856 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4857 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
4858 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
4859 offsetof(struct test_val, foo)),
4860 BPF_EXIT_INSN(),
4861 },
4862 .fixup_map_hash_48b = { 3, 11 },
4863 .errstr = "R0 pointer += pointer",
4864 .result = REJECT,
4865 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4866 },
4867 {
4868 "direct packet read test#1 for CGROUP_SKB",
4869 .insns = {
4870 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4871 offsetof(struct __sk_buff, data)),
4872 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4873 offsetof(struct __sk_buff, data_end)),
4874 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
4875 offsetof(struct __sk_buff, len)),
4876 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4877 offsetof(struct __sk_buff, pkt_type)),
4878 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4879 offsetof(struct __sk_buff, mark)),
4880 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
4881 offsetof(struct __sk_buff, mark)),
4882 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4883 offsetof(struct __sk_buff, queue_mapping)),
4884 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
4885 offsetof(struct __sk_buff, protocol)),
4886 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
4887 offsetof(struct __sk_buff, vlan_present)),
4888 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4889 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4890 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4891 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4892 BPF_MOV64_IMM(BPF_REG_0, 0),
4893 BPF_EXIT_INSN(),
4894 },
4895 .result = ACCEPT,
4896 .result_unpriv = REJECT,
4897 .errstr_unpriv = "invalid bpf_context access off=76 size=4",
4898 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4899 },
4900 {
4901 "direct packet read test#2 for CGROUP_SKB",
4902 .insns = {
4903 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
4904 offsetof(struct __sk_buff, vlan_tci)),
4905 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4906 offsetof(struct __sk_buff, vlan_proto)),
4907 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4908 offsetof(struct __sk_buff, priority)),
4909 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
4910 offsetof(struct __sk_buff, priority)),
4911 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4912 offsetof(struct __sk_buff,
4913 ingress_ifindex)),
4914 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
4915 offsetof(struct __sk_buff, tc_index)),
4916 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
4917 offsetof(struct __sk_buff, hash)),
4918 BPF_MOV64_IMM(BPF_REG_0, 0),
4919 BPF_EXIT_INSN(),
4920 },
4921 .result = ACCEPT,
4922 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4923 },
4924 {
4925 "direct packet read test#3 for CGROUP_SKB",
4926 .insns = {
4927 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
4928 offsetof(struct __sk_buff, cb[0])),
4929 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4930 offsetof(struct __sk_buff, cb[1])),
4931 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4932 offsetof(struct __sk_buff, cb[2])),
4933 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4934 offsetof(struct __sk_buff, cb[3])),
4935 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
4936 offsetof(struct __sk_buff, cb[4])),
4937 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
4938 offsetof(struct __sk_buff, napi_id)),
4939 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_4,
4940 offsetof(struct __sk_buff, cb[0])),
4941 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_5,
4942 offsetof(struct __sk_buff, cb[1])),
4943 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
4944 offsetof(struct __sk_buff, cb[2])),
4945 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_7,
4946 offsetof(struct __sk_buff, cb[3])),
4947 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_8,
4948 offsetof(struct __sk_buff, cb[4])),
4949 BPF_MOV64_IMM(BPF_REG_0, 0),
4950 BPF_EXIT_INSN(),
4951 },
4952 .result = ACCEPT,
4953 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4954 },
4955 {
4956 "direct packet read test#4 for CGROUP_SKB",
4957 .insns = {
4958 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4959 offsetof(struct __sk_buff, family)),
4960 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4961 offsetof(struct __sk_buff, remote_ip4)),
4962 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
4963 offsetof(struct __sk_buff, local_ip4)),
4964 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4965 offsetof(struct __sk_buff, remote_ip6[0])),
4966 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4967 offsetof(struct __sk_buff, remote_ip6[1])),
4968 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4969 offsetof(struct __sk_buff, remote_ip6[2])),
4970 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1,
4971 offsetof(struct __sk_buff, remote_ip6[3])),
4972 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4973 offsetof(struct __sk_buff, local_ip6[0])),
4974 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4975 offsetof(struct __sk_buff, local_ip6[1])),
4976 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4977 offsetof(struct __sk_buff, local_ip6[2])),
4978 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4979 offsetof(struct __sk_buff, local_ip6[3])),
4980 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4981 offsetof(struct __sk_buff, remote_port)),
4982 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
4983 offsetof(struct __sk_buff, local_port)),
4984 BPF_MOV64_IMM(BPF_REG_0, 0),
4985 BPF_EXIT_INSN(),
4986 },
4987 .result = ACCEPT,
4988 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4989 },
4990 {
4991 "invalid access of tc_classid for CGROUP_SKB",
4992 .insns = {
4993 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4994 offsetof(struct __sk_buff, tc_classid)),
4995 BPF_MOV64_IMM(BPF_REG_0, 0),
4996 BPF_EXIT_INSN(),
4997 },
4998 .result = REJECT,
4999 .errstr = "invalid bpf_context access",
5000 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5001 },
5002 {
5003 "invalid access of data_meta for CGROUP_SKB",
5004 .insns = {
5005 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5006 offsetof(struct __sk_buff, data_meta)),
5007 BPF_MOV64_IMM(BPF_REG_0, 0),
5008 BPF_EXIT_INSN(),
5009 },
5010 .result = REJECT,
5011 .errstr = "invalid bpf_context access",
5012 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5013 },
5014 {
5015 "invalid access of flow_keys for CGROUP_SKB",
5016 .insns = {
5017 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5018 offsetof(struct __sk_buff, flow_keys)),
5019 BPF_MOV64_IMM(BPF_REG_0, 0),
5020 BPF_EXIT_INSN(),
5021 },
5022 .result = REJECT,
5023 .errstr = "invalid bpf_context access",
5024 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5025 },
5026 {
5027 "invalid write access to napi_id for CGROUP_SKB",
5028 .insns = {
5029 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
5030 offsetof(struct __sk_buff, napi_id)),
5031 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_9,
5032 offsetof(struct __sk_buff, napi_id)),
5033 BPF_MOV64_IMM(BPF_REG_0, 0),
5034 BPF_EXIT_INSN(),
5035 },
5036 .result = REJECT,
5037 .errstr = "invalid bpf_context access",
5038 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5039 },
5040 {
5041 "valid cgroup storage access",
5042 .insns = {
5043 BPF_MOV64_IMM(BPF_REG_2, 0),
5044 BPF_LD_MAP_FD(BPF_REG_1, 0),
5045 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5046 BPF_FUNC_get_local_storage),
5047 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5048 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5049 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5050 BPF_EXIT_INSN(),
5051 },
5052 .fixup_cgroup_storage = { 1 },
5053 .result = ACCEPT,
5054 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5055 },
5056 {
5057 "invalid cgroup storage access 1",
5058 .insns = {
5059 BPF_MOV64_IMM(BPF_REG_2, 0),
5060 BPF_LD_MAP_FD(BPF_REG_1, 0),
5061 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5062 BPF_FUNC_get_local_storage),
5063 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5064 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5065 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5066 BPF_EXIT_INSN(),
5067 },
5068 .fixup_map_hash_8b = { 1 },
5069 .result = REJECT,
5070 .errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
5071 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5072 },
5073 {
5074 "invalid cgroup storage access 2",
5075 .insns = {
5076 BPF_MOV64_IMM(BPF_REG_2, 0),
5077 BPF_LD_MAP_FD(BPF_REG_1, 1),
5078 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5079 BPF_FUNC_get_local_storage),
5080 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5081 BPF_EXIT_INSN(),
5082 },
5083 .result = REJECT,
5084 .errstr = "fd 1 is not pointing to valid bpf_map",
5085 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5086 },
5087 {
5088 "invalid cgroup storage access 3",
5089 .insns = {
5090 BPF_MOV64_IMM(BPF_REG_2, 0),
5091 BPF_LD_MAP_FD(BPF_REG_1, 0),
5092 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5093 BPF_FUNC_get_local_storage),
5094 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
5095 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5096 BPF_MOV64_IMM(BPF_REG_0, 0),
5097 BPF_EXIT_INSN(),
5098 },
5099 .fixup_cgroup_storage = { 1 },
5100 .result = REJECT,
5101 .errstr = "invalid access to map value, value_size=64 off=256 size=4",
5102 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5103 },
5104 {
5105 "invalid cgroup storage access 4",
5106 .insns = {
5107 BPF_MOV64_IMM(BPF_REG_2, 0),
5108 BPF_LD_MAP_FD(BPF_REG_1, 0),
5109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5110 BPF_FUNC_get_local_storage),
5111 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
5112 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5113 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5114 BPF_EXIT_INSN(),
5115 },
5116 .fixup_cgroup_storage = { 1 },
5117 .result = REJECT,
5118 .errstr = "invalid access to map value, value_size=64 off=-2 size=4",
5119 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5120 },
5121 {
5122 "invalid cgroup storage access 5",
5123 .insns = {
5124 BPF_MOV64_IMM(BPF_REG_2, 7),
5125 BPF_LD_MAP_FD(BPF_REG_1, 0),
5126 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5127 BPF_FUNC_get_local_storage),
5128 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5129 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5130 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5131 BPF_EXIT_INSN(),
5132 },
5133 .fixup_cgroup_storage = { 1 },
5134 .result = REJECT,
5135 .errstr = "get_local_storage() doesn't support non-zero flags",
5136 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5137 },
5138 {
5139 "invalid cgroup storage access 6",
5140 .insns = {
5141 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
5142 BPF_LD_MAP_FD(BPF_REG_1, 0),
5143 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5144 BPF_FUNC_get_local_storage),
5145 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5146 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5147 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5148 BPF_EXIT_INSN(),
5149 },
5150 .fixup_cgroup_storage = { 1 },
5151 .result = REJECT,
5152 .errstr = "get_local_storage() doesn't support non-zero flags",
5153 .errstr_unpriv = "R2 leaks addr into helper function",
5154 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5155 },
5156 {
5157 "valid per-cpu cgroup storage access",
5158 .insns = {
5159 BPF_MOV64_IMM(BPF_REG_2, 0),
5160 BPF_LD_MAP_FD(BPF_REG_1, 0),
5161 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5162 BPF_FUNC_get_local_storage),
5163 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5164 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5165 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5166 BPF_EXIT_INSN(),
5167 },
5168 .fixup_percpu_cgroup_storage = { 1 },
5169 .result = ACCEPT,
5170 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5171 },
5172 {
5173 "invalid per-cpu cgroup storage access 1",
5174 .insns = {
5175 BPF_MOV64_IMM(BPF_REG_2, 0),
5176 BPF_LD_MAP_FD(BPF_REG_1, 0),
5177 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5178 BPF_FUNC_get_local_storage),
5179 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5180 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5181 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5182 BPF_EXIT_INSN(),
5183 },
5184 .fixup_map_hash_8b = { 1 },
5185 .result = REJECT,
5186 .errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
5187 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5188 },
5189 {
5190 "invalid per-cpu cgroup storage access 2",
5191 .insns = {
5192 BPF_MOV64_IMM(BPF_REG_2, 0),
5193 BPF_LD_MAP_FD(BPF_REG_1, 1),
5194 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5195 BPF_FUNC_get_local_storage),
5196 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5197 BPF_EXIT_INSN(),
5198 },
5199 .result = REJECT,
5200 .errstr = "fd 1 is not pointing to valid bpf_map",
5201 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5202 },
5203 {
5204 "invalid per-cpu cgroup storage access 3",
5205 .insns = {
5206 BPF_MOV64_IMM(BPF_REG_2, 0),
5207 BPF_LD_MAP_FD(BPF_REG_1, 0),
5208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5209 BPF_FUNC_get_local_storage),
5210 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
5211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5212 BPF_MOV64_IMM(BPF_REG_0, 0),
5213 BPF_EXIT_INSN(),
5214 },
5215 .fixup_percpu_cgroup_storage = { 1 },
5216 .result = REJECT,
5217 .errstr = "invalid access to map value, value_size=64 off=256 size=4",
5218 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5219 },
5220 {
5221 "invalid per-cpu cgroup storage access 4",
5222 .insns = {
5223 BPF_MOV64_IMM(BPF_REG_2, 0),
5224 BPF_LD_MAP_FD(BPF_REG_1, 0),
5225 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5226 BPF_FUNC_get_local_storage),
5227 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
5228 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5230 BPF_EXIT_INSN(),
5231 },
5232 .fixup_cgroup_storage = { 1 },
5233 .result = REJECT,
5234 .errstr = "invalid access to map value, value_size=64 off=-2 size=4",
5235 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5236 },
5237 {
5238 "invalid per-cpu cgroup storage access 5",
5239 .insns = {
5240 BPF_MOV64_IMM(BPF_REG_2, 7),
5241 BPF_LD_MAP_FD(BPF_REG_1, 0),
5242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5243 BPF_FUNC_get_local_storage),
5244 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5245 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5246 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5247 BPF_EXIT_INSN(),
5248 },
5249 .fixup_percpu_cgroup_storage = { 1 },
5250 .result = REJECT,
5251 .errstr = "get_local_storage() doesn't support non-zero flags",
5252 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5253 },
5254 {
5255 "invalid per-cpu cgroup storage access 6",
5256 .insns = {
5257 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
5258 BPF_LD_MAP_FD(BPF_REG_1, 0),
5259 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5260 BPF_FUNC_get_local_storage),
5261 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5262 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5263 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
5264 BPF_EXIT_INSN(),
5265 },
5266 .fixup_percpu_cgroup_storage = { 1 },
5267 .result = REJECT,
5268 .errstr = "get_local_storage() doesn't support non-zero flags",
5269 .errstr_unpriv = "R2 leaks addr into helper function",
5270 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
5271 },
5272 {
5273 "multiple registers share map_lookup_elem result",
5274 .insns = {
5275 BPF_MOV64_IMM(BPF_REG_1, 10),
5276 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5277 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5279 BPF_LD_MAP_FD(BPF_REG_1, 0),
5280 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5281 BPF_FUNC_map_lookup_elem),
5282 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5283 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5284 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5285 BPF_EXIT_INSN(),
5286 },
5287 .fixup_map_hash_8b = { 4 },
5288 .result = ACCEPT,
5289 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5290 },
5291 {
5292 "alu ops on ptr_to_map_value_or_null, 1",
5293 .insns = {
5294 BPF_MOV64_IMM(BPF_REG_1, 10),
5295 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5296 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5298 BPF_LD_MAP_FD(BPF_REG_1, 0),
5299 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5300 BPF_FUNC_map_lookup_elem),
5301 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
5303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
5304 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5305 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5306 BPF_EXIT_INSN(),
5307 },
5308 .fixup_map_hash_8b = { 4 },
5309 .errstr = "R4 pointer arithmetic on map_value_or_null",
5310 .result = REJECT,
5311 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5312 },
5313 {
5314 "alu ops on ptr_to_map_value_or_null, 2",
5315 .insns = {
5316 BPF_MOV64_IMM(BPF_REG_1, 10),
5317 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5318 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5319 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5320 BPF_LD_MAP_FD(BPF_REG_1, 0),
5321 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5322 BPF_FUNC_map_lookup_elem),
5323 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5324 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
5325 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5326 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5327 BPF_EXIT_INSN(),
5328 },
5329 .fixup_map_hash_8b = { 4 },
5330 .errstr = "R4 pointer arithmetic on map_value_or_null",
5331 .result = REJECT,
5332 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5333 },
5334 {
5335 "alu ops on ptr_to_map_value_or_null, 3",
5336 .insns = {
5337 BPF_MOV64_IMM(BPF_REG_1, 10),
5338 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5339 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5340 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5341 BPF_LD_MAP_FD(BPF_REG_1, 0),
5342 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5343 BPF_FUNC_map_lookup_elem),
5344 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5345 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
5346 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5347 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5348 BPF_EXIT_INSN(),
5349 },
5350 .fixup_map_hash_8b = { 4 },
5351 .errstr = "R4 pointer arithmetic on map_value_or_null",
5352 .result = REJECT,
5353 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5354 },
5355 {
5356 "invalid memory access with multiple map_lookup_elem calls",
5357 .insns = {
5358 BPF_MOV64_IMM(BPF_REG_1, 10),
5359 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5360 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5362 BPF_LD_MAP_FD(BPF_REG_1, 0),
5363 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
5364 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
5365 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5366 BPF_FUNC_map_lookup_elem),
5367 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5368 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
5369 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
5370 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5371 BPF_FUNC_map_lookup_elem),
5372 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5373 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5374 BPF_EXIT_INSN(),
5375 },
5376 .fixup_map_hash_8b = { 4 },
5377 .result = REJECT,
5378 .errstr = "R4 !read_ok",
5379 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5380 },
5381 {
5382 "valid indirect map_lookup_elem access with 2nd lookup in branch",
5383 .insns = {
5384 BPF_MOV64_IMM(BPF_REG_1, 10),
5385 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
5386 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5387 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5388 BPF_LD_MAP_FD(BPF_REG_1, 0),
5389 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
5390 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
5391 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5392 BPF_FUNC_map_lookup_elem),
5393 BPF_MOV64_IMM(BPF_REG_2, 10),
5394 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
5395 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
5396 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
5397 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5398 BPF_FUNC_map_lookup_elem),
5399 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
5400 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5401 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
5402 BPF_EXIT_INSN(),
5403 },
5404 .fixup_map_hash_8b = { 4 },
5405 .result = ACCEPT,
5406 .prog_type = BPF_PROG_TYPE_SCHED_CLS
5407 },
5408 {
5409 "invalid map access from else condition",
5410 .insns = {
5411 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5412 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5413 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5414 BPF_LD_MAP_FD(BPF_REG_1, 0),
5415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
5416 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5417 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5418 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
5419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5420 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
5421 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5422 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
5423 BPF_EXIT_INSN(),
5424 },
5425 .fixup_map_hash_48b = { 3 },
5426 .errstr = "R0 unbounded memory access",
5427 .result = REJECT,
5428 .errstr_unpriv = "R0 leaks addr",
5429 .result_unpriv = REJECT,
5430 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5431 },
5432 {
5433 "constant register |= constant should keep constant type",
5434 .insns = {
5435 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5437 BPF_MOV64_IMM(BPF_REG_2, 34),
5438 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
5439 BPF_MOV64_IMM(BPF_REG_3, 0),
5440 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5441 BPF_EXIT_INSN(),
5442 },
5443 .result = ACCEPT,
5444 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5445 },
5446 {
5447 "constant register |= constant should not bypass stack boundary checks",
5448 .insns = {
5449 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5450 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5451 BPF_MOV64_IMM(BPF_REG_2, 34),
5452 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
5453 BPF_MOV64_IMM(BPF_REG_3, 0),
5454 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5455 BPF_EXIT_INSN(),
5456 },
5457 .errstr = "invalid stack type R1 off=-48 access_size=58",
5458 .result = REJECT,
5459 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5460 },
5461 {
5462 "constant register |= constant register should keep constant type",
5463 .insns = {
5464 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5465 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5466 BPF_MOV64_IMM(BPF_REG_2, 34),
5467 BPF_MOV64_IMM(BPF_REG_4, 13),
5468 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
5469 BPF_MOV64_IMM(BPF_REG_3, 0),
5470 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5471 BPF_EXIT_INSN(),
5472 },
5473 .result = ACCEPT,
5474 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5475 },
5476 {
5477 "constant register |= constant register should not bypass stack boundary checks",
5478 .insns = {
5479 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5481 BPF_MOV64_IMM(BPF_REG_2, 34),
5482 BPF_MOV64_IMM(BPF_REG_4, 24),
5483 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
5484 BPF_MOV64_IMM(BPF_REG_3, 0),
5485 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5486 BPF_EXIT_INSN(),
5487 },
5488 .errstr = "invalid stack type R1 off=-48 access_size=58",
5489 .result = REJECT,
5490 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5491 },
5492 {
5493 "invalid direct packet write for LWT_IN",
5494 .insns = {
5495 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5496 offsetof(struct __sk_buff, data)),
5497 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5498 offsetof(struct __sk_buff, data_end)),
5499 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5500 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5501 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5502 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5503 BPF_MOV64_IMM(BPF_REG_0, 0),
5504 BPF_EXIT_INSN(),
5505 },
5506 .errstr = "cannot write into packet",
5507 .result = REJECT,
5508 .prog_type = BPF_PROG_TYPE_LWT_IN,
5509 },
5510 {
5511 "invalid direct packet write for LWT_OUT",
5512 .insns = {
5513 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5514 offsetof(struct __sk_buff, data)),
5515 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5516 offsetof(struct __sk_buff, data_end)),
5517 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5518 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5519 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5520 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5521 BPF_MOV64_IMM(BPF_REG_0, 0),
5522 BPF_EXIT_INSN(),
5523 },
5524 .errstr = "cannot write into packet",
5525 .result = REJECT,
5526 .prog_type = BPF_PROG_TYPE_LWT_OUT,
5527 },
5528 {
5529 "direct packet write for LWT_XMIT",
5530 .insns = {
5531 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5532 offsetof(struct __sk_buff, data)),
5533 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5534 offsetof(struct __sk_buff, data_end)),
5535 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5536 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5537 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5538 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5539 BPF_MOV64_IMM(BPF_REG_0, 0),
5540 BPF_EXIT_INSN(),
5541 },
5542 .result = ACCEPT,
5543 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5544 },
5545 {
5546 "direct packet read for LWT_IN",
5547 .insns = {
5548 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5549 offsetof(struct __sk_buff, data)),
5550 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5551 offsetof(struct __sk_buff, data_end)),
5552 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5553 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5554 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5555 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5556 BPF_MOV64_IMM(BPF_REG_0, 0),
5557 BPF_EXIT_INSN(),
5558 },
5559 .result = ACCEPT,
5560 .prog_type = BPF_PROG_TYPE_LWT_IN,
5561 },
5562 {
5563 "direct packet read for LWT_OUT",
5564 .insns = {
5565 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5566 offsetof(struct __sk_buff, data)),
5567 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5568 offsetof(struct __sk_buff, data_end)),
5569 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5570 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5571 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5572 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5573 BPF_MOV64_IMM(BPF_REG_0, 0),
5574 BPF_EXIT_INSN(),
5575 },
5576 .result = ACCEPT,
5577 .prog_type = BPF_PROG_TYPE_LWT_OUT,
5578 },
5579 {
5580 "direct packet read for LWT_XMIT",
5581 .insns = {
5582 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5583 offsetof(struct __sk_buff, data)),
5584 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5585 offsetof(struct __sk_buff, data_end)),
5586 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5588 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5589 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5590 BPF_MOV64_IMM(BPF_REG_0, 0),
5591 BPF_EXIT_INSN(),
5592 },
5593 .result = ACCEPT,
5594 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5595 },
5596 {
5597 "overlapping checks for direct packet access",
5598 .insns = {
5599 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5600 offsetof(struct __sk_buff, data)),
5601 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5602 offsetof(struct __sk_buff, data_end)),
5603 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5605 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
5606 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
5608 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
5609 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
5610 BPF_MOV64_IMM(BPF_REG_0, 0),
5611 BPF_EXIT_INSN(),
5612 },
5613 .result = ACCEPT,
5614 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5615 },
5616 {
5617 "make headroom for LWT_XMIT",
5618 .insns = {
5619 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5620 BPF_MOV64_IMM(BPF_REG_2, 34),
5621 BPF_MOV64_IMM(BPF_REG_3, 0),
5622 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
5623 /* split for s390 to succeed */
5624 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
5625 BPF_MOV64_IMM(BPF_REG_2, 42),
5626 BPF_MOV64_IMM(BPF_REG_3, 0),
5627 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
5628 BPF_MOV64_IMM(BPF_REG_0, 0),
5629 BPF_EXIT_INSN(),
5630 },
5631 .result = ACCEPT,
5632 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5633 },
5634 {
5635 "invalid access of tc_classid for LWT_IN",
5636 .insns = {
5637 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5638 offsetof(struct __sk_buff, tc_classid)),
5639 BPF_EXIT_INSN(),
5640 },
5641 .result = REJECT,
5642 .errstr = "invalid bpf_context access",
5643 },
5644 {
5645 "invalid access of tc_classid for LWT_OUT",
5646 .insns = {
5647 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5648 offsetof(struct __sk_buff, tc_classid)),
5649 BPF_EXIT_INSN(),
5650 },
5651 .result = REJECT,
5652 .errstr = "invalid bpf_context access",
5653 },
5654 {
5655 "invalid access of tc_classid for LWT_XMIT",
5656 .insns = {
5657 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5658 offsetof(struct __sk_buff, tc_classid)),
5659 BPF_EXIT_INSN(),
5660 },
5661 .result = REJECT,
5662 .errstr = "invalid bpf_context access",
5663 },
5664 {
5665 "leak pointer into ctx 1",
5666 .insns = {
5667 BPF_MOV64_IMM(BPF_REG_0, 0),
5668 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5669 offsetof(struct __sk_buff, cb[0])),
5670 BPF_LD_MAP_FD(BPF_REG_2, 0),
5671 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
5672 offsetof(struct __sk_buff, cb[0])),
5673 BPF_EXIT_INSN(),
5674 },
5675 .fixup_map_hash_8b = { 2 },
5676 .errstr_unpriv = "R2 leaks addr into mem",
5677 .result_unpriv = REJECT,
5678 .result = REJECT,
5679 .errstr = "BPF_XADD stores into R1 ctx is not allowed",
5680 },
5681 {
5682 "leak pointer into ctx 2",
5683 .insns = {
5684 BPF_MOV64_IMM(BPF_REG_0, 0),
5685 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5686 offsetof(struct __sk_buff, cb[0])),
5687 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
5688 offsetof(struct __sk_buff, cb[0])),
5689 BPF_EXIT_INSN(),
5690 },
5691 .errstr_unpriv = "R10 leaks addr into mem",
5692 .result_unpriv = REJECT,
5693 .result = REJECT,
5694 .errstr = "BPF_XADD stores into R1 ctx is not allowed",
5695 },
5696 {
5697 "leak pointer into ctx 3",
5698 .insns = {
5699 BPF_MOV64_IMM(BPF_REG_0, 0),
5700 BPF_LD_MAP_FD(BPF_REG_2, 0),
5701 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
5702 offsetof(struct __sk_buff, cb[0])),
5703 BPF_EXIT_INSN(),
5704 },
5705 .fixup_map_hash_8b = { 1 },
5706 .errstr_unpriv = "R2 leaks addr into ctx",
5707 .result_unpriv = REJECT,
5708 .result = ACCEPT,
5709 },
5710 {
5711 "leak pointer into map val",
5712 .insns = {
5713 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5714 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5715 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5716 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5717 BPF_LD_MAP_FD(BPF_REG_1, 0),
5718 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5719 BPF_FUNC_map_lookup_elem),
5720 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5721 BPF_MOV64_IMM(BPF_REG_3, 0),
5722 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
5723 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
5724 BPF_MOV64_IMM(BPF_REG_0, 0),
5725 BPF_EXIT_INSN(),
5726 },
5727 .fixup_map_hash_8b = { 4 },
5728 .errstr_unpriv = "R6 leaks addr into mem",
5729 .result_unpriv = REJECT,
5730 .result = ACCEPT,
5731 },
5732 {
5733 "helper access to map: full range",
5734 .insns = {
5735 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5736 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5737 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5738 BPF_LD_MAP_FD(BPF_REG_1, 0),
5739 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5740 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5741 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5742 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5743 BPF_MOV64_IMM(BPF_REG_3, 0),
5744 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5745 BPF_EXIT_INSN(),
5746 },
5747 .fixup_map_hash_48b = { 3 },
5748 .result = ACCEPT,
5749 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5750 },
5751 {
5752 "helper access to map: partial range",
5753 .insns = {
5754 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5755 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5756 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5757 BPF_LD_MAP_FD(BPF_REG_1, 0),
5758 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5759 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5760 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5761 BPF_MOV64_IMM(BPF_REG_2, 8),
5762 BPF_MOV64_IMM(BPF_REG_3, 0),
5763 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5764 BPF_EXIT_INSN(),
5765 },
5766 .fixup_map_hash_48b = { 3 },
5767 .result = ACCEPT,
5768 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5769 },
5770 {
5771 "helper access to map: empty range",
5772 .insns = {
5773 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5775 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5776 BPF_LD_MAP_FD(BPF_REG_1, 0),
5777 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5778 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5779 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5780 BPF_MOV64_IMM(BPF_REG_2, 0),
5781 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5782 BPF_EXIT_INSN(),
5783 },
5784 .fixup_map_hash_48b = { 3 },
5785 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
5786 .result = REJECT,
5787 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5788 },
5789 {
5790 "helper access to map: out-of-bound range",
5791 .insns = {
5792 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5794 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5795 BPF_LD_MAP_FD(BPF_REG_1, 0),
5796 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5797 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5798 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5799 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
5800 BPF_MOV64_IMM(BPF_REG_3, 0),
5801 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5802 BPF_EXIT_INSN(),
5803 },
5804 .fixup_map_hash_48b = { 3 },
5805 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
5806 .result = REJECT,
5807 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5808 },
5809 {
5810 "helper access to map: negative range",
5811 .insns = {
5812 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5813 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5814 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5815 BPF_LD_MAP_FD(BPF_REG_1, 0),
5816 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5817 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5818 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5819 BPF_MOV64_IMM(BPF_REG_2, -8),
5820 BPF_MOV64_IMM(BPF_REG_3, 0),
5821 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5822 BPF_EXIT_INSN(),
5823 },
5824 .fixup_map_hash_48b = { 3 },
5825 .errstr = "R2 min value is negative",
5826 .result = REJECT,
5827 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5828 },
5829 {
5830 "helper access to adjusted map (via const imm): full range",
5831 .insns = {
5832 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5833 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5834 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5835 BPF_LD_MAP_FD(BPF_REG_1, 0),
5836 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5837 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5838 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5839 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5840 offsetof(struct test_val, foo)),
5841 BPF_MOV64_IMM(BPF_REG_2,
5842 sizeof(struct test_val) -
5843 offsetof(struct test_val, foo)),
5844 BPF_MOV64_IMM(BPF_REG_3, 0),
5845 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5846 BPF_EXIT_INSN(),
5847 },
5848 .fixup_map_hash_48b = { 3 },
5849 .result = ACCEPT,
5850 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5851 },
5852 {
5853 "helper access to adjusted map (via const imm): partial range",
5854 .insns = {
5855 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5856 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5857 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5858 BPF_LD_MAP_FD(BPF_REG_1, 0),
5859 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5860 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5861 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5863 offsetof(struct test_val, foo)),
5864 BPF_MOV64_IMM(BPF_REG_2, 8),
5865 BPF_MOV64_IMM(BPF_REG_3, 0),
5866 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5867 BPF_EXIT_INSN(),
5868 },
5869 .fixup_map_hash_48b = { 3 },
5870 .result = ACCEPT,
5871 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5872 },
5873 {
5874 "helper access to adjusted map (via const imm): empty range",
5875 .insns = {
5876 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5878 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5879 BPF_LD_MAP_FD(BPF_REG_1, 0),
5880 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5881 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5882 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5883 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5884 offsetof(struct test_val, foo)),
5885 BPF_MOV64_IMM(BPF_REG_2, 0),
5886 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
5887 BPF_EXIT_INSN(),
5888 },
5889 .fixup_map_hash_48b = { 3 },
5890 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
5891 .result = REJECT,
5892 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5893 },
5894 {
5895 "helper access to adjusted map (via const imm): out-of-bound range",
5896 .insns = {
5897 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5898 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5899 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5900 BPF_LD_MAP_FD(BPF_REG_1, 0),
5901 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5902 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5903 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5904 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5905 offsetof(struct test_val, foo)),
5906 BPF_MOV64_IMM(BPF_REG_2,
5907 sizeof(struct test_val) -
5908 offsetof(struct test_val, foo) + 8),
5909 BPF_MOV64_IMM(BPF_REG_3, 0),
5910 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5911 BPF_EXIT_INSN(),
5912 },
5913 .fixup_map_hash_48b = { 3 },
5914 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5915 .result = REJECT,
5916 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5917 },
5918 {
5919 "helper access to adjusted map (via const imm): negative range (> adjustment)",
5920 .insns = {
5921 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5923 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5924 BPF_LD_MAP_FD(BPF_REG_1, 0),
5925 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5926 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5927 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5928 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5929 offsetof(struct test_val, foo)),
5930 BPF_MOV64_IMM(BPF_REG_2, -8),
5931 BPF_MOV64_IMM(BPF_REG_3, 0),
5932 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5933 BPF_EXIT_INSN(),
5934 },
5935 .fixup_map_hash_48b = { 3 },
5936 .errstr = "R2 min value is negative",
5937 .result = REJECT,
5938 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5939 },
5940 {
5941 "helper access to adjusted map (via const imm): negative range (< adjustment)",
5942 .insns = {
5943 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5944 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5945 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5946 BPF_LD_MAP_FD(BPF_REG_1, 0),
5947 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5948 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5949 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5950 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5951 offsetof(struct test_val, foo)),
5952 BPF_MOV64_IMM(BPF_REG_2, -1),
5953 BPF_MOV64_IMM(BPF_REG_3, 0),
5954 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5955 BPF_EXIT_INSN(),
5956 },
5957 .fixup_map_hash_48b = { 3 },
5958 .errstr = "R2 min value is negative",
5959 .result = REJECT,
5960 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5961 },
5962 {
5963 "helper access to adjusted map (via const reg): full range",
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_1, BPF_REG_0),
5972 BPF_MOV64_IMM(BPF_REG_3,
5973 offsetof(struct test_val, foo)),
5974 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5975 BPF_MOV64_IMM(BPF_REG_2,
5976 sizeof(struct test_val) -
5977 offsetof(struct test_val, foo)),
5978 BPF_MOV64_IMM(BPF_REG_3, 0),
5979 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5980 BPF_EXIT_INSN(),
5981 },
5982 .fixup_map_hash_48b = { 3 },
5983 .result = ACCEPT,
5984 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5985 },
5986 {
5987 "helper access to adjusted map (via const reg): partial range",
5988 .insns = {
5989 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5990 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5991 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5992 BPF_LD_MAP_FD(BPF_REG_1, 0),
5993 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5994 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5995 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5996 BPF_MOV64_IMM(BPF_REG_3,
5997 offsetof(struct test_val, foo)),
5998 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5999 BPF_MOV64_IMM(BPF_REG_2, 8),
6000 BPF_MOV64_IMM(BPF_REG_3, 0),
6001 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6002 BPF_EXIT_INSN(),
6003 },
6004 .fixup_map_hash_48b = { 3 },
6005 .result = ACCEPT,
6006 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6007 },
6008 {
6009 "helper access to adjusted map (via const reg): empty range",
6010 .insns = {
6011 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6012 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6013 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6014 BPF_LD_MAP_FD(BPF_REG_1, 0),
6015 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6016 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6017 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6018 BPF_MOV64_IMM(BPF_REG_3, 0),
6019 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6020 BPF_MOV64_IMM(BPF_REG_2, 0),
6021 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
6022 BPF_EXIT_INSN(),
6023 },
6024 .fixup_map_hash_48b = { 3 },
6025 .errstr = "R1 min value is outside of the array range",
6026 .result = REJECT,
6027 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6028 },
6029 {
6030 "helper access to adjusted map (via const reg): out-of-bound range",
6031 .insns = {
6032 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6033 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6034 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6035 BPF_LD_MAP_FD(BPF_REG_1, 0),
6036 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6037 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6038 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6039 BPF_MOV64_IMM(BPF_REG_3,
6040 offsetof(struct test_val, foo)),
6041 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6042 BPF_MOV64_IMM(BPF_REG_2,
6043 sizeof(struct test_val) -
6044 offsetof(struct test_val, foo) + 8),
6045 BPF_MOV64_IMM(BPF_REG_3, 0),
6046 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6047 BPF_EXIT_INSN(),
6048 },
6049 .fixup_map_hash_48b = { 3 },
6050 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
6051 .result = REJECT,
6052 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6053 },
6054 {
6055 "helper access to adjusted map (via const reg): negative range (> adjustment)",
6056 .insns = {
6057 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6059 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6060 BPF_LD_MAP_FD(BPF_REG_1, 0),
6061 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6062 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6063 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6064 BPF_MOV64_IMM(BPF_REG_3,
6065 offsetof(struct test_val, foo)),
6066 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6067 BPF_MOV64_IMM(BPF_REG_2, -8),
6068 BPF_MOV64_IMM(BPF_REG_3, 0),
6069 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6070 BPF_EXIT_INSN(),
6071 },
6072 .fixup_map_hash_48b = { 3 },
6073 .errstr = "R2 min value is negative",
6074 .result = REJECT,
6075 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6076 },
6077 {
6078 "helper access to adjusted map (via const reg): negative range (< adjustment)",
6079 .insns = {
6080 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6082 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6083 BPF_LD_MAP_FD(BPF_REG_1, 0),
6084 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6085 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6086 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6087 BPF_MOV64_IMM(BPF_REG_3,
6088 offsetof(struct test_val, foo)),
6089 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6090 BPF_MOV64_IMM(BPF_REG_2, -1),
6091 BPF_MOV64_IMM(BPF_REG_3, 0),
6092 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6093 BPF_EXIT_INSN(),
6094 },
6095 .fixup_map_hash_48b = { 3 },
6096 .errstr = "R2 min value is negative",
6097 .result = REJECT,
6098 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6099 },
6100 {
6101 "helper access to adjusted map (via variable): full range",
6102 .insns = {
6103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6105 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6106 BPF_LD_MAP_FD(BPF_REG_1, 0),
6107 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6108 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6109 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6110 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6111 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6112 offsetof(struct test_val, foo), 4),
6113 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6114 BPF_MOV64_IMM(BPF_REG_2,
6115 sizeof(struct test_val) -
6116 offsetof(struct test_val, foo)),
6117 BPF_MOV64_IMM(BPF_REG_3, 0),
6118 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6119 BPF_EXIT_INSN(),
6120 },
6121 .fixup_map_hash_48b = { 3 },
6122 .result = ACCEPT,
6123 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6124 },
6125 {
6126 "helper access to adjusted map (via variable): partial range",
6127 .insns = {
6128 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6130 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6131 BPF_LD_MAP_FD(BPF_REG_1, 0),
6132 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6133 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6134 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6135 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6136 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6137 offsetof(struct test_val, foo), 4),
6138 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6139 BPF_MOV64_IMM(BPF_REG_2, 8),
6140 BPF_MOV64_IMM(BPF_REG_3, 0),
6141 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6142 BPF_EXIT_INSN(),
6143 },
6144 .fixup_map_hash_48b = { 3 },
6145 .result = ACCEPT,
6146 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6147 },
6148 {
6149 "helper access to adjusted map (via variable): empty range",
6150 .insns = {
6151 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6153 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6154 BPF_LD_MAP_FD(BPF_REG_1, 0),
6155 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6156 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6157 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6158 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6159 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6160 offsetof(struct test_val, foo), 3),
6161 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6162 BPF_MOV64_IMM(BPF_REG_2, 0),
6163 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
6164 BPF_EXIT_INSN(),
6165 },
6166 .fixup_map_hash_48b = { 3 },
6167 .errstr = "R1 min value is outside of the array range",
6168 .result = REJECT,
6169 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6170 },
6171 {
6172 "helper access to adjusted map (via variable): no max check",
6173 .insns = {
6174 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6175 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6176 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6177 BPF_LD_MAP_FD(BPF_REG_1, 0),
6178 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6179 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6180 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6181 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6182 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6183 BPF_MOV64_IMM(BPF_REG_2, 1),
6184 BPF_MOV64_IMM(BPF_REG_3, 0),
6185 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6186 BPF_EXIT_INSN(),
6187 },
6188 .fixup_map_hash_48b = { 3 },
6189 .errstr = "R1 unbounded memory access",
6190 .result = REJECT,
6191 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6192 },
6193 {
6194 "helper access to adjusted map (via variable): wrong max check",
6195 .insns = {
6196 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6198 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6199 BPF_LD_MAP_FD(BPF_REG_1, 0),
6200 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6201 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6202 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6203 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6204 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6205 offsetof(struct test_val, foo), 4),
6206 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6207 BPF_MOV64_IMM(BPF_REG_2,
6208 sizeof(struct test_val) -
6209 offsetof(struct test_val, foo) + 1),
6210 BPF_MOV64_IMM(BPF_REG_3, 0),
6211 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6212 BPF_EXIT_INSN(),
6213 },
6214 .fixup_map_hash_48b = { 3 },
6215 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
6216 .result = REJECT,
6217 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6218 },
6219 {
6220 "helper access to map: bounds check using <, good access",
6221 .insns = {
6222 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6223 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6224 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6225 BPF_LD_MAP_FD(BPF_REG_1, 0),
6226 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6227 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6228 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6229 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6230 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
6231 BPF_MOV64_IMM(BPF_REG_0, 0),
6232 BPF_EXIT_INSN(),
6233 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6234 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6235 BPF_MOV64_IMM(BPF_REG_0, 0),
6236 BPF_EXIT_INSN(),
6237 },
6238 .fixup_map_hash_48b = { 3 },
6239 .result = ACCEPT,
6240 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6241 },
6242 {
6243 "helper access to map: bounds check using <, bad access",
6244 .insns = {
6245 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6247 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6248 BPF_LD_MAP_FD(BPF_REG_1, 0),
6249 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6251 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6252 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6253 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
6254 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6255 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6256 BPF_MOV64_IMM(BPF_REG_0, 0),
6257 BPF_EXIT_INSN(),
6258 BPF_MOV64_IMM(BPF_REG_0, 0),
6259 BPF_EXIT_INSN(),
6260 },
6261 .fixup_map_hash_48b = { 3 },
6262 .result = REJECT,
6263 .errstr = "R1 unbounded memory access",
6264 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6265 },
6266 {
6267 "helper access to map: bounds check using <=, good access",
6268 .insns = {
6269 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6271 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6272 BPF_LD_MAP_FD(BPF_REG_1, 0),
6273 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6274 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6275 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6276 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6277 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
6278 BPF_MOV64_IMM(BPF_REG_0, 0),
6279 BPF_EXIT_INSN(),
6280 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6281 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6282 BPF_MOV64_IMM(BPF_REG_0, 0),
6283 BPF_EXIT_INSN(),
6284 },
6285 .fixup_map_hash_48b = { 3 },
6286 .result = ACCEPT,
6287 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6288 },
6289 {
6290 "helper access to map: bounds check using <=, bad access",
6291 .insns = {
6292 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6293 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6294 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6295 BPF_LD_MAP_FD(BPF_REG_1, 0),
6296 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6297 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6298 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6299 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6300 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
6301 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6302 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6303 BPF_MOV64_IMM(BPF_REG_0, 0),
6304 BPF_EXIT_INSN(),
6305 BPF_MOV64_IMM(BPF_REG_0, 0),
6306 BPF_EXIT_INSN(),
6307 },
6308 .fixup_map_hash_48b = { 3 },
6309 .result = REJECT,
6310 .errstr = "R1 unbounded memory access",
6311 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6312 },
6313 {
6314 "helper access to map: bounds check using s<, good access",
6315 .insns = {
6316 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6317 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6318 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6319 BPF_LD_MAP_FD(BPF_REG_1, 0),
6320 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6321 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6323 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6324 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
6325 BPF_MOV64_IMM(BPF_REG_0, 0),
6326 BPF_EXIT_INSN(),
6327 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
6328 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6329 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6330 BPF_MOV64_IMM(BPF_REG_0, 0),
6331 BPF_EXIT_INSN(),
6332 },
6333 .fixup_map_hash_48b = { 3 },
6334 .result = ACCEPT,
6335 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6336 },
6337 {
6338 "helper access to map: bounds check using s<, good access 2",
6339 .insns = {
6340 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6341 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6342 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6343 BPF_LD_MAP_FD(BPF_REG_1, 0),
6344 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6345 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6346 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6347 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6348 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
6349 BPF_MOV64_IMM(BPF_REG_0, 0),
6350 BPF_EXIT_INSN(),
6351 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
6352 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6353 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6354 BPF_MOV64_IMM(BPF_REG_0, 0),
6355 BPF_EXIT_INSN(),
6356 },
6357 .fixup_map_hash_48b = { 3 },
6358 .result = ACCEPT,
6359 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6360 },
6361 {
6362 "helper access to map: bounds check using s<, bad access",
6363 .insns = {
6364 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6366 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6367 BPF_LD_MAP_FD(BPF_REG_1, 0),
6368 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6369 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6370 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6371 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
6372 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
6373 BPF_MOV64_IMM(BPF_REG_0, 0),
6374 BPF_EXIT_INSN(),
6375 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
6376 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6377 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6378 BPF_MOV64_IMM(BPF_REG_0, 0),
6379 BPF_EXIT_INSN(),
6380 },
6381 .fixup_map_hash_48b = { 3 },
6382 .result = REJECT,
6383 .errstr = "R1 min value is negative",
6384 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6385 },
6386 {
6387 "helper access to map: bounds check using s<=, good access",
6388 .insns = {
6389 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6391 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6392 BPF_LD_MAP_FD(BPF_REG_1, 0),
6393 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6394 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6395 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6396 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6397 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
6398 BPF_MOV64_IMM(BPF_REG_0, 0),
6399 BPF_EXIT_INSN(),
6400 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
6401 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6402 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6403 BPF_MOV64_IMM(BPF_REG_0, 0),
6404 BPF_EXIT_INSN(),
6405 },
6406 .fixup_map_hash_48b = { 3 },
6407 .result = ACCEPT,
6408 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6409 },
6410 {
6411 "helper access to map: bounds check using s<=, good access 2",
6412 .insns = {
6413 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6414 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6415 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6416 BPF_LD_MAP_FD(BPF_REG_1, 0),
6417 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6418 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6419 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6420 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6421 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
6422 BPF_MOV64_IMM(BPF_REG_0, 0),
6423 BPF_EXIT_INSN(),
6424 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
6425 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6426 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6427 BPF_MOV64_IMM(BPF_REG_0, 0),
6428 BPF_EXIT_INSN(),
6429 },
6430 .fixup_map_hash_48b = { 3 },
6431 .result = ACCEPT,
6432 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6433 },
6434 {
6435 "helper access to map: bounds check using s<=, bad access",
6436 .insns = {
6437 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6438 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6439 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6440 BPF_LD_MAP_FD(BPF_REG_1, 0),
6441 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6442 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6443 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6444 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
6445 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
6446 BPF_MOV64_IMM(BPF_REG_0, 0),
6447 BPF_EXIT_INSN(),
6448 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
6449 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6450 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6451 BPF_MOV64_IMM(BPF_REG_0, 0),
6452 BPF_EXIT_INSN(),
6453 },
6454 .fixup_map_hash_48b = { 3 },
6455 .result = REJECT,
6456 .errstr = "R1 min value is negative",
6457 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6458 },
6459 {
6460 "map access: known scalar += value_ptr",
6461 .insns = {
6462 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6463 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6464 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6465 BPF_LD_MAP_FD(BPF_REG_1, 0),
6466 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6467 BPF_FUNC_map_lookup_elem),
6468 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
6469 BPF_MOV64_IMM(BPF_REG_1, 4),
6470 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
6471 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
6472 BPF_MOV64_IMM(BPF_REG_0, 1),
6473 BPF_EXIT_INSN(),
6474 },
6475 .fixup_map_array_48b = { 3 },
6476 .result = ACCEPT,
6477 .retval = 1,
6478 },
6479 {
6480 "map access: value_ptr += known scalar",
6481 .insns = {
6482 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6483 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6485 BPF_LD_MAP_FD(BPF_REG_1, 0),
6486 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6487 BPF_FUNC_map_lookup_elem),
6488 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
6489 BPF_MOV64_IMM(BPF_REG_1, 4),
6490 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6491 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6492 BPF_MOV64_IMM(BPF_REG_0, 1),
6493 BPF_EXIT_INSN(),
6494 },
6495 .fixup_map_array_48b = { 3 },
6496 .result = ACCEPT,
6497 .retval = 1,
6498 },
6499 {
6500 "map access: unknown scalar += value_ptr",
6501 .insns = {
6502 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6503 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6504 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6505 BPF_LD_MAP_FD(BPF_REG_1, 0),
6506 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6507 BPF_FUNC_map_lookup_elem),
6508 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6509 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6510 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
6511 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
6512 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
6513 BPF_MOV64_IMM(BPF_REG_0, 1),
6514 BPF_EXIT_INSN(),
6515 },
6516 .fixup_map_array_48b = { 3 },
6517 .result = ACCEPT,
6518 .retval = 1,
6519 },
6520 {
6521 "map access: value_ptr += unknown scalar",
6522 .insns = {
6523 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6524 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6525 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6526 BPF_LD_MAP_FD(BPF_REG_1, 0),
6527 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6528 BPF_FUNC_map_lookup_elem),
6529 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6530 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6531 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
6532 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6533 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6534 BPF_MOV64_IMM(BPF_REG_0, 1),
6535 BPF_EXIT_INSN(),
6536 },
6537 .fixup_map_array_48b = { 3 },
6538 .result = ACCEPT,
6539 .retval = 1,
6540 },
6541 {
6542 "map access: value_ptr += value_ptr",
6543 .insns = {
6544 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6545 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6546 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6547 BPF_LD_MAP_FD(BPF_REG_1, 0),
6548 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6549 BPF_FUNC_map_lookup_elem),
6550 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6551 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_0),
6552 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6553 BPF_MOV64_IMM(BPF_REG_0, 1),
6554 BPF_EXIT_INSN(),
6555 },
6556 .fixup_map_array_48b = { 3 },
6557 .result = REJECT,
6558 .errstr = "R0 pointer += pointer prohibited",
6559 },
6560 {
6561 "map access: known scalar -= value_ptr",
6562 .insns = {
6563 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6564 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6566 BPF_LD_MAP_FD(BPF_REG_1, 0),
6567 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6568 BPF_FUNC_map_lookup_elem),
6569 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
6570 BPF_MOV64_IMM(BPF_REG_1, 4),
6571 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
6572 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
6573 BPF_MOV64_IMM(BPF_REG_0, 1),
6574 BPF_EXIT_INSN(),
6575 },
6576 .fixup_map_array_48b = { 3 },
6577 .result = REJECT,
6578 .errstr = "R1 tried to subtract pointer from scalar",
6579 },
6580 {
6581 "map access: value_ptr -= known scalar",
6582 .insns = {
6583 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6584 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6585 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6586 BPF_LD_MAP_FD(BPF_REG_1, 0),
6587 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6588 BPF_FUNC_map_lookup_elem),
6589 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
6590 BPF_MOV64_IMM(BPF_REG_1, 4),
6591 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
6592 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6593 BPF_MOV64_IMM(BPF_REG_0, 1),
6594 BPF_EXIT_INSN(),
6595 },
6596 .fixup_map_array_48b = { 3 },
6597 .result = REJECT,
6598 .errstr = "R0 min value is outside of the array range",
6599 },
6600 {
6601 "map access: value_ptr -= known scalar, 2",
6602 .insns = {
6603 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6604 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6606 BPF_LD_MAP_FD(BPF_REG_1, 0),
6607 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6608 BPF_FUNC_map_lookup_elem),
6609 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6610 BPF_MOV64_IMM(BPF_REG_1, 6),
6611 BPF_MOV64_IMM(BPF_REG_2, 4),
6612 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6613 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
6614 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6615 BPF_MOV64_IMM(BPF_REG_0, 1),
6616 BPF_EXIT_INSN(),
6617 },
6618 .fixup_map_array_48b = { 3 },
6619 .result = ACCEPT,
6620 .retval = 1,
6621 },
6622 {
6623 "map access: unknown scalar -= value_ptr",
6624 .insns = {
6625 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6626 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6627 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6628 BPF_LD_MAP_FD(BPF_REG_1, 0),
6629 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6630 BPF_FUNC_map_lookup_elem),
6631 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6632 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6633 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
6634 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
6635 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
6636 BPF_MOV64_IMM(BPF_REG_0, 1),
6637 BPF_EXIT_INSN(),
6638 },
6639 .fixup_map_array_48b = { 3 },
6640 .result = REJECT,
6641 .errstr = "R1 tried to subtract pointer from scalar",
6642 },
6643 {
6644 "map access: value_ptr -= unknown scalar",
6645 .insns = {
6646 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6649 BPF_LD_MAP_FD(BPF_REG_1, 0),
6650 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6651 BPF_FUNC_map_lookup_elem),
6652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6653 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6654 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
6655 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
6656 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6657 BPF_MOV64_IMM(BPF_REG_0, 1),
6658 BPF_EXIT_INSN(),
6659 },
6660 .fixup_map_array_48b = { 3 },
6661 .result = REJECT,
6662 .errstr = "R0 min value is negative",
6663 },
6664 {
6665 "map access: value_ptr -= unknown scalar, 2",
6666 .insns = {
6667 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6668 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6669 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6670 BPF_LD_MAP_FD(BPF_REG_1, 0),
6671 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6672 BPF_FUNC_map_lookup_elem),
6673 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6674 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6675 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
6676 BPF_ALU64_IMM(BPF_OR, BPF_REG_1, 0x7),
6677 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6678 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6679 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7),
6680 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
6681 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6682 BPF_MOV64_IMM(BPF_REG_0, 1),
6683 BPF_EXIT_INSN(),
6684 },
6685 .fixup_map_array_48b = { 3 },
6686 .result = ACCEPT,
6687 .retval = 1,
6688 },
6689 {
6690 "map access: value_ptr -= value_ptr",
6691 .insns = {
6692 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6693 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6695 BPF_LD_MAP_FD(BPF_REG_1, 0),
6696 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6697 BPF_FUNC_map_lookup_elem),
6698 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6699 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_0),
6700 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6701 BPF_MOV64_IMM(BPF_REG_0, 1),
6702 BPF_EXIT_INSN(),
6703 },
6704 .fixup_map_array_48b = { 3 },
6705 .result = REJECT,
6706 .errstr = "R0 invalid mem access 'inv'",
6707 .errstr_unpriv = "R0 pointer -= pointer prohibited",
6708 },
6709 {
6710 "map lookup helper access to map",
6711 .insns = {
6712 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6714 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6715 BPF_LD_MAP_FD(BPF_REG_1, 0),
6716 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6717 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6718 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6719 BPF_LD_MAP_FD(BPF_REG_1, 0),
6720 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6721 BPF_EXIT_INSN(),
6722 },
6723 .fixup_map_hash_16b = { 3, 8 },
6724 .result = ACCEPT,
6725 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6726 },
6727 {
6728 "map update helper access to map",
6729 .insns = {
6730 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6731 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6732 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6733 BPF_LD_MAP_FD(BPF_REG_1, 0),
6734 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6735 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6736 BPF_MOV64_IMM(BPF_REG_4, 0),
6737 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
6738 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6739 BPF_LD_MAP_FD(BPF_REG_1, 0),
6740 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
6741 BPF_EXIT_INSN(),
6742 },
6743 .fixup_map_hash_16b = { 3, 10 },
6744 .result = ACCEPT,
6745 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6746 },
6747 {
6748 "map update helper access to map: wrong size",
6749 .insns = {
6750 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6751 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6752 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6753 BPF_LD_MAP_FD(BPF_REG_1, 0),
6754 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6756 BPF_MOV64_IMM(BPF_REG_4, 0),
6757 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
6758 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6759 BPF_LD_MAP_FD(BPF_REG_1, 0),
6760 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
6761 BPF_EXIT_INSN(),
6762 },
6763 .fixup_map_hash_8b = { 3 },
6764 .fixup_map_hash_16b = { 10 },
6765 .result = REJECT,
6766 .errstr = "invalid access to map value, value_size=8 off=0 size=16",
6767 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6768 },
6769 {
6770 "map helper access to adjusted map (via const imm)",
6771 .insns = {
6772 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6773 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6774 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6775 BPF_LD_MAP_FD(BPF_REG_1, 0),
6776 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6777 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6778 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
6780 offsetof(struct other_val, bar)),
6781 BPF_LD_MAP_FD(BPF_REG_1, 0),
6782 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6783 BPF_EXIT_INSN(),
6784 },
6785 .fixup_map_hash_16b = { 3, 9 },
6786 .result = ACCEPT,
6787 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6788 },
6789 {
6790 "map helper access to adjusted map (via const imm): out-of-bound 1",
6791 .insns = {
6792 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6794 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6795 BPF_LD_MAP_FD(BPF_REG_1, 0),
6796 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6797 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6798 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6799 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
6800 sizeof(struct other_val) - 4),
6801 BPF_LD_MAP_FD(BPF_REG_1, 0),
6802 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6803 BPF_EXIT_INSN(),
6804 },
6805 .fixup_map_hash_16b = { 3, 9 },
6806 .result = REJECT,
6807 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
6808 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6809 },
6810 {
6811 "map helper access to adjusted map (via const imm): out-of-bound 2",
6812 .insns = {
6813 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6814 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6815 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6816 BPF_LD_MAP_FD(BPF_REG_1, 0),
6817 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6818 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6819 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6821 BPF_LD_MAP_FD(BPF_REG_1, 0),
6822 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6823 BPF_EXIT_INSN(),
6824 },
6825 .fixup_map_hash_16b = { 3, 9 },
6826 .result = REJECT,
6827 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
6828 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6829 },
6830 {
6831 "map helper access to adjusted map (via const reg)",
6832 .insns = {
6833 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6834 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6835 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6836 BPF_LD_MAP_FD(BPF_REG_1, 0),
6837 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6838 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6839 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6840 BPF_MOV64_IMM(BPF_REG_3,
6841 offsetof(struct other_val, bar)),
6842 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6843 BPF_LD_MAP_FD(BPF_REG_1, 0),
6844 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6845 BPF_EXIT_INSN(),
6846 },
6847 .fixup_map_hash_16b = { 3, 10 },
6848 .result = ACCEPT,
6849 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6850 },
6851 {
6852 "map helper access to adjusted map (via const reg): out-of-bound 1",
6853 .insns = {
6854 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6855 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6856 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6857 BPF_LD_MAP_FD(BPF_REG_1, 0),
6858 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6859 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6860 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6861 BPF_MOV64_IMM(BPF_REG_3,
6862 sizeof(struct other_val) - 4),
6863 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6864 BPF_LD_MAP_FD(BPF_REG_1, 0),
6865 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6866 BPF_EXIT_INSN(),
6867 },
6868 .fixup_map_hash_16b = { 3, 10 },
6869 .result = REJECT,
6870 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
6871 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6872 },
6873 {
6874 "map helper access to adjusted map (via const reg): out-of-bound 2",
6875 .insns = {
6876 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6878 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6879 BPF_LD_MAP_FD(BPF_REG_1, 0),
6880 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6881 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6882 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6883 BPF_MOV64_IMM(BPF_REG_3, -4),
6884 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6885 BPF_LD_MAP_FD(BPF_REG_1, 0),
6886 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6887 BPF_EXIT_INSN(),
6888 },
6889 .fixup_map_hash_16b = { 3, 10 },
6890 .result = REJECT,
6891 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
6892 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6893 },
6894 {
6895 "map helper access to adjusted map (via variable)",
6896 .insns = {
6897 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6898 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6899 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6900 BPF_LD_MAP_FD(BPF_REG_1, 0),
6901 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6902 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6903 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6904 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6905 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6906 offsetof(struct other_val, bar), 4),
6907 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6908 BPF_LD_MAP_FD(BPF_REG_1, 0),
6909 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6910 BPF_EXIT_INSN(),
6911 },
6912 .fixup_map_hash_16b = { 3, 11 },
6913 .result = ACCEPT,
6914 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6915 },
6916 {
6917 "map helper access to adjusted map (via variable): no max check",
6918 .insns = {
6919 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6920 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6921 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6922 BPF_LD_MAP_FD(BPF_REG_1, 0),
6923 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6924 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6925 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6926 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6927 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6928 BPF_LD_MAP_FD(BPF_REG_1, 0),
6929 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6930 BPF_EXIT_INSN(),
6931 },
6932 .fixup_map_hash_16b = { 3, 10 },
6933 .result = REJECT,
6934 .errstr = "R2 unbounded memory access, make sure to bounds check any array access into a map",
6935 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6936 },
6937 {
6938 "map helper access to adjusted map (via variable): wrong max check",
6939 .insns = {
6940 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6941 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6942 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6943 BPF_LD_MAP_FD(BPF_REG_1, 0),
6944 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6945 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6946 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6947 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6948 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6949 offsetof(struct other_val, bar) + 1, 4),
6950 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6951 BPF_LD_MAP_FD(BPF_REG_1, 0),
6952 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6953 BPF_EXIT_INSN(),
6954 },
6955 .fixup_map_hash_16b = { 3, 11 },
6956 .result = REJECT,
6957 .errstr = "invalid access to map value, value_size=16 off=9 size=8",
6958 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6959 },
6960 {
6961 "map element value is preserved across register spilling",
6962 .insns = {
6963 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6964 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6965 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6966 BPF_LD_MAP_FD(BPF_REG_1, 0),
6967 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6968 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6969 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6970 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6971 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6972 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6973 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6974 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6975 BPF_EXIT_INSN(),
6976 },
6977 .fixup_map_hash_48b = { 3 },
6978 .errstr_unpriv = "R0 leaks addr",
6979 .result = ACCEPT,
6980 .result_unpriv = REJECT,
6981 },
6982 {
6983 "map element value or null is marked on register spilling",
6984 .insns = {
6985 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6986 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6987 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6988 BPF_LD_MAP_FD(BPF_REG_1, 0),
6989 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6990 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
6992 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6993 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6994 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6995 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6996 BPF_EXIT_INSN(),
6997 },
6998 .fixup_map_hash_48b = { 3 },
6999 .errstr_unpriv = "R0 leaks addr",
7000 .result = ACCEPT,
7001 .result_unpriv = REJECT,
7002 },
7003 {
7004 "map element value store of cleared call register",
7005 .insns = {
7006 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7008 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7009 BPF_LD_MAP_FD(BPF_REG_1, 0),
7010 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7011 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
7012 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
7013 BPF_EXIT_INSN(),
7014 },
7015 .fixup_map_hash_48b = { 3 },
7016 .errstr_unpriv = "R1 !read_ok",
7017 .errstr = "R1 !read_ok",
7018 .result = REJECT,
7019 .result_unpriv = REJECT,
7020 },
7021 {
7022 "map element value with unaligned store",
7023 .insns = {
7024 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7026 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7027 BPF_LD_MAP_FD(BPF_REG_1, 0),
7028 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
7030 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
7031 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
7032 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
7033 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
7034 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
7035 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
7036 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
7037 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
7038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
7039 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
7040 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
7041 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
7042 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
7043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
7044 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
7045 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
7046 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
7047 BPF_EXIT_INSN(),
7048 },
7049 .fixup_map_hash_48b = { 3 },
7050 .errstr_unpriv = "R0 leaks addr",
7051 .result = ACCEPT,
7052 .result_unpriv = REJECT,
7053 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7054 },
7055 {
7056 "map element value with unaligned load",
7057 .insns = {
7058 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7059 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7060 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7061 BPF_LD_MAP_FD(BPF_REG_1, 0),
7062 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7063 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
7064 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
7065 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
7066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
7067 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
7068 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
7069 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
7070 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
7071 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
7072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
7073 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
7074 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
7075 BPF_EXIT_INSN(),
7076 },
7077 .fixup_map_hash_48b = { 3 },
7078 .errstr_unpriv = "R0 leaks addr",
7079 .result = ACCEPT,
7080 .result_unpriv = REJECT,
7081 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7082 },
7083 {
7084 "map element value illegal alu op, 1",
7085 .insns = {
7086 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7087 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7088 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7089 BPF_LD_MAP_FD(BPF_REG_1, 0),
7090 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7091 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7092 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
7093 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
7094 BPF_EXIT_INSN(),
7095 },
7096 .fixup_map_hash_48b = { 3 },
7097 .errstr = "R0 bitwise operator &= on pointer",
7098 .result = REJECT,
7099 },
7100 {
7101 "map element value illegal alu op, 2",
7102 .insns = {
7103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7105 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7106 BPF_LD_MAP_FD(BPF_REG_1, 0),
7107 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7108 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7109 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
7110 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
7111 BPF_EXIT_INSN(),
7112 },
7113 .fixup_map_hash_48b = { 3 },
7114 .errstr = "R0 32-bit pointer arithmetic prohibited",
7115 .result = REJECT,
7116 },
7117 {
7118 "map element value illegal alu op, 3",
7119 .insns = {
7120 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7122 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7123 BPF_LD_MAP_FD(BPF_REG_1, 0),
7124 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7125 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7126 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
7127 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
7128 BPF_EXIT_INSN(),
7129 },
7130 .fixup_map_hash_48b = { 3 },
7131 .errstr = "R0 pointer arithmetic with /= operator",
7132 .result = REJECT,
7133 },
7134 {
7135 "map element value illegal alu op, 4",
7136 .insns = {
7137 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7138 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7139 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7140 BPF_LD_MAP_FD(BPF_REG_1, 0),
7141 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7142 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7143 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
7144 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
7145 BPF_EXIT_INSN(),
7146 },
7147 .fixup_map_hash_48b = { 3 },
7148 .errstr_unpriv = "R0 pointer arithmetic prohibited",
7149 .errstr = "invalid mem access 'inv'",
7150 .result = REJECT,
7151 .result_unpriv = REJECT,
7152 },
7153 {
7154 "map element value illegal alu op, 5",
7155 .insns = {
7156 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7157 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7158 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7159 BPF_LD_MAP_FD(BPF_REG_1, 0),
7160 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7161 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7162 BPF_MOV64_IMM(BPF_REG_3, 4096),
7163 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7165 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7166 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
7167 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
7168 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
7169 BPF_EXIT_INSN(),
7170 },
7171 .fixup_map_hash_48b = { 3 },
7172 .errstr = "R0 invalid mem access 'inv'",
7173 .result = REJECT,
7174 },
7175 {
7176 "map element value is preserved across register spilling",
7177 .insns = {
7178 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7179 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7180 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7181 BPF_LD_MAP_FD(BPF_REG_1, 0),
7182 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7183 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7184 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
7185 offsetof(struct test_val, foo)),
7186 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
7187 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
7189 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
7190 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
7191 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
7192 BPF_EXIT_INSN(),
7193 },
7194 .fixup_map_hash_48b = { 3 },
7195 .errstr_unpriv = "R0 leaks addr",
7196 .result = ACCEPT,
7197 .result_unpriv = REJECT,
7198 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7199 },
7200 {
7201 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
7202 .insns = {
7203 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7205 BPF_MOV64_IMM(BPF_REG_0, 0),
7206 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7207 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7208 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7209 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7210 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
7211 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7212 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7213 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7214 BPF_MOV64_IMM(BPF_REG_2, 16),
7215 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7216 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7217 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
7218 BPF_MOV64_IMM(BPF_REG_4, 0),
7219 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
7220 BPF_MOV64_IMM(BPF_REG_3, 0),
7221 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7222 BPF_MOV64_IMM(BPF_REG_0, 0),
7223 BPF_EXIT_INSN(),
7224 },
7225 .result = ACCEPT,
7226 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7227 },
7228 {
7229 "helper access to variable memory: stack, bitwise AND, zero included",
7230 .insns = {
7231 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7232 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7233 BPF_MOV64_IMM(BPF_REG_2, 16),
7234 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7235 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7236 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
7237 BPF_MOV64_IMM(BPF_REG_3, 0),
7238 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7239 BPF_EXIT_INSN(),
7240 },
7241 .errstr = "invalid indirect read from stack off -64+0 size 64",
7242 .result = REJECT,
7243 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7244 },
7245 {
7246 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
7247 .insns = {
7248 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7249 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7250 BPF_MOV64_IMM(BPF_REG_2, 16),
7251 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7252 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7253 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
7254 BPF_MOV64_IMM(BPF_REG_4, 0),
7255 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
7256 BPF_MOV64_IMM(BPF_REG_3, 0),
7257 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7258 BPF_MOV64_IMM(BPF_REG_0, 0),
7259 BPF_EXIT_INSN(),
7260 },
7261 .errstr = "invalid stack type R1 off=-64 access_size=65",
7262 .result = REJECT,
7263 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7264 },
7265 {
7266 "helper access to variable memory: stack, JMP, correct bounds",
7267 .insns = {
7268 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7269 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7270 BPF_MOV64_IMM(BPF_REG_0, 0),
7271 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7272 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7273 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7274 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7275 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
7276 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7277 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7278 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7279 BPF_MOV64_IMM(BPF_REG_2, 16),
7280 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7281 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7282 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
7283 BPF_MOV64_IMM(BPF_REG_4, 0),
7284 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
7285 BPF_MOV64_IMM(BPF_REG_3, 0),
7286 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7287 BPF_MOV64_IMM(BPF_REG_0, 0),
7288 BPF_EXIT_INSN(),
7289 },
7290 .result = ACCEPT,
7291 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7292 },
7293 {
7294 "helper access to variable memory: stack, JMP (signed), correct bounds",
7295 .insns = {
7296 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7298 BPF_MOV64_IMM(BPF_REG_0, 0),
7299 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7300 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7301 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7302 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7303 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
7304 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7305 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7306 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7307 BPF_MOV64_IMM(BPF_REG_2, 16),
7308 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7309 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7310 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
7311 BPF_MOV64_IMM(BPF_REG_4, 0),
7312 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
7313 BPF_MOV64_IMM(BPF_REG_3, 0),
7314 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7315 BPF_MOV64_IMM(BPF_REG_0, 0),
7316 BPF_EXIT_INSN(),
7317 },
7318 .result = ACCEPT,
7319 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7320 },
7321 {
7322 "helper access to variable memory: stack, JMP, bounds + offset",
7323 .insns = {
7324 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7325 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7326 BPF_MOV64_IMM(BPF_REG_2, 16),
7327 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7328 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7329 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
7330 BPF_MOV64_IMM(BPF_REG_4, 0),
7331 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
7332 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
7333 BPF_MOV64_IMM(BPF_REG_3, 0),
7334 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7335 BPF_MOV64_IMM(BPF_REG_0, 0),
7336 BPF_EXIT_INSN(),
7337 },
7338 .errstr = "invalid stack type R1 off=-64 access_size=65",
7339 .result = REJECT,
7340 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7341 },
7342 {
7343 "helper access to variable memory: stack, JMP, wrong max",
7344 .insns = {
7345 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7346 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7347 BPF_MOV64_IMM(BPF_REG_2, 16),
7348 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7349 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7350 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
7351 BPF_MOV64_IMM(BPF_REG_4, 0),
7352 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
7353 BPF_MOV64_IMM(BPF_REG_3, 0),
7354 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7355 BPF_MOV64_IMM(BPF_REG_0, 0),
7356 BPF_EXIT_INSN(),
7357 },
7358 .errstr = "invalid stack type R1 off=-64 access_size=65",
7359 .result = REJECT,
7360 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7361 },
7362 {
7363 "helper access to variable memory: stack, JMP, no max check",
7364 .insns = {
7365 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7367 BPF_MOV64_IMM(BPF_REG_2, 16),
7368 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7369 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7370 BPF_MOV64_IMM(BPF_REG_4, 0),
7371 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
7372 BPF_MOV64_IMM(BPF_REG_3, 0),
7373 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7374 BPF_MOV64_IMM(BPF_REG_0, 0),
7375 BPF_EXIT_INSN(),
7376 },
7377 /* because max wasn't checked, signed min is negative */
7378 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
7379 .result = REJECT,
7380 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7381 },
7382 {
7383 "helper access to variable memory: stack, JMP, no min check",
7384 .insns = {
7385 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7387 BPF_MOV64_IMM(BPF_REG_2, 16),
7388 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7389 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7390 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
7391 BPF_MOV64_IMM(BPF_REG_3, 0),
7392 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7393 BPF_MOV64_IMM(BPF_REG_0, 0),
7394 BPF_EXIT_INSN(),
7395 },
7396 .errstr = "invalid indirect read from stack off -64+0 size 64",
7397 .result = REJECT,
7398 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7399 },
7400 {
7401 "helper access to variable memory: stack, JMP (signed), no min check",
7402 .insns = {
7403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7405 BPF_MOV64_IMM(BPF_REG_2, 16),
7406 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
7407 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
7408 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
7409 BPF_MOV64_IMM(BPF_REG_3, 0),
7410 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7411 BPF_MOV64_IMM(BPF_REG_0, 0),
7412 BPF_EXIT_INSN(),
7413 },
7414 .errstr = "R2 min value is negative",
7415 .result = REJECT,
7416 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7417 },
7418 {
7419 "helper access to variable memory: map, JMP, correct bounds",
7420 .insns = {
7421 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7423 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7424 BPF_LD_MAP_FD(BPF_REG_1, 0),
7425 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7426 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
7427 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7428 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
7429 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7430 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7431 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
7432 sizeof(struct test_val), 4),
7433 BPF_MOV64_IMM(BPF_REG_4, 0),
7434 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
7435 BPF_MOV64_IMM(BPF_REG_3, 0),
7436 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7437 BPF_MOV64_IMM(BPF_REG_0, 0),
7438 BPF_EXIT_INSN(),
7439 },
7440 .fixup_map_hash_48b = { 3 },
7441 .result = ACCEPT,
7442 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7443 },
7444 {
7445 "helper access to variable memory: map, JMP, wrong max",
7446 .insns = {
7447 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7448 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7449 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7450 BPF_LD_MAP_FD(BPF_REG_1, 0),
7451 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7452 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
7453 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7454 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
7455 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7456 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7457 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
7458 sizeof(struct test_val) + 1, 4),
7459 BPF_MOV64_IMM(BPF_REG_4, 0),
7460 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
7461 BPF_MOV64_IMM(BPF_REG_3, 0),
7462 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7463 BPF_MOV64_IMM(BPF_REG_0, 0),
7464 BPF_EXIT_INSN(),
7465 },
7466 .fixup_map_hash_48b = { 3 },
7467 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
7468 .result = REJECT,
7469 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7470 },
7471 {
7472 "helper access to variable memory: map adjusted, JMP, correct bounds",
7473 .insns = {
7474 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7476 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7477 BPF_LD_MAP_FD(BPF_REG_1, 0),
7478 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7479 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
7480 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7481 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
7482 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
7483 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7484 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7485 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
7486 sizeof(struct test_val) - 20, 4),
7487 BPF_MOV64_IMM(BPF_REG_4, 0),
7488 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
7489 BPF_MOV64_IMM(BPF_REG_3, 0),
7490 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7491 BPF_MOV64_IMM(BPF_REG_0, 0),
7492 BPF_EXIT_INSN(),
7493 },
7494 .fixup_map_hash_48b = { 3 },
7495 .result = ACCEPT,
7496 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7497 },
7498 {
7499 "helper access to variable memory: map adjusted, JMP, wrong max",
7500 .insns = {
7501 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7502 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7503 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
7504 BPF_LD_MAP_FD(BPF_REG_1, 0),
7505 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7506 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
7507 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7508 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
7509 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
7510 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7511 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7512 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
7513 sizeof(struct test_val) - 19, 4),
7514 BPF_MOV64_IMM(BPF_REG_4, 0),
7515 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
7516 BPF_MOV64_IMM(BPF_REG_3, 0),
7517 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7518 BPF_MOV64_IMM(BPF_REG_0, 0),
7519 BPF_EXIT_INSN(),
7520 },
7521 .fixup_map_hash_48b = { 3 },
7522 .errstr = "R1 min value is outside of the array range",
7523 .result = REJECT,
7524 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7525 },
7526 {
7527 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
7528 .insns = {
7529 BPF_MOV64_IMM(BPF_REG_1, 0),
7530 BPF_MOV64_IMM(BPF_REG_2, 0),
7531 BPF_MOV64_IMM(BPF_REG_3, 0),
7532 BPF_MOV64_IMM(BPF_REG_4, 0),
7533 BPF_MOV64_IMM(BPF_REG_5, 0),
7534 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7535 BPF_EXIT_INSN(),
7536 },
7537 .result = ACCEPT,
7538 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7539 },
7540 {
7541 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
7542 .insns = {
7543 BPF_MOV64_IMM(BPF_REG_1, 0),
7544 BPF_MOV64_IMM(BPF_REG_2, 1),
7545 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7546 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7547 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
7548 BPF_MOV64_IMM(BPF_REG_3, 0),
7549 BPF_MOV64_IMM(BPF_REG_4, 0),
7550 BPF_MOV64_IMM(BPF_REG_5, 0),
7551 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7552 BPF_EXIT_INSN(),
7553 },
7554 .errstr = "R1 type=inv expected=fp",
7555 .result = REJECT,
7556 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7557 },
7558 {
7559 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
7560 .insns = {
7561 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7562 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7563 BPF_MOV64_IMM(BPF_REG_2, 0),
7564 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
7565 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
7566 BPF_MOV64_IMM(BPF_REG_3, 0),
7567 BPF_MOV64_IMM(BPF_REG_4, 0),
7568 BPF_MOV64_IMM(BPF_REG_5, 0),
7569 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7570 BPF_EXIT_INSN(),
7571 },
7572 .result = ACCEPT,
7573 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7574 },
7575 {
7576 "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
7577 .insns = {
7578 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7579 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7581 BPF_LD_MAP_FD(BPF_REG_1, 0),
7582 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7583 BPF_FUNC_map_lookup_elem),
7584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7585 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7586 BPF_MOV64_IMM(BPF_REG_2, 0),
7587 BPF_MOV64_IMM(BPF_REG_3, 0),
7588 BPF_MOV64_IMM(BPF_REG_4, 0),
7589 BPF_MOV64_IMM(BPF_REG_5, 0),
7590 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7591 BPF_EXIT_INSN(),
7592 },
7593 .fixup_map_hash_8b = { 3 },
7594 .result = ACCEPT,
7595 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7596 },
7597 {
7598 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
7599 .insns = {
7600 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7601 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7603 BPF_LD_MAP_FD(BPF_REG_1, 0),
7604 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7605 BPF_FUNC_map_lookup_elem),
7606 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7607 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7608 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
7609 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7610 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7611 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
7612 BPF_MOV64_IMM(BPF_REG_3, 0),
7613 BPF_MOV64_IMM(BPF_REG_4, 0),
7614 BPF_MOV64_IMM(BPF_REG_5, 0),
7615 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7616 BPF_EXIT_INSN(),
7617 },
7618 .fixup_map_hash_8b = { 3 },
7619 .result = ACCEPT,
7620 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7621 },
7622 {
7623 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
7624 .insns = {
7625 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7626 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7627 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7628 BPF_LD_MAP_FD(BPF_REG_1, 0),
7629 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7630 BPF_FUNC_map_lookup_elem),
7631 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7632 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7633 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7634 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
7635 BPF_MOV64_IMM(BPF_REG_3, 0),
7636 BPF_MOV64_IMM(BPF_REG_4, 0),
7637 BPF_MOV64_IMM(BPF_REG_5, 0),
7638 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7639 BPF_EXIT_INSN(),
7640 },
7641 .fixup_map_hash_8b = { 3 },
7642 .result = ACCEPT,
7643 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7644 },
7645 {
7646 "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
7647 .insns = {
7648 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
7649 offsetof(struct __sk_buff, data)),
7650 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7651 offsetof(struct __sk_buff, data_end)),
7652 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
7653 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7654 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
7655 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
7656 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
7657 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
7658 BPF_MOV64_IMM(BPF_REG_3, 0),
7659 BPF_MOV64_IMM(BPF_REG_4, 0),
7660 BPF_MOV64_IMM(BPF_REG_5, 0),
7661 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7662 BPF_EXIT_INSN(),
7663 },
7664 .result = ACCEPT,
7665 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7666 .retval = 0 /* csum_diff of 64-byte packet */,
7667 },
7668 {
7669 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
7670 .insns = {
7671 BPF_MOV64_IMM(BPF_REG_1, 0),
7672 BPF_MOV64_IMM(BPF_REG_2, 0),
7673 BPF_MOV64_IMM(BPF_REG_3, 0),
7674 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7675 BPF_EXIT_INSN(),
7676 },
7677 .errstr = "R1 type=inv expected=fp",
7678 .result = REJECT,
7679 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7680 },
7681 {
7682 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
7683 .insns = {
7684 BPF_MOV64_IMM(BPF_REG_1, 0),
7685 BPF_MOV64_IMM(BPF_REG_2, 1),
7686 BPF_MOV64_IMM(BPF_REG_3, 0),
7687 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7688 BPF_EXIT_INSN(),
7689 },
7690 .errstr = "R1 type=inv expected=fp",
7691 .result = REJECT,
7692 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7693 },
7694 {
7695 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7696 .insns = {
7697 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7698 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7699 BPF_MOV64_IMM(BPF_REG_2, 0),
7700 BPF_MOV64_IMM(BPF_REG_3, 0),
7701 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7702 BPF_EXIT_INSN(),
7703 },
7704 .result = ACCEPT,
7705 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7706 },
7707 {
7708 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7709 .insns = {
7710 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7711 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7712 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7713 BPF_LD_MAP_FD(BPF_REG_1, 0),
7714 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7715 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7716 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7717 BPF_MOV64_IMM(BPF_REG_2, 0),
7718 BPF_MOV64_IMM(BPF_REG_3, 0),
7719 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7720 BPF_EXIT_INSN(),
7721 },
7722 .fixup_map_hash_8b = { 3 },
7723 .result = ACCEPT,
7724 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7725 },
7726 {
7727 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7728 .insns = {
7729 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7730 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7731 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7732 BPF_LD_MAP_FD(BPF_REG_1, 0),
7733 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7734 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7735 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7736 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
7737 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7739 BPF_MOV64_IMM(BPF_REG_3, 0),
7740 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7741 BPF_EXIT_INSN(),
7742 },
7743 .fixup_map_hash_8b = { 3 },
7744 .result = ACCEPT,
7745 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7746 },
7747 {
7748 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7749 .insns = {
7750 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7751 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7752 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7753 BPF_LD_MAP_FD(BPF_REG_1, 0),
7754 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7756 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7757 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7758 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
7759 BPF_MOV64_IMM(BPF_REG_3, 0),
7760 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7761 BPF_EXIT_INSN(),
7762 },
7763 .fixup_map_hash_8b = { 3 },
7764 .result = ACCEPT,
7765 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7766 },
7767 {
7768 "helper access to variable memory: 8 bytes leak",
7769 .insns = {
7770 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7771 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7772 BPF_MOV64_IMM(BPF_REG_0, 0),
7773 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7774 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7775 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7776 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7777 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7778 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7779 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7780 BPF_MOV64_IMM(BPF_REG_2, 1),
7781 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7782 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
7783 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
7784 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
7785 BPF_MOV64_IMM(BPF_REG_3, 0),
7786 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7787 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7788 BPF_EXIT_INSN(),
7789 },
7790 .errstr = "invalid indirect read from stack off -64+32 size 64",
7791 .result = REJECT,
7792 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7793 },
7794 {
7795 "helper access to variable memory: 8 bytes no leak (init memory)",
7796 .insns = {
7797 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7798 BPF_MOV64_IMM(BPF_REG_0, 0),
7799 BPF_MOV64_IMM(BPF_REG_0, 0),
7800 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7801 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7802 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7803 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7804 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
7805 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7806 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7807 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7809 BPF_MOV64_IMM(BPF_REG_2, 0),
7810 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
7811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
7812 BPF_MOV64_IMM(BPF_REG_3, 0),
7813 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7814 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7815 BPF_EXIT_INSN(),
7816 },
7817 .result = ACCEPT,
7818 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7819 },
7820 {
7821 "invalid and of negative number",
7822 .insns = {
7823 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7824 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7825 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7826 BPF_LD_MAP_FD(BPF_REG_1, 0),
7827 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7828 BPF_FUNC_map_lookup_elem),
7829 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7830 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7831 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
7832 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
7833 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7834 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
7835 offsetof(struct test_val, foo)),
7836 BPF_EXIT_INSN(),
7837 },
7838 .fixup_map_hash_48b = { 3 },
7839 .errstr = "R0 max value is outside of the array range",
7840 .result = REJECT,
7841 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7842 },
7843 {
7844 "invalid range check",
7845 .insns = {
7846 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7847 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7849 BPF_LD_MAP_FD(BPF_REG_1, 0),
7850 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7851 BPF_FUNC_map_lookup_elem),
7852 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
7853 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
7854 BPF_MOV64_IMM(BPF_REG_9, 1),
7855 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
7856 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
7857 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
7858 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
7859 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
7860 BPF_MOV32_IMM(BPF_REG_3, 1),
7861 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
7862 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
7863 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
7864 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
7865 BPF_MOV64_REG(BPF_REG_0, 0),
7866 BPF_EXIT_INSN(),
7867 },
7868 .fixup_map_hash_48b = { 3 },
7869 .errstr = "R0 max value is outside of the array range",
7870 .result = REJECT,
7871 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7872 },
7873 {
7874 "map in map access",
7875 .insns = {
7876 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7877 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7879 BPF_LD_MAP_FD(BPF_REG_1, 0),
7880 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7881 BPF_FUNC_map_lookup_elem),
7882 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7883 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7884 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7885 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7886 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7887 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7888 BPF_FUNC_map_lookup_elem),
7889 BPF_MOV64_IMM(BPF_REG_0, 0),
7890 BPF_EXIT_INSN(),
7891 },
7892 .fixup_map_in_map = { 3 },
7893 .result = ACCEPT,
7894 },
7895 {
7896 "invalid inner map pointer",
7897 .insns = {
7898 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7899 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7900 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7901 BPF_LD_MAP_FD(BPF_REG_1, 0),
7902 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7903 BPF_FUNC_map_lookup_elem),
7904 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7905 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7906 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7907 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7908 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7909 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7910 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7911 BPF_FUNC_map_lookup_elem),
7912 BPF_MOV64_IMM(BPF_REG_0, 0),
7913 BPF_EXIT_INSN(),
7914 },
7915 .fixup_map_in_map = { 3 },
7916 .errstr = "R1 pointer arithmetic on map_ptr prohibited",
7917 .result = REJECT,
7918 },
7919 {
7920 "forgot null checking on the inner map pointer",
7921 .insns = {
7922 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7923 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7924 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7925 BPF_LD_MAP_FD(BPF_REG_1, 0),
7926 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7927 BPF_FUNC_map_lookup_elem),
7928 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7929 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7931 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7932 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7933 BPF_FUNC_map_lookup_elem),
7934 BPF_MOV64_IMM(BPF_REG_0, 0),
7935 BPF_EXIT_INSN(),
7936 },
7937 .fixup_map_in_map = { 3 },
7938 .errstr = "R1 type=map_value_or_null expected=map_ptr",
7939 .result = REJECT,
7940 },
7941 {
7942 "ld_abs: check calling conv, r1",
7943 .insns = {
7944 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7945 BPF_MOV64_IMM(BPF_REG_1, 0),
7946 BPF_LD_ABS(BPF_W, -0x200000),
7947 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7948 BPF_EXIT_INSN(),
7949 },
7950 .errstr = "R1 !read_ok",
7951 .result = REJECT,
7952 },
7953 {
7954 "ld_abs: check calling conv, r2",
7955 .insns = {
7956 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7957 BPF_MOV64_IMM(BPF_REG_2, 0),
7958 BPF_LD_ABS(BPF_W, -0x200000),
7959 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7960 BPF_EXIT_INSN(),
7961 },
7962 .errstr = "R2 !read_ok",
7963 .result = REJECT,
7964 },
7965 {
7966 "ld_abs: check calling conv, r3",
7967 .insns = {
7968 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7969 BPF_MOV64_IMM(BPF_REG_3, 0),
7970 BPF_LD_ABS(BPF_W, -0x200000),
7971 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7972 BPF_EXIT_INSN(),
7973 },
7974 .errstr = "R3 !read_ok",
7975 .result = REJECT,
7976 },
7977 {
7978 "ld_abs: check calling conv, r4",
7979 .insns = {
7980 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7981 BPF_MOV64_IMM(BPF_REG_4, 0),
7982 BPF_LD_ABS(BPF_W, -0x200000),
7983 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7984 BPF_EXIT_INSN(),
7985 },
7986 .errstr = "R4 !read_ok",
7987 .result = REJECT,
7988 },
7989 {
7990 "ld_abs: check calling conv, r5",
7991 .insns = {
7992 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7993 BPF_MOV64_IMM(BPF_REG_5, 0),
7994 BPF_LD_ABS(BPF_W, -0x200000),
7995 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7996 BPF_EXIT_INSN(),
7997 },
7998 .errstr = "R5 !read_ok",
7999 .result = REJECT,
8000 },
8001 {
8002 "ld_abs: check calling conv, r7",
8003 .insns = {
8004 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8005 BPF_MOV64_IMM(BPF_REG_7, 0),
8006 BPF_LD_ABS(BPF_W, -0x200000),
8007 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8008 BPF_EXIT_INSN(),
8009 },
8010 .result = ACCEPT,
8011 },
8012 {
8013 "ld_abs: tests on r6 and skb data reload helper",
8014 .insns = {
8015 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8016 BPF_LD_ABS(BPF_B, 0),
8017 BPF_LD_ABS(BPF_H, 0),
8018 BPF_LD_ABS(BPF_W, 0),
8019 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
8020 BPF_MOV64_IMM(BPF_REG_6, 0),
8021 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8022 BPF_MOV64_IMM(BPF_REG_2, 1),
8023 BPF_MOV64_IMM(BPF_REG_3, 2),
8024 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8025 BPF_FUNC_skb_vlan_push),
8026 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
8027 BPF_LD_ABS(BPF_B, 0),
8028 BPF_LD_ABS(BPF_H, 0),
8029 BPF_LD_ABS(BPF_W, 0),
8030 BPF_MOV64_IMM(BPF_REG_0, 42),
8031 BPF_EXIT_INSN(),
8032 },
8033 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8034 .result = ACCEPT,
8035 .retval = 42 /* ultimate return value */,
8036 },
8037 {
8038 "ld_ind: check calling conv, r1",
8039 .insns = {
8040 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8041 BPF_MOV64_IMM(BPF_REG_1, 1),
8042 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
8043 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8044 BPF_EXIT_INSN(),
8045 },
8046 .errstr = "R1 !read_ok",
8047 .result = REJECT,
8048 },
8049 {
8050 "ld_ind: check calling conv, r2",
8051 .insns = {
8052 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8053 BPF_MOV64_IMM(BPF_REG_2, 1),
8054 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
8055 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8056 BPF_EXIT_INSN(),
8057 },
8058 .errstr = "R2 !read_ok",
8059 .result = REJECT,
8060 },
8061 {
8062 "ld_ind: check calling conv, r3",
8063 .insns = {
8064 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8065 BPF_MOV64_IMM(BPF_REG_3, 1),
8066 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
8067 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8068 BPF_EXIT_INSN(),
8069 },
8070 .errstr = "R3 !read_ok",
8071 .result = REJECT,
8072 },
8073 {
8074 "ld_ind: check calling conv, r4",
8075 .insns = {
8076 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8077 BPF_MOV64_IMM(BPF_REG_4, 1),
8078 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
8079 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
8080 BPF_EXIT_INSN(),
8081 },
8082 .errstr = "R4 !read_ok",
8083 .result = REJECT,
8084 },
8085 {
8086 "ld_ind: check calling conv, r5",
8087 .insns = {
8088 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8089 BPF_MOV64_IMM(BPF_REG_5, 1),
8090 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
8091 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
8092 BPF_EXIT_INSN(),
8093 },
8094 .errstr = "R5 !read_ok",
8095 .result = REJECT,
8096 },
8097 {
8098 "ld_ind: check calling conv, r7",
8099 .insns = {
8100 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8101 BPF_MOV64_IMM(BPF_REG_7, 1),
8102 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
8103 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8104 BPF_EXIT_INSN(),
8105 },
8106 .result = ACCEPT,
8107 .retval = 1,
8108 },
8109 {
8110 "check bpf_perf_event_data->sample_period byte load permitted",
8111 .insns = {
8112 BPF_MOV64_IMM(BPF_REG_0, 0),
8113 #if __BYTE_ORDER == __LITTLE_ENDIAN
8114 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
8115 offsetof(struct bpf_perf_event_data, sample_period)),
8116 #else
8117 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
8118 offsetof(struct bpf_perf_event_data, sample_period) + 7),
8119 #endif
8120 BPF_EXIT_INSN(),
8121 },
8122 .result = ACCEPT,
8123 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
8124 },
8125 {
8126 "check bpf_perf_event_data->sample_period half load permitted",
8127 .insns = {
8128 BPF_MOV64_IMM(BPF_REG_0, 0),
8129 #if __BYTE_ORDER == __LITTLE_ENDIAN
8130 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8131 offsetof(struct bpf_perf_event_data, sample_period)),
8132 #else
8133 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8134 offsetof(struct bpf_perf_event_data, sample_period) + 6),
8135 #endif
8136 BPF_EXIT_INSN(),
8137 },
8138 .result = ACCEPT,
8139 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
8140 },
8141 {
8142 "check bpf_perf_event_data->sample_period word load permitted",
8143 .insns = {
8144 BPF_MOV64_IMM(BPF_REG_0, 0),
8145 #if __BYTE_ORDER == __LITTLE_ENDIAN
8146 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8147 offsetof(struct bpf_perf_event_data, sample_period)),
8148 #else
8149 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8150 offsetof(struct bpf_perf_event_data, sample_period) + 4),
8151 #endif
8152 BPF_EXIT_INSN(),
8153 },
8154 .result = ACCEPT,
8155 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
8156 },
8157 {
8158 "check bpf_perf_event_data->sample_period dword load permitted",
8159 .insns = {
8160 BPF_MOV64_IMM(BPF_REG_0, 0),
8161 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
8162 offsetof(struct bpf_perf_event_data, sample_period)),
8163 BPF_EXIT_INSN(),
8164 },
8165 .result = ACCEPT,
8166 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
8167 },
8168 {
8169 "check skb->data half load not permitted",
8170 .insns = {
8171 BPF_MOV64_IMM(BPF_REG_0, 0),
8172 #if __BYTE_ORDER == __LITTLE_ENDIAN
8173 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8174 offsetof(struct __sk_buff, data)),
8175 #else
8176 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8177 offsetof(struct __sk_buff, data) + 2),
8178 #endif
8179 BPF_EXIT_INSN(),
8180 },
8181 .result = REJECT,
8182 .errstr = "invalid bpf_context access",
8183 },
8184 {
8185 "check skb->tc_classid half load not permitted for lwt prog",
8186 .insns = {
8187 BPF_MOV64_IMM(BPF_REG_0, 0),
8188 #if __BYTE_ORDER == __LITTLE_ENDIAN
8189 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8190 offsetof(struct __sk_buff, tc_classid)),
8191 #else
8192 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
8193 offsetof(struct __sk_buff, tc_classid) + 2),
8194 #endif
8195 BPF_EXIT_INSN(),
8196 },
8197 .result = REJECT,
8198 .errstr = "invalid bpf_context access",
8199 .prog_type = BPF_PROG_TYPE_LWT_IN,
8200 },
8201 {
8202 "bounds checks mixing signed and unsigned, positive bounds",
8203 .insns = {
8204 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8205 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8207 BPF_LD_MAP_FD(BPF_REG_1, 0),
8208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8209 BPF_FUNC_map_lookup_elem),
8210 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
8211 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8212 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8213 BPF_MOV64_IMM(BPF_REG_2, 2),
8214 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
8215 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
8216 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8217 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8218 BPF_MOV64_IMM(BPF_REG_0, 0),
8219 BPF_EXIT_INSN(),
8220 },
8221 .fixup_map_hash_8b = { 3 },
8222 .errstr = "unbounded min value",
8223 .result = REJECT,
8224 },
8225 {
8226 "bounds checks mixing signed and unsigned",
8227 .insns = {
8228 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8229 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8230 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8231 BPF_LD_MAP_FD(BPF_REG_1, 0),
8232 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8233 BPF_FUNC_map_lookup_elem),
8234 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
8235 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8236 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8237 BPF_MOV64_IMM(BPF_REG_2, -1),
8238 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
8239 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8240 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8241 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8242 BPF_MOV64_IMM(BPF_REG_0, 0),
8243 BPF_EXIT_INSN(),
8244 },
8245 .fixup_map_hash_8b = { 3 },
8246 .errstr = "unbounded min value",
8247 .result = REJECT,
8248 },
8249 {
8250 "bounds checks mixing signed and unsigned, variant 2",
8251 .insns = {
8252 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8253 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8255 BPF_LD_MAP_FD(BPF_REG_1, 0),
8256 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8257 BPF_FUNC_map_lookup_elem),
8258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8259 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8260 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8261 BPF_MOV64_IMM(BPF_REG_2, -1),
8262 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
8263 BPF_MOV64_IMM(BPF_REG_8, 0),
8264 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
8265 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
8266 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
8267 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
8268 BPF_MOV64_IMM(BPF_REG_0, 0),
8269 BPF_EXIT_INSN(),
8270 },
8271 .fixup_map_hash_8b = { 3 },
8272 .errstr = "unbounded min value",
8273 .result = REJECT,
8274 },
8275 {
8276 "bounds checks mixing signed and unsigned, variant 3",
8277 .insns = {
8278 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8279 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8280 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8281 BPF_LD_MAP_FD(BPF_REG_1, 0),
8282 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8283 BPF_FUNC_map_lookup_elem),
8284 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8285 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8286 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8287 BPF_MOV64_IMM(BPF_REG_2, -1),
8288 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
8289 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
8290 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
8291 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
8292 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
8293 BPF_MOV64_IMM(BPF_REG_0, 0),
8294 BPF_EXIT_INSN(),
8295 },
8296 .fixup_map_hash_8b = { 3 },
8297 .errstr = "unbounded min value",
8298 .result = REJECT,
8299 },
8300 {
8301 "bounds checks mixing signed and unsigned, variant 4",
8302 .insns = {
8303 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8304 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8305 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8306 BPF_LD_MAP_FD(BPF_REG_1, 0),
8307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8308 BPF_FUNC_map_lookup_elem),
8309 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
8310 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8311 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8312 BPF_MOV64_IMM(BPF_REG_2, 1),
8313 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
8314 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8315 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8316 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8317 BPF_MOV64_IMM(BPF_REG_0, 0),
8318 BPF_EXIT_INSN(),
8319 },
8320 .fixup_map_hash_8b = { 3 },
8321 .result = ACCEPT,
8322 },
8323 {
8324 "bounds checks mixing signed and unsigned, variant 5",
8325 .insns = {
8326 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8327 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8328 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8329 BPF_LD_MAP_FD(BPF_REG_1, 0),
8330 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8331 BPF_FUNC_map_lookup_elem),
8332 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8333 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8334 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8335 BPF_MOV64_IMM(BPF_REG_2, -1),
8336 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
8337 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
8338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
8339 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
8340 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8341 BPF_MOV64_IMM(BPF_REG_0, 0),
8342 BPF_EXIT_INSN(),
8343 },
8344 .fixup_map_hash_8b = { 3 },
8345 .errstr = "unbounded min value",
8346 .result = REJECT,
8347 },
8348 {
8349 "bounds checks mixing signed and unsigned, variant 6",
8350 .insns = {
8351 BPF_MOV64_IMM(BPF_REG_2, 0),
8352 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
8353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
8354 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8355 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
8356 BPF_MOV64_IMM(BPF_REG_6, -1),
8357 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
8358 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
8359 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
8360 BPF_MOV64_IMM(BPF_REG_5, 0),
8361 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
8362 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8363 BPF_FUNC_skb_load_bytes),
8364 BPF_MOV64_IMM(BPF_REG_0, 0),
8365 BPF_EXIT_INSN(),
8366 },
8367 .errstr = "R4 min value is negative, either use unsigned",
8368 .result = REJECT,
8369 },
8370 {
8371 "bounds checks mixing signed and unsigned, variant 7",
8372 .insns = {
8373 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8374 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8375 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8376 BPF_LD_MAP_FD(BPF_REG_1, 0),
8377 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8378 BPF_FUNC_map_lookup_elem),
8379 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
8380 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8381 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8382 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
8383 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
8384 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8385 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8386 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8387 BPF_MOV64_IMM(BPF_REG_0, 0),
8388 BPF_EXIT_INSN(),
8389 },
8390 .fixup_map_hash_8b = { 3 },
8391 .result = ACCEPT,
8392 },
8393 {
8394 "bounds checks mixing signed and unsigned, variant 8",
8395 .insns = {
8396 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8397 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8398 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8399 BPF_LD_MAP_FD(BPF_REG_1, 0),
8400 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8401 BPF_FUNC_map_lookup_elem),
8402 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8403 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8404 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8405 BPF_MOV64_IMM(BPF_REG_2, -1),
8406 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
8407 BPF_MOV64_IMM(BPF_REG_0, 0),
8408 BPF_EXIT_INSN(),
8409 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8410 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8411 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8412 BPF_MOV64_IMM(BPF_REG_0, 0),
8413 BPF_EXIT_INSN(),
8414 },
8415 .fixup_map_hash_8b = { 3 },
8416 .errstr = "unbounded min value",
8417 .result = REJECT,
8418 },
8419 {
8420 "bounds checks mixing signed and unsigned, variant 9",
8421 .insns = {
8422 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8423 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8425 BPF_LD_MAP_FD(BPF_REG_1, 0),
8426 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8427 BPF_FUNC_map_lookup_elem),
8428 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
8429 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8430 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8431 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
8432 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
8433 BPF_MOV64_IMM(BPF_REG_0, 0),
8434 BPF_EXIT_INSN(),
8435 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8436 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8437 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8438 BPF_MOV64_IMM(BPF_REG_0, 0),
8439 BPF_EXIT_INSN(),
8440 },
8441 .fixup_map_hash_8b = { 3 },
8442 .result = ACCEPT,
8443 },
8444 {
8445 "bounds checks mixing signed and unsigned, variant 10",
8446 .insns = {
8447 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8448 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8450 BPF_LD_MAP_FD(BPF_REG_1, 0),
8451 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8452 BPF_FUNC_map_lookup_elem),
8453 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8454 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8455 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8456 BPF_MOV64_IMM(BPF_REG_2, 0),
8457 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
8458 BPF_MOV64_IMM(BPF_REG_0, 0),
8459 BPF_EXIT_INSN(),
8460 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8461 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8462 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8463 BPF_MOV64_IMM(BPF_REG_0, 0),
8464 BPF_EXIT_INSN(),
8465 },
8466 .fixup_map_hash_8b = { 3 },
8467 .errstr = "unbounded min value",
8468 .result = REJECT,
8469 },
8470 {
8471 "bounds checks mixing signed and unsigned, variant 11",
8472 .insns = {
8473 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8474 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8476 BPF_LD_MAP_FD(BPF_REG_1, 0),
8477 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8478 BPF_FUNC_map_lookup_elem),
8479 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8480 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8481 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8482 BPF_MOV64_IMM(BPF_REG_2, -1),
8483 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
8484 /* Dead branch. */
8485 BPF_MOV64_IMM(BPF_REG_0, 0),
8486 BPF_EXIT_INSN(),
8487 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8488 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8489 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8490 BPF_MOV64_IMM(BPF_REG_0, 0),
8491 BPF_EXIT_INSN(),
8492 },
8493 .fixup_map_hash_8b = { 3 },
8494 .errstr = "unbounded min value",
8495 .result = REJECT,
8496 },
8497 {
8498 "bounds checks mixing signed and unsigned, variant 12",
8499 .insns = {
8500 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8501 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8502 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8503 BPF_LD_MAP_FD(BPF_REG_1, 0),
8504 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8505 BPF_FUNC_map_lookup_elem),
8506 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8507 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8508 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8509 BPF_MOV64_IMM(BPF_REG_2, -6),
8510 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
8511 BPF_MOV64_IMM(BPF_REG_0, 0),
8512 BPF_EXIT_INSN(),
8513 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8514 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8515 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8516 BPF_MOV64_IMM(BPF_REG_0, 0),
8517 BPF_EXIT_INSN(),
8518 },
8519 .fixup_map_hash_8b = { 3 },
8520 .errstr = "unbounded min value",
8521 .result = REJECT,
8522 },
8523 {
8524 "bounds checks mixing signed and unsigned, variant 13",
8525 .insns = {
8526 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8527 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8528 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8529 BPF_LD_MAP_FD(BPF_REG_1, 0),
8530 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8531 BPF_FUNC_map_lookup_elem),
8532 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8533 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8534 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8535 BPF_MOV64_IMM(BPF_REG_2, 2),
8536 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
8537 BPF_MOV64_IMM(BPF_REG_7, 1),
8538 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
8539 BPF_MOV64_IMM(BPF_REG_0, 0),
8540 BPF_EXIT_INSN(),
8541 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
8542 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
8543 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
8544 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8545 BPF_MOV64_IMM(BPF_REG_0, 0),
8546 BPF_EXIT_INSN(),
8547 },
8548 .fixup_map_hash_8b = { 3 },
8549 .errstr = "unbounded min value",
8550 .result = REJECT,
8551 },
8552 {
8553 "bounds checks mixing signed and unsigned, variant 14",
8554 .insns = {
8555 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
8556 offsetof(struct __sk_buff, mark)),
8557 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8558 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8560 BPF_LD_MAP_FD(BPF_REG_1, 0),
8561 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8562 BPF_FUNC_map_lookup_elem),
8563 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8564 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8565 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8566 BPF_MOV64_IMM(BPF_REG_2, -1),
8567 BPF_MOV64_IMM(BPF_REG_8, 2),
8568 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
8569 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
8570 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
8571 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8572 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8573 BPF_MOV64_IMM(BPF_REG_0, 0),
8574 BPF_EXIT_INSN(),
8575 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
8576 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
8577 },
8578 .fixup_map_hash_8b = { 4 },
8579 .errstr = "R0 invalid mem access 'inv'",
8580 .result = REJECT,
8581 },
8582 {
8583 "bounds checks mixing signed and unsigned, variant 15",
8584 .insns = {
8585 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8586 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8588 BPF_LD_MAP_FD(BPF_REG_1, 0),
8589 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8590 BPF_FUNC_map_lookup_elem),
8591 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8592 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
8593 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
8594 BPF_MOV64_IMM(BPF_REG_2, -6),
8595 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
8596 BPF_MOV64_IMM(BPF_REG_0, 0),
8597 BPF_EXIT_INSN(),
8598 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8599 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
8600 BPF_MOV64_IMM(BPF_REG_0, 0),
8601 BPF_EXIT_INSN(),
8602 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
8603 BPF_MOV64_IMM(BPF_REG_0, 0),
8604 BPF_EXIT_INSN(),
8605 },
8606 .fixup_map_hash_8b = { 3 },
8607 .errstr = "unbounded min value",
8608 .result = REJECT,
8609 .result_unpriv = REJECT,
8610 },
8611 {
8612 "subtraction bounds (map value) variant 1",
8613 .insns = {
8614 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8615 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8616 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8617 BPF_LD_MAP_FD(BPF_REG_1, 0),
8618 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8619 BPF_FUNC_map_lookup_elem),
8620 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8621 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8622 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
8623 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
8624 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
8625 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
8626 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
8627 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8628 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8629 BPF_EXIT_INSN(),
8630 BPF_MOV64_IMM(BPF_REG_0, 0),
8631 BPF_EXIT_INSN(),
8632 },
8633 .fixup_map_hash_8b = { 3 },
8634 .errstr = "R0 max value is outside of the array range",
8635 .result = REJECT,
8636 },
8637 {
8638 "subtraction bounds (map value) variant 2",
8639 .insns = {
8640 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8641 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8643 BPF_LD_MAP_FD(BPF_REG_1, 0),
8644 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8645 BPF_FUNC_map_lookup_elem),
8646 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8647 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8648 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
8649 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
8650 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
8651 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
8652 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8653 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8654 BPF_EXIT_INSN(),
8655 BPF_MOV64_IMM(BPF_REG_0, 0),
8656 BPF_EXIT_INSN(),
8657 },
8658 .fixup_map_hash_8b = { 3 },
8659 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
8660 .result = REJECT,
8661 },
8662 {
8663 "bounds check based on zero-extended MOV",
8664 .insns = {
8665 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8666 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8667 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8668 BPF_LD_MAP_FD(BPF_REG_1, 0),
8669 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8670 BPF_FUNC_map_lookup_elem),
8671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8672 /* r2 = 0x0000'0000'ffff'ffff */
8673 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
8674 /* r2 = 0 */
8675 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
8676 /* no-op */
8677 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8678 /* access at offset 0 */
8679 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8680 /* exit */
8681 BPF_MOV64_IMM(BPF_REG_0, 0),
8682 BPF_EXIT_INSN(),
8683 },
8684 .fixup_map_hash_8b = { 3 },
8685 .result = ACCEPT
8686 },
8687 {
8688 "bounds check based on sign-extended MOV. test1",
8689 .insns = {
8690 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8691 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8692 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8693 BPF_LD_MAP_FD(BPF_REG_1, 0),
8694 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8695 BPF_FUNC_map_lookup_elem),
8696 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8697 /* r2 = 0xffff'ffff'ffff'ffff */
8698 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
8699 /* r2 = 0xffff'ffff */
8700 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
8701 /* r0 = <oob pointer> */
8702 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8703 /* access to OOB pointer */
8704 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8705 /* exit */
8706 BPF_MOV64_IMM(BPF_REG_0, 0),
8707 BPF_EXIT_INSN(),
8708 },
8709 .fixup_map_hash_8b = { 3 },
8710 .errstr = "map_value pointer and 4294967295",
8711 .result = REJECT
8712 },
8713 {
8714 "bounds check based on sign-extended MOV. test2",
8715 .insns = {
8716 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8717 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8719 BPF_LD_MAP_FD(BPF_REG_1, 0),
8720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8721 BPF_FUNC_map_lookup_elem),
8722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8723 /* r2 = 0xffff'ffff'ffff'ffff */
8724 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
8725 /* r2 = 0xfff'ffff */
8726 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
8727 /* r0 = <oob pointer> */
8728 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8729 /* access to OOB pointer */
8730 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8731 /* exit */
8732 BPF_MOV64_IMM(BPF_REG_0, 0),
8733 BPF_EXIT_INSN(),
8734 },
8735 .fixup_map_hash_8b = { 3 },
8736 .errstr = "R0 min value is outside of the array range",
8737 .result = REJECT
8738 },
8739 {
8740 "bounds check based on reg_off + var_off + insn_off. test1",
8741 .insns = {
8742 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8743 offsetof(struct __sk_buff, mark)),
8744 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8745 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8747 BPF_LD_MAP_FD(BPF_REG_1, 0),
8748 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8749 BPF_FUNC_map_lookup_elem),
8750 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8751 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
8752 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
8753 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
8754 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
8755 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
8756 BPF_MOV64_IMM(BPF_REG_0, 0),
8757 BPF_EXIT_INSN(),
8758 },
8759 .fixup_map_hash_8b = { 4 },
8760 .errstr = "value_size=8 off=1073741825",
8761 .result = REJECT,
8762 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8763 },
8764 {
8765 "bounds check based on reg_off + var_off + insn_off. test2",
8766 .insns = {
8767 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8768 offsetof(struct __sk_buff, mark)),
8769 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8770 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8771 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8772 BPF_LD_MAP_FD(BPF_REG_1, 0),
8773 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8774 BPF_FUNC_map_lookup_elem),
8775 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8776 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
8777 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
8778 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
8779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
8780 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
8781 BPF_MOV64_IMM(BPF_REG_0, 0),
8782 BPF_EXIT_INSN(),
8783 },
8784 .fixup_map_hash_8b = { 4 },
8785 .errstr = "value 1073741823",
8786 .result = REJECT,
8787 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8788 },
8789 {
8790 "bounds check after truncation of non-boundary-crossing range",
8791 .insns = {
8792 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8793 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8794 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8795 BPF_LD_MAP_FD(BPF_REG_1, 0),
8796 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8797 BPF_FUNC_map_lookup_elem),
8798 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8799 /* r1 = [0x00, 0xff] */
8800 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8801 BPF_MOV64_IMM(BPF_REG_2, 1),
8802 /* r2 = 0x10'0000'0000 */
8803 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
8804 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
8805 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
8806 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
8807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8808 /* r1 = [0x00, 0xff] */
8809 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
8810 /* r1 = 0 */
8811 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8812 /* no-op */
8813 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8814 /* access at offset 0 */
8815 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8816 /* exit */
8817 BPF_MOV64_IMM(BPF_REG_0, 0),
8818 BPF_EXIT_INSN(),
8819 },
8820 .fixup_map_hash_8b = { 3 },
8821 .result = ACCEPT
8822 },
8823 {
8824 "bounds check after truncation of boundary-crossing range (1)",
8825 .insns = {
8826 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8827 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8829 BPF_LD_MAP_FD(BPF_REG_1, 0),
8830 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8831 BPF_FUNC_map_lookup_elem),
8832 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8833 /* r1 = [0x00, 0xff] */
8834 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8835 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8836 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
8837 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8838 /* r1 = [0xffff'ff80, 0xffff'ffff] or
8839 * [0x0000'0000, 0x0000'007f]
8840 */
8841 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
8842 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8843 /* r1 = [0x00, 0xff] or
8844 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
8845 */
8846 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8847 /* r1 = 0 or
8848 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
8849 */
8850 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8851 /* no-op or OOB pointer computation */
8852 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8853 /* potentially OOB access */
8854 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8855 /* exit */
8856 BPF_MOV64_IMM(BPF_REG_0, 0),
8857 BPF_EXIT_INSN(),
8858 },
8859 .fixup_map_hash_8b = { 3 },
8860 /* not actually fully unbounded, but the bound is very high */
8861 .errstr = "R0 unbounded memory access",
8862 .result = REJECT
8863 },
8864 {
8865 "bounds check after truncation of boundary-crossing range (2)",
8866 .insns = {
8867 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8868 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8869 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8870 BPF_LD_MAP_FD(BPF_REG_1, 0),
8871 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8872 BPF_FUNC_map_lookup_elem),
8873 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8874 /* r1 = [0x00, 0xff] */
8875 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8876 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8877 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
8878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8879 /* r1 = [0xffff'ff80, 0xffff'ffff] or
8880 * [0x0000'0000, 0x0000'007f]
8881 * difference to previous test: truncation via MOV32
8882 * instead of ALU32.
8883 */
8884 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
8885 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8886 /* r1 = [0x00, 0xff] or
8887 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
8888 */
8889 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8890 /* r1 = 0 or
8891 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
8892 */
8893 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8894 /* no-op or OOB pointer computation */
8895 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8896 /* potentially OOB access */
8897 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8898 /* exit */
8899 BPF_MOV64_IMM(BPF_REG_0, 0),
8900 BPF_EXIT_INSN(),
8901 },
8902 .fixup_map_hash_8b = { 3 },
8903 /* not actually fully unbounded, but the bound is very high */
8904 .errstr = "R0 unbounded memory access",
8905 .result = REJECT
8906 },
8907 {
8908 "bounds check after wrapping 32-bit addition",
8909 .insns = {
8910 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8911 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8912 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8913 BPF_LD_MAP_FD(BPF_REG_1, 0),
8914 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8915 BPF_FUNC_map_lookup_elem),
8916 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
8917 /* r1 = 0x7fff'ffff */
8918 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
8919 /* r1 = 0xffff'fffe */
8920 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8921 /* r1 = 0 */
8922 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
8923 /* no-op */
8924 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8925 /* access at offset 0 */
8926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8927 /* exit */
8928 BPF_MOV64_IMM(BPF_REG_0, 0),
8929 BPF_EXIT_INSN(),
8930 },
8931 .fixup_map_hash_8b = { 3 },
8932 .result = ACCEPT
8933 },
8934 {
8935 "bounds check after shift with oversized count operand",
8936 .insns = {
8937 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8938 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8940 BPF_LD_MAP_FD(BPF_REG_1, 0),
8941 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8942 BPF_FUNC_map_lookup_elem),
8943 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8944 BPF_MOV64_IMM(BPF_REG_2, 32),
8945 BPF_MOV64_IMM(BPF_REG_1, 1),
8946 /* r1 = (u32)1 << (u32)32 = ? */
8947 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
8948 /* r1 = [0x0000, 0xffff] */
8949 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
8950 /* computes unknown pointer, potentially OOB */
8951 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8952 /* potentially OOB access */
8953 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8954 /* exit */
8955 BPF_MOV64_IMM(BPF_REG_0, 0),
8956 BPF_EXIT_INSN(),
8957 },
8958 .fixup_map_hash_8b = { 3 },
8959 .errstr = "R0 max value is outside of the array range",
8960 .result = REJECT
8961 },
8962 {
8963 "bounds check after right shift of maybe-negative number",
8964 .insns = {
8965 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8966 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8968 BPF_LD_MAP_FD(BPF_REG_1, 0),
8969 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8970 BPF_FUNC_map_lookup_elem),
8971 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8972 /* r1 = [0x00, 0xff] */
8973 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8974 /* r1 = [-0x01, 0xfe] */
8975 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
8976 /* r1 = 0 or 0xff'ffff'ffff'ffff */
8977 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8978 /* r1 = 0 or 0xffff'ffff'ffff */
8979 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8980 /* computes unknown pointer, potentially OOB */
8981 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8982 /* potentially OOB access */
8983 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8984 /* exit */
8985 BPF_MOV64_IMM(BPF_REG_0, 0),
8986 BPF_EXIT_INSN(),
8987 },
8988 .fixup_map_hash_8b = { 3 },
8989 .errstr = "R0 unbounded memory access",
8990 .result = REJECT
8991 },
8992 {
8993 "bounds check map access with off+size signed 32bit overflow. test1",
8994 .insns = {
8995 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8996 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8998 BPF_LD_MAP_FD(BPF_REG_1, 0),
8999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9000 BPF_FUNC_map_lookup_elem),
9001 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9002 BPF_EXIT_INSN(),
9003 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
9004 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
9005 BPF_JMP_A(0),
9006 BPF_EXIT_INSN(),
9007 },
9008 .fixup_map_hash_8b = { 3 },
9009 .errstr = "map_value pointer and 2147483646",
9010 .result = REJECT
9011 },
9012 {
9013 "bounds check map access with off+size signed 32bit overflow. test2",
9014 .insns = {
9015 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9016 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9017 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9018 BPF_LD_MAP_FD(BPF_REG_1, 0),
9019 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9020 BPF_FUNC_map_lookup_elem),
9021 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9022 BPF_EXIT_INSN(),
9023 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
9024 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
9025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
9026 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
9027 BPF_JMP_A(0),
9028 BPF_EXIT_INSN(),
9029 },
9030 .fixup_map_hash_8b = { 3 },
9031 .errstr = "pointer offset 1073741822",
9032 .result = REJECT
9033 },
9034 {
9035 "bounds check map access with off+size signed 32bit overflow. test3",
9036 .insns = {
9037 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9038 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9039 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9040 BPF_LD_MAP_FD(BPF_REG_1, 0),
9041 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9042 BPF_FUNC_map_lookup_elem),
9043 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9044 BPF_EXIT_INSN(),
9045 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
9046 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
9047 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
9048 BPF_JMP_A(0),
9049 BPF_EXIT_INSN(),
9050 },
9051 .fixup_map_hash_8b = { 3 },
9052 .errstr = "pointer offset -1073741822",
9053 .result = REJECT
9054 },
9055 {
9056 "bounds check map access with off+size signed 32bit overflow. test4",
9057 .insns = {
9058 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9059 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9060 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9061 BPF_LD_MAP_FD(BPF_REG_1, 0),
9062 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9063 BPF_FUNC_map_lookup_elem),
9064 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9065 BPF_EXIT_INSN(),
9066 BPF_MOV64_IMM(BPF_REG_1, 1000000),
9067 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
9068 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
9069 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
9070 BPF_JMP_A(0),
9071 BPF_EXIT_INSN(),
9072 },
9073 .fixup_map_hash_8b = { 3 },
9074 .errstr = "map_value pointer and 1000000000000",
9075 .result = REJECT
9076 },
9077 {
9078 "pointer/scalar confusion in state equality check (way 1)",
9079 .insns = {
9080 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9081 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9083 BPF_LD_MAP_FD(BPF_REG_1, 0),
9084 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9085 BPF_FUNC_map_lookup_elem),
9086 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
9087 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
9088 BPF_JMP_A(1),
9089 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
9090 BPF_JMP_A(0),
9091 BPF_EXIT_INSN(),
9092 },
9093 .fixup_map_hash_8b = { 3 },
9094 .result = ACCEPT,
9095 .retval = POINTER_VALUE,
9096 .result_unpriv = REJECT,
9097 .errstr_unpriv = "R0 leaks addr as return value"
9098 },
9099 {
9100 "pointer/scalar confusion in state equality check (way 2)",
9101 .insns = {
9102 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9105 BPF_LD_MAP_FD(BPF_REG_1, 0),
9106 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9107 BPF_FUNC_map_lookup_elem),
9108 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
9109 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
9110 BPF_JMP_A(1),
9111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
9112 BPF_EXIT_INSN(),
9113 },
9114 .fixup_map_hash_8b = { 3 },
9115 .result = ACCEPT,
9116 .retval = POINTER_VALUE,
9117 .result_unpriv = REJECT,
9118 .errstr_unpriv = "R0 leaks addr as return value"
9119 },
9120 {
9121 "variable-offset ctx access",
9122 .insns = {
9123 /* Get an unknown value */
9124 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
9125 /* Make it small and 4-byte aligned */
9126 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
9127 /* add it to skb. We now have either &skb->len or
9128 * &skb->pkt_type, but we don't know which
9129 */
9130 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
9131 /* dereference it */
9132 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9133 BPF_EXIT_INSN(),
9134 },
9135 .errstr = "variable ctx access var_off=(0x0; 0x4)",
9136 .result = REJECT,
9137 .prog_type = BPF_PROG_TYPE_LWT_IN,
9138 },
9139 {
9140 "variable-offset stack access",
9141 .insns = {
9142 /* Fill the top 8 bytes of the stack */
9143 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9144 /* Get an unknown value */
9145 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
9146 /* Make it small and 4-byte aligned */
9147 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
9148 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
9149 /* add it to fp. We now have either fp-4 or fp-8, but
9150 * we don't know which
9151 */
9152 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
9153 /* dereference it */
9154 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
9155 BPF_EXIT_INSN(),
9156 },
9157 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
9158 .result = REJECT,
9159 .prog_type = BPF_PROG_TYPE_LWT_IN,
9160 },
9161 {
9162 "indirect variable-offset stack access",
9163 .insns = {
9164 /* Fill the top 8 bytes of the stack */
9165 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9166 /* Get an unknown value */
9167 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
9168 /* Make it small and 4-byte aligned */
9169 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
9170 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
9171 /* add it to fp. We now have either fp-4 or fp-8, but
9172 * we don't know which
9173 */
9174 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
9175 /* dereference it indirectly */
9176 BPF_LD_MAP_FD(BPF_REG_1, 0),
9177 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9178 BPF_FUNC_map_lookup_elem),
9179 BPF_MOV64_IMM(BPF_REG_0, 0),
9180 BPF_EXIT_INSN(),
9181 },
9182 .fixup_map_hash_8b = { 5 },
9183 .errstr = "variable stack read R2",
9184 .result = REJECT,
9185 .prog_type = BPF_PROG_TYPE_LWT_IN,
9186 },
9187 {
9188 "direct stack access with 32-bit wraparound. test1",
9189 .insns = {
9190 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9191 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
9192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
9193 BPF_MOV32_IMM(BPF_REG_0, 0),
9194 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
9195 BPF_EXIT_INSN()
9196 },
9197 .errstr = "fp pointer and 2147483647",
9198 .result = REJECT
9199 },
9200 {
9201 "direct stack access with 32-bit wraparound. test2",
9202 .insns = {
9203 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
9205 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
9206 BPF_MOV32_IMM(BPF_REG_0, 0),
9207 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
9208 BPF_EXIT_INSN()
9209 },
9210 .errstr = "fp pointer and 1073741823",
9211 .result = REJECT
9212 },
9213 {
9214 "direct stack access with 32-bit wraparound. test3",
9215 .insns = {
9216 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
9218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
9219 BPF_MOV32_IMM(BPF_REG_0, 0),
9220 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
9221 BPF_EXIT_INSN()
9222 },
9223 .errstr = "fp pointer offset 1073741822",
9224 .result = REJECT
9225 },
9226 {
9227 "liveness pruning and write screening",
9228 .insns = {
9229 /* Get an unknown value */
9230 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
9231 /* branch conditions teach us nothing about R2 */
9232 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
9233 BPF_MOV64_IMM(BPF_REG_0, 0),
9234 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
9235 BPF_MOV64_IMM(BPF_REG_0, 0),
9236 BPF_EXIT_INSN(),
9237 },
9238 .errstr = "R0 !read_ok",
9239 .result = REJECT,
9240 .prog_type = BPF_PROG_TYPE_LWT_IN,
9241 },
9242 {
9243 "varlen_map_value_access pruning",
9244 .insns = {
9245 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9246 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9248 BPF_LD_MAP_FD(BPF_REG_1, 0),
9249 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9250 BPF_FUNC_map_lookup_elem),
9251 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
9252 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
9253 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
9254 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
9255 BPF_MOV32_IMM(BPF_REG_1, 0),
9256 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
9257 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
9258 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
9259 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
9260 offsetof(struct test_val, foo)),
9261 BPF_EXIT_INSN(),
9262 },
9263 .fixup_map_hash_48b = { 3 },
9264 .errstr_unpriv = "R0 leaks addr",
9265 .errstr = "R0 unbounded memory access",
9266 .result_unpriv = REJECT,
9267 .result = REJECT,
9268 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9269 },
9270 {
9271 "invalid 64-bit BPF_END",
9272 .insns = {
9273 BPF_MOV32_IMM(BPF_REG_0, 0),
9274 {
9275 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
9276 .dst_reg = BPF_REG_0,
9277 .src_reg = 0,
9278 .off = 0,
9279 .imm = 32,
9280 },
9281 BPF_EXIT_INSN(),
9282 },
9283 .errstr = "unknown opcode d7",
9284 .result = REJECT,
9285 },
9286 {
9287 "XDP, using ifindex from netdev",
9288 .insns = {
9289 BPF_MOV64_IMM(BPF_REG_0, 0),
9290 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9291 offsetof(struct xdp_md, ingress_ifindex)),
9292 BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
9293 BPF_MOV64_IMM(BPF_REG_0, 1),
9294 BPF_EXIT_INSN(),
9295 },
9296 .result = ACCEPT,
9297 .prog_type = BPF_PROG_TYPE_XDP,
9298 .retval = 1,
9299 },
9300 {
9301 "meta access, test1",
9302 .insns = {
9303 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9304 offsetof(struct xdp_md, data_meta)),
9305 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9306 offsetof(struct xdp_md, data)),
9307 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9308 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9309 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
9310 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9311 BPF_MOV64_IMM(BPF_REG_0, 0),
9312 BPF_EXIT_INSN(),
9313 },
9314 .result = ACCEPT,
9315 .prog_type = BPF_PROG_TYPE_XDP,
9316 },
9317 {
9318 "meta access, test2",
9319 .insns = {
9320 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9321 offsetof(struct xdp_md, data_meta)),
9322 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9323 offsetof(struct xdp_md, data)),
9324 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9325 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
9326 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
9327 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
9328 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
9329 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9330 BPF_MOV64_IMM(BPF_REG_0, 0),
9331 BPF_EXIT_INSN(),
9332 },
9333 .result = REJECT,
9334 .errstr = "invalid access to packet, off=-8",
9335 .prog_type = BPF_PROG_TYPE_XDP,
9336 },
9337 {
9338 "meta access, test3",
9339 .insns = {
9340 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9341 offsetof(struct xdp_md, data_meta)),
9342 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9343 offsetof(struct xdp_md, data_end)),
9344 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9346 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
9347 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9348 BPF_MOV64_IMM(BPF_REG_0, 0),
9349 BPF_EXIT_INSN(),
9350 },
9351 .result = REJECT,
9352 .errstr = "invalid access to packet",
9353 .prog_type = BPF_PROG_TYPE_XDP,
9354 },
9355 {
9356 "meta access, test4",
9357 .insns = {
9358 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9359 offsetof(struct xdp_md, data_meta)),
9360 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9361 offsetof(struct xdp_md, data_end)),
9362 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
9363 offsetof(struct xdp_md, data)),
9364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
9365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9366 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
9367 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9368 BPF_MOV64_IMM(BPF_REG_0, 0),
9369 BPF_EXIT_INSN(),
9370 },
9371 .result = REJECT,
9372 .errstr = "invalid access to packet",
9373 .prog_type = BPF_PROG_TYPE_XDP,
9374 },
9375 {
9376 "meta access, test5",
9377 .insns = {
9378 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9379 offsetof(struct xdp_md, data_meta)),
9380 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
9381 offsetof(struct xdp_md, data)),
9382 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
9383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9384 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
9385 BPF_MOV64_IMM(BPF_REG_2, -8),
9386 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9387 BPF_FUNC_xdp_adjust_meta),
9388 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
9389 BPF_MOV64_IMM(BPF_REG_0, 0),
9390 BPF_EXIT_INSN(),
9391 },
9392 .result = REJECT,
9393 .errstr = "R3 !read_ok",
9394 .prog_type = BPF_PROG_TYPE_XDP,
9395 },
9396 {
9397 "meta access, test6",
9398 .insns = {
9399 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9400 offsetof(struct xdp_md, data_meta)),
9401 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9402 offsetof(struct xdp_md, data)),
9403 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
9404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9405 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
9406 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
9407 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
9408 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9409 BPF_MOV64_IMM(BPF_REG_0, 0),
9410 BPF_EXIT_INSN(),
9411 },
9412 .result = REJECT,
9413 .errstr = "invalid access to packet",
9414 .prog_type = BPF_PROG_TYPE_XDP,
9415 },
9416 {
9417 "meta access, test7",
9418 .insns = {
9419 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9420 offsetof(struct xdp_md, data_meta)),
9421 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9422 offsetof(struct xdp_md, data)),
9423 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
9424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9425 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
9426 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
9427 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
9428 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9429 BPF_MOV64_IMM(BPF_REG_0, 0),
9430 BPF_EXIT_INSN(),
9431 },
9432 .result = ACCEPT,
9433 .prog_type = BPF_PROG_TYPE_XDP,
9434 },
9435 {
9436 "meta access, test8",
9437 .insns = {
9438 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9439 offsetof(struct xdp_md, data_meta)),
9440 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9441 offsetof(struct xdp_md, data)),
9442 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
9443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
9444 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
9445 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9446 BPF_MOV64_IMM(BPF_REG_0, 0),
9447 BPF_EXIT_INSN(),
9448 },
9449 .result = ACCEPT,
9450 .prog_type = BPF_PROG_TYPE_XDP,
9451 },
9452 {
9453 "meta access, test9",
9454 .insns = {
9455 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9456 offsetof(struct xdp_md, data_meta)),
9457 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9458 offsetof(struct xdp_md, data)),
9459 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
9460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
9461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
9462 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
9463 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9464 BPF_MOV64_IMM(BPF_REG_0, 0),
9465 BPF_EXIT_INSN(),
9466 },
9467 .result = REJECT,
9468 .errstr = "invalid access to packet",
9469 .prog_type = BPF_PROG_TYPE_XDP,
9470 },
9471 {
9472 "meta access, test10",
9473 .insns = {
9474 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9475 offsetof(struct xdp_md, data_meta)),
9476 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9477 offsetof(struct xdp_md, data)),
9478 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
9479 offsetof(struct xdp_md, data_end)),
9480 BPF_MOV64_IMM(BPF_REG_5, 42),
9481 BPF_MOV64_IMM(BPF_REG_6, 24),
9482 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
9483 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
9484 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
9485 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
9486 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
9487 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
9488 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
9489 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
9490 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
9491 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
9492 BPF_MOV64_IMM(BPF_REG_0, 0),
9493 BPF_EXIT_INSN(),
9494 },
9495 .result = REJECT,
9496 .errstr = "invalid access to packet",
9497 .prog_type = BPF_PROG_TYPE_XDP,
9498 },
9499 {
9500 "meta access, test11",
9501 .insns = {
9502 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9503 offsetof(struct xdp_md, data_meta)),
9504 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9505 offsetof(struct xdp_md, data)),
9506 BPF_MOV64_IMM(BPF_REG_5, 42),
9507 BPF_MOV64_IMM(BPF_REG_6, 24),
9508 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
9509 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
9510 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
9511 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
9512 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
9513 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
9514 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
9515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
9516 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
9517 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
9518 BPF_MOV64_IMM(BPF_REG_0, 0),
9519 BPF_EXIT_INSN(),
9520 },
9521 .result = ACCEPT,
9522 .prog_type = BPF_PROG_TYPE_XDP,
9523 },
9524 {
9525 "meta access, test12",
9526 .insns = {
9527 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9528 offsetof(struct xdp_md, data_meta)),
9529 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9530 offsetof(struct xdp_md, data)),
9531 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
9532 offsetof(struct xdp_md, data_end)),
9533 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
9534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
9535 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
9536 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
9537 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
9538 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
9539 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
9540 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
9541 BPF_MOV64_IMM(BPF_REG_0, 0),
9542 BPF_EXIT_INSN(),
9543 },
9544 .result = ACCEPT,
9545 .prog_type = BPF_PROG_TYPE_XDP,
9546 },
9547 {
9548 "arithmetic ops make PTR_TO_CTX unusable",
9549 .insns = {
9550 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
9551 offsetof(struct __sk_buff, data) -
9552 offsetof(struct __sk_buff, mark)),
9553 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9554 offsetof(struct __sk_buff, mark)),
9555 BPF_EXIT_INSN(),
9556 },
9557 .errstr = "dereference of modified ctx ptr",
9558 .result = REJECT,
9559 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9560 },
9561 {
9562 "pkt_end - pkt_start is allowed",
9563 .insns = {
9564 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9565 offsetof(struct __sk_buff, data_end)),
9566 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9567 offsetof(struct __sk_buff, data)),
9568 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
9569 BPF_EXIT_INSN(),
9570 },
9571 .result = ACCEPT,
9572 .retval = TEST_DATA_LEN,
9573 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9574 },
9575 {
9576 "XDP pkt read, pkt_end mangling, bad access 1",
9577 .insns = {
9578 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9579 offsetof(struct xdp_md, data)),
9580 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9581 offsetof(struct xdp_md, data_end)),
9582 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9584 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
9585 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9586 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9587 BPF_MOV64_IMM(BPF_REG_0, 0),
9588 BPF_EXIT_INSN(),
9589 },
9590 .errstr = "R3 pointer arithmetic on pkt_end",
9591 .result = REJECT,
9592 .prog_type = BPF_PROG_TYPE_XDP,
9593 },
9594 {
9595 "XDP pkt read, pkt_end mangling, bad access 2",
9596 .insns = {
9597 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9598 offsetof(struct xdp_md, data)),
9599 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9600 offsetof(struct xdp_md, data_end)),
9601 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9603 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
9604 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9605 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9606 BPF_MOV64_IMM(BPF_REG_0, 0),
9607 BPF_EXIT_INSN(),
9608 },
9609 .errstr = "R3 pointer arithmetic on pkt_end",
9610 .result = REJECT,
9611 .prog_type = BPF_PROG_TYPE_XDP,
9612 },
9613 {
9614 "XDP pkt read, pkt_data' > pkt_end, good access",
9615 .insns = {
9616 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9617 offsetof(struct xdp_md, data)),
9618 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9619 offsetof(struct xdp_md, data_end)),
9620 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9621 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9622 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9623 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9624 BPF_MOV64_IMM(BPF_REG_0, 0),
9625 BPF_EXIT_INSN(),
9626 },
9627 .result = ACCEPT,
9628 .prog_type = BPF_PROG_TYPE_XDP,
9629 },
9630 {
9631 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
9632 .insns = {
9633 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9634 offsetof(struct xdp_md, data)),
9635 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9636 offsetof(struct xdp_md, data_end)),
9637 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9638 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9639 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9640 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9641 BPF_MOV64_IMM(BPF_REG_0, 0),
9642 BPF_EXIT_INSN(),
9643 },
9644 .errstr = "R1 offset is outside of the packet",
9645 .result = REJECT,
9646 .prog_type = BPF_PROG_TYPE_XDP,
9647 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9648 },
9649 {
9650 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
9651 .insns = {
9652 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9653 offsetof(struct xdp_md, data)),
9654 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9655 offsetof(struct xdp_md, data_end)),
9656 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9657 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9658 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
9659 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9660 BPF_MOV64_IMM(BPF_REG_0, 0),
9661 BPF_EXIT_INSN(),
9662 },
9663 .errstr = "R1 offset is outside of the packet",
9664 .result = REJECT,
9665 .prog_type = BPF_PROG_TYPE_XDP,
9666 },
9667 {
9668 "XDP pkt read, pkt_end > pkt_data', good access",
9669 .insns = {
9670 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9671 offsetof(struct xdp_md, data)),
9672 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9673 offsetof(struct xdp_md, data_end)),
9674 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9675 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9676 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9677 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9678 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9679 BPF_MOV64_IMM(BPF_REG_0, 0),
9680 BPF_EXIT_INSN(),
9681 },
9682 .result = ACCEPT,
9683 .prog_type = BPF_PROG_TYPE_XDP,
9684 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9685 },
9686 {
9687 "XDP pkt read, pkt_end > pkt_data', bad access 1",
9688 .insns = {
9689 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9690 offsetof(struct xdp_md, data)),
9691 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9692 offsetof(struct xdp_md, data_end)),
9693 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9695 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9696 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9697 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9698 BPF_MOV64_IMM(BPF_REG_0, 0),
9699 BPF_EXIT_INSN(),
9700 },
9701 .errstr = "R1 offset is outside of the packet",
9702 .result = REJECT,
9703 .prog_type = BPF_PROG_TYPE_XDP,
9704 },
9705 {
9706 "XDP pkt read, pkt_end > pkt_data', bad access 2",
9707 .insns = {
9708 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9709 offsetof(struct xdp_md, data)),
9710 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9711 offsetof(struct xdp_md, data_end)),
9712 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9714 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9715 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9716 BPF_MOV64_IMM(BPF_REG_0, 0),
9717 BPF_EXIT_INSN(),
9718 },
9719 .errstr = "R1 offset is outside of the packet",
9720 .result = REJECT,
9721 .prog_type = BPF_PROG_TYPE_XDP,
9722 },
9723 {
9724 "XDP pkt read, pkt_data' < pkt_end, good access",
9725 .insns = {
9726 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9727 offsetof(struct xdp_md, data)),
9728 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9729 offsetof(struct xdp_md, data_end)),
9730 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9731 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9732 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9733 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9734 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9735 BPF_MOV64_IMM(BPF_REG_0, 0),
9736 BPF_EXIT_INSN(),
9737 },
9738 .result = ACCEPT,
9739 .prog_type = BPF_PROG_TYPE_XDP,
9740 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9741 },
9742 {
9743 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
9744 .insns = {
9745 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9746 offsetof(struct xdp_md, data)),
9747 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9748 offsetof(struct xdp_md, data_end)),
9749 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9750 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9751 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9752 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9753 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9754 BPF_MOV64_IMM(BPF_REG_0, 0),
9755 BPF_EXIT_INSN(),
9756 },
9757 .errstr = "R1 offset is outside of the packet",
9758 .result = REJECT,
9759 .prog_type = BPF_PROG_TYPE_XDP,
9760 },
9761 {
9762 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
9763 .insns = {
9764 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9765 offsetof(struct xdp_md, data)),
9766 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9767 offsetof(struct xdp_md, data_end)),
9768 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9770 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9771 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9772 BPF_MOV64_IMM(BPF_REG_0, 0),
9773 BPF_EXIT_INSN(),
9774 },
9775 .errstr = "R1 offset is outside of the packet",
9776 .result = REJECT,
9777 .prog_type = BPF_PROG_TYPE_XDP,
9778 },
9779 {
9780 "XDP pkt read, pkt_end < pkt_data', good access",
9781 .insns = {
9782 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9783 offsetof(struct xdp_md, data)),
9784 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9785 offsetof(struct xdp_md, data_end)),
9786 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9788 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9789 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9790 BPF_MOV64_IMM(BPF_REG_0, 0),
9791 BPF_EXIT_INSN(),
9792 },
9793 .result = ACCEPT,
9794 .prog_type = BPF_PROG_TYPE_XDP,
9795 },
9796 {
9797 "XDP pkt read, pkt_end < pkt_data', bad access 1",
9798 .insns = {
9799 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9800 offsetof(struct xdp_md, data)),
9801 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9802 offsetof(struct xdp_md, data_end)),
9803 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9804 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9805 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9806 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9807 BPF_MOV64_IMM(BPF_REG_0, 0),
9808 BPF_EXIT_INSN(),
9809 },
9810 .errstr = "R1 offset is outside of the packet",
9811 .result = REJECT,
9812 .prog_type = BPF_PROG_TYPE_XDP,
9813 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9814 },
9815 {
9816 "XDP pkt read, pkt_end < pkt_data', bad access 2",
9817 .insns = {
9818 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9819 offsetof(struct xdp_md, data)),
9820 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9821 offsetof(struct xdp_md, data_end)),
9822 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9824 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9825 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9826 BPF_MOV64_IMM(BPF_REG_0, 0),
9827 BPF_EXIT_INSN(),
9828 },
9829 .errstr = "R1 offset is outside of the packet",
9830 .result = REJECT,
9831 .prog_type = BPF_PROG_TYPE_XDP,
9832 },
9833 {
9834 "XDP pkt read, pkt_data' >= pkt_end, good access",
9835 .insns = {
9836 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9837 offsetof(struct xdp_md, data)),
9838 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9839 offsetof(struct xdp_md, data_end)),
9840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9842 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9843 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9844 BPF_MOV64_IMM(BPF_REG_0, 0),
9845 BPF_EXIT_INSN(),
9846 },
9847 .result = ACCEPT,
9848 .prog_type = BPF_PROG_TYPE_XDP,
9849 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9850 },
9851 {
9852 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
9853 .insns = {
9854 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9855 offsetof(struct xdp_md, data)),
9856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9857 offsetof(struct xdp_md, data_end)),
9858 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9860 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9861 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9862 BPF_MOV64_IMM(BPF_REG_0, 0),
9863 BPF_EXIT_INSN(),
9864 },
9865 .errstr = "R1 offset is outside of the packet",
9866 .result = REJECT,
9867 .prog_type = BPF_PROG_TYPE_XDP,
9868 },
9869 {
9870 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
9871 .insns = {
9872 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9873 offsetof(struct xdp_md, data)),
9874 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9875 offsetof(struct xdp_md, data_end)),
9876 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9878 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9879 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9880 BPF_MOV64_IMM(BPF_REG_0, 0),
9881 BPF_EXIT_INSN(),
9882 },
9883 .errstr = "R1 offset is outside of the packet",
9884 .result = REJECT,
9885 .prog_type = BPF_PROG_TYPE_XDP,
9886 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9887 },
9888 {
9889 "XDP pkt read, pkt_end >= pkt_data', good access",
9890 .insns = {
9891 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9892 offsetof(struct xdp_md, data)),
9893 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9894 offsetof(struct xdp_md, data_end)),
9895 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9896 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9897 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9898 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9899 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9900 BPF_MOV64_IMM(BPF_REG_0, 0),
9901 BPF_EXIT_INSN(),
9902 },
9903 .result = ACCEPT,
9904 .prog_type = BPF_PROG_TYPE_XDP,
9905 },
9906 {
9907 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
9908 .insns = {
9909 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9910 offsetof(struct xdp_md, data)),
9911 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9912 offsetof(struct xdp_md, data_end)),
9913 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9914 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9915 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9916 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9917 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9918 BPF_MOV64_IMM(BPF_REG_0, 0),
9919 BPF_EXIT_INSN(),
9920 },
9921 .errstr = "R1 offset is outside of the packet",
9922 .result = REJECT,
9923 .prog_type = BPF_PROG_TYPE_XDP,
9924 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9925 },
9926 {
9927 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
9928 .insns = {
9929 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9930 offsetof(struct xdp_md, data)),
9931 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9932 offsetof(struct xdp_md, data_end)),
9933 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9934 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9935 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9936 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9937 BPF_MOV64_IMM(BPF_REG_0, 0),
9938 BPF_EXIT_INSN(),
9939 },
9940 .errstr = "R1 offset is outside of the packet",
9941 .result = REJECT,
9942 .prog_type = BPF_PROG_TYPE_XDP,
9943 },
9944 {
9945 "XDP pkt read, pkt_data' <= pkt_end, good access",
9946 .insns = {
9947 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9948 offsetof(struct xdp_md, data)),
9949 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9950 offsetof(struct xdp_md, data_end)),
9951 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9952 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9953 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9954 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9955 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9956 BPF_MOV64_IMM(BPF_REG_0, 0),
9957 BPF_EXIT_INSN(),
9958 },
9959 .result = ACCEPT,
9960 .prog_type = BPF_PROG_TYPE_XDP,
9961 },
9962 {
9963 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
9964 .insns = {
9965 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9966 offsetof(struct xdp_md, data)),
9967 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9968 offsetof(struct xdp_md, data_end)),
9969 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9970 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9971 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9972 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9973 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9974 BPF_MOV64_IMM(BPF_REG_0, 0),
9975 BPF_EXIT_INSN(),
9976 },
9977 .errstr = "R1 offset is outside of the packet",
9978 .result = REJECT,
9979 .prog_type = BPF_PROG_TYPE_XDP,
9980 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9981 },
9982 {
9983 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
9984 .insns = {
9985 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9986 offsetof(struct xdp_md, data)),
9987 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9988 offsetof(struct xdp_md, data_end)),
9989 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9990 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9991 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9992 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9993 BPF_MOV64_IMM(BPF_REG_0, 0),
9994 BPF_EXIT_INSN(),
9995 },
9996 .errstr = "R1 offset is outside of the packet",
9997 .result = REJECT,
9998 .prog_type = BPF_PROG_TYPE_XDP,
9999 },
10000 {
10001 "XDP pkt read, pkt_end <= pkt_data', good access",
10002 .insns = {
10003 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10004 offsetof(struct xdp_md, data)),
10005 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10006 offsetof(struct xdp_md, data_end)),
10007 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10008 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10009 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
10010 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10011 BPF_MOV64_IMM(BPF_REG_0, 0),
10012 BPF_EXIT_INSN(),
10013 },
10014 .result = ACCEPT,
10015 .prog_type = BPF_PROG_TYPE_XDP,
10016 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10017 },
10018 {
10019 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
10020 .insns = {
10021 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10022 offsetof(struct xdp_md, data)),
10023 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10024 offsetof(struct xdp_md, data_end)),
10025 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10027 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
10028 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10029 BPF_MOV64_IMM(BPF_REG_0, 0),
10030 BPF_EXIT_INSN(),
10031 },
10032 .errstr = "R1 offset is outside of the packet",
10033 .result = REJECT,
10034 .prog_type = BPF_PROG_TYPE_XDP,
10035 },
10036 {
10037 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
10038 .insns = {
10039 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10040 offsetof(struct xdp_md, data)),
10041 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10042 offsetof(struct xdp_md, data_end)),
10043 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10045 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
10046 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10047 BPF_MOV64_IMM(BPF_REG_0, 0),
10048 BPF_EXIT_INSN(),
10049 },
10050 .errstr = "R1 offset is outside of the packet",
10051 .result = REJECT,
10052 .prog_type = BPF_PROG_TYPE_XDP,
10053 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10054 },
10055 {
10056 "XDP pkt read, pkt_meta' > pkt_data, good access",
10057 .insns = {
10058 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10059 offsetof(struct xdp_md, data_meta)),
10060 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10061 offsetof(struct xdp_md, data)),
10062 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10063 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10064 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
10065 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10066 BPF_MOV64_IMM(BPF_REG_0, 0),
10067 BPF_EXIT_INSN(),
10068 },
10069 .result = ACCEPT,
10070 .prog_type = BPF_PROG_TYPE_XDP,
10071 },
10072 {
10073 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
10074 .insns = {
10075 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10076 offsetof(struct xdp_md, data_meta)),
10077 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10078 offsetof(struct xdp_md, data)),
10079 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10080 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10081 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
10082 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
10083 BPF_MOV64_IMM(BPF_REG_0, 0),
10084 BPF_EXIT_INSN(),
10085 },
10086 .errstr = "R1 offset is outside of the packet",
10087 .result = REJECT,
10088 .prog_type = BPF_PROG_TYPE_XDP,
10089 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10090 },
10091 {
10092 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
10093 .insns = {
10094 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10095 offsetof(struct xdp_md, data_meta)),
10096 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10097 offsetof(struct xdp_md, data)),
10098 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10099 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10100 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
10101 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10102 BPF_MOV64_IMM(BPF_REG_0, 0),
10103 BPF_EXIT_INSN(),
10104 },
10105 .errstr = "R1 offset is outside of the packet",
10106 .result = REJECT,
10107 .prog_type = BPF_PROG_TYPE_XDP,
10108 },
10109 {
10110 "XDP pkt read, pkt_data > pkt_meta', good access",
10111 .insns = {
10112 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10113 offsetof(struct xdp_md, data_meta)),
10114 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10115 offsetof(struct xdp_md, data)),
10116 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10118 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
10119 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10120 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10121 BPF_MOV64_IMM(BPF_REG_0, 0),
10122 BPF_EXIT_INSN(),
10123 },
10124 .result = ACCEPT,
10125 .prog_type = BPF_PROG_TYPE_XDP,
10126 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10127 },
10128 {
10129 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
10130 .insns = {
10131 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10132 offsetof(struct xdp_md, data_meta)),
10133 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10134 offsetof(struct xdp_md, data)),
10135 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10136 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10137 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
10138 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10139 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10140 BPF_MOV64_IMM(BPF_REG_0, 0),
10141 BPF_EXIT_INSN(),
10142 },
10143 .errstr = "R1 offset is outside of the packet",
10144 .result = REJECT,
10145 .prog_type = BPF_PROG_TYPE_XDP,
10146 },
10147 {
10148 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
10149 .insns = {
10150 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10151 offsetof(struct xdp_md, data_meta)),
10152 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10153 offsetof(struct xdp_md, data)),
10154 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10155 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10156 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
10157 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10158 BPF_MOV64_IMM(BPF_REG_0, 0),
10159 BPF_EXIT_INSN(),
10160 },
10161 .errstr = "R1 offset is outside of the packet",
10162 .result = REJECT,
10163 .prog_type = BPF_PROG_TYPE_XDP,
10164 },
10165 {
10166 "XDP pkt read, pkt_meta' < pkt_data, good access",
10167 .insns = {
10168 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10169 offsetof(struct xdp_md, data_meta)),
10170 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10171 offsetof(struct xdp_md, data)),
10172 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10174 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
10175 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10176 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10177 BPF_MOV64_IMM(BPF_REG_0, 0),
10178 BPF_EXIT_INSN(),
10179 },
10180 .result = ACCEPT,
10181 .prog_type = BPF_PROG_TYPE_XDP,
10182 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10183 },
10184 {
10185 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
10186 .insns = {
10187 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10188 offsetof(struct xdp_md, data_meta)),
10189 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10190 offsetof(struct xdp_md, data)),
10191 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10193 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
10194 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10195 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10196 BPF_MOV64_IMM(BPF_REG_0, 0),
10197 BPF_EXIT_INSN(),
10198 },
10199 .errstr = "R1 offset is outside of the packet",
10200 .result = REJECT,
10201 .prog_type = BPF_PROG_TYPE_XDP,
10202 },
10203 {
10204 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
10205 .insns = {
10206 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10207 offsetof(struct xdp_md, data_meta)),
10208 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10209 offsetof(struct xdp_md, data)),
10210 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10212 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
10213 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10214 BPF_MOV64_IMM(BPF_REG_0, 0),
10215 BPF_EXIT_INSN(),
10216 },
10217 .errstr = "R1 offset is outside of the packet",
10218 .result = REJECT,
10219 .prog_type = BPF_PROG_TYPE_XDP,
10220 },
10221 {
10222 "XDP pkt read, pkt_data < pkt_meta', good access",
10223 .insns = {
10224 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10225 offsetof(struct xdp_md, data_meta)),
10226 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10227 offsetof(struct xdp_md, data)),
10228 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10230 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
10231 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10232 BPF_MOV64_IMM(BPF_REG_0, 0),
10233 BPF_EXIT_INSN(),
10234 },
10235 .result = ACCEPT,
10236 .prog_type = BPF_PROG_TYPE_XDP,
10237 },
10238 {
10239 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
10240 .insns = {
10241 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10242 offsetof(struct xdp_md, data_meta)),
10243 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10244 offsetof(struct xdp_md, data)),
10245 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10247 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
10248 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
10249 BPF_MOV64_IMM(BPF_REG_0, 0),
10250 BPF_EXIT_INSN(),
10251 },
10252 .errstr = "R1 offset is outside of the packet",
10253 .result = REJECT,
10254 .prog_type = BPF_PROG_TYPE_XDP,
10255 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10256 },
10257 {
10258 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
10259 .insns = {
10260 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10261 offsetof(struct xdp_md, data_meta)),
10262 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10263 offsetof(struct xdp_md, data)),
10264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10266 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
10267 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10268 BPF_MOV64_IMM(BPF_REG_0, 0),
10269 BPF_EXIT_INSN(),
10270 },
10271 .errstr = "R1 offset is outside of the packet",
10272 .result = REJECT,
10273 .prog_type = BPF_PROG_TYPE_XDP,
10274 },
10275 {
10276 "XDP pkt read, pkt_meta' >= pkt_data, good access",
10277 .insns = {
10278 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10279 offsetof(struct xdp_md, data_meta)),
10280 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10281 offsetof(struct xdp_md, data)),
10282 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10284 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
10285 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10286 BPF_MOV64_IMM(BPF_REG_0, 0),
10287 BPF_EXIT_INSN(),
10288 },
10289 .result = ACCEPT,
10290 .prog_type = BPF_PROG_TYPE_XDP,
10291 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10292 },
10293 {
10294 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
10295 .insns = {
10296 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10297 offsetof(struct xdp_md, data_meta)),
10298 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10299 offsetof(struct xdp_md, data)),
10300 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10301 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10302 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
10303 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10304 BPF_MOV64_IMM(BPF_REG_0, 0),
10305 BPF_EXIT_INSN(),
10306 },
10307 .errstr = "R1 offset is outside of the packet",
10308 .result = REJECT,
10309 .prog_type = BPF_PROG_TYPE_XDP,
10310 },
10311 {
10312 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
10313 .insns = {
10314 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10315 offsetof(struct xdp_md, data_meta)),
10316 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10317 offsetof(struct xdp_md, data)),
10318 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10319 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10320 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
10321 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10322 BPF_MOV64_IMM(BPF_REG_0, 0),
10323 BPF_EXIT_INSN(),
10324 },
10325 .errstr = "R1 offset is outside of the packet",
10326 .result = REJECT,
10327 .prog_type = BPF_PROG_TYPE_XDP,
10328 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10329 },
10330 {
10331 "XDP pkt read, pkt_data >= pkt_meta', good access",
10332 .insns = {
10333 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10334 offsetof(struct xdp_md, data_meta)),
10335 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10336 offsetof(struct xdp_md, data)),
10337 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10339 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
10340 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10341 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10342 BPF_MOV64_IMM(BPF_REG_0, 0),
10343 BPF_EXIT_INSN(),
10344 },
10345 .result = ACCEPT,
10346 .prog_type = BPF_PROG_TYPE_XDP,
10347 },
10348 {
10349 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
10350 .insns = {
10351 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10352 offsetof(struct xdp_md, data_meta)),
10353 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10354 offsetof(struct xdp_md, data)),
10355 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10356 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10357 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
10358 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10359 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
10360 BPF_MOV64_IMM(BPF_REG_0, 0),
10361 BPF_EXIT_INSN(),
10362 },
10363 .errstr = "R1 offset is outside of the packet",
10364 .result = REJECT,
10365 .prog_type = BPF_PROG_TYPE_XDP,
10366 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10367 },
10368 {
10369 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
10370 .insns = {
10371 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10372 offsetof(struct xdp_md, data_meta)),
10373 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10374 offsetof(struct xdp_md, data)),
10375 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10376 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10377 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
10378 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10379 BPF_MOV64_IMM(BPF_REG_0, 0),
10380 BPF_EXIT_INSN(),
10381 },
10382 .errstr = "R1 offset is outside of the packet",
10383 .result = REJECT,
10384 .prog_type = BPF_PROG_TYPE_XDP,
10385 },
10386 {
10387 "XDP pkt read, pkt_meta' <= pkt_data, good access",
10388 .insns = {
10389 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10390 offsetof(struct xdp_md, data_meta)),
10391 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10392 offsetof(struct xdp_md, data)),
10393 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10395 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
10396 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10397 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10398 BPF_MOV64_IMM(BPF_REG_0, 0),
10399 BPF_EXIT_INSN(),
10400 },
10401 .result = ACCEPT,
10402 .prog_type = BPF_PROG_TYPE_XDP,
10403 },
10404 {
10405 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
10406 .insns = {
10407 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10408 offsetof(struct xdp_md, data_meta)),
10409 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10410 offsetof(struct xdp_md, data)),
10411 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10413 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
10414 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10415 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
10416 BPF_MOV64_IMM(BPF_REG_0, 0),
10417 BPF_EXIT_INSN(),
10418 },
10419 .errstr = "R1 offset is outside of the packet",
10420 .result = REJECT,
10421 .prog_type = BPF_PROG_TYPE_XDP,
10422 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10423 },
10424 {
10425 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
10426 .insns = {
10427 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10428 offsetof(struct xdp_md, data_meta)),
10429 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10430 offsetof(struct xdp_md, data)),
10431 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10433 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
10434 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10435 BPF_MOV64_IMM(BPF_REG_0, 0),
10436 BPF_EXIT_INSN(),
10437 },
10438 .errstr = "R1 offset is outside of the packet",
10439 .result = REJECT,
10440 .prog_type = BPF_PROG_TYPE_XDP,
10441 },
10442 {
10443 "XDP pkt read, pkt_data <= pkt_meta', good access",
10444 .insns = {
10445 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10446 offsetof(struct xdp_md, data_meta)),
10447 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10448 offsetof(struct xdp_md, data)),
10449 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10450 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10451 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
10452 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10453 BPF_MOV64_IMM(BPF_REG_0, 0),
10454 BPF_EXIT_INSN(),
10455 },
10456 .result = ACCEPT,
10457 .prog_type = BPF_PROG_TYPE_XDP,
10458 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10459 },
10460 {
10461 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
10462 .insns = {
10463 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10464 offsetof(struct xdp_md, data_meta)),
10465 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10466 offsetof(struct xdp_md, data)),
10467 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10468 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10469 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
10470 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
10471 BPF_MOV64_IMM(BPF_REG_0, 0),
10472 BPF_EXIT_INSN(),
10473 },
10474 .errstr = "R1 offset is outside of the packet",
10475 .result = REJECT,
10476 .prog_type = BPF_PROG_TYPE_XDP,
10477 },
10478 {
10479 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
10480 .insns = {
10481 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10482 offsetof(struct xdp_md, data_meta)),
10483 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10484 offsetof(struct xdp_md, data)),
10485 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
10486 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
10487 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
10488 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
10489 BPF_MOV64_IMM(BPF_REG_0, 0),
10490 BPF_EXIT_INSN(),
10491 },
10492 .errstr = "R1 offset is outside of the packet",
10493 .result = REJECT,
10494 .prog_type = BPF_PROG_TYPE_XDP,
10495 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
10496 },
10497 {
10498 "check deducing bounds from const, 1",
10499 .insns = {
10500 BPF_MOV64_IMM(BPF_REG_0, 1),
10501 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
10502 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10503 BPF_EXIT_INSN(),
10504 },
10505 .result = REJECT,
10506 .errstr = "R0 tried to subtract pointer from scalar",
10507 },
10508 {
10509 "check deducing bounds from const, 2",
10510 .insns = {
10511 BPF_MOV64_IMM(BPF_REG_0, 1),
10512 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
10513 BPF_EXIT_INSN(),
10514 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
10515 BPF_EXIT_INSN(),
10516 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
10517 BPF_EXIT_INSN(),
10518 },
10519 .result = ACCEPT,
10520 .retval = 1,
10521 },
10522 {
10523 "check deducing bounds from const, 3",
10524 .insns = {
10525 BPF_MOV64_IMM(BPF_REG_0, 0),
10526 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
10527 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10528 BPF_EXIT_INSN(),
10529 },
10530 .result = REJECT,
10531 .errstr = "R0 tried to subtract pointer from scalar",
10532 },
10533 {
10534 "check deducing bounds from const, 4",
10535 .insns = {
10536 BPF_MOV64_IMM(BPF_REG_0, 0),
10537 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
10538 BPF_EXIT_INSN(),
10539 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
10540 BPF_EXIT_INSN(),
10541 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
10542 BPF_EXIT_INSN(),
10543 },
10544 .result = ACCEPT,
10545 },
10546 {
10547 "check deducing bounds from const, 5",
10548 .insns = {
10549 BPF_MOV64_IMM(BPF_REG_0, 0),
10550 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
10551 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10552 BPF_EXIT_INSN(),
10553 },
10554 .result = REJECT,
10555 .errstr = "R0 tried to subtract pointer from scalar",
10556 },
10557 {
10558 "check deducing bounds from const, 6",
10559 .insns = {
10560 BPF_MOV64_IMM(BPF_REG_0, 0),
10561 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
10562 BPF_EXIT_INSN(),
10563 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10564 BPF_EXIT_INSN(),
10565 },
10566 .result = REJECT,
10567 .errstr = "R0 tried to subtract pointer from scalar",
10568 },
10569 {
10570 "check deducing bounds from const, 7",
10571 .insns = {
10572 BPF_MOV64_IMM(BPF_REG_0, ~0),
10573 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
10574 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
10575 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10576 offsetof(struct __sk_buff, mark)),
10577 BPF_EXIT_INSN(),
10578 },
10579 .result = REJECT,
10580 .errstr = "dereference of modified ctx ptr",
10581 },
10582 {
10583 "check deducing bounds from const, 8",
10584 .insns = {
10585 BPF_MOV64_IMM(BPF_REG_0, ~0),
10586 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
10587 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
10588 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10589 offsetof(struct __sk_buff, mark)),
10590 BPF_EXIT_INSN(),
10591 },
10592 .result = REJECT,
10593 .errstr = "dereference of modified ctx ptr",
10594 },
10595 {
10596 "check deducing bounds from const, 9",
10597 .insns = {
10598 BPF_MOV64_IMM(BPF_REG_0, 0),
10599 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
10600 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10601 BPF_EXIT_INSN(),
10602 },
10603 .result = REJECT,
10604 .errstr = "R0 tried to subtract pointer from scalar",
10605 },
10606 {
10607 "check deducing bounds from const, 10",
10608 .insns = {
10609 BPF_MOV64_IMM(BPF_REG_0, 0),
10610 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
10611 /* Marks reg as unknown. */
10612 BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
10613 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
10614 BPF_EXIT_INSN(),
10615 },
10616 .result = REJECT,
10617 .errstr = "math between ctx pointer and register with unbounded min value is not allowed",
10618 },
10619 {
10620 "bpf_exit with invalid return code. test1",
10621 .insns = {
10622 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10623 BPF_EXIT_INSN(),
10624 },
10625 .errstr = "R0 has value (0x0; 0xffffffff)",
10626 .result = REJECT,
10627 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10628 },
10629 {
10630 "bpf_exit with invalid return code. test2",
10631 .insns = {
10632 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10633 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
10634 BPF_EXIT_INSN(),
10635 },
10636 .result = ACCEPT,
10637 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10638 },
10639 {
10640 "bpf_exit with invalid return code. test3",
10641 .insns = {
10642 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10643 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
10644 BPF_EXIT_INSN(),
10645 },
10646 .errstr = "R0 has value (0x0; 0x3)",
10647 .result = REJECT,
10648 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10649 },
10650 {
10651 "bpf_exit with invalid return code. test4",
10652 .insns = {
10653 BPF_MOV64_IMM(BPF_REG_0, 1),
10654 BPF_EXIT_INSN(),
10655 },
10656 .result = ACCEPT,
10657 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10658 },
10659 {
10660 "bpf_exit with invalid return code. test5",
10661 .insns = {
10662 BPF_MOV64_IMM(BPF_REG_0, 2),
10663 BPF_EXIT_INSN(),
10664 },
10665 .errstr = "R0 has value (0x2; 0x0)",
10666 .result = REJECT,
10667 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10668 },
10669 {
10670 "bpf_exit with invalid return code. test6",
10671 .insns = {
10672 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10673 BPF_EXIT_INSN(),
10674 },
10675 .errstr = "R0 is not a known value (ctx)",
10676 .result = REJECT,
10677 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10678 },
10679 {
10680 "bpf_exit with invalid return code. test7",
10681 .insns = {
10682 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10683 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
10684 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
10685 BPF_EXIT_INSN(),
10686 },
10687 .errstr = "R0 has unknown scalar value",
10688 .result = REJECT,
10689 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10690 },
10691 {
10692 "calls: basic sanity",
10693 .insns = {
10694 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10695 BPF_MOV64_IMM(BPF_REG_0, 1),
10696 BPF_EXIT_INSN(),
10697 BPF_MOV64_IMM(BPF_REG_0, 2),
10698 BPF_EXIT_INSN(),
10699 },
10700 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10701 .result = ACCEPT,
10702 },
10703 {
10704 "calls: not on unpriviledged",
10705 .insns = {
10706 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10707 BPF_MOV64_IMM(BPF_REG_0, 1),
10708 BPF_EXIT_INSN(),
10709 BPF_MOV64_IMM(BPF_REG_0, 2),
10710 BPF_EXIT_INSN(),
10711 },
10712 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
10713 .result_unpriv = REJECT,
10714 .result = ACCEPT,
10715 .retval = 1,
10716 },
10717 {
10718 "calls: div by 0 in subprog",
10719 .insns = {
10720 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10721 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10722 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10723 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10724 offsetof(struct __sk_buff, data_end)),
10725 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10727 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10728 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10729 BPF_MOV64_IMM(BPF_REG_0, 1),
10730 BPF_EXIT_INSN(),
10731 BPF_MOV32_IMM(BPF_REG_2, 0),
10732 BPF_MOV32_IMM(BPF_REG_3, 1),
10733 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
10734 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10735 offsetof(struct __sk_buff, data)),
10736 BPF_EXIT_INSN(),
10737 },
10738 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10739 .result = ACCEPT,
10740 .retval = 1,
10741 },
10742 {
10743 "calls: multiple ret types in subprog 1",
10744 .insns = {
10745 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10746 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10747 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10748 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10749 offsetof(struct __sk_buff, data_end)),
10750 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10751 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10752 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10753 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10754 BPF_MOV64_IMM(BPF_REG_0, 1),
10755 BPF_EXIT_INSN(),
10756 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10757 offsetof(struct __sk_buff, data)),
10758 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
10759 BPF_MOV32_IMM(BPF_REG_0, 42),
10760 BPF_EXIT_INSN(),
10761 },
10762 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10763 .result = REJECT,
10764 .errstr = "R0 invalid mem access 'inv'",
10765 },
10766 {
10767 "calls: multiple ret types in subprog 2",
10768 .insns = {
10769 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10770 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10771 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10772 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10773 offsetof(struct __sk_buff, data_end)),
10774 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10775 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10776 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10777 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10778 BPF_MOV64_IMM(BPF_REG_0, 1),
10779 BPF_EXIT_INSN(),
10780 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10781 offsetof(struct __sk_buff, data)),
10782 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10783 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
10784 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10785 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10786 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10787 BPF_LD_MAP_FD(BPF_REG_1, 0),
10788 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10789 BPF_FUNC_map_lookup_elem),
10790 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
10791 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
10792 offsetof(struct __sk_buff, data)),
10793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
10794 BPF_EXIT_INSN(),
10795 },
10796 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10797 .fixup_map_hash_8b = { 16 },
10798 .result = REJECT,
10799 .errstr = "R0 min value is outside of the array range",
10800 },
10801 {
10802 "calls: overlapping caller/callee",
10803 .insns = {
10804 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
10805 BPF_MOV64_IMM(BPF_REG_0, 1),
10806 BPF_EXIT_INSN(),
10807 },
10808 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10809 .errstr = "last insn is not an exit or jmp",
10810 .result = REJECT,
10811 },
10812 {
10813 "calls: wrong recursive calls",
10814 .insns = {
10815 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10816 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10817 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10818 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10819 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10820 BPF_MOV64_IMM(BPF_REG_0, 1),
10821 BPF_EXIT_INSN(),
10822 },
10823 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10824 .errstr = "jump out of range",
10825 .result = REJECT,
10826 },
10827 {
10828 "calls: wrong src reg",
10829 .insns = {
10830 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
10831 BPF_MOV64_IMM(BPF_REG_0, 1),
10832 BPF_EXIT_INSN(),
10833 },
10834 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10835 .errstr = "BPF_CALL uses reserved fields",
10836 .result = REJECT,
10837 },
10838 {
10839 "calls: wrong off value",
10840 .insns = {
10841 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
10842 BPF_MOV64_IMM(BPF_REG_0, 1),
10843 BPF_EXIT_INSN(),
10844 BPF_MOV64_IMM(BPF_REG_0, 2),
10845 BPF_EXIT_INSN(),
10846 },
10847 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10848 .errstr = "BPF_CALL uses reserved fields",
10849 .result = REJECT,
10850 },
10851 {
10852 "calls: jump back loop",
10853 .insns = {
10854 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10855 BPF_MOV64_IMM(BPF_REG_0, 1),
10856 BPF_EXIT_INSN(),
10857 },
10858 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10859 .errstr = "back-edge from insn 0 to 0",
10860 .result = REJECT,
10861 },
10862 {
10863 "calls: conditional call",
10864 .insns = {
10865 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10866 offsetof(struct __sk_buff, mark)),
10867 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10868 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10869 BPF_MOV64_IMM(BPF_REG_0, 1),
10870 BPF_EXIT_INSN(),
10871 BPF_MOV64_IMM(BPF_REG_0, 2),
10872 BPF_EXIT_INSN(),
10873 },
10874 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10875 .errstr = "jump out of range",
10876 .result = REJECT,
10877 },
10878 {
10879 "calls: conditional call 2",
10880 .insns = {
10881 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10882 offsetof(struct __sk_buff, mark)),
10883 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10884 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10885 BPF_MOV64_IMM(BPF_REG_0, 1),
10886 BPF_EXIT_INSN(),
10887 BPF_MOV64_IMM(BPF_REG_0, 2),
10888 BPF_EXIT_INSN(),
10889 BPF_MOV64_IMM(BPF_REG_0, 3),
10890 BPF_EXIT_INSN(),
10891 },
10892 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10893 .result = ACCEPT,
10894 },
10895 {
10896 "calls: conditional call 3",
10897 .insns = {
10898 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10899 offsetof(struct __sk_buff, mark)),
10900 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10901 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10902 BPF_MOV64_IMM(BPF_REG_0, 1),
10903 BPF_EXIT_INSN(),
10904 BPF_MOV64_IMM(BPF_REG_0, 1),
10905 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10906 BPF_MOV64_IMM(BPF_REG_0, 3),
10907 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10908 },
10909 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10910 .errstr = "back-edge from insn",
10911 .result = REJECT,
10912 },
10913 {
10914 "calls: conditional call 4",
10915 .insns = {
10916 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10917 offsetof(struct __sk_buff, mark)),
10918 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10919 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10920 BPF_MOV64_IMM(BPF_REG_0, 1),
10921 BPF_EXIT_INSN(),
10922 BPF_MOV64_IMM(BPF_REG_0, 1),
10923 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
10924 BPF_MOV64_IMM(BPF_REG_0, 3),
10925 BPF_EXIT_INSN(),
10926 },
10927 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10928 .result = ACCEPT,
10929 },
10930 {
10931 "calls: conditional call 5",
10932 .insns = {
10933 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10934 offsetof(struct __sk_buff, mark)),
10935 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10936 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10937 BPF_MOV64_IMM(BPF_REG_0, 1),
10938 BPF_EXIT_INSN(),
10939 BPF_MOV64_IMM(BPF_REG_0, 1),
10940 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10941 BPF_MOV64_IMM(BPF_REG_0, 3),
10942 BPF_EXIT_INSN(),
10943 },
10944 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10945 .errstr = "back-edge from insn",
10946 .result = REJECT,
10947 },
10948 {
10949 "calls: conditional call 6",
10950 .insns = {
10951 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10952 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
10953 BPF_EXIT_INSN(),
10954 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10955 offsetof(struct __sk_buff, mark)),
10956 BPF_EXIT_INSN(),
10957 },
10958 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10959 .errstr = "back-edge from insn",
10960 .result = REJECT,
10961 },
10962 {
10963 "calls: using r0 returned by callee",
10964 .insns = {
10965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10966 BPF_EXIT_INSN(),
10967 BPF_MOV64_IMM(BPF_REG_0, 2),
10968 BPF_EXIT_INSN(),
10969 },
10970 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10971 .result = ACCEPT,
10972 },
10973 {
10974 "calls: using uninit r0 from callee",
10975 .insns = {
10976 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10977 BPF_EXIT_INSN(),
10978 BPF_EXIT_INSN(),
10979 },
10980 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10981 .errstr = "!read_ok",
10982 .result = REJECT,
10983 },
10984 {
10985 "calls: callee is using r1",
10986 .insns = {
10987 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10988 BPF_EXIT_INSN(),
10989 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10990 offsetof(struct __sk_buff, len)),
10991 BPF_EXIT_INSN(),
10992 },
10993 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
10994 .result = ACCEPT,
10995 .retval = TEST_DATA_LEN,
10996 },
10997 {
10998 "calls: callee using args1",
10999 .insns = {
11000 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11001 BPF_EXIT_INSN(),
11002 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
11003 BPF_EXIT_INSN(),
11004 },
11005 .errstr_unpriv = "allowed for root only",
11006 .result_unpriv = REJECT,
11007 .result = ACCEPT,
11008 .retval = POINTER_VALUE,
11009 },
11010 {
11011 "calls: callee using wrong args2",
11012 .insns = {
11013 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11014 BPF_EXIT_INSN(),
11015 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11016 BPF_EXIT_INSN(),
11017 },
11018 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11019 .errstr = "R2 !read_ok",
11020 .result = REJECT,
11021 },
11022 {
11023 "calls: callee using two args",
11024 .insns = {
11025 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11026 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
11027 offsetof(struct __sk_buff, len)),
11028 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
11029 offsetof(struct __sk_buff, len)),
11030 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11031 BPF_EXIT_INSN(),
11032 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
11033 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
11034 BPF_EXIT_INSN(),
11035 },
11036 .errstr_unpriv = "allowed for root only",
11037 .result_unpriv = REJECT,
11038 .result = ACCEPT,
11039 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
11040 },
11041 {
11042 "calls: callee changing pkt pointers",
11043 .insns = {
11044 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
11045 offsetof(struct xdp_md, data)),
11046 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
11047 offsetof(struct xdp_md, data_end)),
11048 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
11049 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
11050 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
11051 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11052 /* clear_all_pkt_pointers() has to walk all frames
11053 * to make sure that pkt pointers in the caller
11054 * are cleared when callee is calling a helper that
11055 * adjusts packet size
11056 */
11057 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11058 BPF_MOV32_IMM(BPF_REG_0, 0),
11059 BPF_EXIT_INSN(),
11060 BPF_MOV64_IMM(BPF_REG_2, 0),
11061 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11062 BPF_FUNC_xdp_adjust_head),
11063 BPF_EXIT_INSN(),
11064 },
11065 .result = REJECT,
11066 .errstr = "R6 invalid mem access 'inv'",
11067 .prog_type = BPF_PROG_TYPE_XDP,
11068 },
11069 {
11070 "calls: two calls with args",
11071 .insns = {
11072 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11073 BPF_EXIT_INSN(),
11074 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
11076 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
11077 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11078 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11079 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
11080 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
11081 BPF_EXIT_INSN(),
11082 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
11083 offsetof(struct __sk_buff, len)),
11084 BPF_EXIT_INSN(),
11085 },
11086 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11087 .result = ACCEPT,
11088 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
11089 },
11090 {
11091 "calls: calls with stack arith",
11092 .insns = {
11093 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11094 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
11095 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11096 BPF_EXIT_INSN(),
11097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
11098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11099 BPF_EXIT_INSN(),
11100 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
11101 BPF_MOV64_IMM(BPF_REG_0, 42),
11102 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
11103 BPF_EXIT_INSN(),
11104 },
11105 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11106 .result = ACCEPT,
11107 .retval = 42,
11108 },
11109 {
11110 "calls: calls with misaligned stack access",
11111 .insns = {
11112 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11113 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
11114 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11115 BPF_EXIT_INSN(),
11116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
11117 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11118 BPF_EXIT_INSN(),
11119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
11120 BPF_MOV64_IMM(BPF_REG_0, 42),
11121 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
11122 BPF_EXIT_INSN(),
11123 },
11124 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11125 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
11126 .errstr = "misaligned stack access",
11127 .result = REJECT,
11128 },
11129 {
11130 "calls: calls control flow, jump test",
11131 .insns = {
11132 BPF_MOV64_IMM(BPF_REG_0, 42),
11133 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11134 BPF_MOV64_IMM(BPF_REG_0, 43),
11135 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11136 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
11137 BPF_EXIT_INSN(),
11138 },
11139 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11140 .result = ACCEPT,
11141 .retval = 43,
11142 },
11143 {
11144 "calls: calls control flow, jump test 2",
11145 .insns = {
11146 BPF_MOV64_IMM(BPF_REG_0, 42),
11147 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11148 BPF_MOV64_IMM(BPF_REG_0, 43),
11149 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11150 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
11151 BPF_EXIT_INSN(),
11152 },
11153 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11154 .errstr = "jump out of range from insn 1 to 4",
11155 .result = REJECT,
11156 },
11157 {
11158 "calls: two calls with bad jump",
11159 .insns = {
11160 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11161 BPF_EXIT_INSN(),
11162 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
11164 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
11165 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11166 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11167 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
11168 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
11169 BPF_EXIT_INSN(),
11170 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
11171 offsetof(struct __sk_buff, len)),
11172 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
11173 BPF_EXIT_INSN(),
11174 },
11175 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11176 .errstr = "jump out of range from insn 11 to 9",
11177 .result = REJECT,
11178 },
11179 {
11180 "calls: recursive call. test1",
11181 .insns = {
11182 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11183 BPF_EXIT_INSN(),
11184 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
11185 BPF_EXIT_INSN(),
11186 },
11187 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11188 .errstr = "back-edge",
11189 .result = REJECT,
11190 },
11191 {
11192 "calls: recursive call. test2",
11193 .insns = {
11194 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11195 BPF_EXIT_INSN(),
11196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
11197 BPF_EXIT_INSN(),
11198 },
11199 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11200 .errstr = "back-edge",
11201 .result = REJECT,
11202 },
11203 {
11204 "calls: unreachable code",
11205 .insns = {
11206 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11207 BPF_EXIT_INSN(),
11208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11209 BPF_EXIT_INSN(),
11210 BPF_MOV64_IMM(BPF_REG_0, 0),
11211 BPF_EXIT_INSN(),
11212 BPF_MOV64_IMM(BPF_REG_0, 0),
11213 BPF_EXIT_INSN(),
11214 },
11215 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11216 .errstr = "unreachable insn 6",
11217 .result = REJECT,
11218 },
11219 {
11220 "calls: invalid call",
11221 .insns = {
11222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11223 BPF_EXIT_INSN(),
11224 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
11225 BPF_EXIT_INSN(),
11226 },
11227 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11228 .errstr = "invalid destination",
11229 .result = REJECT,
11230 },
11231 {
11232 "calls: invalid call 2",
11233 .insns = {
11234 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11235 BPF_EXIT_INSN(),
11236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
11237 BPF_EXIT_INSN(),
11238 },
11239 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11240 .errstr = "invalid destination",
11241 .result = REJECT,
11242 },
11243 {
11244 "calls: jumping across function bodies. test1",
11245 .insns = {
11246 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11247 BPF_MOV64_IMM(BPF_REG_0, 0),
11248 BPF_EXIT_INSN(),
11249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
11250 BPF_EXIT_INSN(),
11251 },
11252 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11253 .errstr = "jump out of range",
11254 .result = REJECT,
11255 },
11256 {
11257 "calls: jumping across function bodies. test2",
11258 .insns = {
11259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
11260 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11261 BPF_MOV64_IMM(BPF_REG_0, 0),
11262 BPF_EXIT_INSN(),
11263 BPF_EXIT_INSN(),
11264 },
11265 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11266 .errstr = "jump out of range",
11267 .result = REJECT,
11268 },
11269 {
11270 "calls: call without exit",
11271 .insns = {
11272 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11273 BPF_EXIT_INSN(),
11274 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11275 BPF_EXIT_INSN(),
11276 BPF_MOV64_IMM(BPF_REG_0, 0),
11277 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
11278 },
11279 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11280 .errstr = "not an exit",
11281 .result = REJECT,
11282 },
11283 {
11284 "calls: call into middle of ld_imm64",
11285 .insns = {
11286 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11288 BPF_MOV64_IMM(BPF_REG_0, 0),
11289 BPF_EXIT_INSN(),
11290 BPF_LD_IMM64(BPF_REG_0, 0),
11291 BPF_EXIT_INSN(),
11292 },
11293 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11294 .errstr = "last insn",
11295 .result = REJECT,
11296 },
11297 {
11298 "calls: call into middle of other call",
11299 .insns = {
11300 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11301 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11302 BPF_MOV64_IMM(BPF_REG_0, 0),
11303 BPF_EXIT_INSN(),
11304 BPF_MOV64_IMM(BPF_REG_0, 0),
11305 BPF_MOV64_IMM(BPF_REG_0, 0),
11306 BPF_EXIT_INSN(),
11307 },
11308 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11309 .errstr = "last insn",
11310 .result = REJECT,
11311 },
11312 {
11313 "calls: ld_abs with changing ctx data in callee",
11314 .insns = {
11315 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11316 BPF_LD_ABS(BPF_B, 0),
11317 BPF_LD_ABS(BPF_H, 0),
11318 BPF_LD_ABS(BPF_W, 0),
11319 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
11320 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
11321 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
11322 BPF_LD_ABS(BPF_B, 0),
11323 BPF_LD_ABS(BPF_H, 0),
11324 BPF_LD_ABS(BPF_W, 0),
11325 BPF_EXIT_INSN(),
11326 BPF_MOV64_IMM(BPF_REG_2, 1),
11327 BPF_MOV64_IMM(BPF_REG_3, 2),
11328 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11329 BPF_FUNC_skb_vlan_push),
11330 BPF_EXIT_INSN(),
11331 },
11332 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11333 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
11334 .result = REJECT,
11335 },
11336 {
11337 "calls: two calls with bad fallthrough",
11338 .insns = {
11339 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11340 BPF_EXIT_INSN(),
11341 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11342 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
11343 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
11344 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11345 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11346 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
11347 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
11348 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
11349 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
11350 offsetof(struct __sk_buff, len)),
11351 BPF_EXIT_INSN(),
11352 },
11353 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11354 .errstr = "not an exit",
11355 .result = REJECT,
11356 },
11357 {
11358 "calls: two calls with stack read",
11359 .insns = {
11360 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11361 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11362 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11363 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11364 BPF_EXIT_INSN(),
11365 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11366 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
11367 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
11368 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11369 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11370 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
11371 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
11372 BPF_EXIT_INSN(),
11373 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
11374 BPF_EXIT_INSN(),
11375 },
11376 .prog_type = BPF_PROG_TYPE_XDP,
11377 .result = ACCEPT,
11378 },
11379 {
11380 "calls: two calls with stack write",
11381 .insns = {
11382 /* main prog */
11383 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11384 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11385 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11386 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11387 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11388 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11389 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
11390 BPF_EXIT_INSN(),
11391
11392 /* subprog 1 */
11393 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11394 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11395 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
11396 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
11397 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11398 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11399 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
11400 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
11401 /* write into stack frame of main prog */
11402 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11403 BPF_EXIT_INSN(),
11404
11405 /* subprog 2 */
11406 /* read from stack frame of main prog */
11407 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
11408 BPF_EXIT_INSN(),
11409 },
11410 .prog_type = BPF_PROG_TYPE_XDP,
11411 .result = ACCEPT,
11412 },
11413 {
11414 "calls: stack overflow using two frames (pre-call access)",
11415 .insns = {
11416 /* prog 1 */
11417 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11418 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
11419 BPF_EXIT_INSN(),
11420
11421 /* prog 2 */
11422 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11423 BPF_MOV64_IMM(BPF_REG_0, 0),
11424 BPF_EXIT_INSN(),
11425 },
11426 .prog_type = BPF_PROG_TYPE_XDP,
11427 .errstr = "combined stack size",
11428 .result = REJECT,
11429 },
11430 {
11431 "calls: stack overflow using two frames (post-call access)",
11432 .insns = {
11433 /* prog 1 */
11434 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
11435 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11436 BPF_EXIT_INSN(),
11437
11438 /* prog 2 */
11439 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11440 BPF_MOV64_IMM(BPF_REG_0, 0),
11441 BPF_EXIT_INSN(),
11442 },
11443 .prog_type = BPF_PROG_TYPE_XDP,
11444 .errstr = "combined stack size",
11445 .result = REJECT,
11446 },
11447 {
11448 "calls: stack depth check using three frames. test1",
11449 .insns = {
11450 /* main */
11451 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
11452 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
11453 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
11454 BPF_MOV64_IMM(BPF_REG_0, 0),
11455 BPF_EXIT_INSN(),
11456 /* A */
11457 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
11458 BPF_EXIT_INSN(),
11459 /* B */
11460 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
11461 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
11462 BPF_EXIT_INSN(),
11463 },
11464 .prog_type = BPF_PROG_TYPE_XDP,
11465 /* stack_main=32, stack_A=256, stack_B=64
11466 * and max(main+A, main+A+B) < 512
11467 */
11468 .result = ACCEPT,
11469 },
11470 {
11471 "calls: stack depth check using three frames. test2",
11472 .insns = {
11473 /* main */
11474 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
11475 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
11476 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
11477 BPF_MOV64_IMM(BPF_REG_0, 0),
11478 BPF_EXIT_INSN(),
11479 /* A */
11480 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
11481 BPF_EXIT_INSN(),
11482 /* B */
11483 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
11484 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
11485 BPF_EXIT_INSN(),
11486 },
11487 .prog_type = BPF_PROG_TYPE_XDP,
11488 /* stack_main=32, stack_A=64, stack_B=256
11489 * and max(main+A, main+A+B) < 512
11490 */
11491 .result = ACCEPT,
11492 },
11493 {
11494 "calls: stack depth check using three frames. test3",
11495 .insns = {
11496 /* main */
11497 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11498 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
11499 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11500 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
11501 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
11502 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
11503 BPF_MOV64_IMM(BPF_REG_0, 0),
11504 BPF_EXIT_INSN(),
11505 /* A */
11506 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
11507 BPF_EXIT_INSN(),
11508 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
11509 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
11510 /* B */
11511 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
11512 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
11513 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
11514 BPF_EXIT_INSN(),
11515 },
11516 .prog_type = BPF_PROG_TYPE_XDP,
11517 /* stack_main=64, stack_A=224, stack_B=256
11518 * and max(main+A, main+A+B) > 512
11519 */
11520 .errstr = "combined stack",
11521 .result = REJECT,
11522 },
11523 {
11524 "calls: stack depth check using three frames. test4",
11525 /* void main(void) {
11526 * func1(0);
11527 * func1(1);
11528 * func2(1);
11529 * }
11530 * void func1(int alloc_or_recurse) {
11531 * if (alloc_or_recurse) {
11532 * frame_pointer[-300] = 1;
11533 * } else {
11534 * func2(alloc_or_recurse);
11535 * }
11536 * }
11537 * void func2(int alloc_or_recurse) {
11538 * if (alloc_or_recurse) {
11539 * frame_pointer[-300] = 1;
11540 * }
11541 * }
11542 */
11543 .insns = {
11544 /* main */
11545 BPF_MOV64_IMM(BPF_REG_1, 0),
11546 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
11547 BPF_MOV64_IMM(BPF_REG_1, 1),
11548 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
11549 BPF_MOV64_IMM(BPF_REG_1, 1),
11550 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
11551 BPF_MOV64_IMM(BPF_REG_0, 0),
11552 BPF_EXIT_INSN(),
11553 /* A */
11554 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
11555 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11556 BPF_EXIT_INSN(),
11557 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
11558 BPF_EXIT_INSN(),
11559 /* B */
11560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
11561 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
11562 BPF_EXIT_INSN(),
11563 },
11564 .prog_type = BPF_PROG_TYPE_XDP,
11565 .result = REJECT,
11566 .errstr = "combined stack",
11567 },
11568 {
11569 "calls: stack depth check using three frames. test5",
11570 .insns = {
11571 /* main */
11572 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
11573 BPF_EXIT_INSN(),
11574 /* A */
11575 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
11576 BPF_EXIT_INSN(),
11577 /* B */
11578 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
11579 BPF_EXIT_INSN(),
11580 /* C */
11581 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
11582 BPF_EXIT_INSN(),
11583 /* D */
11584 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
11585 BPF_EXIT_INSN(),
11586 /* E */
11587 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
11588 BPF_EXIT_INSN(),
11589 /* F */
11590 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
11591 BPF_EXIT_INSN(),
11592 /* G */
11593 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
11594 BPF_EXIT_INSN(),
11595 /* H */
11596 BPF_MOV64_IMM(BPF_REG_0, 0),
11597 BPF_EXIT_INSN(),
11598 },
11599 .prog_type = BPF_PROG_TYPE_XDP,
11600 .errstr = "call stack",
11601 .result = REJECT,
11602 },
11603 {
11604 "calls: spill into caller stack frame",
11605 .insns = {
11606 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11607 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11608 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11609 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11610 BPF_EXIT_INSN(),
11611 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
11612 BPF_MOV64_IMM(BPF_REG_0, 0),
11613 BPF_EXIT_INSN(),
11614 },
11615 .prog_type = BPF_PROG_TYPE_XDP,
11616 .errstr = "cannot spill",
11617 .result = REJECT,
11618 },
11619 {
11620 "calls: write into caller stack frame",
11621 .insns = {
11622 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11624 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11625 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11626 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11627 BPF_EXIT_INSN(),
11628 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
11629 BPF_MOV64_IMM(BPF_REG_0, 0),
11630 BPF_EXIT_INSN(),
11631 },
11632 .prog_type = BPF_PROG_TYPE_XDP,
11633 .result = ACCEPT,
11634 .retval = 42,
11635 },
11636 {
11637 "calls: write into callee stack frame",
11638 .insns = {
11639 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11640 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
11641 BPF_EXIT_INSN(),
11642 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
11643 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
11644 BPF_EXIT_INSN(),
11645 },
11646 .prog_type = BPF_PROG_TYPE_XDP,
11647 .errstr = "cannot return stack pointer",
11648 .result = REJECT,
11649 },
11650 {
11651 "calls: two calls with stack write and void return",
11652 .insns = {
11653 /* main prog */
11654 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11655 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11656 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11657 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11659 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11660 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
11661 BPF_EXIT_INSN(),
11662
11663 /* subprog 1 */
11664 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11665 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11666 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11667 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11668 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11669 BPF_EXIT_INSN(),
11670
11671 /* subprog 2 */
11672 /* write into stack frame of main prog */
11673 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
11674 BPF_EXIT_INSN(), /* void return */
11675 },
11676 .prog_type = BPF_PROG_TYPE_XDP,
11677 .result = ACCEPT,
11678 },
11679 {
11680 "calls: ambiguous return value",
11681 .insns = {
11682 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11683 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
11684 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11685 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11686 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11687 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11688 BPF_EXIT_INSN(),
11689 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
11690 BPF_MOV64_IMM(BPF_REG_0, 0),
11691 BPF_EXIT_INSN(),
11692 },
11693 .errstr_unpriv = "allowed for root only",
11694 .result_unpriv = REJECT,
11695 .errstr = "R0 !read_ok",
11696 .result = REJECT,
11697 },
11698 {
11699 "calls: two calls that return map_value",
11700 .insns = {
11701 /* main prog */
11702 /* pass fp-16, fp-8 into a function */
11703 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11704 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11705 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11707 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
11708
11709 /* fetch map_value_ptr from the stack of this function */
11710 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11711 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11712 /* write into map value */
11713 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11714 /* fetch secound map_value_ptr from the stack */
11715 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
11716 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11717 /* write into map value */
11718 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11719 BPF_MOV64_IMM(BPF_REG_0, 0),
11720 BPF_EXIT_INSN(),
11721
11722 /* subprog 1 */
11723 /* call 3rd function twice */
11724 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11725 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11726 /* first time with fp-8 */
11727 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11728 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11729 /* second time with fp-16 */
11730 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11731 BPF_EXIT_INSN(),
11732
11733 /* subprog 2 */
11734 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11735 /* lookup from map */
11736 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11737 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11739 BPF_LD_MAP_FD(BPF_REG_1, 0),
11740 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11741 BPF_FUNC_map_lookup_elem),
11742 /* write map_value_ptr into stack frame of main prog */
11743 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11744 BPF_MOV64_IMM(BPF_REG_0, 0),
11745 BPF_EXIT_INSN(), /* return 0 */
11746 },
11747 .prog_type = BPF_PROG_TYPE_XDP,
11748 .fixup_map_hash_8b = { 23 },
11749 .result = ACCEPT,
11750 },
11751 {
11752 "calls: two calls that return map_value with bool condition",
11753 .insns = {
11754 /* main prog */
11755 /* pass fp-16, fp-8 into a function */
11756 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11757 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11758 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11759 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11760 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11761 BPF_MOV64_IMM(BPF_REG_0, 0),
11762 BPF_EXIT_INSN(),
11763
11764 /* subprog 1 */
11765 /* call 3rd function twice */
11766 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11767 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11768 /* first time with fp-8 */
11769 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
11770 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11771 /* fetch map_value_ptr from the stack of this function */
11772 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11773 /* write into map value */
11774 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11775 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11776 /* second time with fp-16 */
11777 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11778 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11779 /* fetch secound map_value_ptr from the stack */
11780 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
11781 /* write into map value */
11782 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11783 BPF_EXIT_INSN(),
11784
11785 /* subprog 2 */
11786 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11787 /* lookup from map */
11788 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11789 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11791 BPF_LD_MAP_FD(BPF_REG_1, 0),
11792 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11793 BPF_FUNC_map_lookup_elem),
11794 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11795 BPF_MOV64_IMM(BPF_REG_0, 0),
11796 BPF_EXIT_INSN(), /* return 0 */
11797 /* write map_value_ptr into stack frame of main prog */
11798 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11799 BPF_MOV64_IMM(BPF_REG_0, 1),
11800 BPF_EXIT_INSN(), /* return 1 */
11801 },
11802 .prog_type = BPF_PROG_TYPE_XDP,
11803 .fixup_map_hash_8b = { 23 },
11804 .result = ACCEPT,
11805 },
11806 {
11807 "calls: two calls that return map_value with incorrect bool check",
11808 .insns = {
11809 /* main prog */
11810 /* pass fp-16, fp-8 into a function */
11811 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11813 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11814 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11815 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11816 BPF_MOV64_IMM(BPF_REG_0, 0),
11817 BPF_EXIT_INSN(),
11818
11819 /* subprog 1 */
11820 /* call 3rd function twice */
11821 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11822 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11823 /* first time with fp-8 */
11824 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
11825 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11826 /* fetch map_value_ptr from the stack of this function */
11827 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11828 /* write into map value */
11829 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11830 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11831 /* second time with fp-16 */
11832 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11833 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11834 /* fetch secound map_value_ptr from the stack */
11835 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
11836 /* write into map value */
11837 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11838 BPF_EXIT_INSN(),
11839
11840 /* subprog 2 */
11841 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11842 /* lookup from map */
11843 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11844 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11845 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11846 BPF_LD_MAP_FD(BPF_REG_1, 0),
11847 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11848 BPF_FUNC_map_lookup_elem),
11849 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11850 BPF_MOV64_IMM(BPF_REG_0, 0),
11851 BPF_EXIT_INSN(), /* return 0 */
11852 /* write map_value_ptr into stack frame of main prog */
11853 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11854 BPF_MOV64_IMM(BPF_REG_0, 1),
11855 BPF_EXIT_INSN(), /* return 1 */
11856 },
11857 .prog_type = BPF_PROG_TYPE_XDP,
11858 .fixup_map_hash_8b = { 23 },
11859 .result = REJECT,
11860 .errstr = "invalid read from stack off -16+0 size 8",
11861 },
11862 {
11863 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
11864 .insns = {
11865 /* main prog */
11866 /* pass fp-16, fp-8 into a function */
11867 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11869 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11871 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11872 BPF_MOV64_IMM(BPF_REG_0, 0),
11873 BPF_EXIT_INSN(),
11874
11875 /* subprog 1 */
11876 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11877 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11878 /* 1st lookup from map */
11879 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11880 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11881 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11882 BPF_LD_MAP_FD(BPF_REG_1, 0),
11883 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11884 BPF_FUNC_map_lookup_elem),
11885 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11886 BPF_MOV64_IMM(BPF_REG_8, 0),
11887 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11888 /* write map_value_ptr into stack frame of main prog at fp-8 */
11889 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11890 BPF_MOV64_IMM(BPF_REG_8, 1),
11891
11892 /* 2nd lookup from map */
11893 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11894 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11895 BPF_LD_MAP_FD(BPF_REG_1, 0),
11896 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11897 BPF_FUNC_map_lookup_elem),
11898 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11899 BPF_MOV64_IMM(BPF_REG_9, 0),
11900 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11901 /* write map_value_ptr into stack frame of main prog at fp-16 */
11902 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11903 BPF_MOV64_IMM(BPF_REG_9, 1),
11904
11905 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11906 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11907 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11908 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11909 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11910 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11911 BPF_EXIT_INSN(),
11912
11913 /* subprog 2 */
11914 /* if arg2 == 1 do *arg1 = 0 */
11915 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11916 /* fetch map_value_ptr from the stack of this function */
11917 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11918 /* write into map value */
11919 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11920
11921 /* if arg4 == 1 do *arg3 = 0 */
11922 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11923 /* fetch map_value_ptr from the stack of this function */
11924 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11925 /* write into map value */
11926 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11927 BPF_EXIT_INSN(),
11928 },
11929 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11930 .fixup_map_hash_8b = { 12, 22 },
11931 .result = REJECT,
11932 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11933 },
11934 {
11935 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
11936 .insns = {
11937 /* main prog */
11938 /* pass fp-16, fp-8 into a function */
11939 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11943 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11944 BPF_MOV64_IMM(BPF_REG_0, 0),
11945 BPF_EXIT_INSN(),
11946
11947 /* subprog 1 */
11948 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11949 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11950 /* 1st lookup from map */
11951 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11952 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11953 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11954 BPF_LD_MAP_FD(BPF_REG_1, 0),
11955 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11956 BPF_FUNC_map_lookup_elem),
11957 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11958 BPF_MOV64_IMM(BPF_REG_8, 0),
11959 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11960 /* write map_value_ptr into stack frame of main prog at fp-8 */
11961 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11962 BPF_MOV64_IMM(BPF_REG_8, 1),
11963
11964 /* 2nd lookup from map */
11965 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11967 BPF_LD_MAP_FD(BPF_REG_1, 0),
11968 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11969 BPF_FUNC_map_lookup_elem),
11970 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11971 BPF_MOV64_IMM(BPF_REG_9, 0),
11972 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11973 /* write map_value_ptr into stack frame of main prog at fp-16 */
11974 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11975 BPF_MOV64_IMM(BPF_REG_9, 1),
11976
11977 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11978 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11979 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11980 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11981 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11982 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11983 BPF_EXIT_INSN(),
11984
11985 /* subprog 2 */
11986 /* if arg2 == 1 do *arg1 = 0 */
11987 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11988 /* fetch map_value_ptr from the stack of this function */
11989 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11990 /* write into map value */
11991 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11992
11993 /* if arg4 == 1 do *arg3 = 0 */
11994 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11995 /* fetch map_value_ptr from the stack of this function */
11996 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11997 /* write into map value */
11998 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11999 BPF_EXIT_INSN(),
12000 },
12001 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12002 .fixup_map_hash_8b = { 12, 22 },
12003 .result = ACCEPT,
12004 },
12005 {
12006 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
12007 .insns = {
12008 /* main prog */
12009 /* pass fp-16, fp-8 into a function */
12010 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
12011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
12012 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
12014 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
12015 BPF_MOV64_IMM(BPF_REG_0, 0),
12016 BPF_EXIT_INSN(),
12017
12018 /* subprog 1 */
12019 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12020 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
12021 /* 1st lookup from map */
12022 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
12023 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12024 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
12025 BPF_LD_MAP_FD(BPF_REG_1, 0),
12026 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12027 BPF_FUNC_map_lookup_elem),
12028 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12029 BPF_MOV64_IMM(BPF_REG_8, 0),
12030 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12031 /* write map_value_ptr into stack frame of main prog at fp-8 */
12032 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
12033 BPF_MOV64_IMM(BPF_REG_8, 1),
12034
12035 /* 2nd lookup from map */
12036 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12037 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
12038 BPF_LD_MAP_FD(BPF_REG_1, 0),
12039 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12040 BPF_FUNC_map_lookup_elem),
12041 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12042 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
12043 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12044 /* write map_value_ptr into stack frame of main prog at fp-16 */
12045 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12046 BPF_MOV64_IMM(BPF_REG_9, 1),
12047
12048 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
12049 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
12050 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
12051 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
12052 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
12053 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
12054 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
12055
12056 /* subprog 2 */
12057 /* if arg2 == 1 do *arg1 = 0 */
12058 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
12059 /* fetch map_value_ptr from the stack of this function */
12060 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
12061 /* write into map value */
12062 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
12063
12064 /* if arg4 == 1 do *arg3 = 0 */
12065 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
12066 /* fetch map_value_ptr from the stack of this function */
12067 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
12068 /* write into map value */
12069 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
12070 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
12071 },
12072 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12073 .fixup_map_hash_8b = { 12, 22 },
12074 .result = REJECT,
12075 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
12076 },
12077 {
12078 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
12079 .insns = {
12080 /* main prog */
12081 /* pass fp-16, fp-8 into a function */
12082 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
12083 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
12084 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12085 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
12086 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
12087 BPF_MOV64_IMM(BPF_REG_0, 0),
12088 BPF_EXIT_INSN(),
12089
12090 /* subprog 1 */
12091 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12092 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
12093 /* 1st lookup from map */
12094 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12095 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12096 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12097 BPF_LD_MAP_FD(BPF_REG_1, 0),
12098 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12099 BPF_FUNC_map_lookup_elem),
12100 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
12101 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
12102 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12103 BPF_MOV64_IMM(BPF_REG_8, 0),
12104 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12105 BPF_MOV64_IMM(BPF_REG_8, 1),
12106
12107 /* 2nd lookup from map */
12108 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12109 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12110 BPF_LD_MAP_FD(BPF_REG_1, 0),
12111 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12112 BPF_FUNC_map_lookup_elem),
12113 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
12114 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12115 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12116 BPF_MOV64_IMM(BPF_REG_9, 0),
12117 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12118 BPF_MOV64_IMM(BPF_REG_9, 1),
12119
12120 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
12121 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12122 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
12123 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
12124 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
12125 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
12126 BPF_EXIT_INSN(),
12127
12128 /* subprog 2 */
12129 /* if arg2 == 1 do *arg1 = 0 */
12130 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
12131 /* fetch map_value_ptr from the stack of this function */
12132 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
12133 /* write into map value */
12134 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
12135
12136 /* if arg4 == 1 do *arg3 = 0 */
12137 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
12138 /* fetch map_value_ptr from the stack of this function */
12139 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
12140 /* write into map value */
12141 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
12142 BPF_EXIT_INSN(),
12143 },
12144 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12145 .fixup_map_hash_8b = { 12, 22 },
12146 .result = ACCEPT,
12147 },
12148 {
12149 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
12150 .insns = {
12151 /* main prog */
12152 /* pass fp-16, fp-8 into a function */
12153 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
12154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
12155 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
12157 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
12158 BPF_MOV64_IMM(BPF_REG_0, 0),
12159 BPF_EXIT_INSN(),
12160
12161 /* subprog 1 */
12162 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12163 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
12164 /* 1st lookup from map */
12165 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12166 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12167 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12168 BPF_LD_MAP_FD(BPF_REG_1, 0),
12169 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12170 BPF_FUNC_map_lookup_elem),
12171 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
12172 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
12173 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12174 BPF_MOV64_IMM(BPF_REG_8, 0),
12175 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12176 BPF_MOV64_IMM(BPF_REG_8, 1),
12177
12178 /* 2nd lookup from map */
12179 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12180 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12181 BPF_LD_MAP_FD(BPF_REG_1, 0),
12182 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12183 BPF_FUNC_map_lookup_elem),
12184 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
12185 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12186 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12187 BPF_MOV64_IMM(BPF_REG_9, 0),
12188 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12189 BPF_MOV64_IMM(BPF_REG_9, 1),
12190
12191 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
12192 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12193 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
12194 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
12195 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
12196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
12197 BPF_EXIT_INSN(),
12198
12199 /* subprog 2 */
12200 /* if arg2 == 1 do *arg1 = 0 */
12201 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
12202 /* fetch map_value_ptr from the stack of this function */
12203 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
12204 /* write into map value */
12205 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
12206
12207 /* if arg4 == 0 do *arg3 = 0 */
12208 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
12209 /* fetch map_value_ptr from the stack of this function */
12210 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
12211 /* write into map value */
12212 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
12213 BPF_EXIT_INSN(),
12214 },
12215 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12216 .fixup_map_hash_8b = { 12, 22 },
12217 .result = REJECT,
12218 .errstr = "R0 invalid mem access 'inv'",
12219 },
12220 {
12221 "calls: pkt_ptr spill into caller stack",
12222 .insns = {
12223 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12224 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12225 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
12226 BPF_EXIT_INSN(),
12227
12228 /* subprog 1 */
12229 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12230 offsetof(struct __sk_buff, data)),
12231 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12232 offsetof(struct __sk_buff, data_end)),
12233 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12235 /* spill unchecked pkt_ptr into stack of caller */
12236 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12237 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
12238 /* now the pkt range is verified, read pkt_ptr from stack */
12239 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
12240 /* write 4 bytes into packet */
12241 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12242 BPF_EXIT_INSN(),
12243 },
12244 .result = ACCEPT,
12245 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12246 .retval = POINTER_VALUE,
12247 },
12248 {
12249 "calls: pkt_ptr spill into caller stack 2",
12250 .insns = {
12251 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12253 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12254 /* Marking is still kept, but not in all cases safe. */
12255 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12256 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
12257 BPF_EXIT_INSN(),
12258
12259 /* subprog 1 */
12260 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12261 offsetof(struct __sk_buff, data)),
12262 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12263 offsetof(struct __sk_buff, data_end)),
12264 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12266 /* spill unchecked pkt_ptr into stack of caller */
12267 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12268 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
12269 /* now the pkt range is verified, read pkt_ptr from stack */
12270 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
12271 /* write 4 bytes into packet */
12272 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12273 BPF_EXIT_INSN(),
12274 },
12275 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12276 .errstr = "invalid access to packet",
12277 .result = REJECT,
12278 },
12279 {
12280 "calls: pkt_ptr spill into caller stack 3",
12281 .insns = {
12282 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12284 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
12285 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
12286 /* Marking is still kept and safe here. */
12287 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12288 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
12289 BPF_EXIT_INSN(),
12290
12291 /* subprog 1 */
12292 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12293 offsetof(struct __sk_buff, data)),
12294 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12295 offsetof(struct __sk_buff, data_end)),
12296 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12298 /* spill unchecked pkt_ptr into stack of caller */
12299 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12300 BPF_MOV64_IMM(BPF_REG_5, 0),
12301 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
12302 BPF_MOV64_IMM(BPF_REG_5, 1),
12303 /* now the pkt range is verified, read pkt_ptr from stack */
12304 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
12305 /* write 4 bytes into packet */
12306 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12307 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12308 BPF_EXIT_INSN(),
12309 },
12310 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12311 .result = ACCEPT,
12312 .retval = 1,
12313 },
12314 {
12315 "calls: pkt_ptr spill into caller stack 4",
12316 .insns = {
12317 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12318 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12319 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
12320 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
12321 /* Check marking propagated. */
12322 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12323 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
12324 BPF_EXIT_INSN(),
12325
12326 /* subprog 1 */
12327 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12328 offsetof(struct __sk_buff, data)),
12329 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12330 offsetof(struct __sk_buff, data_end)),
12331 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12332 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12333 /* spill unchecked pkt_ptr into stack of caller */
12334 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12335 BPF_MOV64_IMM(BPF_REG_5, 0),
12336 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
12337 BPF_MOV64_IMM(BPF_REG_5, 1),
12338 /* don't read back pkt_ptr from stack here */
12339 /* write 4 bytes into packet */
12340 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12341 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12342 BPF_EXIT_INSN(),
12343 },
12344 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12345 .result = ACCEPT,
12346 .retval = 1,
12347 },
12348 {
12349 "calls: pkt_ptr spill into caller stack 5",
12350 .insns = {
12351 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12352 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12353 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
12354 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12355 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12356 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
12357 BPF_EXIT_INSN(),
12358
12359 /* subprog 1 */
12360 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12361 offsetof(struct __sk_buff, data)),
12362 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12363 offsetof(struct __sk_buff, data_end)),
12364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12366 BPF_MOV64_IMM(BPF_REG_5, 0),
12367 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
12368 /* spill checked pkt_ptr into stack of caller */
12369 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12370 BPF_MOV64_IMM(BPF_REG_5, 1),
12371 /* don't read back pkt_ptr from stack here */
12372 /* write 4 bytes into packet */
12373 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12374 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12375 BPF_EXIT_INSN(),
12376 },
12377 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12378 .errstr = "same insn cannot be used with different",
12379 .result = REJECT,
12380 },
12381 {
12382 "calls: pkt_ptr spill into caller stack 6",
12383 .insns = {
12384 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12385 offsetof(struct __sk_buff, data_end)),
12386 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12387 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12388 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12389 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12390 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12391 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
12392 BPF_EXIT_INSN(),
12393
12394 /* subprog 1 */
12395 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12396 offsetof(struct __sk_buff, data)),
12397 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12398 offsetof(struct __sk_buff, data_end)),
12399 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12400 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12401 BPF_MOV64_IMM(BPF_REG_5, 0),
12402 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
12403 /* spill checked pkt_ptr into stack of caller */
12404 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12405 BPF_MOV64_IMM(BPF_REG_5, 1),
12406 /* don't read back pkt_ptr from stack here */
12407 /* write 4 bytes into packet */
12408 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12409 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12410 BPF_EXIT_INSN(),
12411 },
12412 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12413 .errstr = "R4 invalid mem access",
12414 .result = REJECT,
12415 },
12416 {
12417 "calls: pkt_ptr spill into caller stack 7",
12418 .insns = {
12419 BPF_MOV64_IMM(BPF_REG_2, 0),
12420 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12422 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12423 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12424 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12425 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
12426 BPF_EXIT_INSN(),
12427
12428 /* subprog 1 */
12429 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12430 offsetof(struct __sk_buff, data)),
12431 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12432 offsetof(struct __sk_buff, data_end)),
12433 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12435 BPF_MOV64_IMM(BPF_REG_5, 0),
12436 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
12437 /* spill checked pkt_ptr into stack of caller */
12438 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12439 BPF_MOV64_IMM(BPF_REG_5, 1),
12440 /* don't read back pkt_ptr from stack here */
12441 /* write 4 bytes into packet */
12442 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12443 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12444 BPF_EXIT_INSN(),
12445 },
12446 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12447 .errstr = "R4 invalid mem access",
12448 .result = REJECT,
12449 },
12450 {
12451 "calls: pkt_ptr spill into caller stack 8",
12452 .insns = {
12453 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12454 offsetof(struct __sk_buff, data)),
12455 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12456 offsetof(struct __sk_buff, data_end)),
12457 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12458 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12459 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
12460 BPF_EXIT_INSN(),
12461 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12462 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12463 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12464 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12465 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12466 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
12467 BPF_EXIT_INSN(),
12468
12469 /* subprog 1 */
12470 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12471 offsetof(struct __sk_buff, data)),
12472 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12473 offsetof(struct __sk_buff, data_end)),
12474 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12476 BPF_MOV64_IMM(BPF_REG_5, 0),
12477 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
12478 /* spill checked pkt_ptr into stack of caller */
12479 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12480 BPF_MOV64_IMM(BPF_REG_5, 1),
12481 /* don't read back pkt_ptr from stack here */
12482 /* write 4 bytes into packet */
12483 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12484 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12485 BPF_EXIT_INSN(),
12486 },
12487 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12488 .result = ACCEPT,
12489 },
12490 {
12491 "calls: pkt_ptr spill into caller stack 9",
12492 .insns = {
12493 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12494 offsetof(struct __sk_buff, data)),
12495 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12496 offsetof(struct __sk_buff, data_end)),
12497 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12499 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
12500 BPF_EXIT_INSN(),
12501 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
12502 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
12503 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12504 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
12505 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
12506 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
12507 BPF_EXIT_INSN(),
12508
12509 /* subprog 1 */
12510 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12511 offsetof(struct __sk_buff, data)),
12512 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12513 offsetof(struct __sk_buff, data_end)),
12514 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
12515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
12516 BPF_MOV64_IMM(BPF_REG_5, 0),
12517 /* spill unchecked pkt_ptr into stack of caller */
12518 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
12519 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
12520 BPF_MOV64_IMM(BPF_REG_5, 1),
12521 /* don't read back pkt_ptr from stack here */
12522 /* write 4 bytes into packet */
12523 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12524 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
12525 BPF_EXIT_INSN(),
12526 },
12527 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12528 .errstr = "invalid access to packet",
12529 .result = REJECT,
12530 },
12531 {
12532 "calls: caller stack init to zero or map_value_or_null",
12533 .insns = {
12534 BPF_MOV64_IMM(BPF_REG_0, 0),
12535 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12536 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12537 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12538 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
12539 /* fetch map_value_or_null or const_zero from stack */
12540 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12541 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
12542 /* store into map_value */
12543 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
12544 BPF_EXIT_INSN(),
12545
12546 /* subprog 1 */
12547 /* if (ctx == 0) return; */
12548 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
12549 /* else bpf_map_lookup() and *(fp - 8) = r0 */
12550 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
12551 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12552 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12553 BPF_LD_MAP_FD(BPF_REG_1, 0),
12554 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12555 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12556 BPF_FUNC_map_lookup_elem),
12557 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
12558 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
12559 BPF_EXIT_INSN(),
12560 },
12561 .fixup_map_hash_8b = { 13 },
12562 .result = ACCEPT,
12563 .prog_type = BPF_PROG_TYPE_XDP,
12564 },
12565 {
12566 "calls: stack init to zero and pruning",
12567 .insns = {
12568 /* first make allocated_stack 16 byte */
12569 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
12570 /* now fork the execution such that the false branch
12571 * of JGT insn will be verified second and it skisp zero
12572 * init of fp-8 stack slot. If stack liveness marking
12573 * is missing live_read marks from call map_lookup
12574 * processing then pruning will incorrectly assume
12575 * that fp-8 stack slot was unused in the fall-through
12576 * branch and will accept the program incorrectly
12577 */
12578 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
12579 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12580 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
12581 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12582 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12583 BPF_LD_MAP_FD(BPF_REG_1, 0),
12584 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12585 BPF_FUNC_map_lookup_elem),
12586 BPF_EXIT_INSN(),
12587 },
12588 .fixup_map_hash_48b = { 6 },
12589 .errstr = "invalid indirect read from stack off -8+0 size 8",
12590 .result = REJECT,
12591 .prog_type = BPF_PROG_TYPE_XDP,
12592 },
12593 {
12594 "calls: two calls returning different map pointers for lookup (hash, array)",
12595 .insns = {
12596 /* main prog */
12597 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
12598 BPF_CALL_REL(11),
12599 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12600 BPF_CALL_REL(12),
12601 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
12602 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12603 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12605 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12606 BPF_FUNC_map_lookup_elem),
12607 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
12608 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
12609 offsetof(struct test_val, foo)),
12610 BPF_MOV64_IMM(BPF_REG_0, 1),
12611 BPF_EXIT_INSN(),
12612 /* subprog 1 */
12613 BPF_LD_MAP_FD(BPF_REG_0, 0),
12614 BPF_EXIT_INSN(),
12615 /* subprog 2 */
12616 BPF_LD_MAP_FD(BPF_REG_0, 0),
12617 BPF_EXIT_INSN(),
12618 },
12619 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12620 .fixup_map_hash_48b = { 13 },
12621 .fixup_map_array_48b = { 16 },
12622 .result = ACCEPT,
12623 .retval = 1,
12624 },
12625 {
12626 "calls: two calls returning different map pointers for lookup (hash, map in map)",
12627 .insns = {
12628 /* main prog */
12629 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
12630 BPF_CALL_REL(11),
12631 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
12632 BPF_CALL_REL(12),
12633 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
12634 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12635 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12636 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12637 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12638 BPF_FUNC_map_lookup_elem),
12639 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
12640 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
12641 offsetof(struct test_val, foo)),
12642 BPF_MOV64_IMM(BPF_REG_0, 1),
12643 BPF_EXIT_INSN(),
12644 /* subprog 1 */
12645 BPF_LD_MAP_FD(BPF_REG_0, 0),
12646 BPF_EXIT_INSN(),
12647 /* subprog 2 */
12648 BPF_LD_MAP_FD(BPF_REG_0, 0),
12649 BPF_EXIT_INSN(),
12650 },
12651 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12652 .fixup_map_in_map = { 16 },
12653 .fixup_map_array_48b = { 13 },
12654 .result = REJECT,
12655 .errstr = "R0 invalid mem access 'map_ptr'",
12656 },
12657 {
12658 "cond: two branches returning different map pointers for lookup (tail, tail)",
12659 .insns = {
12660 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
12661 offsetof(struct __sk_buff, mark)),
12662 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 3),
12663 BPF_LD_MAP_FD(BPF_REG_2, 0),
12664 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12665 BPF_LD_MAP_FD(BPF_REG_2, 0),
12666 BPF_MOV64_IMM(BPF_REG_3, 7),
12667 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12668 BPF_FUNC_tail_call),
12669 BPF_MOV64_IMM(BPF_REG_0, 1),
12670 BPF_EXIT_INSN(),
12671 },
12672 .fixup_prog1 = { 5 },
12673 .fixup_prog2 = { 2 },
12674 .result_unpriv = REJECT,
12675 .errstr_unpriv = "tail_call abusing map_ptr",
12676 .result = ACCEPT,
12677 .retval = 42,
12678 },
12679 {
12680 "cond: two branches returning same map pointers for lookup (tail, tail)",
12681 .insns = {
12682 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
12683 offsetof(struct __sk_buff, mark)),
12684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 3),
12685 BPF_LD_MAP_FD(BPF_REG_2, 0),
12686 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12687 BPF_LD_MAP_FD(BPF_REG_2, 0),
12688 BPF_MOV64_IMM(BPF_REG_3, 7),
12689 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12690 BPF_FUNC_tail_call),
12691 BPF_MOV64_IMM(BPF_REG_0, 1),
12692 BPF_EXIT_INSN(),
12693 },
12694 .fixup_prog2 = { 2, 5 },
12695 .result_unpriv = ACCEPT,
12696 .result = ACCEPT,
12697 .retval = 42,
12698 },
12699 {
12700 "search pruning: all branches should be verified (nop operation)",
12701 .insns = {
12702 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12703 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12704 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
12705 BPF_LD_MAP_FD(BPF_REG_1, 0),
12706 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
12707 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
12708 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
12709 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
12710 BPF_MOV64_IMM(BPF_REG_4, 0),
12711 BPF_JMP_A(1),
12712 BPF_MOV64_IMM(BPF_REG_4, 1),
12713 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
12714 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
12715 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
12716 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
12717 BPF_MOV64_IMM(BPF_REG_6, 0),
12718 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
12719 BPF_EXIT_INSN(),
12720 },
12721 .fixup_map_hash_8b = { 3 },
12722 .errstr = "R6 invalid mem access 'inv'",
12723 .result = REJECT,
12724 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12725 },
12726 {
12727 "search pruning: all branches should be verified (invalid stack access)",
12728 .insns = {
12729 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12730 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12731 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
12732 BPF_LD_MAP_FD(BPF_REG_1, 0),
12733 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
12734 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
12735 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
12736 BPF_MOV64_IMM(BPF_REG_4, 0),
12737 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
12738 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
12739 BPF_JMP_A(1),
12740 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
12741 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
12742 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
12743 BPF_EXIT_INSN(),
12744 },
12745 .fixup_map_hash_8b = { 3 },
12746 .errstr = "invalid read from stack off -16+0 size 8",
12747 .result = REJECT,
12748 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12749 },
12750 {
12751 "jit: lsh, rsh, arsh by 1",
12752 .insns = {
12753 BPF_MOV64_IMM(BPF_REG_0, 1),
12754 BPF_MOV64_IMM(BPF_REG_1, 0xff),
12755 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
12756 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
12757 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
12758 BPF_EXIT_INSN(),
12759 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
12760 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
12761 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
12762 BPF_EXIT_INSN(),
12763 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
12764 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
12765 BPF_EXIT_INSN(),
12766 BPF_MOV64_IMM(BPF_REG_0, 2),
12767 BPF_EXIT_INSN(),
12768 },
12769 .result = ACCEPT,
12770 .retval = 2,
12771 },
12772 {
12773 "jit: mov32 for ldimm64, 1",
12774 .insns = {
12775 BPF_MOV64_IMM(BPF_REG_0, 2),
12776 BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
12777 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
12778 BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
12779 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
12780 BPF_MOV64_IMM(BPF_REG_0, 1),
12781 BPF_EXIT_INSN(),
12782 },
12783 .result = ACCEPT,
12784 .retval = 2,
12785 },
12786 {
12787 "jit: mov32 for ldimm64, 2",
12788 .insns = {
12789 BPF_MOV64_IMM(BPF_REG_0, 1),
12790 BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
12791 BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
12792 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
12793 BPF_MOV64_IMM(BPF_REG_0, 2),
12794 BPF_EXIT_INSN(),
12795 },
12796 .result = ACCEPT,
12797 .retval = 2,
12798 },
12799 {
12800 "jit: various mul tests",
12801 .insns = {
12802 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
12803 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
12804 BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
12805 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
12806 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
12807 BPF_MOV64_IMM(BPF_REG_0, 1),
12808 BPF_EXIT_INSN(),
12809 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
12810 BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
12811 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
12812 BPF_MOV64_IMM(BPF_REG_0, 1),
12813 BPF_EXIT_INSN(),
12814 BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
12815 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
12816 BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
12817 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
12818 BPF_MOV64_IMM(BPF_REG_0, 1),
12819 BPF_EXIT_INSN(),
12820 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
12821 BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
12822 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
12823 BPF_MOV64_IMM(BPF_REG_0, 1),
12824 BPF_EXIT_INSN(),
12825 BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
12826 BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
12827 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
12828 BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
12829 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
12830 BPF_MOV64_IMM(BPF_REG_0, 1),
12831 BPF_EXIT_INSN(),
12832 BPF_MOV64_IMM(BPF_REG_0, 2),
12833 BPF_EXIT_INSN(),
12834 },
12835 .result = ACCEPT,
12836 .retval = 2,
12837 },
12838 {
12839 "xadd/w check unaligned stack",
12840 .insns = {
12841 BPF_MOV64_IMM(BPF_REG_0, 1),
12842 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12843 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
12844 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12845 BPF_EXIT_INSN(),
12846 },
12847 .result = REJECT,
12848 .errstr = "misaligned stack access off",
12849 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12850 },
12851 {
12852 "xadd/w check unaligned map",
12853 .insns = {
12854 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12855 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12856 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12857 BPF_LD_MAP_FD(BPF_REG_1, 0),
12858 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12859 BPF_FUNC_map_lookup_elem),
12860 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
12861 BPF_EXIT_INSN(),
12862 BPF_MOV64_IMM(BPF_REG_1, 1),
12863 BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
12864 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
12865 BPF_EXIT_INSN(),
12866 },
12867 .fixup_map_hash_8b = { 3 },
12868 .result = REJECT,
12869 .errstr = "misaligned value access off",
12870 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12871 },
12872 {
12873 "xadd/w check unaligned pkt",
12874 .insns = {
12875 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12876 offsetof(struct xdp_md, data)),
12877 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12878 offsetof(struct xdp_md, data_end)),
12879 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
12880 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
12881 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
12882 BPF_MOV64_IMM(BPF_REG_0, 99),
12883 BPF_JMP_IMM(BPF_JA, 0, 0, 6),
12884 BPF_MOV64_IMM(BPF_REG_0, 1),
12885 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12886 BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
12887 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
12888 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
12889 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
12890 BPF_EXIT_INSN(),
12891 },
12892 .result = REJECT,
12893 .errstr = "BPF_XADD stores into R2 pkt is not allowed",
12894 .prog_type = BPF_PROG_TYPE_XDP,
12895 },
12896 {
12897 "xadd/w check whether src/dst got mangled, 1",
12898 .insns = {
12899 BPF_MOV64_IMM(BPF_REG_0, 1),
12900 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12901 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12902 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12903 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12904 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12905 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12906 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12907 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12908 BPF_EXIT_INSN(),
12909 BPF_MOV64_IMM(BPF_REG_0, 42),
12910 BPF_EXIT_INSN(),
12911 },
12912 .result = ACCEPT,
12913 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12914 .retval = 3,
12915 },
12916 {
12917 "xadd/w check whether src/dst got mangled, 2",
12918 .insns = {
12919 BPF_MOV64_IMM(BPF_REG_0, 1),
12920 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12921 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12922 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12923 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12924 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12925 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12926 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12927 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
12928 BPF_EXIT_INSN(),
12929 BPF_MOV64_IMM(BPF_REG_0, 42),
12930 BPF_EXIT_INSN(),
12931 },
12932 .result = ACCEPT,
12933 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12934 .retval = 3,
12935 },
12936 {
12937 "bpf_get_stack return R0 within range",
12938 .insns = {
12939 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12940 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12943 BPF_LD_MAP_FD(BPF_REG_1, 0),
12944 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12945 BPF_FUNC_map_lookup_elem),
12946 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
12947 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
12948 BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
12949 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12950 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12951 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
12952 BPF_MOV64_IMM(BPF_REG_4, 256),
12953 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12954 BPF_MOV64_IMM(BPF_REG_1, 0),
12955 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
12956 BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
12957 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
12958 BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
12959 BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
12960 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12961 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
12962 BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
12963 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
12964 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 32),
12965 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
12966 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
12967 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12968 BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
12969 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
12970 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
12971 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12972 BPF_MOV64_REG(BPF_REG_3, BPF_REG_9),
12973 BPF_MOV64_IMM(BPF_REG_4, 0),
12974 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12975 BPF_EXIT_INSN(),
12976 },
12977 .fixup_map_hash_48b = { 4 },
12978 .result = ACCEPT,
12979 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12980 },
12981 {
12982 "ld_abs: invalid op 1",
12983 .insns = {
12984 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12985 BPF_LD_ABS(BPF_DW, 0),
12986 BPF_EXIT_INSN(),
12987 },
12988 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12989 .result = REJECT,
12990 .errstr = "unknown opcode",
12991 },
12992 {
12993 "ld_abs: invalid op 2",
12994 .insns = {
12995 BPF_MOV32_IMM(BPF_REG_0, 256),
12996 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12997 BPF_LD_IND(BPF_DW, BPF_REG_0, 0),
12998 BPF_EXIT_INSN(),
12999 },
13000 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13001 .result = REJECT,
13002 .errstr = "unknown opcode",
13003 },
13004 {
13005 "ld_abs: nmap reduced",
13006 .insns = {
13007 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13008 BPF_LD_ABS(BPF_H, 12),
13009 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 28),
13010 BPF_LD_ABS(BPF_H, 12),
13011 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 26),
13012 BPF_MOV32_IMM(BPF_REG_0, 18),
13013 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -64),
13014 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -64),
13015 BPF_LD_IND(BPF_W, BPF_REG_7, 14),
13016 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -60),
13017 BPF_MOV32_IMM(BPF_REG_0, 280971478),
13018 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
13019 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
13020 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -60),
13021 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
13022 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 15),
13023 BPF_LD_ABS(BPF_H, 12),
13024 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 13),
13025 BPF_MOV32_IMM(BPF_REG_0, 22),
13026 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
13027 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
13028 BPF_LD_IND(BPF_H, BPF_REG_7, 14),
13029 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -52),
13030 BPF_MOV32_IMM(BPF_REG_0, 17366),
13031 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -48),
13032 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -48),
13033 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -52),
13034 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
13035 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
13036 BPF_MOV32_IMM(BPF_REG_0, 256),
13037 BPF_EXIT_INSN(),
13038 BPF_MOV32_IMM(BPF_REG_0, 0),
13039 BPF_EXIT_INSN(),
13040 },
13041 .data = {
13042 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0,
13043 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13044 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
13045 },
13046 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13047 .result = ACCEPT,
13048 .retval = 256,
13049 },
13050 {
13051 "ld_abs: div + abs, test 1",
13052 .insns = {
13053 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13054 BPF_LD_ABS(BPF_B, 3),
13055 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
13056 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
13057 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
13058 BPF_LD_ABS(BPF_B, 4),
13059 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
13060 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
13061 BPF_EXIT_INSN(),
13062 },
13063 .data = {
13064 10, 20, 30, 40, 50,
13065 },
13066 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13067 .result = ACCEPT,
13068 .retval = 10,
13069 },
13070 {
13071 "ld_abs: div + abs, test 2",
13072 .insns = {
13073 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13074 BPF_LD_ABS(BPF_B, 3),
13075 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
13076 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
13077 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
13078 BPF_LD_ABS(BPF_B, 128),
13079 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
13080 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
13081 BPF_EXIT_INSN(),
13082 },
13083 .data = {
13084 10, 20, 30, 40, 50,
13085 },
13086 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13087 .result = ACCEPT,
13088 .retval = 0,
13089 },
13090 {
13091 "ld_abs: div + abs, test 3",
13092 .insns = {
13093 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13094 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
13095 BPF_LD_ABS(BPF_B, 3),
13096 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
13097 BPF_EXIT_INSN(),
13098 },
13099 .data = {
13100 10, 20, 30, 40, 50,
13101 },
13102 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13103 .result = ACCEPT,
13104 .retval = 0,
13105 },
13106 {
13107 "ld_abs: div + abs, test 4",
13108 .insns = {
13109 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13110 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
13111 BPF_LD_ABS(BPF_B, 256),
13112 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
13113 BPF_EXIT_INSN(),
13114 },
13115 .data = {
13116 10, 20, 30, 40, 50,
13117 },
13118 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13119 .result = ACCEPT,
13120 .retval = 0,
13121 },
13122 {
13123 "ld_abs: vlan + abs, test 1",
13124 .insns = { },
13125 .data = {
13126 0x34,
13127 },
13128 .fill_helper = bpf_fill_ld_abs_vlan_push_pop,
13129 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13130 .result = ACCEPT,
13131 .retval = 0xbef,
13132 },
13133 {
13134 "ld_abs: vlan + abs, test 2",
13135 .insns = {
13136 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13137 BPF_LD_ABS(BPF_B, 0),
13138 BPF_LD_ABS(BPF_H, 0),
13139 BPF_LD_ABS(BPF_W, 0),
13140 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
13141 BPF_MOV64_IMM(BPF_REG_6, 0),
13142 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13143 BPF_MOV64_IMM(BPF_REG_2, 1),
13144 BPF_MOV64_IMM(BPF_REG_3, 2),
13145 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13146 BPF_FUNC_skb_vlan_push),
13147 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
13148 BPF_LD_ABS(BPF_B, 0),
13149 BPF_LD_ABS(BPF_H, 0),
13150 BPF_LD_ABS(BPF_W, 0),
13151 BPF_MOV64_IMM(BPF_REG_0, 42),
13152 BPF_EXIT_INSN(),
13153 },
13154 .data = {
13155 0x34,
13156 },
13157 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13158 .result = ACCEPT,
13159 .retval = 42,
13160 },
13161 {
13162 "ld_abs: jump around ld_abs",
13163 .insns = { },
13164 .data = {
13165 10, 11,
13166 },
13167 .fill_helper = bpf_fill_jump_around_ld_abs,
13168 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13169 .result = ACCEPT,
13170 .retval = 10,
13171 },
13172 {
13173 "ld_dw: xor semi-random 64 bit imms, test 1",
13174 .insns = { },
13175 .data = { },
13176 .fill_helper = bpf_fill_rand_ld_dw,
13177 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13178 .result = ACCEPT,
13179 .retval = 4090,
13180 },
13181 {
13182 "ld_dw: xor semi-random 64 bit imms, test 2",
13183 .insns = { },
13184 .data = { },
13185 .fill_helper = bpf_fill_rand_ld_dw,
13186 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13187 .result = ACCEPT,
13188 .retval = 2047,
13189 },
13190 {
13191 "ld_dw: xor semi-random 64 bit imms, test 3",
13192 .insns = { },
13193 .data = { },
13194 .fill_helper = bpf_fill_rand_ld_dw,
13195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13196 .result = ACCEPT,
13197 .retval = 511,
13198 },
13199 {
13200 "ld_dw: xor semi-random 64 bit imms, test 4",
13201 .insns = { },
13202 .data = { },
13203 .fill_helper = bpf_fill_rand_ld_dw,
13204 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13205 .result = ACCEPT,
13206 .retval = 5,
13207 },
13208 {
13209 "pass unmodified ctx pointer to helper",
13210 .insns = {
13211 BPF_MOV64_IMM(BPF_REG_2, 0),
13212 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13213 BPF_FUNC_csum_update),
13214 BPF_MOV64_IMM(BPF_REG_0, 0),
13215 BPF_EXIT_INSN(),
13216 },
13217 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13218 .result = ACCEPT,
13219 },
13220 {
13221 "reference tracking: leak potential reference",
13222 .insns = {
13223 BPF_SK_LOOKUP,
13224 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), /* leak reference */
13225 BPF_EXIT_INSN(),
13226 },
13227 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13228 .errstr = "Unreleased reference",
13229 .result = REJECT,
13230 },
13231 {
13232 "reference tracking: leak potential reference on stack",
13233 .insns = {
13234 BPF_SK_LOOKUP,
13235 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13236 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
13237 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
13238 BPF_MOV64_IMM(BPF_REG_0, 0),
13239 BPF_EXIT_INSN(),
13240 },
13241 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13242 .errstr = "Unreleased reference",
13243 .result = REJECT,
13244 },
13245 {
13246 "reference tracking: leak potential reference on stack 2",
13247 .insns = {
13248 BPF_SK_LOOKUP,
13249 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13250 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
13251 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
13252 BPF_MOV64_IMM(BPF_REG_0, 0),
13253 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
13254 BPF_EXIT_INSN(),
13255 },
13256 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13257 .errstr = "Unreleased reference",
13258 .result = REJECT,
13259 },
13260 {
13261 "reference tracking: zero potential reference",
13262 .insns = {
13263 BPF_SK_LOOKUP,
13264 BPF_MOV64_IMM(BPF_REG_0, 0), /* leak reference */
13265 BPF_EXIT_INSN(),
13266 },
13267 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13268 .errstr = "Unreleased reference",
13269 .result = REJECT,
13270 },
13271 {
13272 "reference tracking: copy and zero potential references",
13273 .insns = {
13274 BPF_SK_LOOKUP,
13275 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
13276 BPF_MOV64_IMM(BPF_REG_0, 0),
13277 BPF_MOV64_IMM(BPF_REG_7, 0), /* leak reference */
13278 BPF_EXIT_INSN(),
13279 },
13280 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13281 .errstr = "Unreleased reference",
13282 .result = REJECT,
13283 },
13284 {
13285 "reference tracking: release reference without check",
13286 .insns = {
13287 BPF_SK_LOOKUP,
13288 /* reference in r0 may be NULL */
13289 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13290 BPF_MOV64_IMM(BPF_REG_2, 0),
13291 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13292 BPF_EXIT_INSN(),
13293 },
13294 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13295 .errstr = "type=sock_or_null expected=sock",
13296 .result = REJECT,
13297 },
13298 {
13299 "reference tracking: release reference",
13300 .insns = {
13301 BPF_SK_LOOKUP,
13302 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13303 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13304 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13305 BPF_EXIT_INSN(),
13306 },
13307 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13308 .result = ACCEPT,
13309 },
13310 {
13311 "reference tracking: release reference 2",
13312 .insns = {
13313 BPF_SK_LOOKUP,
13314 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13315 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
13316 BPF_EXIT_INSN(),
13317 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13318 BPF_EXIT_INSN(),
13319 },
13320 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13321 .result = ACCEPT,
13322 },
13323 {
13324 "reference tracking: release reference twice",
13325 .insns = {
13326 BPF_SK_LOOKUP,
13327 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13328 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13329 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13330 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13331 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13332 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13333 BPF_EXIT_INSN(),
13334 },
13335 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13336 .errstr = "type=inv expected=sock",
13337 .result = REJECT,
13338 },
13339 {
13340 "reference tracking: release reference twice inside branch",
13341 .insns = {
13342 BPF_SK_LOOKUP,
13343 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13344 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13345 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), /* goto end */
13346 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13347 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13348 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13349 BPF_EXIT_INSN(),
13350 },
13351 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13352 .errstr = "type=inv expected=sock",
13353 .result = REJECT,
13354 },
13355 {
13356 "reference tracking: alloc, check, free in one subbranch",
13357 .insns = {
13358 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
13359 offsetof(struct __sk_buff, data)),
13360 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
13361 offsetof(struct __sk_buff, data_end)),
13362 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
13363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
13364 /* if (offsetof(skb, mark) > data_len) exit; */
13365 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
13366 BPF_EXIT_INSN(),
13367 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
13368 offsetof(struct __sk_buff, mark)),
13369 BPF_SK_LOOKUP,
13370 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 1), /* mark == 0? */
13371 /* Leak reference in R0 */
13372 BPF_EXIT_INSN(),
13373 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
13374 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13375 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13376 BPF_EXIT_INSN(),
13377 },
13378 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13379 .errstr = "Unreleased reference",
13380 .result = REJECT,
13381 },
13382 {
13383 "reference tracking: alloc, check, free in both subbranches",
13384 .insns = {
13385 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
13386 offsetof(struct __sk_buff, data)),
13387 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
13388 offsetof(struct __sk_buff, data_end)),
13389 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
13390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
13391 /* if (offsetof(skb, mark) > data_len) exit; */
13392 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
13393 BPF_EXIT_INSN(),
13394 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
13395 offsetof(struct __sk_buff, mark)),
13396 BPF_SK_LOOKUP,
13397 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 4), /* mark == 0? */
13398 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
13399 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13400 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13401 BPF_EXIT_INSN(),
13402 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
13403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13404 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13405 BPF_EXIT_INSN(),
13406 },
13407 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13408 .result = ACCEPT,
13409 },
13410 {
13411 "reference tracking in call: free reference in subprog",
13412 .insns = {
13413 BPF_SK_LOOKUP,
13414 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
13415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
13416 BPF_MOV64_IMM(BPF_REG_0, 0),
13417 BPF_EXIT_INSN(),
13418
13419 /* subprog 1 */
13420 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
13421 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
13422 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13423 BPF_EXIT_INSN(),
13424 },
13425 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13426 .result = ACCEPT,
13427 },
13428 {
13429 "pass modified ctx pointer to helper, 1",
13430 .insns = {
13431 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
13432 BPF_MOV64_IMM(BPF_REG_2, 0),
13433 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13434 BPF_FUNC_csum_update),
13435 BPF_MOV64_IMM(BPF_REG_0, 0),
13436 BPF_EXIT_INSN(),
13437 },
13438 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13439 .result = REJECT,
13440 .errstr = "dereference of modified ctx ptr",
13441 },
13442 {
13443 "pass modified ctx pointer to helper, 2",
13444 .insns = {
13445 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
13446 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13447 BPF_FUNC_get_socket_cookie),
13448 BPF_MOV64_IMM(BPF_REG_0, 0),
13449 BPF_EXIT_INSN(),
13450 },
13451 .result_unpriv = REJECT,
13452 .result = REJECT,
13453 .errstr_unpriv = "dereference of modified ctx ptr",
13454 .errstr = "dereference of modified ctx ptr",
13455 },
13456 {
13457 "pass modified ctx pointer to helper, 3",
13458 .insns = {
13459 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
13460 BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
13461 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
13462 BPF_MOV64_IMM(BPF_REG_2, 0),
13463 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13464 BPF_FUNC_csum_update),
13465 BPF_MOV64_IMM(BPF_REG_0, 0),
13466 BPF_EXIT_INSN(),
13467 },
13468 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13469 .result = REJECT,
13470 .errstr = "variable ctx access var_off=(0x0; 0x4)",
13471 },
13472 {
13473 "mov64 src == dst",
13474 .insns = {
13475 BPF_MOV64_IMM(BPF_REG_2, 0),
13476 BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
13477 // Check bounds are OK
13478 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
13479 BPF_MOV64_IMM(BPF_REG_0, 0),
13480 BPF_EXIT_INSN(),
13481 },
13482 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13483 .result = ACCEPT,
13484 },
13485 {
13486 "mov64 src != dst",
13487 .insns = {
13488 BPF_MOV64_IMM(BPF_REG_3, 0),
13489 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
13490 // Check bounds are OK
13491 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
13492 BPF_MOV64_IMM(BPF_REG_0, 0),
13493 BPF_EXIT_INSN(),
13494 },
13495 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13496 .result = ACCEPT,
13497 },
13498 {
13499 "reference tracking in call: free reference in subprog and outside",
13500 .insns = {
13501 BPF_SK_LOOKUP,
13502 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
13503 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13504 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
13505 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13506 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13507 BPF_EXIT_INSN(),
13508
13509 /* subprog 1 */
13510 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
13511 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
13512 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13513 BPF_EXIT_INSN(),
13514 },
13515 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13516 .errstr = "type=inv expected=sock",
13517 .result = REJECT,
13518 },
13519 {
13520 "reference tracking in call: alloc & leak reference in subprog",
13521 .insns = {
13522 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
13524 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
13525 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13526 BPF_MOV64_IMM(BPF_REG_0, 0),
13527 BPF_EXIT_INSN(),
13528
13529 /* subprog 1 */
13530 BPF_MOV64_REG(BPF_REG_6, BPF_REG_4),
13531 BPF_SK_LOOKUP,
13532 /* spill unchecked sk_ptr into stack of caller */
13533 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
13534 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13535 BPF_EXIT_INSN(),
13536 },
13537 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13538 .errstr = "Unreleased reference",
13539 .result = REJECT,
13540 },
13541 {
13542 "reference tracking in call: alloc in subprog, release outside",
13543 .insns = {
13544 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13545 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
13546 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13547 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13548 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13549 BPF_EXIT_INSN(),
13550
13551 /* subprog 1 */
13552 BPF_SK_LOOKUP,
13553 BPF_EXIT_INSN(), /* return sk */
13554 },
13555 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13556 .retval = POINTER_VALUE,
13557 .result = ACCEPT,
13558 },
13559 {
13560 "reference tracking in call: sk_ptr leak into caller stack",
13561 .insns = {
13562 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13563 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
13564 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
13565 BPF_MOV64_IMM(BPF_REG_0, 0),
13566 BPF_EXIT_INSN(),
13567
13568 /* subprog 1 */
13569 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
13570 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
13571 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
13572 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
13573 /* spill unchecked sk_ptr into stack of caller */
13574 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
13575 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
13576 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
13577 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
13578 BPF_EXIT_INSN(),
13579
13580 /* subprog 2 */
13581 BPF_SK_LOOKUP,
13582 BPF_EXIT_INSN(),
13583 },
13584 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13585 .errstr = "Unreleased reference",
13586 .result = REJECT,
13587 },
13588 {
13589 "reference tracking in call: sk_ptr spill into caller stack",
13590 .insns = {
13591 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
13592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
13593 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
13594 BPF_MOV64_IMM(BPF_REG_0, 0),
13595 BPF_EXIT_INSN(),
13596
13597 /* subprog 1 */
13598 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
13599 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
13600 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
13601 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
13602 /* spill unchecked sk_ptr into stack of caller */
13603 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
13604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
13605 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
13606 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
13607 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
13608 /* now the sk_ptr is verified, free the reference */
13609 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_4, 0),
13610 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13611 BPF_EXIT_INSN(),
13612
13613 /* subprog 2 */
13614 BPF_SK_LOOKUP,
13615 BPF_EXIT_INSN(),
13616 },
13617 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13618 .result = ACCEPT,
13619 },
13620 {
13621 "reference tracking: allow LD_ABS",
13622 .insns = {
13623 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13624 BPF_SK_LOOKUP,
13625 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13626 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13627 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13628 BPF_LD_ABS(BPF_B, 0),
13629 BPF_LD_ABS(BPF_H, 0),
13630 BPF_LD_ABS(BPF_W, 0),
13631 BPF_EXIT_INSN(),
13632 },
13633 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13634 .result = ACCEPT,
13635 },
13636 {
13637 "reference tracking: forbid LD_ABS while holding reference",
13638 .insns = {
13639 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13640 BPF_SK_LOOKUP,
13641 BPF_LD_ABS(BPF_B, 0),
13642 BPF_LD_ABS(BPF_H, 0),
13643 BPF_LD_ABS(BPF_W, 0),
13644 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13645 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13646 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13647 BPF_EXIT_INSN(),
13648 },
13649 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13650 .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
13651 .result = REJECT,
13652 },
13653 {
13654 "reference tracking: allow LD_IND",
13655 .insns = {
13656 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13657 BPF_SK_LOOKUP,
13658 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13660 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13661 BPF_MOV64_IMM(BPF_REG_7, 1),
13662 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
13663 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
13664 BPF_EXIT_INSN(),
13665 },
13666 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13667 .result = ACCEPT,
13668 .retval = 1,
13669 },
13670 {
13671 "reference tracking: forbid LD_IND while holding reference",
13672 .insns = {
13673 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13674 BPF_SK_LOOKUP,
13675 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
13676 BPF_MOV64_IMM(BPF_REG_7, 1),
13677 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
13678 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
13679 BPF_MOV64_REG(BPF_REG_1, BPF_REG_4),
13680 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
13681 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13682 BPF_EXIT_INSN(),
13683 },
13684 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13685 .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
13686 .result = REJECT,
13687 },
13688 {
13689 "reference tracking: check reference or tail call",
13690 .insns = {
13691 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
13692 BPF_SK_LOOKUP,
13693 /* if (sk) bpf_sk_release() */
13694 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13695 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 7),
13696 /* bpf_tail_call() */
13697 BPF_MOV64_IMM(BPF_REG_3, 2),
13698 BPF_LD_MAP_FD(BPF_REG_2, 0),
13699 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13700 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13701 BPF_FUNC_tail_call),
13702 BPF_MOV64_IMM(BPF_REG_0, 0),
13703 BPF_EXIT_INSN(),
13704 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13705 BPF_EXIT_INSN(),
13706 },
13707 .fixup_prog1 = { 17 },
13708 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13709 .result = ACCEPT,
13710 },
13711 {
13712 "reference tracking: release reference then tail call",
13713 .insns = {
13714 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
13715 BPF_SK_LOOKUP,
13716 /* if (sk) bpf_sk_release() */
13717 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13718 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
13719 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13720 /* bpf_tail_call() */
13721 BPF_MOV64_IMM(BPF_REG_3, 2),
13722 BPF_LD_MAP_FD(BPF_REG_2, 0),
13723 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13724 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13725 BPF_FUNC_tail_call),
13726 BPF_MOV64_IMM(BPF_REG_0, 0),
13727 BPF_EXIT_INSN(),
13728 },
13729 .fixup_prog1 = { 18 },
13730 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13731 .result = ACCEPT,
13732 },
13733 {
13734 "reference tracking: leak possible reference over tail call",
13735 .insns = {
13736 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
13737 /* Look up socket and store in REG_6 */
13738 BPF_SK_LOOKUP,
13739 /* bpf_tail_call() */
13740 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13741 BPF_MOV64_IMM(BPF_REG_3, 2),
13742 BPF_LD_MAP_FD(BPF_REG_2, 0),
13743 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13744 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13745 BPF_FUNC_tail_call),
13746 BPF_MOV64_IMM(BPF_REG_0, 0),
13747 /* if (sk) bpf_sk_release() */
13748 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13749 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
13750 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13751 BPF_EXIT_INSN(),
13752 },
13753 .fixup_prog1 = { 16 },
13754 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13755 .errstr = "tail_call would lead to reference leak",
13756 .result = REJECT,
13757 },
13758 {
13759 "reference tracking: leak checked reference over tail call",
13760 .insns = {
13761 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
13762 /* Look up socket and store in REG_6 */
13763 BPF_SK_LOOKUP,
13764 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13765 /* if (!sk) goto end */
13766 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
13767 /* bpf_tail_call() */
13768 BPF_MOV64_IMM(BPF_REG_3, 0),
13769 BPF_LD_MAP_FD(BPF_REG_2, 0),
13770 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13771 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13772 BPF_FUNC_tail_call),
13773 BPF_MOV64_IMM(BPF_REG_0, 0),
13774 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13775 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13776 BPF_EXIT_INSN(),
13777 },
13778 .fixup_prog1 = { 17 },
13779 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13780 .errstr = "tail_call would lead to reference leak",
13781 .result = REJECT,
13782 },
13783 {
13784 "reference tracking: mangle and release sock_or_null",
13785 .insns = {
13786 BPF_SK_LOOKUP,
13787 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
13789 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
13790 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13791 BPF_EXIT_INSN(),
13792 },
13793 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13794 .errstr = "R1 pointer arithmetic on sock_or_null prohibited",
13795 .result = REJECT,
13796 },
13797 {
13798 "reference tracking: mangle and release sock",
13799 .insns = {
13800 BPF_SK_LOOKUP,
13801 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13802 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
13803 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
13804 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13805 BPF_EXIT_INSN(),
13806 },
13807 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13808 .errstr = "R1 pointer arithmetic on sock prohibited",
13809 .result = REJECT,
13810 },
13811 {
13812 "reference tracking: access member",
13813 .insns = {
13814 BPF_SK_LOOKUP,
13815 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13816 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
13817 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
13818 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13819 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13820 BPF_EXIT_INSN(),
13821 },
13822 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13823 .result = ACCEPT,
13824 },
13825 {
13826 "reference tracking: write to member",
13827 .insns = {
13828 BPF_SK_LOOKUP,
13829 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13830 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
13831 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13832 BPF_LD_IMM64(BPF_REG_2, 42),
13833 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_2,
13834 offsetof(struct bpf_sock, mark)),
13835 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13836 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13837 BPF_LD_IMM64(BPF_REG_0, 0),
13838 BPF_EXIT_INSN(),
13839 },
13840 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13841 .errstr = "cannot write into socket",
13842 .result = REJECT,
13843 },
13844 {
13845 "reference tracking: invalid 64-bit access of member",
13846 .insns = {
13847 BPF_SK_LOOKUP,
13848 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13849 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
13850 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
13851 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13852 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13853 BPF_EXIT_INSN(),
13854 },
13855 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13856 .errstr = "invalid bpf_sock access off=0 size=8",
13857 .result = REJECT,
13858 },
13859 {
13860 "reference tracking: access after release",
13861 .insns = {
13862 BPF_SK_LOOKUP,
13863 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13864 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
13865 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13866 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
13867 BPF_EXIT_INSN(),
13868 },
13869 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13870 .errstr = "!read_ok",
13871 .result = REJECT,
13872 },
13873 {
13874 "reference tracking: direct access for lookup",
13875 .insns = {
13876 /* Check that the packet is at least 64B long */
13877 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
13878 offsetof(struct __sk_buff, data)),
13879 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
13880 offsetof(struct __sk_buff, data_end)),
13881 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
13882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
13883 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
13884 /* sk = sk_lookup_tcp(ctx, skb->data, ...) */
13885 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct bpf_sock_tuple)),
13886 BPF_MOV64_IMM(BPF_REG_4, 0),
13887 BPF_MOV64_IMM(BPF_REG_5, 0),
13888 BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
13889 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13890 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
13891 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
13892 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13893 BPF_EMIT_CALL(BPF_FUNC_sk_release),
13894 BPF_EXIT_INSN(),
13895 },
13896 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
13897 .result = ACCEPT,
13898 },
13899 {
13900 "calls: ctx read at start of subprog",
13901 .insns = {
13902 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
13903 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
13904 BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
13905 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
13906 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
13907 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13908 BPF_EXIT_INSN(),
13909 BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
13910 BPF_MOV64_IMM(BPF_REG_0, 0),
13911 BPF_EXIT_INSN(),
13912 },
13913 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
13914 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
13915 .result_unpriv = REJECT,
13916 .result = ACCEPT,
13917 },
13918 };
13919
13920 static int probe_filter_length(const struct bpf_insn *fp)
13921 {
13922 int len;
13923
13924 for (len = MAX_INSNS - 1; len > 0; --len)
13925 if (fp[len].code != 0 || fp[len].imm != 0)
13926 break;
13927 return len + 1;
13928 }
13929
13930 static int create_map(uint32_t type, uint32_t size_key,
13931 uint32_t size_value, uint32_t max_elem)
13932 {
13933 int fd;
13934
13935 fd = bpf_create_map(type, size_key, size_value, max_elem,
13936 type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0);
13937 if (fd < 0)
13938 printf("Failed to create hash map '%s'!\n", strerror(errno));
13939
13940 return fd;
13941 }
13942
13943 static int create_prog_dummy1(enum bpf_map_type prog_type)
13944 {
13945 struct bpf_insn prog[] = {
13946 BPF_MOV64_IMM(BPF_REG_0, 42),
13947 BPF_EXIT_INSN(),
13948 };
13949
13950 return bpf_load_program(prog_type, prog,
13951 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
13952 }
13953
13954 static int create_prog_dummy2(enum bpf_map_type prog_type, int mfd, int idx)
13955 {
13956 struct bpf_insn prog[] = {
13957 BPF_MOV64_IMM(BPF_REG_3, idx),
13958 BPF_LD_MAP_FD(BPF_REG_2, mfd),
13959 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13960 BPF_FUNC_tail_call),
13961 BPF_MOV64_IMM(BPF_REG_0, 41),
13962 BPF_EXIT_INSN(),
13963 };
13964
13965 return bpf_load_program(prog_type, prog,
13966 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
13967 }
13968
13969 static int create_prog_array(enum bpf_map_type prog_type, uint32_t max_elem,
13970 int p1key)
13971 {
13972 int p2key = 1;
13973 int mfd, p1fd, p2fd;
13974
13975 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
13976 sizeof(int), max_elem, 0);
13977 if (mfd < 0) {
13978 printf("Failed to create prog array '%s'!\n", strerror(errno));
13979 return -1;
13980 }
13981
13982 p1fd = create_prog_dummy1(prog_type);
13983 p2fd = create_prog_dummy2(prog_type, mfd, p2key);
13984 if (p1fd < 0 || p2fd < 0)
13985 goto out;
13986 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
13987 goto out;
13988 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
13989 goto out;
13990 close(p2fd);
13991 close(p1fd);
13992
13993 return mfd;
13994 out:
13995 close(p2fd);
13996 close(p1fd);
13997 close(mfd);
13998 return -1;
13999 }
14000
14001 static int create_map_in_map(void)
14002 {
14003 int inner_map_fd, outer_map_fd;
14004
14005 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
14006 sizeof(int), 1, 0);
14007 if (inner_map_fd < 0) {
14008 printf("Failed to create array '%s'!\n", strerror(errno));
14009 return inner_map_fd;
14010 }
14011
14012 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
14013 sizeof(int), inner_map_fd, 1, 0);
14014 if (outer_map_fd < 0)
14015 printf("Failed to create array of maps '%s'!\n",
14016 strerror(errno));
14017
14018 close(inner_map_fd);
14019
14020 return outer_map_fd;
14021 }
14022
14023 static int create_cgroup_storage(bool percpu)
14024 {
14025 enum bpf_map_type type = percpu ? BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE :
14026 BPF_MAP_TYPE_CGROUP_STORAGE;
14027 int fd;
14028
14029 fd = bpf_create_map(type, sizeof(struct bpf_cgroup_storage_key),
14030 TEST_DATA_LEN, 0, 0);
14031 if (fd < 0)
14032 printf("Failed to create cgroup storage '%s'!\n",
14033 strerror(errno));
14034
14035 return fd;
14036 }
14037
14038 static char bpf_vlog[UINT_MAX >> 8];
14039
14040 static void do_test_fixup(struct bpf_test *test, enum bpf_map_type prog_type,
14041 struct bpf_insn *prog, int *map_fds)
14042 {
14043 int *fixup_map_hash_8b = test->fixup_map_hash_8b;
14044 int *fixup_map_hash_48b = test->fixup_map_hash_48b;
14045 int *fixup_map_hash_16b = test->fixup_map_hash_16b;
14046 int *fixup_map_array_48b = test->fixup_map_array_48b;
14047 int *fixup_map_sockmap = test->fixup_map_sockmap;
14048 int *fixup_map_sockhash = test->fixup_map_sockhash;
14049 int *fixup_map_xskmap = test->fixup_map_xskmap;
14050 int *fixup_map_stacktrace = test->fixup_map_stacktrace;
14051 int *fixup_prog1 = test->fixup_prog1;
14052 int *fixup_prog2 = test->fixup_prog2;
14053 int *fixup_map_in_map = test->fixup_map_in_map;
14054 int *fixup_cgroup_storage = test->fixup_cgroup_storage;
14055 int *fixup_percpu_cgroup_storage = test->fixup_percpu_cgroup_storage;
14056
14057 if (test->fill_helper)
14058 test->fill_helper(test);
14059
14060 /* Allocating HTs with 1 elem is fine here, since we only test
14061 * for verifier and not do a runtime lookup, so the only thing
14062 * that really matters is value size in this case.
14063 */
14064 if (*fixup_map_hash_8b) {
14065 map_fds[0] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
14066 sizeof(long long), 1);
14067 do {
14068 prog[*fixup_map_hash_8b].imm = map_fds[0];
14069 fixup_map_hash_8b++;
14070 } while (*fixup_map_hash_8b);
14071 }
14072
14073 if (*fixup_map_hash_48b) {
14074 map_fds[1] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
14075 sizeof(struct test_val), 1);
14076 do {
14077 prog[*fixup_map_hash_48b].imm = map_fds[1];
14078 fixup_map_hash_48b++;
14079 } while (*fixup_map_hash_48b);
14080 }
14081
14082 if (*fixup_map_hash_16b) {
14083 map_fds[2] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
14084 sizeof(struct other_val), 1);
14085 do {
14086 prog[*fixup_map_hash_16b].imm = map_fds[2];
14087 fixup_map_hash_16b++;
14088 } while (*fixup_map_hash_16b);
14089 }
14090
14091 if (*fixup_map_array_48b) {
14092 map_fds[3] = create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
14093 sizeof(struct test_val), 1);
14094 do {
14095 prog[*fixup_map_array_48b].imm = map_fds[3];
14096 fixup_map_array_48b++;
14097 } while (*fixup_map_array_48b);
14098 }
14099
14100 if (*fixup_prog1) {
14101 map_fds[4] = create_prog_array(prog_type, 4, 0);
14102 do {
14103 prog[*fixup_prog1].imm = map_fds[4];
14104 fixup_prog1++;
14105 } while (*fixup_prog1);
14106 }
14107
14108 if (*fixup_prog2) {
14109 map_fds[5] = create_prog_array(prog_type, 8, 7);
14110 do {
14111 prog[*fixup_prog2].imm = map_fds[5];
14112 fixup_prog2++;
14113 } while (*fixup_prog2);
14114 }
14115
14116 if (*fixup_map_in_map) {
14117 map_fds[6] = create_map_in_map();
14118 do {
14119 prog[*fixup_map_in_map].imm = map_fds[6];
14120 fixup_map_in_map++;
14121 } while (*fixup_map_in_map);
14122 }
14123
14124 if (*fixup_cgroup_storage) {
14125 map_fds[7] = create_cgroup_storage(false);
14126 do {
14127 prog[*fixup_cgroup_storage].imm = map_fds[7];
14128 fixup_cgroup_storage++;
14129 } while (*fixup_cgroup_storage);
14130 }
14131
14132 if (*fixup_percpu_cgroup_storage) {
14133 map_fds[8] = create_cgroup_storage(true);
14134 do {
14135 prog[*fixup_percpu_cgroup_storage].imm = map_fds[8];
14136 fixup_percpu_cgroup_storage++;
14137 } while (*fixup_percpu_cgroup_storage);
14138 }
14139 if (*fixup_map_sockmap) {
14140 map_fds[9] = create_map(BPF_MAP_TYPE_SOCKMAP, sizeof(int),
14141 sizeof(int), 1);
14142 do {
14143 prog[*fixup_map_sockmap].imm = map_fds[9];
14144 fixup_map_sockmap++;
14145 } while (*fixup_map_sockmap);
14146 }
14147 if (*fixup_map_sockhash) {
14148 map_fds[10] = create_map(BPF_MAP_TYPE_SOCKHASH, sizeof(int),
14149 sizeof(int), 1);
14150 do {
14151 prog[*fixup_map_sockhash].imm = map_fds[10];
14152 fixup_map_sockhash++;
14153 } while (*fixup_map_sockhash);
14154 }
14155 if (*fixup_map_xskmap) {
14156 map_fds[11] = create_map(BPF_MAP_TYPE_XSKMAP, sizeof(int),
14157 sizeof(int), 1);
14158 do {
14159 prog[*fixup_map_xskmap].imm = map_fds[11];
14160 fixup_map_xskmap++;
14161 } while (*fixup_map_xskmap);
14162 }
14163 if (*fixup_map_stacktrace) {
14164 map_fds[12] = create_map(BPF_MAP_TYPE_STACK_TRACE, sizeof(u32),
14165 sizeof(u64), 1);
14166 do {
14167 prog[*fixup_map_stacktrace].imm = map_fds[12];
14168 fixup_map_stacktrace++;
14169 } while (fixup_map_stacktrace);
14170 }
14171 }
14172
14173 static int set_admin(bool admin)
14174 {
14175 cap_t caps;
14176 const cap_value_t cap_val = CAP_SYS_ADMIN;
14177 int ret = -1;
14178
14179 caps = cap_get_proc();
14180 if (!caps) {
14181 perror("cap_get_proc");
14182 return -1;
14183 }
14184 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
14185 admin ? CAP_SET : CAP_CLEAR)) {
14186 perror("cap_set_flag");
14187 goto out;
14188 }
14189 if (cap_set_proc(caps)) {
14190 perror("cap_set_proc");
14191 goto out;
14192 }
14193 ret = 0;
14194 out:
14195 if (cap_free(caps))
14196 perror("cap_free");
14197 return ret;
14198 }
14199
14200 static void do_test_single(struct bpf_test *test, bool unpriv,
14201 int *passes, int *errors)
14202 {
14203 int fd_prog, expected_ret, reject_from_alignment;
14204 int prog_len, prog_type = test->prog_type;
14205 struct bpf_insn *prog = test->insns;
14206 int map_fds[MAX_NR_MAPS];
14207 const char *expected_err;
14208 uint32_t expected_val;
14209 uint32_t retval;
14210 int i, err;
14211
14212 for (i = 0; i < MAX_NR_MAPS; i++)
14213 map_fds[i] = -1;
14214
14215 if (!prog_type)
14216 prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
14217 do_test_fixup(test, prog_type, prog, map_fds);
14218 prog_len = probe_filter_length(prog);
14219
14220 fd_prog = bpf_verify_program(prog_type, prog, prog_len,
14221 test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
14222 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
14223
14224 expected_ret = unpriv && test->result_unpriv != UNDEF ?
14225 test->result_unpriv : test->result;
14226 expected_err = unpriv && test->errstr_unpriv ?
14227 test->errstr_unpriv : test->errstr;
14228 expected_val = unpriv && test->retval_unpriv ?
14229 test->retval_unpriv : test->retval;
14230
14231 reject_from_alignment = fd_prog < 0 &&
14232 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
14233 strstr(bpf_vlog, "Unknown alignment.");
14234 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
14235 if (reject_from_alignment) {
14236 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
14237 strerror(errno));
14238 goto fail_log;
14239 }
14240 #endif
14241 if (expected_ret == ACCEPT) {
14242 if (fd_prog < 0 && !reject_from_alignment) {
14243 printf("FAIL\nFailed to load prog '%s'!\n",
14244 strerror(errno));
14245 goto fail_log;
14246 }
14247 } else {
14248 if (fd_prog >= 0) {
14249 printf("FAIL\nUnexpected success to load!\n");
14250 goto fail_log;
14251 }
14252 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
14253 printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
14254 expected_err, bpf_vlog);
14255 goto fail_log;
14256 }
14257 }
14258
14259 if (fd_prog >= 0) {
14260 __u8 tmp[TEST_DATA_LEN << 2];
14261 __u32 size_tmp = sizeof(tmp);
14262
14263 if (unpriv)
14264 set_admin(true);
14265 err = bpf_prog_test_run(fd_prog, 1, test->data,
14266 sizeof(test->data), tmp, &size_tmp,
14267 &retval, NULL);
14268 if (unpriv)
14269 set_admin(false);
14270 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
14271 printf("Unexpected bpf_prog_test_run error\n");
14272 goto fail_log;
14273 }
14274 if (!err && retval != expected_val &&
14275 expected_val != POINTER_VALUE) {
14276 printf("FAIL retval %d != %d\n", retval, expected_val);
14277 goto fail_log;
14278 }
14279 }
14280 (*passes)++;
14281 printf("OK%s\n", reject_from_alignment ?
14282 " (NOTE: reject due to unknown alignment)" : "");
14283 close_fds:
14284 close(fd_prog);
14285 for (i = 0; i < MAX_NR_MAPS; i++)
14286 close(map_fds[i]);
14287 sched_yield();
14288 return;
14289 fail_log:
14290 (*errors)++;
14291 printf("%s", bpf_vlog);
14292 goto close_fds;
14293 }
14294
14295 static bool is_admin(void)
14296 {
14297 cap_t caps;
14298 cap_flag_value_t sysadmin = CAP_CLEAR;
14299 const cap_value_t cap_val = CAP_SYS_ADMIN;
14300
14301 #ifdef CAP_IS_SUPPORTED
14302 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
14303 perror("cap_get_flag");
14304 return false;
14305 }
14306 #endif
14307 caps = cap_get_proc();
14308 if (!caps) {
14309 perror("cap_get_proc");
14310 return false;
14311 }
14312 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
14313 perror("cap_get_flag");
14314 if (cap_free(caps))
14315 perror("cap_free");
14316 return (sysadmin == CAP_SET);
14317 }
14318
14319 static void get_unpriv_disabled()
14320 {
14321 char buf[2];
14322 FILE *fd;
14323
14324 fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
14325 if (!fd) {
14326 perror("fopen /proc/sys/"UNPRIV_SYSCTL);
14327 unpriv_disabled = true;
14328 return;
14329 }
14330 if (fgets(buf, 2, fd) == buf && atoi(buf))
14331 unpriv_disabled = true;
14332 fclose(fd);
14333 }
14334
14335 static bool test_as_unpriv(struct bpf_test *test)
14336 {
14337 return !test->prog_type ||
14338 test->prog_type == BPF_PROG_TYPE_SOCKET_FILTER ||
14339 test->prog_type == BPF_PROG_TYPE_CGROUP_SKB;
14340 }
14341
14342 static int do_test(bool unpriv, unsigned int from, unsigned int to)
14343 {
14344 int i, passes = 0, errors = 0, skips = 0;
14345
14346 for (i = from; i < to; i++) {
14347 struct bpf_test *test = &tests[i];
14348
14349 /* Program types that are not supported by non-root we
14350 * skip right away.
14351 */
14352 if (test_as_unpriv(test) && unpriv_disabled) {
14353 printf("#%d/u %s SKIP\n", i, test->descr);
14354 skips++;
14355 } else if (test_as_unpriv(test)) {
14356 if (!unpriv)
14357 set_admin(false);
14358 printf("#%d/u %s ", i, test->descr);
14359 do_test_single(test, true, &passes, &errors);
14360 if (!unpriv)
14361 set_admin(true);
14362 }
14363
14364 if (unpriv) {
14365 printf("#%d/p %s SKIP\n", i, test->descr);
14366 skips++;
14367 } else {
14368 printf("#%d/p %s ", i, test->descr);
14369 do_test_single(test, false, &passes, &errors);
14370 }
14371 }
14372
14373 printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
14374 skips, errors);
14375 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
14376 }
14377
14378 int main(int argc, char **argv)
14379 {
14380 unsigned int from = 0, to = ARRAY_SIZE(tests);
14381 bool unpriv = !is_admin();
14382
14383 if (argc == 3) {
14384 unsigned int l = atoi(argv[argc - 2]);
14385 unsigned int u = atoi(argv[argc - 1]);
14386
14387 if (l < to && u < to) {
14388 from = l;
14389 to = u + 1;
14390 }
14391 } else if (argc == 2) {
14392 unsigned int t = atoi(argv[argc - 1]);
14393
14394 if (t < to) {
14395 from = t;
14396 to = t + 1;
14397 }
14398 }
14399
14400 get_unpriv_disabled();
14401 if (unpriv && unpriv_disabled) {
14402 printf("Cannot run as unprivileged user with sysctl %s.\n",
14403 UNPRIV_SYSCTL);
14404 return EXIT_FAILURE;
14405 }
14406
14407 bpf_semi_rand_init();
14408 return do_test(unpriv, from, to);
14409 }