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