aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/bpf/test_verifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/bpf/test_verifier.c')
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c2348
1 files changed, 2337 insertions, 11 deletions
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 5ed4175c4ff8..c0f16e93f9bd 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -2,6 +2,7 @@
2 * Testsuite for eBPF verifier 2 * Testsuite for eBPF verifier
3 * 3 *
4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com 4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5 * Copyright (c) 2017 Facebook
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 8 * modify it under the terms of version 2 of the GNU General Public
@@ -20,6 +21,7 @@
20#include <stddef.h> 21#include <stddef.h>
21#include <stdbool.h> 22#include <stdbool.h>
22#include <sched.h> 23#include <sched.h>
24#include <limits.h>
23 25
24#include <sys/capability.h> 26#include <sys/capability.h>
25#include <sys/resource.h> 27#include <sys/resource.h>
@@ -28,6 +30,7 @@
28#include <linux/filter.h> 30#include <linux/filter.h>
29#include <linux/bpf_perf_event.h> 31#include <linux/bpf_perf_event.h>
30#include <linux/bpf.h> 32#include <linux/bpf.h>
33#include <linux/if_ether.h>
31 34
32#include <bpf/bpf.h> 35#include <bpf/bpf.h>
33 36
@@ -48,6 +51,8 @@
48#define MAX_INSNS 512 51#define MAX_INSNS 512
49#define MAX_FIXUPS 8 52#define MAX_FIXUPS 8
50#define MAX_NR_MAPS 4 53#define MAX_NR_MAPS 4
54#define POINTER_VALUE 0xcafe4all
55#define TEST_DATA_LEN 64
51 56
52#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) 57#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
53#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1) 58#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
@@ -61,6 +66,7 @@ struct bpf_test {
61 int fixup_map_in_map[MAX_FIXUPS]; 66 int fixup_map_in_map[MAX_FIXUPS];
62 const char *errstr; 67 const char *errstr;
63 const char *errstr_unpriv; 68 const char *errstr_unpriv;
69 uint32_t retval;
64 enum { 70 enum {
65 UNDEF, 71 UNDEF,
66 ACCEPT, 72 ACCEPT,
@@ -94,6 +100,326 @@ static struct bpf_test tests[] = {
94 BPF_EXIT_INSN(), 100 BPF_EXIT_INSN(),
95 }, 101 },
96 .result = ACCEPT, 102 .result = ACCEPT,
103 .retval = -3,
104 },
105 {
106 "DIV32 by 0, zero check 1",
107 .insns = {
108 BPF_MOV32_IMM(BPF_REG_0, 42),
109 BPF_MOV32_IMM(BPF_REG_1, 0),
110 BPF_MOV32_IMM(BPF_REG_2, 1),
111 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
112 BPF_EXIT_INSN(),
113 },
114 .result = ACCEPT,
115 .retval = 42,
116 },
117 {
118 "DIV32 by 0, zero check 2",
119 .insns = {
120 BPF_MOV32_IMM(BPF_REG_0, 42),
121 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
122 BPF_MOV32_IMM(BPF_REG_2, 1),
123 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
124 BPF_EXIT_INSN(),
125 },
126 .result = ACCEPT,
127 .retval = 42,
128 },
129 {
130 "DIV64 by 0, zero check",
131 .insns = {
132 BPF_MOV32_IMM(BPF_REG_0, 42),
133 BPF_MOV32_IMM(BPF_REG_1, 0),
134 BPF_MOV32_IMM(BPF_REG_2, 1),
135 BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
136 BPF_EXIT_INSN(),
137 },
138 .result = ACCEPT,
139 .retval = 42,
140 },
141 {
142 "MOD32 by 0, zero check 1",
143 .insns = {
144 BPF_MOV32_IMM(BPF_REG_0, 42),
145 BPF_MOV32_IMM(BPF_REG_1, 0),
146 BPF_MOV32_IMM(BPF_REG_2, 1),
147 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
148 BPF_EXIT_INSN(),
149 },
150 .result = ACCEPT,
151 .retval = 42,
152 },
153 {
154 "MOD32 by 0, zero check 2",
155 .insns = {
156 BPF_MOV32_IMM(BPF_REG_0, 42),
157 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
158 BPF_MOV32_IMM(BPF_REG_2, 1),
159 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
160 BPF_EXIT_INSN(),
161 },
162 .result = ACCEPT,
163 .retval = 42,
164 },
165 {
166 "MOD64 by 0, zero check",
167 .insns = {
168 BPF_MOV32_IMM(BPF_REG_0, 42),
169 BPF_MOV32_IMM(BPF_REG_1, 0),
170 BPF_MOV32_IMM(BPF_REG_2, 1),
171 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
172 BPF_EXIT_INSN(),
173 },
174 .result = ACCEPT,
175 .retval = 42,
176 },
177 {
178 "DIV32 by 0, zero check ok, cls",
179 .insns = {
180 BPF_MOV32_IMM(BPF_REG_0, 42),
181 BPF_MOV32_IMM(BPF_REG_1, 2),
182 BPF_MOV32_IMM(BPF_REG_2, 16),
183 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
184 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
185 BPF_EXIT_INSN(),
186 },
187 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
188 .result = ACCEPT,
189 .retval = 8,
190 },
191 {
192 "DIV32 by 0, zero check 1, cls",
193 .insns = {
194 BPF_MOV32_IMM(BPF_REG_1, 0),
195 BPF_MOV32_IMM(BPF_REG_0, 1),
196 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
197 BPF_EXIT_INSN(),
198 },
199 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
200 .result = ACCEPT,
201 .retval = 0,
202 },
203 {
204 "DIV32 by 0, zero check 2, cls",
205 .insns = {
206 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
207 BPF_MOV32_IMM(BPF_REG_0, 1),
208 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
209 BPF_EXIT_INSN(),
210 },
211 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
212 .result = ACCEPT,
213 .retval = 0,
214 },
215 {
216 "DIV64 by 0, zero check, cls",
217 .insns = {
218 BPF_MOV32_IMM(BPF_REG_1, 0),
219 BPF_MOV32_IMM(BPF_REG_0, 1),
220 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
221 BPF_EXIT_INSN(),
222 },
223 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
224 .result = ACCEPT,
225 .retval = 0,
226 },
227 {
228 "MOD32 by 0, zero check ok, cls",
229 .insns = {
230 BPF_MOV32_IMM(BPF_REG_0, 42),
231 BPF_MOV32_IMM(BPF_REG_1, 3),
232 BPF_MOV32_IMM(BPF_REG_2, 5),
233 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
234 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
235 BPF_EXIT_INSN(),
236 },
237 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
238 .result = ACCEPT,
239 .retval = 2,
240 },
241 {
242 "MOD32 by 0, zero check 1, cls",
243 .insns = {
244 BPF_MOV32_IMM(BPF_REG_1, 0),
245 BPF_MOV32_IMM(BPF_REG_0, 1),
246 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
247 BPF_EXIT_INSN(),
248 },
249 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
250 .result = ACCEPT,
251 .retval = 1,
252 },
253 {
254 "MOD32 by 0, zero check 2, cls",
255 .insns = {
256 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
257 BPF_MOV32_IMM(BPF_REG_0, 1),
258 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
259 BPF_EXIT_INSN(),
260 },
261 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
262 .result = ACCEPT,
263 .retval = 1,
264 },
265 {
266 "MOD64 by 0, zero check 1, cls",
267 .insns = {
268 BPF_MOV32_IMM(BPF_REG_1, 0),
269 BPF_MOV32_IMM(BPF_REG_0, 2),
270 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
271 BPF_EXIT_INSN(),
272 },
273 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
274 .result = ACCEPT,
275 .retval = 2,
276 },
277 {
278 "MOD64 by 0, zero check 2, cls",
279 .insns = {
280 BPF_MOV32_IMM(BPF_REG_1, 0),
281 BPF_MOV32_IMM(BPF_REG_0, -1),
282 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
283 BPF_EXIT_INSN(),
284 },
285 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
286 .result = ACCEPT,
287 .retval = -1,
288 },
289 /* Just make sure that JITs used udiv/umod as otherwise we get
290 * an exception from INT_MIN/-1 overflow similarly as with div
291 * by zero.
292 */
293 {
294 "DIV32 overflow, check 1",
295 .insns = {
296 BPF_MOV32_IMM(BPF_REG_1, -1),
297 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
298 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
299 BPF_EXIT_INSN(),
300 },
301 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
302 .result = ACCEPT,
303 .retval = 0,
304 },
305 {
306 "DIV32 overflow, check 2",
307 .insns = {
308 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
309 BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
310 BPF_EXIT_INSN(),
311 },
312 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
313 .result = ACCEPT,
314 .retval = 0,
315 },
316 {
317 "DIV64 overflow, check 1",
318 .insns = {
319 BPF_MOV64_IMM(BPF_REG_1, -1),
320 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
321 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
322 BPF_EXIT_INSN(),
323 },
324 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
325 .result = ACCEPT,
326 .retval = 0,
327 },
328 {
329 "DIV64 overflow, check 2",
330 .insns = {
331 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
332 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
333 BPF_EXIT_INSN(),
334 },
335 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
336 .result = ACCEPT,
337 .retval = 0,
338 },
339 {
340 "MOD32 overflow, check 1",
341 .insns = {
342 BPF_MOV32_IMM(BPF_REG_1, -1),
343 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
344 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
345 BPF_EXIT_INSN(),
346 },
347 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
348 .result = ACCEPT,
349 .retval = INT_MIN,
350 },
351 {
352 "MOD32 overflow, check 2",
353 .insns = {
354 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
355 BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
356 BPF_EXIT_INSN(),
357 },
358 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
359 .result = ACCEPT,
360 .retval = INT_MIN,
361 },
362 {
363 "MOD64 overflow, check 1",
364 .insns = {
365 BPF_MOV64_IMM(BPF_REG_1, -1),
366 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
367 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
368 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
369 BPF_MOV32_IMM(BPF_REG_0, 0),
370 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
371 BPF_MOV32_IMM(BPF_REG_0, 1),
372 BPF_EXIT_INSN(),
373 },
374 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
375 .result = ACCEPT,
376 .retval = 1,
377 },
378 {
379 "MOD64 overflow, check 2",
380 .insns = {
381 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
382 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
383 BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
384 BPF_MOV32_IMM(BPF_REG_0, 0),
385 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
386 BPF_MOV32_IMM(BPF_REG_0, 1),
387 BPF_EXIT_INSN(),
388 },
389 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
390 .result = ACCEPT,
391 .retval = 1,
392 },
393 {
394 "xor32 zero extend check",
395 .insns = {
396 BPF_MOV32_IMM(BPF_REG_2, -1),
397 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
398 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
399 BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
400 BPF_MOV32_IMM(BPF_REG_0, 2),
401 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
402 BPF_MOV32_IMM(BPF_REG_0, 1),
403 BPF_EXIT_INSN(),
404 },
405 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
406 .result = ACCEPT,
407 .retval = 1,
408 },
409 {
410 "empty prog",
411 .insns = {
412 },
413 .errstr = "unknown opcode 00",
414 .result = REJECT,
415 },
416 {
417 "only exit insn",
418 .insns = {
419 BPF_EXIT_INSN(),
420 },
421 .errstr = "R0 !read_ok",
422 .result = REJECT,
97 }, 423 },
98 { 424 {
99 "unreachable", 425 "unreachable",
@@ -209,6 +535,7 @@ static struct bpf_test tests[] = {
209 BPF_EXIT_INSN(), 535 BPF_EXIT_INSN(),
210 }, 536 },
211 .result = ACCEPT, 537 .result = ACCEPT,
538 .retval = 1,
212 }, 539 },
213 { 540 {
214 "test8 ld_imm64", 541 "test8 ld_imm64",
@@ -280,7 +607,7 @@ static struct bpf_test tests[] = {
280 BPF_EXIT_INSN(), 607 BPF_EXIT_INSN(),
281 }, 608 },
282 .result = REJECT, 609 .result = REJECT,
283 .errstr = "BPF_ARSH not supported for 32 bit ALU", 610 .errstr = "unknown opcode c4",
284 }, 611 },
285 { 612 {
286 "arsh32 on reg", 613 "arsh32 on reg",
@@ -291,7 +618,7 @@ static struct bpf_test tests[] = {
291 BPF_EXIT_INSN(), 618 BPF_EXIT_INSN(),
292 }, 619 },
293 .result = REJECT, 620 .result = REJECT,
294 .errstr = "BPF_ARSH not supported for 32 bit ALU", 621 .errstr = "unknown opcode cc",
295 }, 622 },
296 { 623 {
297 "arsh64 on imm", 624 "arsh64 on imm",
@@ -317,7 +644,7 @@ static struct bpf_test tests[] = {
317 .insns = { 644 .insns = {
318 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2), 645 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
319 }, 646 },
320 .errstr = "jump out of range", 647 .errstr = "not an exit",
321 .result = REJECT, 648 .result = REJECT,
322 }, 649 },
323 { 650 {
@@ -407,7 +734,7 @@ static struct bpf_test tests[] = {
407 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0), 734 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
408 BPF_EXIT_INSN(), 735 BPF_EXIT_INSN(),
409 }, 736 },
410 .errstr = "BPF_CALL uses reserved", 737 .errstr = "unknown opcode 8d",
411 .result = REJECT, 738 .result = REJECT,
412 }, 739 },
413 { 740 {
@@ -516,6 +843,7 @@ static struct bpf_test tests[] = {
516 .errstr_unpriv = "R0 leaks addr", 843 .errstr_unpriv = "R0 leaks addr",
517 .result = ACCEPT, 844 .result = ACCEPT,
518 .result_unpriv = REJECT, 845 .result_unpriv = REJECT,
846 .retval = POINTER_VALUE,
519 }, 847 },
520 { 848 {
521 "check valid spill/fill, skb mark", 849 "check valid spill/fill, skb mark",
@@ -596,7 +924,7 @@ static struct bpf_test tests[] = {
596 BPF_RAW_INSN(0, 0, 0, 0, 0), 924 BPF_RAW_INSN(0, 0, 0, 0, 0),
597 BPF_EXIT_INSN(), 925 BPF_EXIT_INSN(),
598 }, 926 },
599 .errstr = "invalid BPF_LD_IMM", 927 .errstr = "unknown opcode 00",
600 .result = REJECT, 928 .result = REJECT,
601 }, 929 },
602 { 930 {
@@ -614,7 +942,7 @@ static struct bpf_test tests[] = {
614 BPF_RAW_INSN(-1, 0, 0, 0, 0), 942 BPF_RAW_INSN(-1, 0, 0, 0, 0),
615 BPF_EXIT_INSN(), 943 BPF_EXIT_INSN(),
616 }, 944 },
617 .errstr = "invalid BPF_ALU opcode f0", 945 .errstr = "unknown opcode ff",
618 .result = REJECT, 946 .result = REJECT,
619 }, 947 },
620 { 948 {
@@ -623,7 +951,7 @@ static struct bpf_test tests[] = {
623 BPF_RAW_INSN(-1, -1, -1, -1, -1), 951 BPF_RAW_INSN(-1, -1, -1, -1, -1),
624 BPF_EXIT_INSN(), 952 BPF_EXIT_INSN(),
625 }, 953 },
626 .errstr = "invalid BPF_ALU opcode f0", 954 .errstr = "unknown opcode ff",
627 .result = REJECT, 955 .result = REJECT,
628 }, 956 },
629 { 957 {
@@ -802,6 +1130,7 @@ static struct bpf_test tests[] = {
802 .errstr_unpriv = "R1 pointer comparison", 1130 .errstr_unpriv = "R1 pointer comparison",
803 .result_unpriv = REJECT, 1131 .result_unpriv = REJECT,
804 .result = ACCEPT, 1132 .result = ACCEPT,
1133 .retval = -ENOENT,
805 }, 1134 },
806 { 1135 {
807 "jump test 4", 1136 "jump test 4",
@@ -1822,6 +2151,7 @@ static struct bpf_test tests[] = {
1822 BPF_EXIT_INSN(), 2151 BPF_EXIT_INSN(),
1823 }, 2152 },
1824 .result = ACCEPT, 2153 .result = ACCEPT,
2154 .retval = 0xfaceb00c,
1825 }, 2155 },
1826 { 2156 {
1827 "PTR_TO_STACK store/load - bad alignment on off", 2157 "PTR_TO_STACK store/load - bad alignment on off",
@@ -1880,6 +2210,7 @@ static struct bpf_test tests[] = {
1880 .result = ACCEPT, 2210 .result = ACCEPT,
1881 .result_unpriv = REJECT, 2211 .result_unpriv = REJECT,
1882 .errstr_unpriv = "R0 leaks addr", 2212 .errstr_unpriv = "R0 leaks addr",
2213 .retval = POINTER_VALUE,
1883 }, 2214 },
1884 { 2215 {
1885 "unpriv: add const to pointer", 2216 "unpriv: add const to pointer",
@@ -2053,6 +2384,7 @@ static struct bpf_test tests[] = {
2053 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 2384 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2054 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2385 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2055 BPF_FUNC_get_hash_recalc), 2386 BPF_FUNC_get_hash_recalc),
2387 BPF_MOV64_IMM(BPF_REG_0, 0),
2056 BPF_EXIT_INSN(), 2388 BPF_EXIT_INSN(),
2057 }, 2389 },
2058 .result = ACCEPT, 2390 .result = ACCEPT,
@@ -2840,6 +3172,7 @@ static struct bpf_test tests[] = {
2840 }, 3172 },
2841 .result = ACCEPT, 3173 .result = ACCEPT,
2842 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3174 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3175 .retval = 1,
2843 }, 3176 },
2844 { 3177 {
2845 "direct packet access: test12 (and, good access)", 3178 "direct packet access: test12 (and, good access)",
@@ -2864,6 +3197,7 @@ static struct bpf_test tests[] = {
2864 }, 3197 },
2865 .result = ACCEPT, 3198 .result = ACCEPT,
2866 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3199 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3200 .retval = 1,
2867 }, 3201 },
2868 { 3202 {
2869 "direct packet access: test13 (branches, good access)", 3203 "direct packet access: test13 (branches, good access)",
@@ -2894,6 +3228,7 @@ static struct bpf_test tests[] = {
2894 }, 3228 },
2895 .result = ACCEPT, 3229 .result = ACCEPT,
2896 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3230 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3231 .retval = 1,
2897 }, 3232 },
2898 { 3233 {
2899 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)", 3234 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
@@ -2917,6 +3252,7 @@ static struct bpf_test tests[] = {
2917 }, 3252 },
2918 .result = ACCEPT, 3253 .result = ACCEPT,
2919 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3254 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3255 .retval = 1,
2920 }, 3256 },
2921 { 3257 {
2922 "direct packet access: test15 (spill with xadd)", 3258 "direct packet access: test15 (spill with xadd)",
@@ -3203,6 +3539,7 @@ static struct bpf_test tests[] = {
3203 }, 3539 },
3204 .result = ACCEPT, 3540 .result = ACCEPT,
3205 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3541 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3542 .retval = 1,
3206 }, 3543 },
3207 { 3544 {
3208 "direct packet access: test28 (marking on <=, bad access)", 3545 "direct packet access: test28 (marking on <=, bad access)",
@@ -5700,7 +6037,7 @@ static struct bpf_test tests[] = {
5700 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)", 6037 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
5701 .insns = { 6038 .insns = {
5702 BPF_MOV64_IMM(BPF_REG_1, 0), 6039 BPF_MOV64_IMM(BPF_REG_1, 0),
5703 BPF_MOV64_IMM(BPF_REG_2, 0), 6040 BPF_MOV64_IMM(BPF_REG_2, 1),
5704 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128), 6041 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5705 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128), 6042 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5706 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64), 6043 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
@@ -5822,6 +6159,7 @@ static struct bpf_test tests[] = {
5822 }, 6159 },
5823 .result = ACCEPT, 6160 .result = ACCEPT,
5824 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 6161 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6162 .retval = 0 /* csum_diff of 64-byte packet */,
5825 }, 6163 },
5826 { 6164 {
5827 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)", 6165 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
@@ -5935,7 +6273,7 @@ static struct bpf_test tests[] = {
5935 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24), 6273 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5936 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16), 6274 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5937 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 6275 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5938 BPF_MOV64_IMM(BPF_REG_2, 0), 6276 BPF_MOV64_IMM(BPF_REG_2, 1),
5939 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128), 6277 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5940 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128), 6278 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5941 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63), 6279 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
@@ -6190,6 +6528,7 @@ static struct bpf_test tests[] = {
6190 }, 6528 },
6191 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 6529 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6192 .result = ACCEPT, 6530 .result = ACCEPT,
6531 .retval = 42 /* ultimate return value */,
6193 }, 6532 },
6194 { 6533 {
6195 "ld_ind: check calling conv, r1", 6534 "ld_ind: check calling conv, r1",
@@ -6261,6 +6600,7 @@ static struct bpf_test tests[] = {
6261 BPF_EXIT_INSN(), 6600 BPF_EXIT_INSN(),
6262 }, 6601 },
6263 .result = ACCEPT, 6602 .result = ACCEPT,
6603 .retval = 1,
6264 }, 6604 },
6265 { 6605 {
6266 "check bpf_perf_event_data->sample_period byte load permitted", 6606 "check bpf_perf_event_data->sample_period byte load permitted",
@@ -7248,6 +7588,7 @@ static struct bpf_test tests[] = {
7248 }, 7588 },
7249 .fixup_map1 = { 3 }, 7589 .fixup_map1 = { 3 },
7250 .result = ACCEPT, 7590 .result = ACCEPT,
7591 .retval = POINTER_VALUE,
7251 .result_unpriv = REJECT, 7592 .result_unpriv = REJECT,
7252 .errstr_unpriv = "R0 leaks addr as return value" 7593 .errstr_unpriv = "R0 leaks addr as return value"
7253 }, 7594 },
@@ -7268,6 +7609,7 @@ static struct bpf_test tests[] = {
7268 }, 7609 },
7269 .fixup_map1 = { 3 }, 7610 .fixup_map1 = { 3 },
7270 .result = ACCEPT, 7611 .result = ACCEPT,
7612 .retval = POINTER_VALUE,
7271 .result_unpriv = REJECT, 7613 .result_unpriv = REJECT,
7272 .errstr_unpriv = "R0 leaks addr as return value" 7614 .errstr_unpriv = "R0 leaks addr as return value"
7273 }, 7615 },
@@ -7434,10 +7776,24 @@ static struct bpf_test tests[] = {
7434 }, 7776 },
7435 BPF_EXIT_INSN(), 7777 BPF_EXIT_INSN(),
7436 }, 7778 },
7437 .errstr = "BPF_END uses reserved fields", 7779 .errstr = "unknown opcode d7",
7438 .result = REJECT, 7780 .result = REJECT,
7439 }, 7781 },
7440 { 7782 {
7783 "XDP, using ifindex from netdev",
7784 .insns = {
7785 BPF_MOV64_IMM(BPF_REG_0, 0),
7786 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7787 offsetof(struct xdp_md, ingress_ifindex)),
7788 BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
7789 BPF_MOV64_IMM(BPF_REG_0, 1),
7790 BPF_EXIT_INSN(),
7791 },
7792 .result = ACCEPT,
7793 .prog_type = BPF_PROG_TYPE_XDP,
7794 .retval = 1,
7795 },
7796 {
7441 "meta access, test1", 7797 "meta access, test1",
7442 .insns = { 7798 .insns = {
7443 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7799 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
@@ -7709,6 +8065,7 @@ static struct bpf_test tests[] = {
7709 BPF_EXIT_INSN(), 8065 BPF_EXIT_INSN(),
7710 }, 8066 },
7711 .result = ACCEPT, 8067 .result = ACCEPT,
8068 .retval = TEST_DATA_LEN,
7712 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 8069 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7713 }, 8070 },
7714 { 8071 {
@@ -8656,6 +9013,7 @@ static struct bpf_test tests[] = {
8656 BPF_EXIT_INSN(), 9013 BPF_EXIT_INSN(),
8657 }, 9014 },
8658 .result = ACCEPT, 9015 .result = ACCEPT,
9016 .retval = 1,
8659 }, 9017 },
8660 { 9018 {
8661 "check deducing bounds from const, 3", 9019 "check deducing bounds from const, 3",
@@ -8826,6 +9184,1959 @@ static struct bpf_test tests[] = {
8826 .result = REJECT, 9184 .result = REJECT,
8827 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK, 9185 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8828 }, 9186 },
9187 {
9188 "calls: basic sanity",
9189 .insns = {
9190 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9191 BPF_MOV64_IMM(BPF_REG_0, 1),
9192 BPF_EXIT_INSN(),
9193 BPF_MOV64_IMM(BPF_REG_0, 2),
9194 BPF_EXIT_INSN(),
9195 },
9196 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9197 .result = ACCEPT,
9198 },
9199 {
9200 "calls: not on unpriviledged",
9201 .insns = {
9202 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9203 BPF_MOV64_IMM(BPF_REG_0, 1),
9204 BPF_EXIT_INSN(),
9205 BPF_MOV64_IMM(BPF_REG_0, 2),
9206 BPF_EXIT_INSN(),
9207 },
9208 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
9209 .result_unpriv = REJECT,
9210 .result = ACCEPT,
9211 .retval = 1,
9212 },
9213 {
9214 "calls: div by 0 in subprog",
9215 .insns = {
9216 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9217 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9218 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9219 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9220 offsetof(struct __sk_buff, data_end)),
9221 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9223 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9224 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9225 BPF_MOV64_IMM(BPF_REG_0, 1),
9226 BPF_EXIT_INSN(),
9227 BPF_MOV32_IMM(BPF_REG_2, 0),
9228 BPF_MOV32_IMM(BPF_REG_3, 1),
9229 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
9230 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9231 offsetof(struct __sk_buff, data)),
9232 BPF_EXIT_INSN(),
9233 },
9234 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9235 .result = ACCEPT,
9236 .retval = 1,
9237 },
9238 {
9239 "calls: multiple ret types in subprog 1",
9240 .insns = {
9241 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9243 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9244 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9245 offsetof(struct __sk_buff, data_end)),
9246 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9248 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9249 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9250 BPF_MOV64_IMM(BPF_REG_0, 1),
9251 BPF_EXIT_INSN(),
9252 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9253 offsetof(struct __sk_buff, data)),
9254 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9255 BPF_MOV32_IMM(BPF_REG_0, 42),
9256 BPF_EXIT_INSN(),
9257 },
9258 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9259 .result = REJECT,
9260 .errstr = "R0 invalid mem access 'inv'",
9261 },
9262 {
9263 "calls: multiple ret types in subprog 2",
9264 .insns = {
9265 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9266 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9267 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9268 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9269 offsetof(struct __sk_buff, data_end)),
9270 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9271 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9272 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9273 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9274 BPF_MOV64_IMM(BPF_REG_0, 1),
9275 BPF_EXIT_INSN(),
9276 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9277 offsetof(struct __sk_buff, data)),
9278 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9279 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
9280 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9281 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9283 BPF_LD_MAP_FD(BPF_REG_1, 0),
9284 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9285 BPF_FUNC_map_lookup_elem),
9286 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9287 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
9288 offsetof(struct __sk_buff, data)),
9289 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
9290 BPF_EXIT_INSN(),
9291 },
9292 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9293 .fixup_map1 = { 16 },
9294 .result = REJECT,
9295 .errstr = "R0 min value is outside of the array range",
9296 },
9297 {
9298 "calls: overlapping caller/callee",
9299 .insns = {
9300 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
9301 BPF_MOV64_IMM(BPF_REG_0, 1),
9302 BPF_EXIT_INSN(),
9303 },
9304 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9305 .errstr = "last insn is not an exit or jmp",
9306 .result = REJECT,
9307 },
9308 {
9309 "calls: wrong recursive calls",
9310 .insns = {
9311 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9312 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9313 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9314 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9315 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9316 BPF_MOV64_IMM(BPF_REG_0, 1),
9317 BPF_EXIT_INSN(),
9318 },
9319 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9320 .errstr = "jump out of range",
9321 .result = REJECT,
9322 },
9323 {
9324 "calls: wrong src reg",
9325 .insns = {
9326 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
9327 BPF_MOV64_IMM(BPF_REG_0, 1),
9328 BPF_EXIT_INSN(),
9329 },
9330 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9331 .errstr = "BPF_CALL uses reserved fields",
9332 .result = REJECT,
9333 },
9334 {
9335 "calls: wrong off value",
9336 .insns = {
9337 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
9338 BPF_MOV64_IMM(BPF_REG_0, 1),
9339 BPF_EXIT_INSN(),
9340 BPF_MOV64_IMM(BPF_REG_0, 2),
9341 BPF_EXIT_INSN(),
9342 },
9343 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9344 .errstr = "BPF_CALL uses reserved fields",
9345 .result = REJECT,
9346 },
9347 {
9348 "calls: jump back loop",
9349 .insns = {
9350 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
9351 BPF_MOV64_IMM(BPF_REG_0, 1),
9352 BPF_EXIT_INSN(),
9353 },
9354 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9355 .errstr = "back-edge from insn 0 to 0",
9356 .result = REJECT,
9357 },
9358 {
9359 "calls: conditional call",
9360 .insns = {
9361 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9362 offsetof(struct __sk_buff, mark)),
9363 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9364 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9365 BPF_MOV64_IMM(BPF_REG_0, 1),
9366 BPF_EXIT_INSN(),
9367 BPF_MOV64_IMM(BPF_REG_0, 2),
9368 BPF_EXIT_INSN(),
9369 },
9370 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9371 .errstr = "jump out of range",
9372 .result = REJECT,
9373 },
9374 {
9375 "calls: conditional call 2",
9376 .insns = {
9377 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9378 offsetof(struct __sk_buff, mark)),
9379 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9380 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9381 BPF_MOV64_IMM(BPF_REG_0, 1),
9382 BPF_EXIT_INSN(),
9383 BPF_MOV64_IMM(BPF_REG_0, 2),
9384 BPF_EXIT_INSN(),
9385 BPF_MOV64_IMM(BPF_REG_0, 3),
9386 BPF_EXIT_INSN(),
9387 },
9388 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9389 .result = ACCEPT,
9390 },
9391 {
9392 "calls: conditional call 3",
9393 .insns = {
9394 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9395 offsetof(struct __sk_buff, mark)),
9396 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9397 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9398 BPF_MOV64_IMM(BPF_REG_0, 1),
9399 BPF_EXIT_INSN(),
9400 BPF_MOV64_IMM(BPF_REG_0, 1),
9401 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
9402 BPF_MOV64_IMM(BPF_REG_0, 3),
9403 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
9404 },
9405 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9406 .errstr = "back-edge from insn",
9407 .result = REJECT,
9408 },
9409 {
9410 "calls: conditional call 4",
9411 .insns = {
9412 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9413 offsetof(struct __sk_buff, mark)),
9414 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9416 BPF_MOV64_IMM(BPF_REG_0, 1),
9417 BPF_EXIT_INSN(),
9418 BPF_MOV64_IMM(BPF_REG_0, 1),
9419 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
9420 BPF_MOV64_IMM(BPF_REG_0, 3),
9421 BPF_EXIT_INSN(),
9422 },
9423 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9424 .result = ACCEPT,
9425 },
9426 {
9427 "calls: conditional call 5",
9428 .insns = {
9429 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9430 offsetof(struct __sk_buff, mark)),
9431 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9432 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9433 BPF_MOV64_IMM(BPF_REG_0, 1),
9434 BPF_EXIT_INSN(),
9435 BPF_MOV64_IMM(BPF_REG_0, 1),
9436 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
9437 BPF_MOV64_IMM(BPF_REG_0, 3),
9438 BPF_EXIT_INSN(),
9439 },
9440 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9441 .errstr = "back-edge from insn",
9442 .result = REJECT,
9443 },
9444 {
9445 "calls: conditional call 6",
9446 .insns = {
9447 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9448 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
9449 BPF_EXIT_INSN(),
9450 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9451 offsetof(struct __sk_buff, mark)),
9452 BPF_EXIT_INSN(),
9453 },
9454 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9455 .errstr = "back-edge from insn",
9456 .result = REJECT,
9457 },
9458 {
9459 "calls: using r0 returned by callee",
9460 .insns = {
9461 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9462 BPF_EXIT_INSN(),
9463 BPF_MOV64_IMM(BPF_REG_0, 2),
9464 BPF_EXIT_INSN(),
9465 },
9466 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9467 .result = ACCEPT,
9468 },
9469 {
9470 "calls: using uninit r0 from callee",
9471 .insns = {
9472 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9473 BPF_EXIT_INSN(),
9474 BPF_EXIT_INSN(),
9475 },
9476 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9477 .errstr = "!read_ok",
9478 .result = REJECT,
9479 },
9480 {
9481 "calls: callee is using r1",
9482 .insns = {
9483 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9484 BPF_EXIT_INSN(),
9485 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9486 offsetof(struct __sk_buff, len)),
9487 BPF_EXIT_INSN(),
9488 },
9489 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
9490 .result = ACCEPT,
9491 .retval = TEST_DATA_LEN,
9492 },
9493 {
9494 "calls: callee using args1",
9495 .insns = {
9496 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9497 BPF_EXIT_INSN(),
9498 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9499 BPF_EXIT_INSN(),
9500 },
9501 .errstr_unpriv = "allowed for root only",
9502 .result_unpriv = REJECT,
9503 .result = ACCEPT,
9504 .retval = POINTER_VALUE,
9505 },
9506 {
9507 "calls: callee using wrong args2",
9508 .insns = {
9509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9510 BPF_EXIT_INSN(),
9511 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9512 BPF_EXIT_INSN(),
9513 },
9514 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9515 .errstr = "R2 !read_ok",
9516 .result = REJECT,
9517 },
9518 {
9519 "calls: callee using two args",
9520 .insns = {
9521 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9522 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
9523 offsetof(struct __sk_buff, len)),
9524 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
9525 offsetof(struct __sk_buff, len)),
9526 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9527 BPF_EXIT_INSN(),
9528 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9529 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
9530 BPF_EXIT_INSN(),
9531 },
9532 .errstr_unpriv = "allowed for root only",
9533 .result_unpriv = REJECT,
9534 .result = ACCEPT,
9535 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
9536 },
9537 {
9538 "calls: callee changing pkt pointers",
9539 .insns = {
9540 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
9541 offsetof(struct xdp_md, data)),
9542 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
9543 offsetof(struct xdp_md, data_end)),
9544 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
9545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
9546 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
9547 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9548 /* clear_all_pkt_pointers() has to walk all frames
9549 * to make sure that pkt pointers in the caller
9550 * are cleared when callee is calling a helper that
9551 * adjusts packet size
9552 */
9553 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
9554 BPF_MOV32_IMM(BPF_REG_0, 0),
9555 BPF_EXIT_INSN(),
9556 BPF_MOV64_IMM(BPF_REG_2, 0),
9557 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9558 BPF_FUNC_xdp_adjust_head),
9559 BPF_EXIT_INSN(),
9560 },
9561 .result = REJECT,
9562 .errstr = "R6 invalid mem access 'inv'",
9563 .prog_type = BPF_PROG_TYPE_XDP,
9564 },
9565 {
9566 "calls: two calls with args",
9567 .insns = {
9568 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9569 BPF_EXIT_INSN(),
9570 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9571 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9572 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9573 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9574 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9575 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9576 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9577 BPF_EXIT_INSN(),
9578 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9579 offsetof(struct __sk_buff, len)),
9580 BPF_EXIT_INSN(),
9581 },
9582 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9583 .result = ACCEPT,
9584 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
9585 },
9586 {
9587 "calls: calls with stack arith",
9588 .insns = {
9589 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9590 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
9591 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9592 BPF_EXIT_INSN(),
9593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
9594 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9595 BPF_EXIT_INSN(),
9596 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
9597 BPF_MOV64_IMM(BPF_REG_0, 42),
9598 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
9599 BPF_EXIT_INSN(),
9600 },
9601 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9602 .result = ACCEPT,
9603 .retval = 42,
9604 },
9605 {
9606 "calls: calls with misaligned stack access",
9607 .insns = {
9608 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
9610 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9611 BPF_EXIT_INSN(),
9612 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
9613 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9614 BPF_EXIT_INSN(),
9615 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
9616 BPF_MOV64_IMM(BPF_REG_0, 42),
9617 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
9618 BPF_EXIT_INSN(),
9619 },
9620 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9621 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
9622 .errstr = "misaligned stack access",
9623 .result = REJECT,
9624 },
9625 {
9626 "calls: calls control flow, jump test",
9627 .insns = {
9628 BPF_MOV64_IMM(BPF_REG_0, 42),
9629 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9630 BPF_MOV64_IMM(BPF_REG_0, 43),
9631 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9632 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
9633 BPF_EXIT_INSN(),
9634 },
9635 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9636 .result = ACCEPT,
9637 .retval = 43,
9638 },
9639 {
9640 "calls: calls control flow, jump test 2",
9641 .insns = {
9642 BPF_MOV64_IMM(BPF_REG_0, 42),
9643 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
9644 BPF_MOV64_IMM(BPF_REG_0, 43),
9645 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9646 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
9647 BPF_EXIT_INSN(),
9648 },
9649 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9650 .errstr = "jump out of range from insn 1 to 4",
9651 .result = REJECT,
9652 },
9653 {
9654 "calls: two calls with bad jump",
9655 .insns = {
9656 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9657 BPF_EXIT_INSN(),
9658 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9659 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9660 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9661 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9662 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9663 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9664 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9665 BPF_EXIT_INSN(),
9666 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9667 offsetof(struct __sk_buff, len)),
9668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
9669 BPF_EXIT_INSN(),
9670 },
9671 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9672 .errstr = "jump out of range from insn 11 to 9",
9673 .result = REJECT,
9674 },
9675 {
9676 "calls: recursive call. test1",
9677 .insns = {
9678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9679 BPF_EXIT_INSN(),
9680 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
9681 BPF_EXIT_INSN(),
9682 },
9683 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9684 .errstr = "back-edge",
9685 .result = REJECT,
9686 },
9687 {
9688 "calls: recursive call. test2",
9689 .insns = {
9690 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9691 BPF_EXIT_INSN(),
9692 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
9693 BPF_EXIT_INSN(),
9694 },
9695 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9696 .errstr = "back-edge",
9697 .result = REJECT,
9698 },
9699 {
9700 "calls: unreachable code",
9701 .insns = {
9702 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9703 BPF_EXIT_INSN(),
9704 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9705 BPF_EXIT_INSN(),
9706 BPF_MOV64_IMM(BPF_REG_0, 0),
9707 BPF_EXIT_INSN(),
9708 BPF_MOV64_IMM(BPF_REG_0, 0),
9709 BPF_EXIT_INSN(),
9710 },
9711 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9712 .errstr = "unreachable insn 6",
9713 .result = REJECT,
9714 },
9715 {
9716 "calls: invalid call",
9717 .insns = {
9718 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9719 BPF_EXIT_INSN(),
9720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
9721 BPF_EXIT_INSN(),
9722 },
9723 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9724 .errstr = "invalid destination",
9725 .result = REJECT,
9726 },
9727 {
9728 "calls: invalid call 2",
9729 .insns = {
9730 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9731 BPF_EXIT_INSN(),
9732 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
9733 BPF_EXIT_INSN(),
9734 },
9735 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9736 .errstr = "invalid destination",
9737 .result = REJECT,
9738 },
9739 {
9740 "calls: jumping across function bodies. test1",
9741 .insns = {
9742 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9743 BPF_MOV64_IMM(BPF_REG_0, 0),
9744 BPF_EXIT_INSN(),
9745 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
9746 BPF_EXIT_INSN(),
9747 },
9748 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9749 .errstr = "jump out of range",
9750 .result = REJECT,
9751 },
9752 {
9753 "calls: jumping across function bodies. test2",
9754 .insns = {
9755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
9756 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9757 BPF_MOV64_IMM(BPF_REG_0, 0),
9758 BPF_EXIT_INSN(),
9759 BPF_EXIT_INSN(),
9760 },
9761 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9762 .errstr = "jump out of range",
9763 .result = REJECT,
9764 },
9765 {
9766 "calls: call without exit",
9767 .insns = {
9768 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9769 BPF_EXIT_INSN(),
9770 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9771 BPF_EXIT_INSN(),
9772 BPF_MOV64_IMM(BPF_REG_0, 0),
9773 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
9774 },
9775 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9776 .errstr = "not an exit",
9777 .result = REJECT,
9778 },
9779 {
9780 "calls: call into middle of ld_imm64",
9781 .insns = {
9782 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9783 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9784 BPF_MOV64_IMM(BPF_REG_0, 0),
9785 BPF_EXIT_INSN(),
9786 BPF_LD_IMM64(BPF_REG_0, 0),
9787 BPF_EXIT_INSN(),
9788 },
9789 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9790 .errstr = "last insn",
9791 .result = REJECT,
9792 },
9793 {
9794 "calls: call into middle of other call",
9795 .insns = {
9796 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9798 BPF_MOV64_IMM(BPF_REG_0, 0),
9799 BPF_EXIT_INSN(),
9800 BPF_MOV64_IMM(BPF_REG_0, 0),
9801 BPF_MOV64_IMM(BPF_REG_0, 0),
9802 BPF_EXIT_INSN(),
9803 },
9804 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9805 .errstr = "last insn",
9806 .result = REJECT,
9807 },
9808 {
9809 "calls: ld_abs with changing ctx data in callee",
9810 .insns = {
9811 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9812 BPF_LD_ABS(BPF_B, 0),
9813 BPF_LD_ABS(BPF_H, 0),
9814 BPF_LD_ABS(BPF_W, 0),
9815 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
9816 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
9817 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
9818 BPF_LD_ABS(BPF_B, 0),
9819 BPF_LD_ABS(BPF_H, 0),
9820 BPF_LD_ABS(BPF_W, 0),
9821 BPF_EXIT_INSN(),
9822 BPF_MOV64_IMM(BPF_REG_2, 1),
9823 BPF_MOV64_IMM(BPF_REG_3, 2),
9824 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9825 BPF_FUNC_skb_vlan_push),
9826 BPF_EXIT_INSN(),
9827 },
9828 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9829 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
9830 .result = REJECT,
9831 },
9832 {
9833 "calls: two calls with bad fallthrough",
9834 .insns = {
9835 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9836 BPF_EXIT_INSN(),
9837 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9838 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9839 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9841 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9842 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9843 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9844 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
9845 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9846 offsetof(struct __sk_buff, len)),
9847 BPF_EXIT_INSN(),
9848 },
9849 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9850 .errstr = "not an exit",
9851 .result = REJECT,
9852 },
9853 {
9854 "calls: two calls with stack read",
9855 .insns = {
9856 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9857 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9858 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9859 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9860 BPF_EXIT_INSN(),
9861 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9862 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
9863 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
9864 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9865 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
9866 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9867 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
9868 BPF_EXIT_INSN(),
9869 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9870 BPF_EXIT_INSN(),
9871 },
9872 .prog_type = BPF_PROG_TYPE_XDP,
9873 .result = ACCEPT,
9874 },
9875 {
9876 "calls: two calls with stack write",
9877 .insns = {
9878 /* main prog */
9879 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9880 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
9881 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
9882 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9883 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
9884 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9885 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
9886 BPF_EXIT_INSN(),
9887
9888 /* subprog 1 */
9889 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9890 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
9891 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
9892 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
9893 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9894 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9895 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
9896 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
9897 /* write into stack frame of main prog */
9898 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9899 BPF_EXIT_INSN(),
9900
9901 /* subprog 2 */
9902 /* read from stack frame of main prog */
9903 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9904 BPF_EXIT_INSN(),
9905 },
9906 .prog_type = BPF_PROG_TYPE_XDP,
9907 .result = ACCEPT,
9908 },
9909 {
9910 "calls: stack overflow using two frames (pre-call access)",
9911 .insns = {
9912 /* prog 1 */
9913 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9914 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
9915 BPF_EXIT_INSN(),
9916
9917 /* prog 2 */
9918 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9919 BPF_MOV64_IMM(BPF_REG_0, 0),
9920 BPF_EXIT_INSN(),
9921 },
9922 .prog_type = BPF_PROG_TYPE_XDP,
9923 .errstr = "combined stack size",
9924 .result = REJECT,
9925 },
9926 {
9927 "calls: stack overflow using two frames (post-call access)",
9928 .insns = {
9929 /* prog 1 */
9930 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
9931 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9932 BPF_EXIT_INSN(),
9933
9934 /* prog 2 */
9935 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
9936 BPF_MOV64_IMM(BPF_REG_0, 0),
9937 BPF_EXIT_INSN(),
9938 },
9939 .prog_type = BPF_PROG_TYPE_XDP,
9940 .errstr = "combined stack size",
9941 .result = REJECT,
9942 },
9943 {
9944 "calls: stack depth check using three frames. test1",
9945 .insns = {
9946 /* main */
9947 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
9948 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
9949 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
9950 BPF_MOV64_IMM(BPF_REG_0, 0),
9951 BPF_EXIT_INSN(),
9952 /* A */
9953 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
9954 BPF_EXIT_INSN(),
9955 /* B */
9956 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
9957 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9958 BPF_EXIT_INSN(),
9959 },
9960 .prog_type = BPF_PROG_TYPE_XDP,
9961 /* stack_main=32, stack_A=256, stack_B=64
9962 * and max(main+A, main+A+B) < 512
9963 */
9964 .result = ACCEPT,
9965 },
9966 {
9967 "calls: stack depth check using three frames. test2",
9968 .insns = {
9969 /* main */
9970 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
9971 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
9972 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
9973 BPF_MOV64_IMM(BPF_REG_0, 0),
9974 BPF_EXIT_INSN(),
9975 /* A */
9976 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9977 BPF_EXIT_INSN(),
9978 /* B */
9979 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
9980 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
9981 BPF_EXIT_INSN(),
9982 },
9983 .prog_type = BPF_PROG_TYPE_XDP,
9984 /* stack_main=32, stack_A=64, stack_B=256
9985 * and max(main+A, main+A+B) < 512
9986 */
9987 .result = ACCEPT,
9988 },
9989 {
9990 "calls: stack depth check using three frames. test3",
9991 .insns = {
9992 /* main */
9993 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9994 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
9995 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9996 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
9997 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
9998 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
9999 BPF_MOV64_IMM(BPF_REG_0, 0),
10000 BPF_EXIT_INSN(),
10001 /* A */
10002 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
10003 BPF_EXIT_INSN(),
10004 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
10005 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10006 /* B */
10007 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
10008 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
10009 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10010 BPF_EXIT_INSN(),
10011 },
10012 .prog_type = BPF_PROG_TYPE_XDP,
10013 /* stack_main=64, stack_A=224, stack_B=256
10014 * and max(main+A, main+A+B) > 512
10015 */
10016 .errstr = "combined stack",
10017 .result = REJECT,
10018 },
10019 {
10020 "calls: stack depth check using three frames. test4",
10021 /* void main(void) {
10022 * func1(0);
10023 * func1(1);
10024 * func2(1);
10025 * }
10026 * void func1(int alloc_or_recurse) {
10027 * if (alloc_or_recurse) {
10028 * frame_pointer[-300] = 1;
10029 * } else {
10030 * func2(alloc_or_recurse);
10031 * }
10032 * }
10033 * void func2(int alloc_or_recurse) {
10034 * if (alloc_or_recurse) {
10035 * frame_pointer[-300] = 1;
10036 * }
10037 * }
10038 */
10039 .insns = {
10040 /* main */
10041 BPF_MOV64_IMM(BPF_REG_1, 0),
10042 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10043 BPF_MOV64_IMM(BPF_REG_1, 1),
10044 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10045 BPF_MOV64_IMM(BPF_REG_1, 1),
10046 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
10047 BPF_MOV64_IMM(BPF_REG_0, 0),
10048 BPF_EXIT_INSN(),
10049 /* A */
10050 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
10051 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10052 BPF_EXIT_INSN(),
10053 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10054 BPF_EXIT_INSN(),
10055 /* B */
10056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10057 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10058 BPF_EXIT_INSN(),
10059 },
10060 .prog_type = BPF_PROG_TYPE_XDP,
10061 .result = REJECT,
10062 .errstr = "combined stack",
10063 },
10064 {
10065 "calls: stack depth check using three frames. test5",
10066 .insns = {
10067 /* main */
10068 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
10069 BPF_EXIT_INSN(),
10070 /* A */
10071 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10072 BPF_EXIT_INSN(),
10073 /* B */
10074 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
10075 BPF_EXIT_INSN(),
10076 /* C */
10077 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
10078 BPF_EXIT_INSN(),
10079 /* D */
10080 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
10081 BPF_EXIT_INSN(),
10082 /* E */
10083 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
10084 BPF_EXIT_INSN(),
10085 /* F */
10086 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
10087 BPF_EXIT_INSN(),
10088 /* G */
10089 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
10090 BPF_EXIT_INSN(),
10091 /* H */
10092 BPF_MOV64_IMM(BPF_REG_0, 0),
10093 BPF_EXIT_INSN(),
10094 },
10095 .prog_type = BPF_PROG_TYPE_XDP,
10096 .errstr = "call stack",
10097 .result = REJECT,
10098 },
10099 {
10100 "calls: spill into caller stack frame",
10101 .insns = {
10102 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10103 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10105 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10106 BPF_EXIT_INSN(),
10107 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
10108 BPF_MOV64_IMM(BPF_REG_0, 0),
10109 BPF_EXIT_INSN(),
10110 },
10111 .prog_type = BPF_PROG_TYPE_XDP,
10112 .errstr = "cannot spill",
10113 .result = REJECT,
10114 },
10115 {
10116 "calls: write into caller stack frame",
10117 .insns = {
10118 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10120 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10121 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10122 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10123 BPF_EXIT_INSN(),
10124 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
10125 BPF_MOV64_IMM(BPF_REG_0, 0),
10126 BPF_EXIT_INSN(),
10127 },
10128 .prog_type = BPF_PROG_TYPE_XDP,
10129 .result = ACCEPT,
10130 .retval = 42,
10131 },
10132 {
10133 "calls: write into callee stack frame",
10134 .insns = {
10135 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10136 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
10137 BPF_EXIT_INSN(),
10138 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
10139 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
10140 BPF_EXIT_INSN(),
10141 },
10142 .prog_type = BPF_PROG_TYPE_XDP,
10143 .errstr = "cannot return stack pointer",
10144 .result = REJECT,
10145 },
10146 {
10147 "calls: two calls with stack write and void return",
10148 .insns = {
10149 /* main prog */
10150 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10151 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10155 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10156 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10157 BPF_EXIT_INSN(),
10158
10159 /* subprog 1 */
10160 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10161 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10162 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10163 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10164 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10165 BPF_EXIT_INSN(),
10166
10167 /* subprog 2 */
10168 /* write into stack frame of main prog */
10169 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
10170 BPF_EXIT_INSN(), /* void return */
10171 },
10172 .prog_type = BPF_PROG_TYPE_XDP,
10173 .result = ACCEPT,
10174 },
10175 {
10176 "calls: ambiguous return value",
10177 .insns = {
10178 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10179 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10180 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10181 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10182 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10183 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10184 BPF_EXIT_INSN(),
10185 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10186 BPF_MOV64_IMM(BPF_REG_0, 0),
10187 BPF_EXIT_INSN(),
10188 },
10189 .errstr_unpriv = "allowed for root only",
10190 .result_unpriv = REJECT,
10191 .errstr = "R0 !read_ok",
10192 .result = REJECT,
10193 },
10194 {
10195 "calls: two calls that return map_value",
10196 .insns = {
10197 /* main prog */
10198 /* pass fp-16, fp-8 into a function */
10199 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10200 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10201 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10203 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10204
10205 /* fetch map_value_ptr from the stack of this function */
10206 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
10207 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10208 /* write into map value */
10209 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10210 /* fetch secound map_value_ptr from the stack */
10211 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10213 /* write into map value */
10214 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10215 BPF_MOV64_IMM(BPF_REG_0, 0),
10216 BPF_EXIT_INSN(),
10217
10218 /* subprog 1 */
10219 /* call 3rd function twice */
10220 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10221 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10222 /* first time with fp-8 */
10223 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10224 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10225 /* second time with fp-16 */
10226 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10227 BPF_EXIT_INSN(),
10228
10229 /* subprog 2 */
10230 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10231 /* lookup from map */
10232 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10233 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10235 BPF_LD_MAP_FD(BPF_REG_1, 0),
10236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10237 BPF_FUNC_map_lookup_elem),
10238 /* write map_value_ptr into stack frame of main prog */
10239 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10240 BPF_MOV64_IMM(BPF_REG_0, 0),
10241 BPF_EXIT_INSN(), /* return 0 */
10242 },
10243 .prog_type = BPF_PROG_TYPE_XDP,
10244 .fixup_map1 = { 23 },
10245 .result = ACCEPT,
10246 },
10247 {
10248 "calls: two calls that return map_value with bool condition",
10249 .insns = {
10250 /* main prog */
10251 /* pass fp-16, fp-8 into a function */
10252 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10253 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10254 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10255 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10256 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10257 BPF_MOV64_IMM(BPF_REG_0, 0),
10258 BPF_EXIT_INSN(),
10259
10260 /* subprog 1 */
10261 /* call 3rd function twice */
10262 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10263 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10264 /* first time with fp-8 */
10265 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10266 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10267 /* fetch map_value_ptr from the stack of this function */
10268 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10269 /* write into map value */
10270 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10271 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10272 /* second time with fp-16 */
10273 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10274 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10275 /* fetch secound map_value_ptr from the stack */
10276 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10277 /* write into map value */
10278 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10279 BPF_EXIT_INSN(),
10280
10281 /* subprog 2 */
10282 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10283 /* lookup from map */
10284 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10285 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10286 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10287 BPF_LD_MAP_FD(BPF_REG_1, 0),
10288 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10289 BPF_FUNC_map_lookup_elem),
10290 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10291 BPF_MOV64_IMM(BPF_REG_0, 0),
10292 BPF_EXIT_INSN(), /* return 0 */
10293 /* write map_value_ptr into stack frame of main prog */
10294 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10295 BPF_MOV64_IMM(BPF_REG_0, 1),
10296 BPF_EXIT_INSN(), /* return 1 */
10297 },
10298 .prog_type = BPF_PROG_TYPE_XDP,
10299 .fixup_map1 = { 23 },
10300 .result = ACCEPT,
10301 },
10302 {
10303 "calls: two calls that return map_value with incorrect bool check",
10304 .insns = {
10305 /* main prog */
10306 /* pass fp-16, fp-8 into a function */
10307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10308 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10309 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10310 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10311 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10312 BPF_MOV64_IMM(BPF_REG_0, 0),
10313 BPF_EXIT_INSN(),
10314
10315 /* subprog 1 */
10316 /* call 3rd function twice */
10317 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10318 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10319 /* first time with fp-8 */
10320 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10321 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10322 /* fetch map_value_ptr from the stack of this function */
10323 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10324 /* write into map value */
10325 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10326 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10327 /* second time with fp-16 */
10328 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10329 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10330 /* fetch secound map_value_ptr from the stack */
10331 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10332 /* write into map value */
10333 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10334 BPF_EXIT_INSN(),
10335
10336 /* subprog 2 */
10337 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10338 /* lookup from map */
10339 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10340 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10341 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10342 BPF_LD_MAP_FD(BPF_REG_1, 0),
10343 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10344 BPF_FUNC_map_lookup_elem),
10345 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10346 BPF_MOV64_IMM(BPF_REG_0, 0),
10347 BPF_EXIT_INSN(), /* return 0 */
10348 /* write map_value_ptr into stack frame of main prog */
10349 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10350 BPF_MOV64_IMM(BPF_REG_0, 1),
10351 BPF_EXIT_INSN(), /* return 1 */
10352 },
10353 .prog_type = BPF_PROG_TYPE_XDP,
10354 .fixup_map1 = { 23 },
10355 .result = REJECT,
10356 .errstr = "invalid read from stack off -16+0 size 8",
10357 },
10358 {
10359 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
10360 .insns = {
10361 /* main prog */
10362 /* pass fp-16, fp-8 into a function */
10363 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10365 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10367 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10368 BPF_MOV64_IMM(BPF_REG_0, 0),
10369 BPF_EXIT_INSN(),
10370
10371 /* subprog 1 */
10372 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10373 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10374 /* 1st lookup from map */
10375 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10376 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10378 BPF_LD_MAP_FD(BPF_REG_1, 0),
10379 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10380 BPF_FUNC_map_lookup_elem),
10381 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10382 BPF_MOV64_IMM(BPF_REG_8, 0),
10383 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10384 /* write map_value_ptr into stack frame of main prog at fp-8 */
10385 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10386 BPF_MOV64_IMM(BPF_REG_8, 1),
10387
10388 /* 2nd lookup from map */
10389 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
10390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10391 BPF_LD_MAP_FD(BPF_REG_1, 0),
10392 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
10393 BPF_FUNC_map_lookup_elem),
10394 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10395 BPF_MOV64_IMM(BPF_REG_9, 0),
10396 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10397 /* write map_value_ptr into stack frame of main prog at fp-16 */
10398 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10399 BPF_MOV64_IMM(BPF_REG_9, 1),
10400
10401 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10402 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
10403 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10404 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10405 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10406 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
10407 BPF_EXIT_INSN(),
10408
10409 /* subprog 2 */
10410 /* if arg2 == 1 do *arg1 = 0 */
10411 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10412 /* fetch map_value_ptr from the stack of this function */
10413 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10414 /* write into map value */
10415 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10416
10417 /* if arg4 == 1 do *arg3 = 0 */
10418 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10419 /* fetch map_value_ptr from the stack of this function */
10420 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10421 /* write into map value */
10422 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
10423 BPF_EXIT_INSN(),
10424 },
10425 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10426 .fixup_map1 = { 12, 22 },
10427 .result = REJECT,
10428 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
10429 },
10430 {
10431 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
10432 .insns = {
10433 /* main prog */
10434 /* pass fp-16, fp-8 into a function */
10435 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10437 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10438 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10439 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10440 BPF_MOV64_IMM(BPF_REG_0, 0),
10441 BPF_EXIT_INSN(),
10442
10443 /* subprog 1 */
10444 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10445 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10446 /* 1st lookup from map */
10447 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10448 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10450 BPF_LD_MAP_FD(BPF_REG_1, 0),
10451 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10452 BPF_FUNC_map_lookup_elem),
10453 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10454 BPF_MOV64_IMM(BPF_REG_8, 0),
10455 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10456 /* write map_value_ptr into stack frame of main prog at fp-8 */
10457 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10458 BPF_MOV64_IMM(BPF_REG_8, 1),
10459
10460 /* 2nd lookup from map */
10461 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
10462 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10463 BPF_LD_MAP_FD(BPF_REG_1, 0),
10464 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
10465 BPF_FUNC_map_lookup_elem),
10466 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10467 BPF_MOV64_IMM(BPF_REG_9, 0),
10468 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10469 /* write map_value_ptr into stack frame of main prog at fp-16 */
10470 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10471 BPF_MOV64_IMM(BPF_REG_9, 1),
10472
10473 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10474 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
10475 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10476 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10477 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10478 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
10479 BPF_EXIT_INSN(),
10480
10481 /* subprog 2 */
10482 /* if arg2 == 1 do *arg1 = 0 */
10483 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10484 /* fetch map_value_ptr from the stack of this function */
10485 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10486 /* write into map value */
10487 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10488
10489 /* if arg4 == 1 do *arg3 = 0 */
10490 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10491 /* fetch map_value_ptr from the stack of this function */
10492 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10493 /* write into map value */
10494 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10495 BPF_EXIT_INSN(),
10496 },
10497 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10498 .fixup_map1 = { 12, 22 },
10499 .result = ACCEPT,
10500 },
10501 {
10502 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
10503 .insns = {
10504 /* main prog */
10505 /* pass fp-16, fp-8 into a function */
10506 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10507 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10508 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10510 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
10511 BPF_MOV64_IMM(BPF_REG_0, 0),
10512 BPF_EXIT_INSN(),
10513
10514 /* subprog 1 */
10515 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10516 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10517 /* 1st lookup from map */
10518 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
10519 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10520 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
10521 BPF_LD_MAP_FD(BPF_REG_1, 0),
10522 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10523 BPF_FUNC_map_lookup_elem),
10524 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10525 BPF_MOV64_IMM(BPF_REG_8, 0),
10526 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10527 /* write map_value_ptr into stack frame of main prog at fp-8 */
10528 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10529 BPF_MOV64_IMM(BPF_REG_8, 1),
10530
10531 /* 2nd lookup from map */
10532 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
10534 BPF_LD_MAP_FD(BPF_REG_1, 0),
10535 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10536 BPF_FUNC_map_lookup_elem),
10537 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10538 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
10539 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10540 /* write map_value_ptr into stack frame of main prog at fp-16 */
10541 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10542 BPF_MOV64_IMM(BPF_REG_9, 1),
10543
10544 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10545 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
10546 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10547 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10548 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10549 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
10550 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
10551
10552 /* subprog 2 */
10553 /* if arg2 == 1 do *arg1 = 0 */
10554 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10555 /* fetch map_value_ptr from the stack of this function */
10556 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10557 /* write into map value */
10558 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10559
10560 /* if arg4 == 1 do *arg3 = 0 */
10561 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10562 /* fetch map_value_ptr from the stack of this function */
10563 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10564 /* write into map value */
10565 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
10566 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
10567 },
10568 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10569 .fixup_map1 = { 12, 22 },
10570 .result = REJECT,
10571 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
10572 },
10573 {
10574 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
10575 .insns = {
10576 /* main prog */
10577 /* pass fp-16, fp-8 into a function */
10578 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10579 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10582 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10583 BPF_MOV64_IMM(BPF_REG_0, 0),
10584 BPF_EXIT_INSN(),
10585
10586 /* subprog 1 */
10587 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10588 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10589 /* 1st lookup from map */
10590 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10591 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10593 BPF_LD_MAP_FD(BPF_REG_1, 0),
10594 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10595 BPF_FUNC_map_lookup_elem),
10596 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
10597 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10598 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10599 BPF_MOV64_IMM(BPF_REG_8, 0),
10600 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10601 BPF_MOV64_IMM(BPF_REG_8, 1),
10602
10603 /* 2nd lookup from map */
10604 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10606 BPF_LD_MAP_FD(BPF_REG_1, 0),
10607 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10608 BPF_FUNC_map_lookup_elem),
10609 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
10610 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10611 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10612 BPF_MOV64_IMM(BPF_REG_9, 0),
10613 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10614 BPF_MOV64_IMM(BPF_REG_9, 1),
10615
10616 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10617 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10618 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10619 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10620 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10621 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10622 BPF_EXIT_INSN(),
10623
10624 /* subprog 2 */
10625 /* if arg2 == 1 do *arg1 = 0 */
10626 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10627 /* fetch map_value_ptr from the stack of this function */
10628 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10629 /* write into map value */
10630 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10631
10632 /* if arg4 == 1 do *arg3 = 0 */
10633 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10634 /* fetch map_value_ptr from the stack of this function */
10635 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10636 /* write into map value */
10637 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10638 BPF_EXIT_INSN(),
10639 },
10640 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10641 .fixup_map1 = { 12, 22 },
10642 .result = ACCEPT,
10643 },
10644 {
10645 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
10646 .insns = {
10647 /* main prog */
10648 /* pass fp-16, fp-8 into a function */
10649 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10651 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10652 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10653 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10654 BPF_MOV64_IMM(BPF_REG_0, 0),
10655 BPF_EXIT_INSN(),
10656
10657 /* subprog 1 */
10658 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10659 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10660 /* 1st lookup from map */
10661 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10662 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10664 BPF_LD_MAP_FD(BPF_REG_1, 0),
10665 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10666 BPF_FUNC_map_lookup_elem),
10667 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
10668 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10669 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10670 BPF_MOV64_IMM(BPF_REG_8, 0),
10671 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10672 BPF_MOV64_IMM(BPF_REG_8, 1),
10673
10674 /* 2nd lookup from map */
10675 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10676 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10677 BPF_LD_MAP_FD(BPF_REG_1, 0),
10678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10679 BPF_FUNC_map_lookup_elem),
10680 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
10681 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10682 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10683 BPF_MOV64_IMM(BPF_REG_9, 0),
10684 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10685 BPF_MOV64_IMM(BPF_REG_9, 1),
10686
10687 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10688 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10689 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10690 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10691 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10692 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10693 BPF_EXIT_INSN(),
10694
10695 /* subprog 2 */
10696 /* if arg2 == 1 do *arg1 = 0 */
10697 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10698 /* fetch map_value_ptr from the stack of this function */
10699 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10700 /* write into map value */
10701 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10702
10703 /* if arg4 == 0 do *arg3 = 0 */
10704 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
10705 /* fetch map_value_ptr from the stack of this function */
10706 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10707 /* write into map value */
10708 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10709 BPF_EXIT_INSN(),
10710 },
10711 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10712 .fixup_map1 = { 12, 22 },
10713 .result = REJECT,
10714 .errstr = "R0 invalid mem access 'inv'",
10715 },
10716 {
10717 "calls: pkt_ptr spill into caller stack",
10718 .insns = {
10719 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10721 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10722 BPF_EXIT_INSN(),
10723
10724 /* subprog 1 */
10725 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10726 offsetof(struct __sk_buff, data)),
10727 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10728 offsetof(struct __sk_buff, data_end)),
10729 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10730 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10731 /* spill unchecked pkt_ptr into stack of caller */
10732 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10733 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10734 /* now the pkt range is verified, read pkt_ptr from stack */
10735 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10736 /* write 4 bytes into packet */
10737 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10738 BPF_EXIT_INSN(),
10739 },
10740 .result = ACCEPT,
10741 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10742 .retval = POINTER_VALUE,
10743 },
10744 {
10745 "calls: pkt_ptr spill into caller stack 2",
10746 .insns = {
10747 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10748 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10749 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10750 /* Marking is still kept, but not in all cases safe. */
10751 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10752 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10753 BPF_EXIT_INSN(),
10754
10755 /* subprog 1 */
10756 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10757 offsetof(struct __sk_buff, data)),
10758 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10759 offsetof(struct __sk_buff, data_end)),
10760 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10762 /* spill unchecked pkt_ptr into stack of caller */
10763 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10764 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10765 /* now the pkt range is verified, read pkt_ptr from stack */
10766 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10767 /* write 4 bytes into packet */
10768 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10769 BPF_EXIT_INSN(),
10770 },
10771 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10772 .errstr = "invalid access to packet",
10773 .result = REJECT,
10774 },
10775 {
10776 "calls: pkt_ptr spill into caller stack 3",
10777 .insns = {
10778 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10780 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10781 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
10782 /* Marking is still kept and safe here. */
10783 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10784 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10785 BPF_EXIT_INSN(),
10786
10787 /* subprog 1 */
10788 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10789 offsetof(struct __sk_buff, data)),
10790 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10791 offsetof(struct __sk_buff, data_end)),
10792 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10794 /* spill unchecked pkt_ptr into stack of caller */
10795 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10796 BPF_MOV64_IMM(BPF_REG_5, 0),
10797 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10798 BPF_MOV64_IMM(BPF_REG_5, 1),
10799 /* now the pkt range is verified, read pkt_ptr from stack */
10800 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
10801 /* write 4 bytes into packet */
10802 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10803 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10804 BPF_EXIT_INSN(),
10805 },
10806 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10807 .result = ACCEPT,
10808 .retval = 1,
10809 },
10810 {
10811 "calls: pkt_ptr spill into caller stack 4",
10812 .insns = {
10813 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10814 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10815 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10816 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
10817 /* Check marking propagated. */
10818 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10819 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
10820 BPF_EXIT_INSN(),
10821
10822 /* subprog 1 */
10823 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10824 offsetof(struct __sk_buff, data)),
10825 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10826 offsetof(struct __sk_buff, data_end)),
10827 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10829 /* spill unchecked pkt_ptr into stack of caller */
10830 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10831 BPF_MOV64_IMM(BPF_REG_5, 0),
10832 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
10833 BPF_MOV64_IMM(BPF_REG_5, 1),
10834 /* don't read back pkt_ptr from stack here */
10835 /* write 4 bytes into packet */
10836 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10837 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10838 BPF_EXIT_INSN(),
10839 },
10840 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10841 .result = ACCEPT,
10842 .retval = 1,
10843 },
10844 {
10845 "calls: pkt_ptr spill into caller stack 5",
10846 .insns = {
10847 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10849 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
10850 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10851 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10852 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10853 BPF_EXIT_INSN(),
10854
10855 /* subprog 1 */
10856 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10857 offsetof(struct __sk_buff, data)),
10858 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10859 offsetof(struct __sk_buff, data_end)),
10860 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10861 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10862 BPF_MOV64_IMM(BPF_REG_5, 0),
10863 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10864 /* spill checked pkt_ptr into stack of caller */
10865 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10866 BPF_MOV64_IMM(BPF_REG_5, 1),
10867 /* don't read back pkt_ptr from stack here */
10868 /* write 4 bytes into packet */
10869 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10870 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10871 BPF_EXIT_INSN(),
10872 },
10873 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10874 .errstr = "same insn cannot be used with different",
10875 .result = REJECT,
10876 },
10877 {
10878 "calls: pkt_ptr spill into caller stack 6",
10879 .insns = {
10880 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10881 offsetof(struct __sk_buff, data_end)),
10882 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10883 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10884 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10885 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10886 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10887 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10888 BPF_EXIT_INSN(),
10889
10890 /* subprog 1 */
10891 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10892 offsetof(struct __sk_buff, data)),
10893 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10894 offsetof(struct __sk_buff, data_end)),
10895 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10896 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10897 BPF_MOV64_IMM(BPF_REG_5, 0),
10898 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10899 /* spill checked pkt_ptr into stack of caller */
10900 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10901 BPF_MOV64_IMM(BPF_REG_5, 1),
10902 /* don't read back pkt_ptr from stack here */
10903 /* write 4 bytes into packet */
10904 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10905 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10906 BPF_EXIT_INSN(),
10907 },
10908 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10909 .errstr = "R4 invalid mem access",
10910 .result = REJECT,
10911 },
10912 {
10913 "calls: pkt_ptr spill into caller stack 7",
10914 .insns = {
10915 BPF_MOV64_IMM(BPF_REG_2, 0),
10916 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10917 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10918 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10919 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10920 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10921 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10922 BPF_EXIT_INSN(),
10923
10924 /* subprog 1 */
10925 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10926 offsetof(struct __sk_buff, data)),
10927 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10928 offsetof(struct __sk_buff, data_end)),
10929 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10931 BPF_MOV64_IMM(BPF_REG_5, 0),
10932 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10933 /* spill checked pkt_ptr into stack of caller */
10934 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10935 BPF_MOV64_IMM(BPF_REG_5, 1),
10936 /* don't read back pkt_ptr from stack here */
10937 /* write 4 bytes into packet */
10938 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10939 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10940 BPF_EXIT_INSN(),
10941 },
10942 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10943 .errstr = "R4 invalid mem access",
10944 .result = REJECT,
10945 },
10946 {
10947 "calls: pkt_ptr spill into caller stack 8",
10948 .insns = {
10949 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10950 offsetof(struct __sk_buff, data)),
10951 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10952 offsetof(struct __sk_buff, data_end)),
10953 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10955 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
10956 BPF_EXIT_INSN(),
10957 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10959 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10960 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10961 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
10962 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
10963 BPF_EXIT_INSN(),
10964
10965 /* subprog 1 */
10966 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10967 offsetof(struct __sk_buff, data)),
10968 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10969 offsetof(struct __sk_buff, data_end)),
10970 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10971 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10972 BPF_MOV64_IMM(BPF_REG_5, 0),
10973 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
10974 /* spill checked pkt_ptr into stack of caller */
10975 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
10976 BPF_MOV64_IMM(BPF_REG_5, 1),
10977 /* don't read back pkt_ptr from stack here */
10978 /* write 4 bytes into packet */
10979 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
10980 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
10981 BPF_EXIT_INSN(),
10982 },
10983 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10984 .result = ACCEPT,
10985 },
10986 {
10987 "calls: pkt_ptr spill into caller stack 9",
10988 .insns = {
10989 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
10990 offsetof(struct __sk_buff, data)),
10991 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
10992 offsetof(struct __sk_buff, data_end)),
10993 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10994 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
10995 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
10996 BPF_EXIT_INSN(),
10997 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
10998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
10999 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11000 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11001 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11002 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11003 BPF_EXIT_INSN(),
11004
11005 /* subprog 1 */
11006 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11007 offsetof(struct __sk_buff, data)),
11008 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11009 offsetof(struct __sk_buff, data_end)),
11010 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11012 BPF_MOV64_IMM(BPF_REG_5, 0),
11013 /* spill unchecked pkt_ptr into stack of caller */
11014 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11015 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11016 BPF_MOV64_IMM(BPF_REG_5, 1),
11017 /* don't read back pkt_ptr from stack here */
11018 /* write 4 bytes into packet */
11019 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11020 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11021 BPF_EXIT_INSN(),
11022 },
11023 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11024 .errstr = "invalid access to packet",
11025 .result = REJECT,
11026 },
11027 {
11028 "calls: caller stack init to zero or map_value_or_null",
11029 .insns = {
11030 BPF_MOV64_IMM(BPF_REG_0, 0),
11031 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11032 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11033 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11034 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11035 /* fetch map_value_or_null or const_zero from stack */
11036 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11037 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11038 /* store into map_value */
11039 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
11040 BPF_EXIT_INSN(),
11041
11042 /* subprog 1 */
11043 /* if (ctx == 0) return; */
11044 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
11045 /* else bpf_map_lookup() and *(fp - 8) = r0 */
11046 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
11047 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11048 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11049 BPF_LD_MAP_FD(BPF_REG_1, 0),
11050 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11051 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11052 BPF_FUNC_map_lookup_elem),
11053 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11054 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11055 BPF_EXIT_INSN(),
11056 },
11057 .fixup_map1 = { 13 },
11058 .result = ACCEPT,
11059 .prog_type = BPF_PROG_TYPE_XDP,
11060 },
11061 {
11062 "calls: stack init to zero and pruning",
11063 .insns = {
11064 /* first make allocated_stack 16 byte */
11065 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
11066 /* now fork the execution such that the false branch
11067 * of JGT insn will be verified second and it skisp zero
11068 * init of fp-8 stack slot. If stack liveness marking
11069 * is missing live_read marks from call map_lookup
11070 * processing then pruning will incorrectly assume
11071 * that fp-8 stack slot was unused in the fall-through
11072 * branch and will accept the program incorrectly
11073 */
11074 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
11075 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11076 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
11077 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11079 BPF_LD_MAP_FD(BPF_REG_1, 0),
11080 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11081 BPF_FUNC_map_lookup_elem),
11082 BPF_EXIT_INSN(),
11083 },
11084 .fixup_map2 = { 6 },
11085 .errstr = "invalid indirect read from stack off -8+0 size 8",
11086 .result = REJECT,
11087 .prog_type = BPF_PROG_TYPE_XDP,
11088 },
11089 {
11090 "search pruning: all branches should be verified (nop operation)",
11091 .insns = {
11092 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11093 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11094 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11095 BPF_LD_MAP_FD(BPF_REG_1, 0),
11096 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11097 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
11098 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11099 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11100 BPF_MOV64_IMM(BPF_REG_4, 0),
11101 BPF_JMP_A(1),
11102 BPF_MOV64_IMM(BPF_REG_4, 1),
11103 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11104 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11105 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11106 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
11107 BPF_MOV64_IMM(BPF_REG_6, 0),
11108 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
11109 BPF_EXIT_INSN(),
11110 },
11111 .fixup_map1 = { 3 },
11112 .errstr = "R6 invalid mem access 'inv'",
11113 .result = REJECT,
11114 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11115 },
11116 {
11117 "search pruning: all branches should be verified (invalid stack access)",
11118 .insns = {
11119 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11120 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11121 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11122 BPF_LD_MAP_FD(BPF_REG_1, 0),
11123 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11124 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
11125 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11126 BPF_MOV64_IMM(BPF_REG_4, 0),
11127 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11128 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11129 BPF_JMP_A(1),
11130 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
11131 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11132 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11133 BPF_EXIT_INSN(),
11134 },
11135 .fixup_map1 = { 3 },
11136 .errstr = "invalid read from stack off -16+0 size 8",
11137 .result = REJECT,
11138 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11139 },
8829}; 11140};
8830 11141
8831static int probe_filter_length(const struct bpf_insn *fp) 11142static int probe_filter_length(const struct bpf_insn *fp)
@@ -8937,10 +11248,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
8937 int fd_prog, expected_ret, reject_from_alignment; 11248 int fd_prog, expected_ret, reject_from_alignment;
8938 struct bpf_insn *prog = test->insns; 11249 struct bpf_insn *prog = test->insns;
8939 int prog_len = probe_filter_length(prog); 11250 int prog_len = probe_filter_length(prog);
11251 char data_in[TEST_DATA_LEN] = {};
8940 int prog_type = test->prog_type; 11252 int prog_type = test->prog_type;
8941 int map_fds[MAX_NR_MAPS]; 11253 int map_fds[MAX_NR_MAPS];
8942 const char *expected_err; 11254 const char *expected_err;
8943 int i; 11255 uint32_t retval;
11256 int i, err;
8944 11257
8945 for (i = 0; i < MAX_NR_MAPS; i++) 11258 for (i = 0; i < MAX_NR_MAPS; i++)
8946 map_fds[i] = -1; 11259 map_fds[i] = -1;
@@ -8983,6 +11296,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
8983 } 11296 }
8984 } 11297 }
8985 11298
11299 if (fd_prog >= 0) {
11300 err = bpf_prog_test_run(fd_prog, 1, data_in, sizeof(data_in),
11301 NULL, NULL, &retval, NULL);
11302 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
11303 printf("Unexpected bpf_prog_test_run error\n");
11304 goto fail_log;
11305 }
11306 if (!err && retval != test->retval &&
11307 test->retval != POINTER_VALUE) {
11308 printf("FAIL retval %d != %d\n", retval, test->retval);
11309 goto fail_log;
11310 }
11311 }
8986 (*passes)++; 11312 (*passes)++;
8987 printf("OK%s\n", reject_from_alignment ? 11313 printf("OK%s\n", reject_from_alignment ?
8988 " (NOTE: reject due to unknown alignment)" : ""); 11314 " (NOTE: reject due to unknown alignment)" : "");