diff options
Diffstat (limited to 'tools/testing/selftests/bpf/test_verifier.c')
-rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 2348 |
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 | ||
8831 | static int probe_filter_length(const struct bpf_insn *fp) | 11142 | static 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)" : ""); |