blob: 67e7c41674d26fb59d0e2c9dc2a53886b47a5894 [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 */
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020010
Daniel Borkmann2c460622017-08-04 22:24:41 +020011#include <endian.h>
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080012#include <asm/types.h>
13#include <linux/types.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010014#include <stdint.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070015#include <stdio.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010016#include <stdlib.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070017#include <unistd.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070018#include <errno.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070019#include <string.h>
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -070020#include <stddef.h>
Alexei Starovoitovbf508872015-10-07 22:23:23 -070021#include <stdbool.h>
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020022#include <sched.h>
23
Mickaël Salaünd02d8982017-02-10 00:21:37 +010024#include <sys/capability.h>
Alexei Starovoitovbf508872015-10-07 22:23:23 -070025#include <sys/resource.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070026
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020027#include <linux/unistd.h>
28#include <linux/filter.h>
29#include <linux/bpf_perf_event.h>
30#include <linux/bpf.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070031
Mickaël Salaün2ee89fb2017-02-10 00:21:38 +010032#include <bpf/bpf.h>
33
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020034#ifdef HAVE_GENHDR
35# include "autoconf.h"
36#else
37# if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
38# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
39# endif
40#endif
41
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020042#include "../../../include/linux/filter.h"
43
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020044#ifndef ARRAY_SIZE
45# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
46#endif
47
48#define MAX_INSNS 512
49#define MAX_FIXUPS 8
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070050#define MAX_NR_MAPS 4
Alexei Starovoitovbf508872015-10-07 22:23:23 -070051
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020052#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
Daniel Borkmann614d0d72017-05-25 01:05:09 +020053#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020054
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070055struct bpf_test {
56 const char *descr;
57 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020058 int fixup_map1[MAX_FIXUPS];
59 int fixup_map2[MAX_FIXUPS];
60 int fixup_prog[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070061 int fixup_map_in_map[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070062 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070063 const char *errstr_unpriv;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070064 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070065 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070066 ACCEPT,
67 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070068 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070069 enum bpf_prog_type prog_type;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020070 uint8_t flags;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070071};
72
Josef Bacik48461132016-09-28 10:54:32 -040073/* Note we want this to be 64 bit aligned so that the end of our array is
74 * actually the end of the structure.
75 */
76#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040077
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020078struct test_val {
79 unsigned int index;
80 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040081};
82
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070083static struct bpf_test tests[] = {
84 {
85 "add+sub+mul",
86 .insns = {
87 BPF_MOV64_IMM(BPF_REG_1, 1),
88 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
89 BPF_MOV64_IMM(BPF_REG_2, 3),
90 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
91 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
92 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
93 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
94 BPF_EXIT_INSN(),
95 },
96 .result = ACCEPT,
97 },
98 {
99 "unreachable",
100 .insns = {
101 BPF_EXIT_INSN(),
102 BPF_EXIT_INSN(),
103 },
104 .errstr = "unreachable",
105 .result = REJECT,
106 },
107 {
108 "unreachable2",
109 .insns = {
110 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
111 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
112 BPF_EXIT_INSN(),
113 },
114 .errstr = "unreachable",
115 .result = REJECT,
116 },
117 {
118 "out of range jump",
119 .insns = {
120 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
121 BPF_EXIT_INSN(),
122 },
123 .errstr = "jump out of range",
124 .result = REJECT,
125 },
126 {
127 "out of range jump2",
128 .insns = {
129 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
130 BPF_EXIT_INSN(),
131 },
132 .errstr = "jump out of range",
133 .result = REJECT,
134 },
135 {
136 "test1 ld_imm64",
137 .insns = {
138 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
139 BPF_LD_IMM64(BPF_REG_0, 0),
140 BPF_LD_IMM64(BPF_REG_0, 0),
141 BPF_LD_IMM64(BPF_REG_0, 1),
142 BPF_LD_IMM64(BPF_REG_0, 1),
143 BPF_MOV64_IMM(BPF_REG_0, 2),
144 BPF_EXIT_INSN(),
145 },
146 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700147 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700148 .result = REJECT,
149 },
150 {
151 "test2 ld_imm64",
152 .insns = {
153 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
154 BPF_LD_IMM64(BPF_REG_0, 0),
155 BPF_LD_IMM64(BPF_REG_0, 0),
156 BPF_LD_IMM64(BPF_REG_0, 1),
157 BPF_LD_IMM64(BPF_REG_0, 1),
158 BPF_EXIT_INSN(),
159 },
160 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700161 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700162 .result = REJECT,
163 },
164 {
165 "test3 ld_imm64",
166 .insns = {
167 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
168 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
169 BPF_LD_IMM64(BPF_REG_0, 0),
170 BPF_LD_IMM64(BPF_REG_0, 0),
171 BPF_LD_IMM64(BPF_REG_0, 1),
172 BPF_LD_IMM64(BPF_REG_0, 1),
173 BPF_EXIT_INSN(),
174 },
175 .errstr = "invalid bpf_ld_imm64 insn",
176 .result = REJECT,
177 },
178 {
179 "test4 ld_imm64",
180 .insns = {
181 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
182 BPF_EXIT_INSN(),
183 },
184 .errstr = "invalid bpf_ld_imm64 insn",
185 .result = REJECT,
186 },
187 {
188 "test5 ld_imm64",
189 .insns = {
190 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
191 },
192 .errstr = "invalid bpf_ld_imm64 insn",
193 .result = REJECT,
194 },
195 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200196 "test6 ld_imm64",
197 .insns = {
198 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
199 BPF_RAW_INSN(0, 0, 0, 0, 0),
200 BPF_EXIT_INSN(),
201 },
202 .result = ACCEPT,
203 },
204 {
205 "test7 ld_imm64",
206 .insns = {
207 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
208 BPF_RAW_INSN(0, 0, 0, 0, 1),
209 BPF_EXIT_INSN(),
210 },
211 .result = ACCEPT,
212 },
213 {
214 "test8 ld_imm64",
215 .insns = {
216 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
217 BPF_RAW_INSN(0, 0, 0, 0, 1),
218 BPF_EXIT_INSN(),
219 },
220 .errstr = "uses reserved fields",
221 .result = REJECT,
222 },
223 {
224 "test9 ld_imm64",
225 .insns = {
226 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
227 BPF_RAW_INSN(0, 0, 0, 1, 1),
228 BPF_EXIT_INSN(),
229 },
230 .errstr = "invalid bpf_ld_imm64 insn",
231 .result = REJECT,
232 },
233 {
234 "test10 ld_imm64",
235 .insns = {
236 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
237 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
238 BPF_EXIT_INSN(),
239 },
240 .errstr = "invalid bpf_ld_imm64 insn",
241 .result = REJECT,
242 },
243 {
244 "test11 ld_imm64",
245 .insns = {
246 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
247 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
248 BPF_EXIT_INSN(),
249 },
250 .errstr = "invalid bpf_ld_imm64 insn",
251 .result = REJECT,
252 },
253 {
254 "test12 ld_imm64",
255 .insns = {
256 BPF_MOV64_IMM(BPF_REG_1, 0),
257 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
258 BPF_RAW_INSN(0, 0, 0, 0, 1),
259 BPF_EXIT_INSN(),
260 },
261 .errstr = "not pointing to valid bpf_map",
262 .result = REJECT,
263 },
264 {
265 "test13 ld_imm64",
266 .insns = {
267 BPF_MOV64_IMM(BPF_REG_1, 0),
268 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
269 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
270 BPF_EXIT_INSN(),
271 },
272 .errstr = "invalid bpf_ld_imm64 insn",
273 .result = REJECT,
274 },
275 {
Daniel Borkmann7891a872018-01-10 20:04:37 +0100276 "arsh32 on imm",
277 .insns = {
278 BPF_MOV64_IMM(BPF_REG_0, 1),
279 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
280 BPF_EXIT_INSN(),
281 },
282 .result = REJECT,
283 .errstr = "BPF_ARSH not supported for 32 bit ALU",
284 },
285 {
286 "arsh32 on reg",
287 .insns = {
288 BPF_MOV64_IMM(BPF_REG_0, 1),
289 BPF_MOV64_IMM(BPF_REG_1, 5),
290 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
291 BPF_EXIT_INSN(),
292 },
293 .result = REJECT,
294 .errstr = "BPF_ARSH not supported for 32 bit ALU",
295 },
296 {
297 "arsh64 on imm",
298 .insns = {
299 BPF_MOV64_IMM(BPF_REG_0, 1),
300 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
301 BPF_EXIT_INSN(),
302 },
303 .result = ACCEPT,
304 },
305 {
306 "arsh64 on reg",
307 .insns = {
308 BPF_MOV64_IMM(BPF_REG_0, 1),
309 BPF_MOV64_IMM(BPF_REG_1, 5),
310 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
311 BPF_EXIT_INSN(),
312 },
313 .result = ACCEPT,
314 },
315 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700316 "no bpf_exit",
317 .insns = {
318 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
319 },
320 .errstr = "jump out of range",
321 .result = REJECT,
322 },
323 {
324 "loop (back-edge)",
325 .insns = {
326 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
327 BPF_EXIT_INSN(),
328 },
329 .errstr = "back-edge",
330 .result = REJECT,
331 },
332 {
333 "loop2 (back-edge)",
334 .insns = {
335 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
336 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
337 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
338 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
339 BPF_EXIT_INSN(),
340 },
341 .errstr = "back-edge",
342 .result = REJECT,
343 },
344 {
345 "conditional loop",
346 .insns = {
347 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
348 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
349 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
350 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
351 BPF_EXIT_INSN(),
352 },
353 .errstr = "back-edge",
354 .result = REJECT,
355 },
356 {
357 "read uninitialized register",
358 .insns = {
359 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
360 BPF_EXIT_INSN(),
361 },
362 .errstr = "R2 !read_ok",
363 .result = REJECT,
364 },
365 {
366 "read invalid register",
367 .insns = {
368 BPF_MOV64_REG(BPF_REG_0, -1),
369 BPF_EXIT_INSN(),
370 },
371 .errstr = "R15 is invalid",
372 .result = REJECT,
373 },
374 {
375 "program doesn't init R0 before exit",
376 .insns = {
377 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
378 BPF_EXIT_INSN(),
379 },
380 .errstr = "R0 !read_ok",
381 .result = REJECT,
382 },
383 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700384 "program doesn't init R0 before exit in all branches",
385 .insns = {
386 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
387 BPF_MOV64_IMM(BPF_REG_0, 1),
388 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
389 BPF_EXIT_INSN(),
390 },
391 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700392 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700393 .result = REJECT,
394 },
395 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700396 "stack out of bounds",
397 .insns = {
398 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
399 BPF_EXIT_INSN(),
400 },
401 .errstr = "invalid stack",
402 .result = REJECT,
403 },
404 {
405 "invalid call insn1",
406 .insns = {
407 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
408 BPF_EXIT_INSN(),
409 },
410 .errstr = "BPF_CALL uses reserved",
411 .result = REJECT,
412 },
413 {
414 "invalid call insn2",
415 .insns = {
416 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
417 BPF_EXIT_INSN(),
418 },
419 .errstr = "BPF_CALL uses reserved",
420 .result = REJECT,
421 },
422 {
423 "invalid function call",
424 .insns = {
425 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
426 BPF_EXIT_INSN(),
427 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100428 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700429 .result = REJECT,
430 },
431 {
432 "uninitialized stack1",
433 .insns = {
434 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
435 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
436 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200437 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
438 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700439 BPF_EXIT_INSN(),
440 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200441 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700442 .errstr = "invalid indirect read from stack",
443 .result = REJECT,
444 },
445 {
446 "uninitialized stack2",
447 .insns = {
448 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
449 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
450 BPF_EXIT_INSN(),
451 },
452 .errstr = "invalid read from stack",
453 .result = REJECT,
454 },
455 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200456 "invalid fp arithmetic",
457 /* If this gets ever changed, make sure JITs can deal with it. */
458 .insns = {
459 BPF_MOV64_IMM(BPF_REG_0, 0),
460 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
461 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
462 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
463 BPF_EXIT_INSN(),
464 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -0800465 .errstr = "R1 subtraction from stack pointer",
Daniel Borkmann728a8532017-04-27 01:39:32 +0200466 .result = REJECT,
467 },
468 {
469 "non-invalid fp arithmetic",
470 .insns = {
471 BPF_MOV64_IMM(BPF_REG_0, 0),
472 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
473 BPF_EXIT_INSN(),
474 },
475 .result = ACCEPT,
476 },
477 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200478 "invalid argument register",
479 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
481 BPF_FUNC_get_cgroup_classid),
482 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
483 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200484 BPF_EXIT_INSN(),
485 },
486 .errstr = "R1 !read_ok",
487 .result = REJECT,
488 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
489 },
490 {
491 "non-invalid argument register",
492 .insns = {
493 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200494 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
495 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200496 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200497 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
498 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200499 BPF_EXIT_INSN(),
500 },
501 .result = ACCEPT,
502 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
503 },
504 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700505 "check valid spill/fill",
506 .insns = {
507 /* spill R1(ctx) into stack */
508 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700509 /* fill it back into R2 */
510 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700511 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100512 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
513 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700514 BPF_EXIT_INSN(),
515 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700516 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700517 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700518 .result_unpriv = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700519 },
520 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200521 "check valid spill/fill, skb mark",
522 .insns = {
523 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
524 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
525 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
526 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
527 offsetof(struct __sk_buff, mark)),
528 BPF_EXIT_INSN(),
529 },
530 .result = ACCEPT,
531 .result_unpriv = ACCEPT,
532 },
533 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700534 "check corrupted spill/fill",
535 .insns = {
536 /* spill R1(ctx) into stack */
537 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700538 /* mess up with R1 pointer on stack */
539 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700540 /* fill back into R0 should fail */
541 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700542 BPF_EXIT_INSN(),
543 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700544 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700545 .errstr = "corrupted spill",
546 .result = REJECT,
547 },
548 {
549 "invalid src register in STX",
550 .insns = {
551 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
552 BPF_EXIT_INSN(),
553 },
554 .errstr = "R15 is invalid",
555 .result = REJECT,
556 },
557 {
558 "invalid dst register in STX",
559 .insns = {
560 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
561 BPF_EXIT_INSN(),
562 },
563 .errstr = "R14 is invalid",
564 .result = REJECT,
565 },
566 {
567 "invalid dst register in ST",
568 .insns = {
569 BPF_ST_MEM(BPF_B, 14, -1, -1),
570 BPF_EXIT_INSN(),
571 },
572 .errstr = "R14 is invalid",
573 .result = REJECT,
574 },
575 {
576 "invalid src register in LDX",
577 .insns = {
578 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
579 BPF_EXIT_INSN(),
580 },
581 .errstr = "R12 is invalid",
582 .result = REJECT,
583 },
584 {
585 "invalid dst register in LDX",
586 .insns = {
587 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
588 BPF_EXIT_INSN(),
589 },
590 .errstr = "R11 is invalid",
591 .result = REJECT,
592 },
593 {
594 "junk insn",
595 .insns = {
596 BPF_RAW_INSN(0, 0, 0, 0, 0),
597 BPF_EXIT_INSN(),
598 },
599 .errstr = "invalid BPF_LD_IMM",
600 .result = REJECT,
601 },
602 {
603 "junk insn2",
604 .insns = {
605 BPF_RAW_INSN(1, 0, 0, 0, 0),
606 BPF_EXIT_INSN(),
607 },
608 .errstr = "BPF_LDX uses reserved fields",
609 .result = REJECT,
610 },
611 {
612 "junk insn3",
613 .insns = {
614 BPF_RAW_INSN(-1, 0, 0, 0, 0),
615 BPF_EXIT_INSN(),
616 },
617 .errstr = "invalid BPF_ALU opcode f0",
618 .result = REJECT,
619 },
620 {
621 "junk insn4",
622 .insns = {
623 BPF_RAW_INSN(-1, -1, -1, -1, -1),
624 BPF_EXIT_INSN(),
625 },
626 .errstr = "invalid BPF_ALU opcode f0",
627 .result = REJECT,
628 },
629 {
630 "junk insn5",
631 .insns = {
632 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
633 BPF_EXIT_INSN(),
634 },
635 .errstr = "BPF_ALU uses reserved fields",
636 .result = REJECT,
637 },
638 {
639 "misaligned read from stack",
640 .insns = {
641 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
642 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
643 BPF_EXIT_INSN(),
644 },
Edward Creef65b1842017-08-07 15:27:12 +0100645 .errstr = "misaligned stack access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700646 .result = REJECT,
647 },
648 {
649 "invalid map_fd for function call",
650 .insns = {
651 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
652 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
653 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
654 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200655 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
656 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700657 BPF_EXIT_INSN(),
658 },
659 .errstr = "fd 0 is not pointing to valid bpf_map",
660 .result = REJECT,
661 },
662 {
663 "don't check return value before access",
664 .insns = {
665 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
666 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
667 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
668 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200669 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
670 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700671 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
672 BPF_EXIT_INSN(),
673 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200674 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700675 .errstr = "R0 invalid mem access 'map_value_or_null'",
676 .result = REJECT,
677 },
678 {
679 "access memory with incorrect alignment",
680 .insns = {
681 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
682 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
683 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
684 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200685 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
686 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700687 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
688 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
689 BPF_EXIT_INSN(),
690 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200691 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +0100692 .errstr = "misaligned value access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700693 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +0100694 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700695 },
696 {
697 "sometimes access memory with incorrect alignment",
698 .insns = {
699 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
700 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
701 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
702 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
704 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700705 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
706 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
707 BPF_EXIT_INSN(),
708 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
709 BPF_EXIT_INSN(),
710 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200711 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700712 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700713 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700714 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +0100715 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700716 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700717 {
718 "jump test 1",
719 .insns = {
720 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
721 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
723 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
724 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
725 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
726 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
727 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
728 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
729 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
730 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
731 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
732 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
733 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
734 BPF_MOV64_IMM(BPF_REG_0, 0),
735 BPF_EXIT_INSN(),
736 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700737 .errstr_unpriv = "R1 pointer comparison",
738 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700739 .result = ACCEPT,
740 },
741 {
742 "jump test 2",
743 .insns = {
744 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
745 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
746 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
747 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
748 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
749 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
750 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
751 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
752 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
753 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
754 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
755 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
756 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
757 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
758 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
759 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
760 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
761 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
762 BPF_MOV64_IMM(BPF_REG_0, 0),
763 BPF_EXIT_INSN(),
764 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700765 .errstr_unpriv = "R1 pointer comparison",
766 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700767 .result = ACCEPT,
768 },
769 {
770 "jump test 3",
771 .insns = {
772 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
773 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
774 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
775 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
776 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
777 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
778 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
780 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
781 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
782 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
784 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
785 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
786 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
788 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
789 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
790 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
791 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
792 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
793 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
794 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
796 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
798 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700799 BPF_EXIT_INSN(),
800 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200801 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700802 .errstr_unpriv = "R1 pointer comparison",
803 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700804 .result = ACCEPT,
805 },
806 {
807 "jump test 4",
808 .insns = {
809 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
810 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
811 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
812 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
813 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
814 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
815 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
816 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
817 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
818 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
820 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
821 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
822 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
823 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
824 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
825 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
828 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
829 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
830 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
831 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
832 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
833 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
834 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
835 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
836 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
837 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
838 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
839 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
840 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
841 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
842 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
843 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
844 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
845 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
847 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
848 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
849 BPF_MOV64_IMM(BPF_REG_0, 0),
850 BPF_EXIT_INSN(),
851 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700852 .errstr_unpriv = "R1 pointer comparison",
853 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700854 .result = ACCEPT,
855 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700856 {
857 "jump test 5",
858 .insns = {
859 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
860 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
861 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
862 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
863 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
864 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
865 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
866 BPF_MOV64_IMM(BPF_REG_0, 0),
867 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
868 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
869 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
870 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
871 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
872 BPF_MOV64_IMM(BPF_REG_0, 0),
873 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
874 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
875 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
876 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
877 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
878 BPF_MOV64_IMM(BPF_REG_0, 0),
879 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
880 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
881 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
882 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
883 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
884 BPF_MOV64_IMM(BPF_REG_0, 0),
885 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
886 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
887 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
888 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
889 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
890 BPF_MOV64_IMM(BPF_REG_0, 0),
891 BPF_EXIT_INSN(),
892 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700893 .errstr_unpriv = "R1 pointer comparison",
894 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700895 .result = ACCEPT,
896 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700897 {
898 "access skb fields ok",
899 .insns = {
900 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
901 offsetof(struct __sk_buff, len)),
902 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
903 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
904 offsetof(struct __sk_buff, mark)),
905 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
906 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
907 offsetof(struct __sk_buff, pkt_type)),
908 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
909 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
910 offsetof(struct __sk_buff, queue_mapping)),
911 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -0700912 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
913 offsetof(struct __sk_buff, protocol)),
914 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
915 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
916 offsetof(struct __sk_buff, vlan_present)),
917 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
918 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
919 offsetof(struct __sk_buff, vlan_tci)),
920 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Daniel Borkmannb1d9fc42017-04-19 23:01:17 +0200921 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
922 offsetof(struct __sk_buff, napi_id)),
923 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700924 BPF_EXIT_INSN(),
925 },
926 .result = ACCEPT,
927 },
928 {
929 "access skb fields bad1",
930 .insns = {
931 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
932 BPF_EXIT_INSN(),
933 },
934 .errstr = "invalid bpf_context access",
935 .result = REJECT,
936 },
937 {
938 "access skb fields bad2",
939 .insns = {
940 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
941 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
942 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
943 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
944 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200945 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
946 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700947 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
948 BPF_EXIT_INSN(),
949 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
950 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
951 offsetof(struct __sk_buff, pkt_type)),
952 BPF_EXIT_INSN(),
953 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200954 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700955 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700956 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700957 .result = REJECT,
958 },
959 {
960 "access skb fields bad3",
961 .insns = {
962 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
963 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
964 offsetof(struct __sk_buff, pkt_type)),
965 BPF_EXIT_INSN(),
966 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
967 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
969 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200970 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
971 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700972 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
973 BPF_EXIT_INSN(),
974 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
975 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
976 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200977 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700978 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700979 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700980 .result = REJECT,
981 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700982 {
983 "access skb fields bad4",
984 .insns = {
985 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
986 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
987 offsetof(struct __sk_buff, len)),
988 BPF_MOV64_IMM(BPF_REG_0, 0),
989 BPF_EXIT_INSN(),
990 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
991 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
992 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
993 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200994 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
995 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700996 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
997 BPF_EXIT_INSN(),
998 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
999 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1000 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001001 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001002 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001003 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001004 .result = REJECT,
1005 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001006 {
John Fastabend41bc94f2017-08-15 22:33:56 -07001007 "invalid access __sk_buff family",
1008 .insns = {
1009 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1010 offsetof(struct __sk_buff, family)),
1011 BPF_EXIT_INSN(),
1012 },
1013 .errstr = "invalid bpf_context access",
1014 .result = REJECT,
1015 },
1016 {
1017 "invalid access __sk_buff remote_ip4",
1018 .insns = {
1019 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1020 offsetof(struct __sk_buff, remote_ip4)),
1021 BPF_EXIT_INSN(),
1022 },
1023 .errstr = "invalid bpf_context access",
1024 .result = REJECT,
1025 },
1026 {
1027 "invalid access __sk_buff local_ip4",
1028 .insns = {
1029 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1030 offsetof(struct __sk_buff, local_ip4)),
1031 BPF_EXIT_INSN(),
1032 },
1033 .errstr = "invalid bpf_context access",
1034 .result = REJECT,
1035 },
1036 {
1037 "invalid access __sk_buff remote_ip6",
1038 .insns = {
1039 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1040 offsetof(struct __sk_buff, remote_ip6)),
1041 BPF_EXIT_INSN(),
1042 },
1043 .errstr = "invalid bpf_context access",
1044 .result = REJECT,
1045 },
1046 {
1047 "invalid access __sk_buff local_ip6",
1048 .insns = {
1049 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1050 offsetof(struct __sk_buff, local_ip6)),
1051 BPF_EXIT_INSN(),
1052 },
1053 .errstr = "invalid bpf_context access",
1054 .result = REJECT,
1055 },
1056 {
1057 "invalid access __sk_buff remote_port",
1058 .insns = {
1059 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1060 offsetof(struct __sk_buff, remote_port)),
1061 BPF_EXIT_INSN(),
1062 },
1063 .errstr = "invalid bpf_context access",
1064 .result = REJECT,
1065 },
1066 {
1067 "invalid access __sk_buff remote_port",
1068 .insns = {
1069 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1070 offsetof(struct __sk_buff, local_port)),
1071 BPF_EXIT_INSN(),
1072 },
1073 .errstr = "invalid bpf_context access",
1074 .result = REJECT,
1075 },
1076 {
1077 "valid access __sk_buff family",
1078 .insns = {
1079 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1080 offsetof(struct __sk_buff, family)),
1081 BPF_EXIT_INSN(),
1082 },
1083 .result = ACCEPT,
1084 .prog_type = BPF_PROG_TYPE_SK_SKB,
1085 },
1086 {
1087 "valid access __sk_buff remote_ip4",
1088 .insns = {
1089 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1090 offsetof(struct __sk_buff, remote_ip4)),
1091 BPF_EXIT_INSN(),
1092 },
1093 .result = ACCEPT,
1094 .prog_type = BPF_PROG_TYPE_SK_SKB,
1095 },
1096 {
1097 "valid access __sk_buff local_ip4",
1098 .insns = {
1099 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1100 offsetof(struct __sk_buff, local_ip4)),
1101 BPF_EXIT_INSN(),
1102 },
1103 .result = ACCEPT,
1104 .prog_type = BPF_PROG_TYPE_SK_SKB,
1105 },
1106 {
1107 "valid access __sk_buff remote_ip6",
1108 .insns = {
1109 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1110 offsetof(struct __sk_buff, remote_ip6[0])),
1111 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1112 offsetof(struct __sk_buff, remote_ip6[1])),
1113 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1114 offsetof(struct __sk_buff, remote_ip6[2])),
1115 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1116 offsetof(struct __sk_buff, remote_ip6[3])),
1117 BPF_EXIT_INSN(),
1118 },
1119 .result = ACCEPT,
1120 .prog_type = BPF_PROG_TYPE_SK_SKB,
1121 },
1122 {
1123 "valid access __sk_buff local_ip6",
1124 .insns = {
1125 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1126 offsetof(struct __sk_buff, local_ip6[0])),
1127 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1128 offsetof(struct __sk_buff, local_ip6[1])),
1129 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1130 offsetof(struct __sk_buff, local_ip6[2])),
1131 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1132 offsetof(struct __sk_buff, local_ip6[3])),
1133 BPF_EXIT_INSN(),
1134 },
1135 .result = ACCEPT,
1136 .prog_type = BPF_PROG_TYPE_SK_SKB,
1137 },
1138 {
1139 "valid access __sk_buff remote_port",
1140 .insns = {
1141 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1142 offsetof(struct __sk_buff, remote_port)),
1143 BPF_EXIT_INSN(),
1144 },
1145 .result = ACCEPT,
1146 .prog_type = BPF_PROG_TYPE_SK_SKB,
1147 },
1148 {
1149 "valid access __sk_buff remote_port",
1150 .insns = {
1151 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1152 offsetof(struct __sk_buff, local_port)),
1153 BPF_EXIT_INSN(),
1154 },
1155 .result = ACCEPT,
1156 .prog_type = BPF_PROG_TYPE_SK_SKB,
1157 },
1158 {
John Fastabended850542017-08-28 07:11:24 -07001159 "invalid access of tc_classid for SK_SKB",
1160 .insns = {
1161 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1162 offsetof(struct __sk_buff, tc_classid)),
1163 BPF_EXIT_INSN(),
1164 },
1165 .result = REJECT,
1166 .prog_type = BPF_PROG_TYPE_SK_SKB,
1167 .errstr = "invalid bpf_context access",
1168 },
1169 {
John Fastabendf7e9cb12017-10-18 07:10:58 -07001170 "invalid access of skb->mark for SK_SKB",
1171 .insns = {
1172 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1173 offsetof(struct __sk_buff, mark)),
1174 BPF_EXIT_INSN(),
1175 },
1176 .result = REJECT,
1177 .prog_type = BPF_PROG_TYPE_SK_SKB,
1178 .errstr = "invalid bpf_context access",
1179 },
1180 {
1181 "check skb->mark is not writeable by SK_SKB",
John Fastabended850542017-08-28 07:11:24 -07001182 .insns = {
1183 BPF_MOV64_IMM(BPF_REG_0, 0),
1184 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1185 offsetof(struct __sk_buff, mark)),
1186 BPF_EXIT_INSN(),
1187 },
John Fastabendf7e9cb12017-10-18 07:10:58 -07001188 .result = REJECT,
John Fastabended850542017-08-28 07:11:24 -07001189 .prog_type = BPF_PROG_TYPE_SK_SKB,
John Fastabendf7e9cb12017-10-18 07:10:58 -07001190 .errstr = "invalid bpf_context access",
John Fastabended850542017-08-28 07:11:24 -07001191 },
1192 {
1193 "check skb->tc_index is writeable by SK_SKB",
1194 .insns = {
1195 BPF_MOV64_IMM(BPF_REG_0, 0),
1196 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1197 offsetof(struct __sk_buff, tc_index)),
1198 BPF_EXIT_INSN(),
1199 },
1200 .result = ACCEPT,
1201 .prog_type = BPF_PROG_TYPE_SK_SKB,
1202 },
1203 {
1204 "check skb->priority is writeable by SK_SKB",
1205 .insns = {
1206 BPF_MOV64_IMM(BPF_REG_0, 0),
1207 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1208 offsetof(struct __sk_buff, priority)),
1209 BPF_EXIT_INSN(),
1210 },
1211 .result = ACCEPT,
1212 .prog_type = BPF_PROG_TYPE_SK_SKB,
1213 },
1214 {
1215 "direct packet read for SK_SKB",
1216 .insns = {
1217 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1218 offsetof(struct __sk_buff, data)),
1219 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1220 offsetof(struct __sk_buff, data_end)),
1221 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1223 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1224 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1225 BPF_MOV64_IMM(BPF_REG_0, 0),
1226 BPF_EXIT_INSN(),
1227 },
1228 .result = ACCEPT,
1229 .prog_type = BPF_PROG_TYPE_SK_SKB,
1230 },
1231 {
1232 "direct packet write for SK_SKB",
1233 .insns = {
1234 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1235 offsetof(struct __sk_buff, data)),
1236 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1237 offsetof(struct __sk_buff, data_end)),
1238 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1239 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1240 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1241 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1242 BPF_MOV64_IMM(BPF_REG_0, 0),
1243 BPF_EXIT_INSN(),
1244 },
1245 .result = ACCEPT,
1246 .prog_type = BPF_PROG_TYPE_SK_SKB,
1247 },
1248 {
1249 "overlapping checks for direct packet access SK_SKB",
1250 .insns = {
1251 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1252 offsetof(struct __sk_buff, data)),
1253 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1254 offsetof(struct __sk_buff, data_end)),
1255 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1256 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1257 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1258 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1260 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1261 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1262 BPF_MOV64_IMM(BPF_REG_0, 0),
1263 BPF_EXIT_INSN(),
1264 },
1265 .result = ACCEPT,
1266 .prog_type = BPF_PROG_TYPE_SK_SKB,
1267 },
1268 {
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001269 "check skb->mark is not writeable by sockets",
1270 .insns = {
1271 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1272 offsetof(struct __sk_buff, mark)),
1273 BPF_EXIT_INSN(),
1274 },
1275 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001276 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001277 .result = REJECT,
1278 },
1279 {
1280 "check skb->tc_index is not writeable by sockets",
1281 .insns = {
1282 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1283 offsetof(struct __sk_buff, tc_index)),
1284 BPF_EXIT_INSN(),
1285 },
1286 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001287 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001288 .result = REJECT,
1289 },
1290 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001291 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001292 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001293 BPF_MOV64_IMM(BPF_REG_0, 0),
1294 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1295 offsetof(struct __sk_buff, cb[0])),
1296 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1297 offsetof(struct __sk_buff, cb[0]) + 1),
1298 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1299 offsetof(struct __sk_buff, cb[0]) + 2),
1300 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1301 offsetof(struct __sk_buff, cb[0]) + 3),
1302 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1303 offsetof(struct __sk_buff, cb[1])),
1304 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1305 offsetof(struct __sk_buff, cb[1]) + 1),
1306 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1307 offsetof(struct __sk_buff, cb[1]) + 2),
1308 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1309 offsetof(struct __sk_buff, cb[1]) + 3),
1310 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1311 offsetof(struct __sk_buff, cb[2])),
1312 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1313 offsetof(struct __sk_buff, cb[2]) + 1),
1314 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1315 offsetof(struct __sk_buff, cb[2]) + 2),
1316 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1317 offsetof(struct __sk_buff, cb[2]) + 3),
1318 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1319 offsetof(struct __sk_buff, cb[3])),
1320 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1321 offsetof(struct __sk_buff, cb[3]) + 1),
1322 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1323 offsetof(struct __sk_buff, cb[3]) + 2),
1324 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1325 offsetof(struct __sk_buff, cb[3]) + 3),
1326 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1327 offsetof(struct __sk_buff, cb[4])),
1328 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1329 offsetof(struct __sk_buff, cb[4]) + 1),
1330 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1331 offsetof(struct __sk_buff, cb[4]) + 2),
1332 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1333 offsetof(struct __sk_buff, cb[4]) + 3),
1334 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1335 offsetof(struct __sk_buff, cb[0])),
1336 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1337 offsetof(struct __sk_buff, cb[0]) + 1),
1338 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1339 offsetof(struct __sk_buff, cb[0]) + 2),
1340 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1341 offsetof(struct __sk_buff, cb[0]) + 3),
1342 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1343 offsetof(struct __sk_buff, cb[1])),
1344 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1345 offsetof(struct __sk_buff, cb[1]) + 1),
1346 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1347 offsetof(struct __sk_buff, cb[1]) + 2),
1348 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1349 offsetof(struct __sk_buff, cb[1]) + 3),
1350 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1351 offsetof(struct __sk_buff, cb[2])),
1352 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1353 offsetof(struct __sk_buff, cb[2]) + 1),
1354 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1355 offsetof(struct __sk_buff, cb[2]) + 2),
1356 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1357 offsetof(struct __sk_buff, cb[2]) + 3),
1358 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1359 offsetof(struct __sk_buff, cb[3])),
1360 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1361 offsetof(struct __sk_buff, cb[3]) + 1),
1362 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1363 offsetof(struct __sk_buff, cb[3]) + 2),
1364 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1365 offsetof(struct __sk_buff, cb[3]) + 3),
1366 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1367 offsetof(struct __sk_buff, cb[4])),
1368 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1369 offsetof(struct __sk_buff, cb[4]) + 1),
1370 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1371 offsetof(struct __sk_buff, cb[4]) + 2),
1372 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1373 offsetof(struct __sk_buff, cb[4]) + 3),
1374 BPF_EXIT_INSN(),
1375 },
1376 .result = ACCEPT,
1377 },
1378 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001379 "__sk_buff->hash, offset 0, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001380 .insns = {
1381 BPF_MOV64_IMM(BPF_REG_0, 0),
1382 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001383 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001384 BPF_EXIT_INSN(),
1385 },
1386 .errstr = "invalid bpf_context access",
1387 .result = REJECT,
1388 },
1389 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001390 "__sk_buff->tc_index, offset 3, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001391 .insns = {
1392 BPF_MOV64_IMM(BPF_REG_0, 0),
1393 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001394 offsetof(struct __sk_buff, tc_index) + 3),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001395 BPF_EXIT_INSN(),
1396 },
1397 .errstr = "invalid bpf_context access",
1398 .result = REJECT,
1399 },
1400 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001401 "check skb->hash byte load permitted",
1402 .insns = {
1403 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001404#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001405 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1406 offsetof(struct __sk_buff, hash)),
1407#else
1408 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1409 offsetof(struct __sk_buff, hash) + 3),
1410#endif
1411 BPF_EXIT_INSN(),
1412 },
1413 .result = ACCEPT,
1414 },
1415 {
1416 "check skb->hash byte load not permitted 1",
1417 .insns = {
1418 BPF_MOV64_IMM(BPF_REG_0, 0),
1419 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1420 offsetof(struct __sk_buff, hash) + 1),
1421 BPF_EXIT_INSN(),
1422 },
1423 .errstr = "invalid bpf_context access",
1424 .result = REJECT,
1425 },
1426 {
1427 "check skb->hash byte load not permitted 2",
1428 .insns = {
1429 BPF_MOV64_IMM(BPF_REG_0, 0),
1430 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1431 offsetof(struct __sk_buff, hash) + 2),
1432 BPF_EXIT_INSN(),
1433 },
1434 .errstr = "invalid bpf_context access",
1435 .result = REJECT,
1436 },
1437 {
1438 "check skb->hash byte load not permitted 3",
1439 .insns = {
1440 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001441#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001442 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1443 offsetof(struct __sk_buff, hash) + 3),
1444#else
1445 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1446 offsetof(struct __sk_buff, hash)),
1447#endif
1448 BPF_EXIT_INSN(),
1449 },
1450 .errstr = "invalid bpf_context access",
1451 .result = REJECT,
1452 },
1453 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001454 "check cb access: byte, wrong type",
1455 .insns = {
1456 BPF_MOV64_IMM(BPF_REG_0, 0),
1457 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001458 offsetof(struct __sk_buff, cb[0])),
1459 BPF_EXIT_INSN(),
1460 },
1461 .errstr = "invalid bpf_context access",
1462 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001463 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1464 },
1465 {
1466 "check cb access: half",
1467 .insns = {
1468 BPF_MOV64_IMM(BPF_REG_0, 0),
1469 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1470 offsetof(struct __sk_buff, cb[0])),
1471 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1472 offsetof(struct __sk_buff, cb[0]) + 2),
1473 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1474 offsetof(struct __sk_buff, cb[1])),
1475 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1476 offsetof(struct __sk_buff, cb[1]) + 2),
1477 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1478 offsetof(struct __sk_buff, cb[2])),
1479 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1480 offsetof(struct __sk_buff, cb[2]) + 2),
1481 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1482 offsetof(struct __sk_buff, cb[3])),
1483 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1484 offsetof(struct __sk_buff, cb[3]) + 2),
1485 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1486 offsetof(struct __sk_buff, cb[4])),
1487 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1488 offsetof(struct __sk_buff, cb[4]) + 2),
1489 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1490 offsetof(struct __sk_buff, cb[0])),
1491 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1492 offsetof(struct __sk_buff, cb[0]) + 2),
1493 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1494 offsetof(struct __sk_buff, cb[1])),
1495 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1496 offsetof(struct __sk_buff, cb[1]) + 2),
1497 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1498 offsetof(struct __sk_buff, cb[2])),
1499 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1500 offsetof(struct __sk_buff, cb[2]) + 2),
1501 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1502 offsetof(struct __sk_buff, cb[3])),
1503 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1504 offsetof(struct __sk_buff, cb[3]) + 2),
1505 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1506 offsetof(struct __sk_buff, cb[4])),
1507 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1508 offsetof(struct __sk_buff, cb[4]) + 2),
1509 BPF_EXIT_INSN(),
1510 },
1511 .result = ACCEPT,
1512 },
1513 {
1514 "check cb access: half, unaligned",
1515 .insns = {
1516 BPF_MOV64_IMM(BPF_REG_0, 0),
1517 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1518 offsetof(struct __sk_buff, cb[0]) + 1),
1519 BPF_EXIT_INSN(),
1520 },
Edward Creef65b1842017-08-07 15:27:12 +01001521 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001522 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001523 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001524 },
1525 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001526 "check __sk_buff->hash, offset 0, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001527 .insns = {
1528 BPF_MOV64_IMM(BPF_REG_0, 0),
1529 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001530 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001531 BPF_EXIT_INSN(),
1532 },
1533 .errstr = "invalid bpf_context access",
1534 .result = REJECT,
1535 },
1536 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001537 "check __sk_buff->tc_index, offset 2, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001538 .insns = {
1539 BPF_MOV64_IMM(BPF_REG_0, 0),
1540 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001541 offsetof(struct __sk_buff, tc_index) + 2),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001542 BPF_EXIT_INSN(),
1543 },
1544 .errstr = "invalid bpf_context access",
1545 .result = REJECT,
1546 },
1547 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001548 "check skb->hash half load permitted",
1549 .insns = {
1550 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001551#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001552 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1553 offsetof(struct __sk_buff, hash)),
1554#else
1555 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1556 offsetof(struct __sk_buff, hash) + 2),
1557#endif
1558 BPF_EXIT_INSN(),
1559 },
1560 .result = ACCEPT,
1561 },
1562 {
1563 "check skb->hash half load not permitted",
1564 .insns = {
1565 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001566#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001567 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1568 offsetof(struct __sk_buff, hash) + 2),
1569#else
1570 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1571 offsetof(struct __sk_buff, hash)),
1572#endif
1573 BPF_EXIT_INSN(),
1574 },
1575 .errstr = "invalid bpf_context access",
1576 .result = REJECT,
1577 },
1578 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001579 "check cb access: half, wrong type",
1580 .insns = {
1581 BPF_MOV64_IMM(BPF_REG_0, 0),
1582 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1583 offsetof(struct __sk_buff, cb[0])),
1584 BPF_EXIT_INSN(),
1585 },
1586 .errstr = "invalid bpf_context access",
1587 .result = REJECT,
1588 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1589 },
1590 {
1591 "check cb access: word",
1592 .insns = {
1593 BPF_MOV64_IMM(BPF_REG_0, 0),
1594 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1595 offsetof(struct __sk_buff, cb[0])),
1596 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1597 offsetof(struct __sk_buff, cb[1])),
1598 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1599 offsetof(struct __sk_buff, cb[2])),
1600 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1601 offsetof(struct __sk_buff, cb[3])),
1602 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1603 offsetof(struct __sk_buff, cb[4])),
1604 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1605 offsetof(struct __sk_buff, cb[0])),
1606 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1607 offsetof(struct __sk_buff, cb[1])),
1608 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1609 offsetof(struct __sk_buff, cb[2])),
1610 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1611 offsetof(struct __sk_buff, cb[3])),
1612 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1613 offsetof(struct __sk_buff, cb[4])),
1614 BPF_EXIT_INSN(),
1615 },
1616 .result = ACCEPT,
1617 },
1618 {
1619 "check cb access: word, unaligned 1",
1620 .insns = {
1621 BPF_MOV64_IMM(BPF_REG_0, 0),
1622 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1623 offsetof(struct __sk_buff, cb[0]) + 2),
1624 BPF_EXIT_INSN(),
1625 },
Edward Creef65b1842017-08-07 15:27:12 +01001626 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001627 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001628 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001629 },
1630 {
1631 "check cb access: word, unaligned 2",
1632 .insns = {
1633 BPF_MOV64_IMM(BPF_REG_0, 0),
1634 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1635 offsetof(struct __sk_buff, cb[4]) + 1),
1636 BPF_EXIT_INSN(),
1637 },
Edward Creef65b1842017-08-07 15:27:12 +01001638 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001639 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001640 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001641 },
1642 {
1643 "check cb access: word, unaligned 3",
1644 .insns = {
1645 BPF_MOV64_IMM(BPF_REG_0, 0),
1646 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1647 offsetof(struct __sk_buff, cb[4]) + 2),
1648 BPF_EXIT_INSN(),
1649 },
Edward Creef65b1842017-08-07 15:27:12 +01001650 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001651 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001652 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001653 },
1654 {
1655 "check cb access: word, unaligned 4",
1656 .insns = {
1657 BPF_MOV64_IMM(BPF_REG_0, 0),
1658 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1659 offsetof(struct __sk_buff, cb[4]) + 3),
1660 BPF_EXIT_INSN(),
1661 },
Edward Creef65b1842017-08-07 15:27:12 +01001662 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001663 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001664 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001665 },
1666 {
1667 "check cb access: double",
1668 .insns = {
1669 BPF_MOV64_IMM(BPF_REG_0, 0),
1670 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1671 offsetof(struct __sk_buff, cb[0])),
1672 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1673 offsetof(struct __sk_buff, cb[2])),
1674 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1675 offsetof(struct __sk_buff, cb[0])),
1676 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1677 offsetof(struct __sk_buff, cb[2])),
1678 BPF_EXIT_INSN(),
1679 },
1680 .result = ACCEPT,
1681 },
1682 {
1683 "check cb access: double, unaligned 1",
1684 .insns = {
1685 BPF_MOV64_IMM(BPF_REG_0, 0),
1686 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1687 offsetof(struct __sk_buff, cb[1])),
1688 BPF_EXIT_INSN(),
1689 },
Edward Creef65b1842017-08-07 15:27:12 +01001690 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001691 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001692 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001693 },
1694 {
1695 "check cb access: double, unaligned 2",
1696 .insns = {
1697 BPF_MOV64_IMM(BPF_REG_0, 0),
1698 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1699 offsetof(struct __sk_buff, cb[3])),
1700 BPF_EXIT_INSN(),
1701 },
Edward Creef65b1842017-08-07 15:27:12 +01001702 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001703 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001704 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001705 },
1706 {
1707 "check cb access: double, oob 1",
1708 .insns = {
1709 BPF_MOV64_IMM(BPF_REG_0, 0),
1710 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1711 offsetof(struct __sk_buff, cb[4])),
1712 BPF_EXIT_INSN(),
1713 },
1714 .errstr = "invalid bpf_context access",
1715 .result = REJECT,
1716 },
1717 {
1718 "check cb access: double, oob 2",
1719 .insns = {
1720 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001721 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1722 offsetof(struct __sk_buff, cb[4])),
1723 BPF_EXIT_INSN(),
1724 },
1725 .errstr = "invalid bpf_context access",
1726 .result = REJECT,
1727 },
1728 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001729 "check __sk_buff->ifindex dw store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001730 .insns = {
1731 BPF_MOV64_IMM(BPF_REG_0, 0),
Yonghong Song31fd8582017-06-13 15:52:13 -07001732 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1733 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001734 BPF_EXIT_INSN(),
1735 },
1736 .errstr = "invalid bpf_context access",
1737 .result = REJECT,
1738 },
1739 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001740 "check __sk_buff->ifindex dw load not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001741 .insns = {
1742 BPF_MOV64_IMM(BPF_REG_0, 0),
1743 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
Yonghong Song31fd8582017-06-13 15:52:13 -07001744 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001745 BPF_EXIT_INSN(),
1746 },
1747 .errstr = "invalid bpf_context access",
1748 .result = REJECT,
1749 },
1750 {
1751 "check cb access: double, wrong type",
1752 .insns = {
1753 BPF_MOV64_IMM(BPF_REG_0, 0),
1754 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1755 offsetof(struct __sk_buff, cb[0])),
1756 BPF_EXIT_INSN(),
1757 },
1758 .errstr = "invalid bpf_context access",
1759 .result = REJECT,
1760 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001761 },
1762 {
1763 "check out of range skb->cb access",
1764 .insns = {
1765 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001766 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001767 BPF_EXIT_INSN(),
1768 },
1769 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001770 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001771 .result = REJECT,
1772 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
1773 },
1774 {
1775 "write skb fields from socket prog",
1776 .insns = {
1777 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1778 offsetof(struct __sk_buff, cb[4])),
1779 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1780 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1781 offsetof(struct __sk_buff, mark)),
1782 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1783 offsetof(struct __sk_buff, tc_index)),
1784 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1785 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1786 offsetof(struct __sk_buff, cb[0])),
1787 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1788 offsetof(struct __sk_buff, cb[2])),
1789 BPF_EXIT_INSN(),
1790 },
1791 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001792 .errstr_unpriv = "R1 leaks addr",
1793 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001794 },
1795 {
1796 "write skb fields from tc_cls_act prog",
1797 .insns = {
1798 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1799 offsetof(struct __sk_buff, cb[0])),
1800 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1801 offsetof(struct __sk_buff, mark)),
1802 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1803 offsetof(struct __sk_buff, tc_index)),
1804 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1805 offsetof(struct __sk_buff, tc_index)),
1806 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1807 offsetof(struct __sk_buff, cb[3])),
1808 BPF_EXIT_INSN(),
1809 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001810 .errstr_unpriv = "",
1811 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001812 .result = ACCEPT,
1813 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1814 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001815 {
1816 "PTR_TO_STACK store/load",
1817 .insns = {
1818 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1819 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1820 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1821 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1822 BPF_EXIT_INSN(),
1823 },
1824 .result = ACCEPT,
1825 },
1826 {
1827 "PTR_TO_STACK store/load - bad alignment on off",
1828 .insns = {
1829 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1830 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1831 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1832 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1833 BPF_EXIT_INSN(),
1834 },
1835 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001836 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001837 },
1838 {
1839 "PTR_TO_STACK store/load - bad alignment on reg",
1840 .insns = {
1841 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1843 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1844 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1845 BPF_EXIT_INSN(),
1846 },
1847 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001848 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001849 },
1850 {
1851 "PTR_TO_STACK store/load - out of bounds low",
1852 .insns = {
1853 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1854 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1855 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1856 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1857 BPF_EXIT_INSN(),
1858 },
1859 .result = REJECT,
1860 .errstr = "invalid stack off=-79992 size=8",
1861 },
1862 {
1863 "PTR_TO_STACK store/load - out of bounds high",
1864 .insns = {
1865 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1866 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1867 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1868 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1869 BPF_EXIT_INSN(),
1870 },
1871 .result = REJECT,
1872 .errstr = "invalid stack off=0 size=8",
1873 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001874 {
1875 "unpriv: return pointer",
1876 .insns = {
1877 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1878 BPF_EXIT_INSN(),
1879 },
1880 .result = ACCEPT,
1881 .result_unpriv = REJECT,
1882 .errstr_unpriv = "R0 leaks addr",
1883 },
1884 {
1885 "unpriv: add const to pointer",
1886 .insns = {
1887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1888 BPF_MOV64_IMM(BPF_REG_0, 0),
1889 BPF_EXIT_INSN(),
1890 },
1891 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001892 },
1893 {
1894 "unpriv: add pointer to pointer",
1895 .insns = {
1896 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1897 BPF_MOV64_IMM(BPF_REG_0, 0),
1898 BPF_EXIT_INSN(),
1899 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08001900 .result = REJECT,
1901 .errstr = "R1 pointer += pointer",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001902 },
1903 {
1904 "unpriv: neg pointer",
1905 .insns = {
1906 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1907 BPF_MOV64_IMM(BPF_REG_0, 0),
1908 BPF_EXIT_INSN(),
1909 },
1910 .result = ACCEPT,
1911 .result_unpriv = REJECT,
1912 .errstr_unpriv = "R1 pointer arithmetic",
1913 },
1914 {
1915 "unpriv: cmp pointer with const",
1916 .insns = {
1917 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1918 BPF_MOV64_IMM(BPF_REG_0, 0),
1919 BPF_EXIT_INSN(),
1920 },
1921 .result = ACCEPT,
1922 .result_unpriv = REJECT,
1923 .errstr_unpriv = "R1 pointer comparison",
1924 },
1925 {
1926 "unpriv: cmp pointer with pointer",
1927 .insns = {
1928 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1929 BPF_MOV64_IMM(BPF_REG_0, 0),
1930 BPF_EXIT_INSN(),
1931 },
1932 .result = ACCEPT,
1933 .result_unpriv = REJECT,
1934 .errstr_unpriv = "R10 pointer comparison",
1935 },
1936 {
1937 "unpriv: check that printk is disallowed",
1938 .insns = {
1939 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1940 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1941 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1942 BPF_MOV64_IMM(BPF_REG_2, 8),
1943 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001944 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1945 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001946 BPF_MOV64_IMM(BPF_REG_0, 0),
1947 BPF_EXIT_INSN(),
1948 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01001949 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001950 .result_unpriv = REJECT,
1951 .result = ACCEPT,
1952 },
1953 {
1954 "unpriv: pass pointer to helper function",
1955 .insns = {
1956 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1957 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1959 BPF_LD_MAP_FD(BPF_REG_1, 0),
1960 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1961 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1963 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001964 BPF_MOV64_IMM(BPF_REG_0, 0),
1965 BPF_EXIT_INSN(),
1966 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001967 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001968 .errstr_unpriv = "R4 leaks addr",
1969 .result_unpriv = REJECT,
1970 .result = ACCEPT,
1971 },
1972 {
1973 "unpriv: indirectly pass pointer on stack to helper function",
1974 .insns = {
1975 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1976 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1977 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1978 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001979 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1980 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001981 BPF_MOV64_IMM(BPF_REG_0, 0),
1982 BPF_EXIT_INSN(),
1983 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001984 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001985 .errstr = "invalid indirect read from stack off -8+0 size 8",
1986 .result = REJECT,
1987 },
1988 {
1989 "unpriv: mangle pointer on stack 1",
1990 .insns = {
1991 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1992 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1993 BPF_MOV64_IMM(BPF_REG_0, 0),
1994 BPF_EXIT_INSN(),
1995 },
1996 .errstr_unpriv = "attempt to corrupt spilled",
1997 .result_unpriv = REJECT,
1998 .result = ACCEPT,
1999 },
2000 {
2001 "unpriv: mangle pointer on stack 2",
2002 .insns = {
2003 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2004 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2005 BPF_MOV64_IMM(BPF_REG_0, 0),
2006 BPF_EXIT_INSN(),
2007 },
2008 .errstr_unpriv = "attempt to corrupt spilled",
2009 .result_unpriv = REJECT,
2010 .result = ACCEPT,
2011 },
2012 {
2013 "unpriv: read pointer from stack in small chunks",
2014 .insns = {
2015 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2016 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2017 BPF_MOV64_IMM(BPF_REG_0, 0),
2018 BPF_EXIT_INSN(),
2019 },
2020 .errstr = "invalid size",
2021 .result = REJECT,
2022 },
2023 {
2024 "unpriv: write pointer into ctx",
2025 .insns = {
2026 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2027 BPF_MOV64_IMM(BPF_REG_0, 0),
2028 BPF_EXIT_INSN(),
2029 },
2030 .errstr_unpriv = "R1 leaks addr",
2031 .result_unpriv = REJECT,
2032 .errstr = "invalid bpf_context access",
2033 .result = REJECT,
2034 },
2035 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002036 "unpriv: spill/fill of ctx",
2037 .insns = {
2038 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2039 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2040 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2041 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2042 BPF_MOV64_IMM(BPF_REG_0, 0),
2043 BPF_EXIT_INSN(),
2044 },
2045 .result = ACCEPT,
2046 },
2047 {
2048 "unpriv: spill/fill of ctx 2",
2049 .insns = {
2050 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2052 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2053 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002054 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2055 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002056 BPF_EXIT_INSN(),
2057 },
2058 .result = ACCEPT,
2059 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2060 },
2061 {
2062 "unpriv: spill/fill of ctx 3",
2063 .insns = {
2064 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2065 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2066 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2067 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2068 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002069 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2070 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002071 BPF_EXIT_INSN(),
2072 },
2073 .result = REJECT,
2074 .errstr = "R1 type=fp expected=ctx",
2075 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2076 },
2077 {
2078 "unpriv: spill/fill of ctx 4",
2079 .insns = {
2080 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2082 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2083 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002084 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2085 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002086 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002087 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2088 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002089 BPF_EXIT_INSN(),
2090 },
2091 .result = REJECT,
2092 .errstr = "R1 type=inv expected=ctx",
2093 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2094 },
2095 {
2096 "unpriv: spill/fill of different pointers stx",
2097 .insns = {
2098 BPF_MOV64_IMM(BPF_REG_3, 42),
2099 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2100 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2101 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2102 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2104 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2105 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2106 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2107 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2108 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2109 offsetof(struct __sk_buff, mark)),
2110 BPF_MOV64_IMM(BPF_REG_0, 0),
2111 BPF_EXIT_INSN(),
2112 },
2113 .result = REJECT,
2114 .errstr = "same insn cannot be used with different pointers",
2115 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2116 },
2117 {
2118 "unpriv: spill/fill of different pointers ldx",
2119 .insns = {
2120 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2122 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2123 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2124 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2125 -(__s32)offsetof(struct bpf_perf_event_data,
2126 sample_period) - 8),
2127 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2128 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2129 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2130 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2131 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2132 offsetof(struct bpf_perf_event_data,
2133 sample_period)),
2134 BPF_MOV64_IMM(BPF_REG_0, 0),
2135 BPF_EXIT_INSN(),
2136 },
2137 .result = REJECT,
2138 .errstr = "same insn cannot be used with different pointers",
2139 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2140 },
2141 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002142 "unpriv: write pointer into map elem value",
2143 .insns = {
2144 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2145 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2146 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2147 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002148 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2149 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002150 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2151 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2152 BPF_EXIT_INSN(),
2153 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002154 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002155 .errstr_unpriv = "R0 leaks addr",
2156 .result_unpriv = REJECT,
2157 .result = ACCEPT,
2158 },
2159 {
2160 "unpriv: partial copy of pointer",
2161 .insns = {
2162 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2163 BPF_MOV64_IMM(BPF_REG_0, 0),
2164 BPF_EXIT_INSN(),
2165 },
2166 .errstr_unpriv = "R10 partial copy",
2167 .result_unpriv = REJECT,
2168 .result = ACCEPT,
2169 },
2170 {
2171 "unpriv: pass pointer to tail_call",
2172 .insns = {
2173 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2174 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002175 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2176 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002177 BPF_MOV64_IMM(BPF_REG_0, 0),
2178 BPF_EXIT_INSN(),
2179 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002180 .fixup_prog = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002181 .errstr_unpriv = "R3 leaks addr into helper",
2182 .result_unpriv = REJECT,
2183 .result = ACCEPT,
2184 },
2185 {
2186 "unpriv: cmp map pointer with zero",
2187 .insns = {
2188 BPF_MOV64_IMM(BPF_REG_1, 0),
2189 BPF_LD_MAP_FD(BPF_REG_1, 0),
2190 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2191 BPF_MOV64_IMM(BPF_REG_0, 0),
2192 BPF_EXIT_INSN(),
2193 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002194 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002195 .errstr_unpriv = "R1 pointer comparison",
2196 .result_unpriv = REJECT,
2197 .result = ACCEPT,
2198 },
2199 {
2200 "unpriv: write into frame pointer",
2201 .insns = {
2202 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2203 BPF_MOV64_IMM(BPF_REG_0, 0),
2204 BPF_EXIT_INSN(),
2205 },
2206 .errstr = "frame pointer is read only",
2207 .result = REJECT,
2208 },
2209 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002210 "unpriv: spill/fill frame pointer",
2211 .insns = {
2212 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2213 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2214 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2215 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2216 BPF_MOV64_IMM(BPF_REG_0, 0),
2217 BPF_EXIT_INSN(),
2218 },
2219 .errstr = "frame pointer is read only",
2220 .result = REJECT,
2221 },
2222 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002223 "unpriv: cmp of frame pointer",
2224 .insns = {
2225 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2226 BPF_MOV64_IMM(BPF_REG_0, 0),
2227 BPF_EXIT_INSN(),
2228 },
2229 .errstr_unpriv = "R10 pointer comparison",
2230 .result_unpriv = REJECT,
2231 .result = ACCEPT,
2232 },
2233 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02002234 "unpriv: adding of fp",
2235 .insns = {
2236 BPF_MOV64_IMM(BPF_REG_0, 0),
2237 BPF_MOV64_IMM(BPF_REG_1, 0),
2238 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2239 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2240 BPF_EXIT_INSN(),
2241 },
Edward Creef65b1842017-08-07 15:27:12 +01002242 .result = ACCEPT,
Daniel Borkmann728a8532017-04-27 01:39:32 +02002243 },
2244 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002245 "unpriv: cmp of stack pointer",
2246 .insns = {
2247 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2248 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2250 BPF_MOV64_IMM(BPF_REG_0, 0),
2251 BPF_EXIT_INSN(),
2252 },
2253 .errstr_unpriv = "R2 pointer comparison",
2254 .result_unpriv = REJECT,
2255 .result = ACCEPT,
2256 },
2257 {
Yonghong Song332270f2017-04-29 22:52:42 -07002258 "stack pointer arithmetic",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002259 .insns = {
Yonghong Song332270f2017-04-29 22:52:42 -07002260 BPF_MOV64_IMM(BPF_REG_1, 4),
2261 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2262 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2264 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2265 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2266 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2267 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2268 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2269 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2270 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002271 BPF_MOV64_IMM(BPF_REG_0, 0),
2272 BPF_EXIT_INSN(),
2273 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002274 .result = ACCEPT,
2275 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002276 {
2277 "raw_stack: no skb_load_bytes",
2278 .insns = {
2279 BPF_MOV64_IMM(BPF_REG_2, 4),
2280 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2282 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2283 BPF_MOV64_IMM(BPF_REG_4, 8),
2284 /* Call to skb_load_bytes() omitted. */
2285 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2286 BPF_EXIT_INSN(),
2287 },
2288 .result = REJECT,
2289 .errstr = "invalid read from stack off -8+0 size 8",
2290 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2291 },
2292 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002293 "raw_stack: skb_load_bytes, negative len",
2294 .insns = {
2295 BPF_MOV64_IMM(BPF_REG_2, 4),
2296 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2298 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2299 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002300 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2301 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002302 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2303 BPF_EXIT_INSN(),
2304 },
2305 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002306 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002307 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2308 },
2309 {
2310 "raw_stack: skb_load_bytes, negative len 2",
2311 .insns = {
2312 BPF_MOV64_IMM(BPF_REG_2, 4),
2313 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2314 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2315 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2316 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002317 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2318 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002319 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2320 BPF_EXIT_INSN(),
2321 },
2322 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002323 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002324 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2325 },
2326 {
2327 "raw_stack: skb_load_bytes, zero len",
2328 .insns = {
2329 BPF_MOV64_IMM(BPF_REG_2, 4),
2330 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2332 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2333 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002334 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2335 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002336 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2337 BPF_EXIT_INSN(),
2338 },
2339 .result = REJECT,
2340 .errstr = "invalid stack type R3",
2341 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2342 },
2343 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002344 "raw_stack: skb_load_bytes, no init",
2345 .insns = {
2346 BPF_MOV64_IMM(BPF_REG_2, 4),
2347 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2348 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2349 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2350 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002351 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2352 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002353 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2354 BPF_EXIT_INSN(),
2355 },
2356 .result = ACCEPT,
2357 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2358 },
2359 {
2360 "raw_stack: skb_load_bytes, init",
2361 .insns = {
2362 BPF_MOV64_IMM(BPF_REG_2, 4),
2363 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2365 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
2366 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2367 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002368 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2369 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002370 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2371 BPF_EXIT_INSN(),
2372 },
2373 .result = ACCEPT,
2374 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2375 },
2376 {
2377 "raw_stack: skb_load_bytes, spilled regs around bounds",
2378 .insns = {
2379 BPF_MOV64_IMM(BPF_REG_2, 4),
2380 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2381 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002382 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2383 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002384 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2385 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002386 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2387 BPF_FUNC_skb_load_bytes),
2388 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2389 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002390 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2391 offsetof(struct __sk_buff, mark)),
2392 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2393 offsetof(struct __sk_buff, priority)),
2394 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2395 BPF_EXIT_INSN(),
2396 },
2397 .result = ACCEPT,
2398 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2399 },
2400 {
2401 "raw_stack: skb_load_bytes, spilled regs corruption",
2402 .insns = {
2403 BPF_MOV64_IMM(BPF_REG_2, 4),
2404 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2405 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002406 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002407 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2408 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002409 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2410 BPF_FUNC_skb_load_bytes),
2411 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002412 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2413 offsetof(struct __sk_buff, mark)),
2414 BPF_EXIT_INSN(),
2415 },
2416 .result = REJECT,
2417 .errstr = "R0 invalid mem access 'inv'",
2418 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2419 },
2420 {
2421 "raw_stack: skb_load_bytes, spilled regs corruption 2",
2422 .insns = {
2423 BPF_MOV64_IMM(BPF_REG_2, 4),
2424 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2425 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002426 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2427 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2428 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002429 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2430 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002431 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2432 BPF_FUNC_skb_load_bytes),
2433 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2434 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2435 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002436 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2437 offsetof(struct __sk_buff, mark)),
2438 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2439 offsetof(struct __sk_buff, priority)),
2440 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2441 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
2442 offsetof(struct __sk_buff, pkt_type)),
2443 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2444 BPF_EXIT_INSN(),
2445 },
2446 .result = REJECT,
2447 .errstr = "R3 invalid mem access 'inv'",
2448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2449 },
2450 {
2451 "raw_stack: skb_load_bytes, spilled regs + data",
2452 .insns = {
2453 BPF_MOV64_IMM(BPF_REG_2, 4),
2454 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2455 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002456 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2457 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2458 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002459 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2460 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002461 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2462 BPF_FUNC_skb_load_bytes),
2463 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2464 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2465 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002466 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2467 offsetof(struct __sk_buff, mark)),
2468 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2469 offsetof(struct __sk_buff, priority)),
2470 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2471 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2472 BPF_EXIT_INSN(),
2473 },
2474 .result = ACCEPT,
2475 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2476 },
2477 {
2478 "raw_stack: skb_load_bytes, invalid access 1",
2479 .insns = {
2480 BPF_MOV64_IMM(BPF_REG_2, 4),
2481 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2482 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2483 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2484 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002485 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2486 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002487 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2488 BPF_EXIT_INSN(),
2489 },
2490 .result = REJECT,
2491 .errstr = "invalid stack type R3 off=-513 access_size=8",
2492 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2493 },
2494 {
2495 "raw_stack: skb_load_bytes, invalid access 2",
2496 .insns = {
2497 BPF_MOV64_IMM(BPF_REG_2, 4),
2498 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2499 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2500 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2501 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002502 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2503 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002504 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2505 BPF_EXIT_INSN(),
2506 },
2507 .result = REJECT,
2508 .errstr = "invalid stack type R3 off=-1 access_size=8",
2509 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2510 },
2511 {
2512 "raw_stack: skb_load_bytes, invalid access 3",
2513 .insns = {
2514 BPF_MOV64_IMM(BPF_REG_2, 4),
2515 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2516 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2517 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2518 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002519 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2520 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002521 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2522 BPF_EXIT_INSN(),
2523 },
2524 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002525 .errstr = "R4 min value is negative",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002526 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2527 },
2528 {
2529 "raw_stack: skb_load_bytes, invalid access 4",
2530 .insns = {
2531 BPF_MOV64_IMM(BPF_REG_2, 4),
2532 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2534 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2535 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2537 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002538 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2539 BPF_EXIT_INSN(),
2540 },
2541 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002542 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002543 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2544 },
2545 {
2546 "raw_stack: skb_load_bytes, invalid access 5",
2547 .insns = {
2548 BPF_MOV64_IMM(BPF_REG_2, 4),
2549 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2550 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2551 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2552 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002553 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2554 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002555 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2556 BPF_EXIT_INSN(),
2557 },
2558 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002559 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002560 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2561 },
2562 {
2563 "raw_stack: skb_load_bytes, invalid access 6",
2564 .insns = {
2565 BPF_MOV64_IMM(BPF_REG_2, 4),
2566 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2567 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2568 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2569 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002570 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2571 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002572 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2573 BPF_EXIT_INSN(),
2574 },
2575 .result = REJECT,
2576 .errstr = "invalid stack type R3 off=-512 access_size=0",
2577 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2578 },
2579 {
2580 "raw_stack: skb_load_bytes, large access",
2581 .insns = {
2582 BPF_MOV64_IMM(BPF_REG_2, 4),
2583 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2584 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2585 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2586 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002587 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2588 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002589 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2590 BPF_EXIT_INSN(),
2591 },
2592 .result = ACCEPT,
2593 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2594 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002595 {
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01002596 "context stores via ST",
2597 .insns = {
2598 BPF_MOV64_IMM(BPF_REG_0, 0),
2599 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
2600 BPF_EXIT_INSN(),
2601 },
2602 .errstr = "BPF_ST stores into R1 context is not allowed",
2603 .result = REJECT,
2604 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2605 },
2606 {
2607 "context stores via XADD",
2608 .insns = {
2609 BPF_MOV64_IMM(BPF_REG_0, 0),
2610 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
2611 BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
2612 BPF_EXIT_INSN(),
2613 },
2614 .errstr = "BPF_XADD stores into R1 context is not allowed",
2615 .result = REJECT,
2616 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2617 },
2618 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002619 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002620 .insns = {
2621 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2622 offsetof(struct __sk_buff, data)),
2623 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2624 offsetof(struct __sk_buff, data_end)),
2625 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2627 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2628 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2629 BPF_MOV64_IMM(BPF_REG_0, 0),
2630 BPF_EXIT_INSN(),
2631 },
2632 .result = ACCEPT,
2633 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2634 },
2635 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002636 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002637 .insns = {
2638 BPF_MOV64_IMM(BPF_REG_0, 1),
2639 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2640 offsetof(struct __sk_buff, data_end)),
2641 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2642 offsetof(struct __sk_buff, data)),
2643 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2645 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2646 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2647 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2648 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2649 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2650 offsetof(struct __sk_buff, data)),
2651 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08002652 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2653 offsetof(struct __sk_buff, len)),
Edward Cree1f9ab382017-08-07 15:29:11 +01002654 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
2655 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002656 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2657 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2659 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2660 offsetof(struct __sk_buff, data_end)),
2661 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2662 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2663 BPF_MOV64_IMM(BPF_REG_0, 0),
2664 BPF_EXIT_INSN(),
2665 },
2666 .result = ACCEPT,
2667 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2668 },
2669 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002670 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002671 .insns = {
2672 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2673 offsetof(struct __sk_buff, data)),
2674 BPF_MOV64_IMM(BPF_REG_0, 0),
2675 BPF_EXIT_INSN(),
2676 },
2677 .errstr = "invalid bpf_context access off=76",
2678 .result = REJECT,
2679 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2680 },
2681 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002682 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002683 .insns = {
2684 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2685 offsetof(struct __sk_buff, data)),
2686 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2687 offsetof(struct __sk_buff, data_end)),
2688 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2689 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2690 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2691 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2692 BPF_MOV64_IMM(BPF_REG_0, 0),
2693 BPF_EXIT_INSN(),
2694 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002695 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002696 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2697 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002698 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02002699 "direct packet access: test5 (pkt_end >= reg, good access)",
2700 .insns = {
2701 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2702 offsetof(struct __sk_buff, data)),
2703 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2704 offsetof(struct __sk_buff, data_end)),
2705 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2707 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2708 BPF_MOV64_IMM(BPF_REG_0, 1),
2709 BPF_EXIT_INSN(),
2710 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2711 BPF_MOV64_IMM(BPF_REG_0, 0),
2712 BPF_EXIT_INSN(),
2713 },
2714 .result = ACCEPT,
2715 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2716 },
2717 {
2718 "direct packet access: test6 (pkt_end >= reg, bad access)",
2719 .insns = {
2720 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2721 offsetof(struct __sk_buff, data)),
2722 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2723 offsetof(struct __sk_buff, data_end)),
2724 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2725 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2726 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2727 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2728 BPF_MOV64_IMM(BPF_REG_0, 1),
2729 BPF_EXIT_INSN(),
2730 BPF_MOV64_IMM(BPF_REG_0, 0),
2731 BPF_EXIT_INSN(),
2732 },
2733 .errstr = "invalid access to packet",
2734 .result = REJECT,
2735 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2736 },
2737 {
2738 "direct packet access: test7 (pkt_end >= reg, both accesses)",
2739 .insns = {
2740 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2741 offsetof(struct __sk_buff, data)),
2742 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2743 offsetof(struct __sk_buff, data_end)),
2744 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2746 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2747 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2748 BPF_MOV64_IMM(BPF_REG_0, 1),
2749 BPF_EXIT_INSN(),
2750 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2751 BPF_MOV64_IMM(BPF_REG_0, 0),
2752 BPF_EXIT_INSN(),
2753 },
2754 .errstr = "invalid access to packet",
2755 .result = REJECT,
2756 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2757 },
2758 {
2759 "direct packet access: test8 (double test, variant 1)",
2760 .insns = {
2761 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2762 offsetof(struct __sk_buff, data)),
2763 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2764 offsetof(struct __sk_buff, data_end)),
2765 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2766 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2767 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2768 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2769 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2770 BPF_MOV64_IMM(BPF_REG_0, 1),
2771 BPF_EXIT_INSN(),
2772 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2773 BPF_MOV64_IMM(BPF_REG_0, 0),
2774 BPF_EXIT_INSN(),
2775 },
2776 .result = ACCEPT,
2777 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2778 },
2779 {
2780 "direct packet access: test9 (double test, variant 2)",
2781 .insns = {
2782 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2783 offsetof(struct __sk_buff, data)),
2784 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2785 offsetof(struct __sk_buff, data_end)),
2786 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2788 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2789 BPF_MOV64_IMM(BPF_REG_0, 1),
2790 BPF_EXIT_INSN(),
2791 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2792 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2793 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2794 BPF_MOV64_IMM(BPF_REG_0, 0),
2795 BPF_EXIT_INSN(),
2796 },
2797 .result = ACCEPT,
2798 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2799 },
2800 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002801 "direct packet access: test10 (write invalid)",
2802 .insns = {
2803 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2804 offsetof(struct __sk_buff, data)),
2805 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2806 offsetof(struct __sk_buff, data_end)),
2807 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2809 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2810 BPF_MOV64_IMM(BPF_REG_0, 0),
2811 BPF_EXIT_INSN(),
2812 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2813 BPF_MOV64_IMM(BPF_REG_0, 0),
2814 BPF_EXIT_INSN(),
2815 },
2816 .errstr = "invalid access to packet",
2817 .result = REJECT,
2818 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2819 },
2820 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01002821 "direct packet access: test11 (shift, good access)",
2822 .insns = {
2823 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2824 offsetof(struct __sk_buff, data)),
2825 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2826 offsetof(struct __sk_buff, data_end)),
2827 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2829 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2830 BPF_MOV64_IMM(BPF_REG_3, 144),
2831 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2832 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2833 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2834 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2835 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2836 BPF_MOV64_IMM(BPF_REG_0, 1),
2837 BPF_EXIT_INSN(),
2838 BPF_MOV64_IMM(BPF_REG_0, 0),
2839 BPF_EXIT_INSN(),
2840 },
2841 .result = ACCEPT,
2842 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2843 },
2844 {
2845 "direct packet access: test12 (and, good access)",
2846 .insns = {
2847 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2848 offsetof(struct __sk_buff, data)),
2849 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2850 offsetof(struct __sk_buff, data_end)),
2851 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2853 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2854 BPF_MOV64_IMM(BPF_REG_3, 144),
2855 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2856 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2857 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2858 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2859 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2860 BPF_MOV64_IMM(BPF_REG_0, 1),
2861 BPF_EXIT_INSN(),
2862 BPF_MOV64_IMM(BPF_REG_0, 0),
2863 BPF_EXIT_INSN(),
2864 },
2865 .result = ACCEPT,
2866 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2867 },
2868 {
2869 "direct packet access: test13 (branches, good access)",
2870 .insns = {
2871 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2872 offsetof(struct __sk_buff, data)),
2873 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2874 offsetof(struct __sk_buff, data_end)),
2875 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2876 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2877 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2878 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2879 offsetof(struct __sk_buff, mark)),
2880 BPF_MOV64_IMM(BPF_REG_4, 1),
2881 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2882 BPF_MOV64_IMM(BPF_REG_3, 14),
2883 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2884 BPF_MOV64_IMM(BPF_REG_3, 24),
2885 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2886 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2887 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2888 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2889 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2890 BPF_MOV64_IMM(BPF_REG_0, 1),
2891 BPF_EXIT_INSN(),
2892 BPF_MOV64_IMM(BPF_REG_0, 0),
2893 BPF_EXIT_INSN(),
2894 },
2895 .result = ACCEPT,
2896 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2897 },
2898 {
William Tu63dfef72017-02-04 08:37:29 -08002899 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2900 .insns = {
2901 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2902 offsetof(struct __sk_buff, data)),
2903 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2904 offsetof(struct __sk_buff, data_end)),
2905 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2906 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2907 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2908 BPF_MOV64_IMM(BPF_REG_5, 12),
2909 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2910 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2911 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2912 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2913 BPF_MOV64_IMM(BPF_REG_0, 1),
2914 BPF_EXIT_INSN(),
2915 BPF_MOV64_IMM(BPF_REG_0, 0),
2916 BPF_EXIT_INSN(),
2917 },
2918 .result = ACCEPT,
2919 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2920 },
2921 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02002922 "direct packet access: test15 (spill with xadd)",
2923 .insns = {
2924 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2925 offsetof(struct __sk_buff, data)),
2926 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2927 offsetof(struct __sk_buff, data_end)),
2928 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2930 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2931 BPF_MOV64_IMM(BPF_REG_5, 4096),
2932 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2933 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2934 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2935 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
2936 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
2937 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
2938 BPF_MOV64_IMM(BPF_REG_0, 0),
2939 BPF_EXIT_INSN(),
2940 },
2941 .errstr = "R2 invalid mem access 'inv'",
2942 .result = REJECT,
2943 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2944 },
2945 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02002946 "direct packet access: test16 (arith on data_end)",
2947 .insns = {
2948 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2949 offsetof(struct __sk_buff, data)),
2950 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2951 offsetof(struct __sk_buff, data_end)),
2952 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2953 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
2955 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2956 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2957 BPF_MOV64_IMM(BPF_REG_0, 0),
2958 BPF_EXIT_INSN(),
2959 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08002960 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmann728a8532017-04-27 01:39:32 +02002961 .result = REJECT,
2962 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2963 },
2964 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02002965 "direct packet access: test17 (pruning, alignment)",
2966 .insns = {
2967 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2968 offsetof(struct __sk_buff, data)),
2969 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2970 offsetof(struct __sk_buff, data_end)),
2971 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2972 offsetof(struct __sk_buff, mark)),
2973 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2974 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
2975 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
2976 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2977 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
2978 BPF_MOV64_IMM(BPF_REG_0, 0),
2979 BPF_EXIT_INSN(),
2980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
2981 BPF_JMP_A(-6),
2982 },
Edward Creef65b1842017-08-07 15:27:12 +01002983 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02002984 .result = REJECT,
2985 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2986 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2987 },
2988 {
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002989 "direct packet access: test18 (imm += pkt_ptr, 1)",
2990 .insns = {
2991 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2992 offsetof(struct __sk_buff, data)),
2993 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2994 offsetof(struct __sk_buff, data_end)),
2995 BPF_MOV64_IMM(BPF_REG_0, 8),
2996 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2997 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2998 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2999 BPF_MOV64_IMM(BPF_REG_0, 0),
3000 BPF_EXIT_INSN(),
3001 },
3002 .result = ACCEPT,
3003 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3004 },
3005 {
3006 "direct packet access: test19 (imm += pkt_ptr, 2)",
3007 .insns = {
3008 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3009 offsetof(struct __sk_buff, data)),
3010 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3011 offsetof(struct __sk_buff, data_end)),
3012 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3014 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
3015 BPF_MOV64_IMM(BPF_REG_4, 4),
3016 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3017 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
3018 BPF_MOV64_IMM(BPF_REG_0, 0),
3019 BPF_EXIT_INSN(),
3020 },
3021 .result = ACCEPT,
3022 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3023 },
3024 {
3025 "direct packet access: test20 (x += pkt_ptr, 1)",
3026 .insns = {
3027 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3028 offsetof(struct __sk_buff, data)),
3029 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3030 offsetof(struct __sk_buff, data_end)),
3031 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3032 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3033 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003034 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003035 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3036 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3037 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003039 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3040 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3041 BPF_MOV64_IMM(BPF_REG_0, 0),
3042 BPF_EXIT_INSN(),
3043 },
3044 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3045 .result = ACCEPT,
3046 },
3047 {
3048 "direct packet access: test21 (x += pkt_ptr, 2)",
3049 .insns = {
3050 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3051 offsetof(struct __sk_buff, data)),
3052 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3053 offsetof(struct __sk_buff, data_end)),
3054 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3056 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3057 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3058 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3059 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003060 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003061 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3062 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003063 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003064 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3065 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3066 BPF_MOV64_IMM(BPF_REG_0, 0),
3067 BPF_EXIT_INSN(),
3068 },
3069 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3070 .result = ACCEPT,
3071 },
3072 {
3073 "direct packet access: test22 (x += pkt_ptr, 3)",
3074 .insns = {
3075 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3076 offsetof(struct __sk_buff, data)),
3077 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3078 offsetof(struct __sk_buff, data_end)),
3079 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3080 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3081 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3082 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3083 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3084 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3085 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3086 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3087 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3088 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003089 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003090 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3091 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3093 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3094 BPF_MOV64_IMM(BPF_REG_2, 1),
3095 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3096 BPF_MOV64_IMM(BPF_REG_0, 0),
3097 BPF_EXIT_INSN(),
3098 },
3099 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3100 .result = ACCEPT,
3101 },
3102 {
3103 "direct packet access: test23 (x += pkt_ptr, 4)",
3104 .insns = {
3105 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3106 offsetof(struct __sk_buff, data)),
3107 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3108 offsetof(struct __sk_buff, data_end)),
3109 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3110 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3112 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3113 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3114 BPF_MOV64_IMM(BPF_REG_0, 31),
3115 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3116 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3117 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3118 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3119 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3120 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3121 BPF_MOV64_IMM(BPF_REG_0, 0),
3122 BPF_EXIT_INSN(),
3123 },
3124 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3125 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003126 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003127 },
3128 {
3129 "direct packet access: test24 (x += pkt_ptr, 5)",
3130 .insns = {
3131 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3132 offsetof(struct __sk_buff, data)),
3133 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3134 offsetof(struct __sk_buff, data_end)),
3135 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3136 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3137 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3138 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3139 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3140 BPF_MOV64_IMM(BPF_REG_0, 64),
3141 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3142 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3143 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
Edward Cree1f9ab382017-08-07 15:29:11 +01003144 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003145 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3146 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3147 BPF_MOV64_IMM(BPF_REG_0, 0),
3148 BPF_EXIT_INSN(),
3149 },
3150 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3151 .result = ACCEPT,
3152 },
3153 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02003154 "direct packet access: test25 (marking on <, good access)",
3155 .insns = {
3156 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3157 offsetof(struct __sk_buff, data)),
3158 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3159 offsetof(struct __sk_buff, data_end)),
3160 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3161 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3162 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
3163 BPF_MOV64_IMM(BPF_REG_0, 0),
3164 BPF_EXIT_INSN(),
3165 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3166 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3167 },
3168 .result = ACCEPT,
3169 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3170 },
3171 {
3172 "direct packet access: test26 (marking on <, bad access)",
3173 .insns = {
3174 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3175 offsetof(struct __sk_buff, data)),
3176 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3177 offsetof(struct __sk_buff, data_end)),
3178 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3179 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3180 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
3181 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3182 BPF_MOV64_IMM(BPF_REG_0, 0),
3183 BPF_EXIT_INSN(),
3184 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
3185 },
3186 .result = REJECT,
3187 .errstr = "invalid access to packet",
3188 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3189 },
3190 {
3191 "direct packet access: test27 (marking on <=, good access)",
3192 .insns = {
3193 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3194 offsetof(struct __sk_buff, data)),
3195 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3196 offsetof(struct __sk_buff, data_end)),
3197 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3198 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3199 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
3200 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3201 BPF_MOV64_IMM(BPF_REG_0, 1),
3202 BPF_EXIT_INSN(),
3203 },
3204 .result = ACCEPT,
3205 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3206 },
3207 {
3208 "direct packet access: test28 (marking on <=, bad access)",
3209 .insns = {
3210 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3211 offsetof(struct __sk_buff, data)),
3212 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3213 offsetof(struct __sk_buff, data_end)),
3214 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3216 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
3217 BPF_MOV64_IMM(BPF_REG_0, 1),
3218 BPF_EXIT_INSN(),
3219 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3220 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3221 },
3222 .result = REJECT,
3223 .errstr = "invalid access to packet",
3224 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3225 },
3226 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003227 "helper access to packet: test1, valid packet_ptr range",
3228 .insns = {
3229 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3230 offsetof(struct xdp_md, data)),
3231 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3232 offsetof(struct xdp_md, data_end)),
3233 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3235 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3236 BPF_LD_MAP_FD(BPF_REG_1, 0),
3237 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3238 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003239 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3240 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003241 BPF_MOV64_IMM(BPF_REG_0, 0),
3242 BPF_EXIT_INSN(),
3243 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003244 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003245 .result_unpriv = ACCEPT,
3246 .result = ACCEPT,
3247 .prog_type = BPF_PROG_TYPE_XDP,
3248 },
3249 {
3250 "helper access to packet: test2, unchecked packet_ptr",
3251 .insns = {
3252 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3253 offsetof(struct xdp_md, data)),
3254 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003255 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3256 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003257 BPF_MOV64_IMM(BPF_REG_0, 0),
3258 BPF_EXIT_INSN(),
3259 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003260 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003261 .result = REJECT,
3262 .errstr = "invalid access to packet",
3263 .prog_type = BPF_PROG_TYPE_XDP,
3264 },
3265 {
3266 "helper access to packet: test3, variable add",
3267 .insns = {
3268 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3269 offsetof(struct xdp_md, data)),
3270 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3271 offsetof(struct xdp_md, data_end)),
3272 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3273 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3274 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3275 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3276 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3277 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3278 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3280 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3281 BPF_LD_MAP_FD(BPF_REG_1, 0),
3282 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003283 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3284 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003285 BPF_MOV64_IMM(BPF_REG_0, 0),
3286 BPF_EXIT_INSN(),
3287 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003288 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003289 .result = ACCEPT,
3290 .prog_type = BPF_PROG_TYPE_XDP,
3291 },
3292 {
3293 "helper access to packet: test4, packet_ptr with bad range",
3294 .insns = {
3295 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3296 offsetof(struct xdp_md, data)),
3297 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3298 offsetof(struct xdp_md, data_end)),
3299 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3300 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3301 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3302 BPF_MOV64_IMM(BPF_REG_0, 0),
3303 BPF_EXIT_INSN(),
3304 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003305 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3306 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003307 BPF_MOV64_IMM(BPF_REG_0, 0),
3308 BPF_EXIT_INSN(),
3309 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003310 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003311 .result = REJECT,
3312 .errstr = "invalid access to packet",
3313 .prog_type = BPF_PROG_TYPE_XDP,
3314 },
3315 {
3316 "helper access to packet: test5, packet_ptr with too short range",
3317 .insns = {
3318 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3319 offsetof(struct xdp_md, data)),
3320 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3321 offsetof(struct xdp_md, data_end)),
3322 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3323 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3324 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
3325 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
3326 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003327 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3328 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003329 BPF_MOV64_IMM(BPF_REG_0, 0),
3330 BPF_EXIT_INSN(),
3331 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003332 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003333 .result = REJECT,
3334 .errstr = "invalid access to packet",
3335 .prog_type = BPF_PROG_TYPE_XDP,
3336 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003337 {
3338 "helper access to packet: test6, cls valid packet_ptr range",
3339 .insns = {
3340 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3341 offsetof(struct __sk_buff, data)),
3342 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3343 offsetof(struct __sk_buff, data_end)),
3344 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3346 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3347 BPF_LD_MAP_FD(BPF_REG_1, 0),
3348 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3349 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003350 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3351 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003352 BPF_MOV64_IMM(BPF_REG_0, 0),
3353 BPF_EXIT_INSN(),
3354 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003355 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003356 .result = ACCEPT,
3357 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3358 },
3359 {
3360 "helper access to packet: test7, cls unchecked packet_ptr",
3361 .insns = {
3362 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3363 offsetof(struct __sk_buff, data)),
3364 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003365 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3366 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003367 BPF_MOV64_IMM(BPF_REG_0, 0),
3368 BPF_EXIT_INSN(),
3369 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003370 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003371 .result = REJECT,
3372 .errstr = "invalid access to packet",
3373 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3374 },
3375 {
3376 "helper access to packet: test8, cls variable add",
3377 .insns = {
3378 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3379 offsetof(struct __sk_buff, data)),
3380 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3381 offsetof(struct __sk_buff, data_end)),
3382 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3384 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3385 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3386 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3387 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3388 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3390 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3391 BPF_LD_MAP_FD(BPF_REG_1, 0),
3392 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003393 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3394 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003395 BPF_MOV64_IMM(BPF_REG_0, 0),
3396 BPF_EXIT_INSN(),
3397 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003398 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003399 .result = ACCEPT,
3400 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3401 },
3402 {
3403 "helper access to packet: test9, cls packet_ptr with bad range",
3404 .insns = {
3405 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3406 offsetof(struct __sk_buff, data)),
3407 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3408 offsetof(struct __sk_buff, data_end)),
3409 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3411 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3412 BPF_MOV64_IMM(BPF_REG_0, 0),
3413 BPF_EXIT_INSN(),
3414 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3416 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003417 BPF_MOV64_IMM(BPF_REG_0, 0),
3418 BPF_EXIT_INSN(),
3419 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003420 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003421 .result = REJECT,
3422 .errstr = "invalid access to packet",
3423 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3424 },
3425 {
3426 "helper access to packet: test10, cls packet_ptr with too short range",
3427 .insns = {
3428 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3429 offsetof(struct __sk_buff, data)),
3430 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3431 offsetof(struct __sk_buff, data_end)),
3432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3433 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
3435 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
3436 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003437 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3438 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003439 BPF_MOV64_IMM(BPF_REG_0, 0),
3440 BPF_EXIT_INSN(),
3441 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003442 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003443 .result = REJECT,
3444 .errstr = "invalid access to packet",
3445 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3446 },
3447 {
3448 "helper access to packet: test11, cls unsuitable helper 1",
3449 .insns = {
3450 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3451 offsetof(struct __sk_buff, data)),
3452 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3453 offsetof(struct __sk_buff, data_end)),
3454 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3455 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
3457 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
3458 BPF_MOV64_IMM(BPF_REG_2, 0),
3459 BPF_MOV64_IMM(BPF_REG_4, 42),
3460 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003461 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3462 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003463 BPF_MOV64_IMM(BPF_REG_0, 0),
3464 BPF_EXIT_INSN(),
3465 },
3466 .result = REJECT,
3467 .errstr = "helper access to the packet",
3468 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3469 },
3470 {
3471 "helper access to packet: test12, cls unsuitable helper 2",
3472 .insns = {
3473 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3474 offsetof(struct __sk_buff, data)),
3475 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3476 offsetof(struct __sk_buff, data_end)),
3477 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
3479 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
3480 BPF_MOV64_IMM(BPF_REG_2, 0),
3481 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003482 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3483 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003484 BPF_MOV64_IMM(BPF_REG_0, 0),
3485 BPF_EXIT_INSN(),
3486 },
3487 .result = REJECT,
3488 .errstr = "helper access to the packet",
3489 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3490 },
3491 {
3492 "helper access to packet: test13, cls helper ok",
3493 .insns = {
3494 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3495 offsetof(struct __sk_buff, data)),
3496 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3497 offsetof(struct __sk_buff, data_end)),
3498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3499 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3500 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3501 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3502 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3503 BPF_MOV64_IMM(BPF_REG_2, 4),
3504 BPF_MOV64_IMM(BPF_REG_3, 0),
3505 BPF_MOV64_IMM(BPF_REG_4, 0),
3506 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003507 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3508 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003509 BPF_MOV64_IMM(BPF_REG_0, 0),
3510 BPF_EXIT_INSN(),
3511 },
3512 .result = ACCEPT,
3513 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3514 },
3515 {
Edward Creef65b1842017-08-07 15:27:12 +01003516 "helper access to packet: test14, cls helper ok sub",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003517 .insns = {
3518 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3519 offsetof(struct __sk_buff, data)),
3520 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3521 offsetof(struct __sk_buff, data_end)),
3522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3523 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3524 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3525 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3526 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
3527 BPF_MOV64_IMM(BPF_REG_2, 4),
3528 BPF_MOV64_IMM(BPF_REG_3, 0),
3529 BPF_MOV64_IMM(BPF_REG_4, 0),
3530 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003531 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3532 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003533 BPF_MOV64_IMM(BPF_REG_0, 0),
3534 BPF_EXIT_INSN(),
3535 },
Edward Creef65b1842017-08-07 15:27:12 +01003536 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003537 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3538 },
3539 {
Edward Creef65b1842017-08-07 15:27:12 +01003540 "helper access to packet: test15, cls helper fail sub",
3541 .insns = {
3542 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3543 offsetof(struct __sk_buff, data)),
3544 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3545 offsetof(struct __sk_buff, data_end)),
3546 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3547 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3548 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3549 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3550 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
3551 BPF_MOV64_IMM(BPF_REG_2, 4),
3552 BPF_MOV64_IMM(BPF_REG_3, 0),
3553 BPF_MOV64_IMM(BPF_REG_4, 0),
3554 BPF_MOV64_IMM(BPF_REG_5, 0),
3555 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3556 BPF_FUNC_csum_diff),
3557 BPF_MOV64_IMM(BPF_REG_0, 0),
3558 BPF_EXIT_INSN(),
3559 },
3560 .result = REJECT,
3561 .errstr = "invalid access to packet",
3562 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3563 },
3564 {
3565 "helper access to packet: test16, cls helper fail range 1",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003566 .insns = {
3567 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3568 offsetof(struct __sk_buff, data)),
3569 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3570 offsetof(struct __sk_buff, data_end)),
3571 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3572 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3573 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3574 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3575 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3576 BPF_MOV64_IMM(BPF_REG_2, 8),
3577 BPF_MOV64_IMM(BPF_REG_3, 0),
3578 BPF_MOV64_IMM(BPF_REG_4, 0),
3579 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003580 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3581 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003582 BPF_MOV64_IMM(BPF_REG_0, 0),
3583 BPF_EXIT_INSN(),
3584 },
3585 .result = REJECT,
3586 .errstr = "invalid access to packet",
3587 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3588 },
3589 {
Edward Creef65b1842017-08-07 15:27:12 +01003590 "helper access to packet: test17, cls helper fail range 2",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003591 .insns = {
3592 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3593 offsetof(struct __sk_buff, data)),
3594 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3595 offsetof(struct __sk_buff, data_end)),
3596 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3597 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3598 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3599 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3600 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3601 BPF_MOV64_IMM(BPF_REG_2, -9),
3602 BPF_MOV64_IMM(BPF_REG_3, 0),
3603 BPF_MOV64_IMM(BPF_REG_4, 0),
3604 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003605 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3606 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003607 BPF_MOV64_IMM(BPF_REG_0, 0),
3608 BPF_EXIT_INSN(),
3609 },
3610 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003611 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003612 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3613 },
3614 {
Edward Creef65b1842017-08-07 15:27:12 +01003615 "helper access to packet: test18, cls helper fail range 3",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003616 .insns = {
3617 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3618 offsetof(struct __sk_buff, data)),
3619 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3620 offsetof(struct __sk_buff, data_end)),
3621 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3622 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3624 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3625 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3626 BPF_MOV64_IMM(BPF_REG_2, ~0),
3627 BPF_MOV64_IMM(BPF_REG_3, 0),
3628 BPF_MOV64_IMM(BPF_REG_4, 0),
3629 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003630 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3631 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003632 BPF_MOV64_IMM(BPF_REG_0, 0),
3633 BPF_EXIT_INSN(),
3634 },
3635 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003636 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003637 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3638 },
3639 {
Yonghong Songb6ff6392017-11-12 14:49:11 -08003640 "helper access to packet: test19, cls helper range zero",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003641 .insns = {
3642 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3643 offsetof(struct __sk_buff, data)),
3644 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3645 offsetof(struct __sk_buff, data_end)),
3646 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3647 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3649 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3650 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3651 BPF_MOV64_IMM(BPF_REG_2, 0),
3652 BPF_MOV64_IMM(BPF_REG_3, 0),
3653 BPF_MOV64_IMM(BPF_REG_4, 0),
3654 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003655 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3656 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003657 BPF_MOV64_IMM(BPF_REG_0, 0),
3658 BPF_EXIT_INSN(),
3659 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08003660 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003661 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3662 },
3663 {
Edward Creef65b1842017-08-07 15:27:12 +01003664 "helper access to packet: test20, pkt end as input",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003665 .insns = {
3666 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3667 offsetof(struct __sk_buff, data)),
3668 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3669 offsetof(struct __sk_buff, data_end)),
3670 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3671 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3672 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3673 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3674 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
3675 BPF_MOV64_IMM(BPF_REG_2, 4),
3676 BPF_MOV64_IMM(BPF_REG_3, 0),
3677 BPF_MOV64_IMM(BPF_REG_4, 0),
3678 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003679 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3680 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003681 BPF_MOV64_IMM(BPF_REG_0, 0),
3682 BPF_EXIT_INSN(),
3683 },
3684 .result = REJECT,
3685 .errstr = "R1 type=pkt_end expected=fp",
3686 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3687 },
3688 {
Edward Creef65b1842017-08-07 15:27:12 +01003689 "helper access to packet: test21, wrong reg",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003690 .insns = {
3691 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3692 offsetof(struct __sk_buff, data)),
3693 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3694 offsetof(struct __sk_buff, data_end)),
3695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3696 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3697 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3698 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3699 BPF_MOV64_IMM(BPF_REG_2, 4),
3700 BPF_MOV64_IMM(BPF_REG_3, 0),
3701 BPF_MOV64_IMM(BPF_REG_4, 0),
3702 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3704 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003705 BPF_MOV64_IMM(BPF_REG_0, 0),
3706 BPF_EXIT_INSN(),
3707 },
3708 .result = REJECT,
3709 .errstr = "invalid access to packet",
3710 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3711 },
Josef Bacik48461132016-09-28 10:54:32 -04003712 {
3713 "valid map access into an array with a constant",
3714 .insns = {
3715 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3716 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3718 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003719 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3720 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003721 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003722 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3723 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003724 BPF_EXIT_INSN(),
3725 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003726 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003727 .errstr_unpriv = "R0 leaks addr",
3728 .result_unpriv = REJECT,
3729 .result = ACCEPT,
3730 },
3731 {
3732 "valid map access into an array with a register",
3733 .insns = {
3734 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3735 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3736 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3737 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003738 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3739 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003740 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3741 BPF_MOV64_IMM(BPF_REG_1, 4),
3742 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3743 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003744 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3745 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003746 BPF_EXIT_INSN(),
3747 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003748 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003749 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003750 .result_unpriv = REJECT,
3751 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003752 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003753 },
3754 {
3755 "valid map access into an array with a variable",
3756 .insns = {
3757 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3758 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3759 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3760 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003761 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3762 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003763 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3764 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3765 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
3766 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3767 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003768 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3769 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003770 BPF_EXIT_INSN(),
3771 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003772 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003773 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003774 .result_unpriv = REJECT,
3775 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003776 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003777 },
3778 {
3779 "valid map access into an array with a signed variable",
3780 .insns = {
3781 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3782 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3784 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003785 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3786 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003787 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
3788 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3789 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
3790 BPF_MOV32_IMM(BPF_REG_1, 0),
3791 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3792 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3793 BPF_MOV32_IMM(BPF_REG_1, 0),
3794 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3795 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003796 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3797 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003798 BPF_EXIT_INSN(),
3799 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003800 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003801 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003802 .result_unpriv = REJECT,
3803 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003804 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003805 },
3806 {
3807 "invalid map access into an array with a constant",
3808 .insns = {
3809 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3810 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3812 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003813 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3814 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003815 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3816 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
3817 offsetof(struct test_val, foo)),
3818 BPF_EXIT_INSN(),
3819 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003820 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003821 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
3822 .result = REJECT,
3823 },
3824 {
3825 "invalid map access into an array with a register",
3826 .insns = {
3827 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3828 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3830 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003831 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3832 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003833 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3834 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3835 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3836 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003837 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3838 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003839 BPF_EXIT_INSN(),
3840 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003841 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003842 .errstr = "R0 min value is outside of the array range",
3843 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003844 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003845 },
3846 {
3847 "invalid map access into an array with a variable",
3848 .insns = {
3849 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3850 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3851 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3852 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003853 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3854 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003855 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3856 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3857 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3858 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003859 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3860 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003861 BPF_EXIT_INSN(),
3862 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003863 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003864 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
Josef Bacik48461132016-09-28 10:54:32 -04003865 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003866 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003867 },
3868 {
3869 "invalid map access into an array with no floor check",
3870 .insns = {
3871 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3872 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3873 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3874 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003875 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3876 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003877 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
Edward Creef65b1842017-08-07 15:27:12 +01003878 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik48461132016-09-28 10:54:32 -04003879 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3880 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3881 BPF_MOV32_IMM(BPF_REG_1, 0),
3882 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3883 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003884 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3885 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003886 BPF_EXIT_INSN(),
3887 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003888 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003889 .errstr_unpriv = "R0 leaks addr",
3890 .errstr = "R0 unbounded memory access",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003891 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003892 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003893 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003894 },
3895 {
3896 "invalid map access into an array with a invalid max check",
3897 .insns = {
3898 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3899 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3900 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3901 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003902 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3903 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003904 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3905 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3906 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3907 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3908 BPF_MOV32_IMM(BPF_REG_1, 0),
3909 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3910 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003911 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3912 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003913 BPF_EXIT_INSN(),
3914 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003915 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003916 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003917 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003918 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003919 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003920 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003921 },
3922 {
3923 "invalid map access into an array with a invalid max check",
3924 .insns = {
3925 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3926 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3927 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3928 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003929 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3930 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003931 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3932 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3933 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3934 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3935 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3936 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003937 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3938 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003939 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3940 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003941 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3942 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003943 BPF_EXIT_INSN(),
3944 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003945 .fixup_map2 = { 3, 11 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08003946 .errstr = "R0 pointer += pointer",
Josef Bacik48461132016-09-28 10:54:32 -04003947 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003948 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003949 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02003950 {
3951 "multiple registers share map_lookup_elem result",
3952 .insns = {
3953 BPF_MOV64_IMM(BPF_REG_1, 10),
3954 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3955 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3956 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3957 BPF_LD_MAP_FD(BPF_REG_1, 0),
3958 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3959 BPF_FUNC_map_lookup_elem),
3960 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3961 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3962 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3963 BPF_EXIT_INSN(),
3964 },
3965 .fixup_map1 = { 4 },
3966 .result = ACCEPT,
3967 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3968 },
3969 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003970 "alu ops on ptr_to_map_value_or_null, 1",
3971 .insns = {
3972 BPF_MOV64_IMM(BPF_REG_1, 10),
3973 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3974 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3975 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3976 BPF_LD_MAP_FD(BPF_REG_1, 0),
3977 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3978 BPF_FUNC_map_lookup_elem),
3979 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
3981 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
3982 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3983 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3984 BPF_EXIT_INSN(),
3985 },
3986 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08003987 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003988 .result = REJECT,
3989 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3990 },
3991 {
3992 "alu ops on ptr_to_map_value_or_null, 2",
3993 .insns = {
3994 BPF_MOV64_IMM(BPF_REG_1, 10),
3995 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3996 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3998 BPF_LD_MAP_FD(BPF_REG_1, 0),
3999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4000 BPF_FUNC_map_lookup_elem),
4001 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4002 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
4003 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4004 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4005 BPF_EXIT_INSN(),
4006 },
4007 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004008 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004009 .result = REJECT,
4010 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4011 },
4012 {
4013 "alu ops on ptr_to_map_value_or_null, 3",
4014 .insns = {
4015 BPF_MOV64_IMM(BPF_REG_1, 10),
4016 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4017 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4018 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4019 BPF_LD_MAP_FD(BPF_REG_1, 0),
4020 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4021 BPF_FUNC_map_lookup_elem),
4022 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4023 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4024 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4025 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4026 BPF_EXIT_INSN(),
4027 },
4028 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004029 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004030 .result = REJECT,
4031 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4032 },
4033 {
Thomas Graf57a09bf2016-10-18 19:51:19 +02004034 "invalid memory access with multiple map_lookup_elem calls",
4035 .insns = {
4036 BPF_MOV64_IMM(BPF_REG_1, 10),
4037 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4038 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4039 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4040 BPF_LD_MAP_FD(BPF_REG_1, 0),
4041 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4042 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4043 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4044 BPF_FUNC_map_lookup_elem),
4045 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4046 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4047 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4048 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4049 BPF_FUNC_map_lookup_elem),
4050 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4051 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4052 BPF_EXIT_INSN(),
4053 },
4054 .fixup_map1 = { 4 },
4055 .result = REJECT,
4056 .errstr = "R4 !read_ok",
4057 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4058 },
4059 {
4060 "valid indirect map_lookup_elem access with 2nd lookup in branch",
4061 .insns = {
4062 BPF_MOV64_IMM(BPF_REG_1, 10),
4063 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4064 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4065 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4066 BPF_LD_MAP_FD(BPF_REG_1, 0),
4067 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4068 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4069 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4070 BPF_FUNC_map_lookup_elem),
4071 BPF_MOV64_IMM(BPF_REG_2, 10),
4072 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
4073 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4074 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4076 BPF_FUNC_map_lookup_elem),
4077 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4078 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4079 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4080 BPF_EXIT_INSN(),
4081 },
4082 .fixup_map1 = { 4 },
4083 .result = ACCEPT,
4084 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4085 },
Josef Bacike9548902016-11-29 12:35:19 -05004086 {
4087 "invalid map access from else condition",
4088 .insns = {
4089 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4090 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4091 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4092 BPF_LD_MAP_FD(BPF_REG_1, 0),
4093 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
4094 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4095 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4096 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
4097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4098 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4099 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4100 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
4101 BPF_EXIT_INSN(),
4102 },
4103 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004104 .errstr = "R0 unbounded memory access",
Josef Bacike9548902016-11-29 12:35:19 -05004105 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004106 .errstr_unpriv = "R0 leaks addr",
Josef Bacike9548902016-11-29 12:35:19 -05004107 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004108 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacike9548902016-11-29 12:35:19 -05004109 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08004110 {
4111 "constant register |= constant should keep constant type",
4112 .insns = {
4113 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4115 BPF_MOV64_IMM(BPF_REG_2, 34),
4116 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
4117 BPF_MOV64_IMM(BPF_REG_3, 0),
4118 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4119 BPF_EXIT_INSN(),
4120 },
4121 .result = ACCEPT,
4122 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4123 },
4124 {
4125 "constant register |= constant should not bypass stack boundary checks",
4126 .insns = {
4127 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4128 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4129 BPF_MOV64_IMM(BPF_REG_2, 34),
4130 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
4131 BPF_MOV64_IMM(BPF_REG_3, 0),
4132 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4133 BPF_EXIT_INSN(),
4134 },
4135 .errstr = "invalid stack type R1 off=-48 access_size=58",
4136 .result = REJECT,
4137 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4138 },
4139 {
4140 "constant register |= constant register should keep constant type",
4141 .insns = {
4142 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4143 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4144 BPF_MOV64_IMM(BPF_REG_2, 34),
4145 BPF_MOV64_IMM(BPF_REG_4, 13),
4146 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4147 BPF_MOV64_IMM(BPF_REG_3, 0),
4148 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4149 BPF_EXIT_INSN(),
4150 },
4151 .result = ACCEPT,
4152 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4153 },
4154 {
4155 "constant register |= constant register should not bypass stack boundary checks",
4156 .insns = {
4157 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4158 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4159 BPF_MOV64_IMM(BPF_REG_2, 34),
4160 BPF_MOV64_IMM(BPF_REG_4, 24),
4161 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4162 BPF_MOV64_IMM(BPF_REG_3, 0),
4163 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4164 BPF_EXIT_INSN(),
4165 },
4166 .errstr = "invalid stack type R1 off=-48 access_size=58",
4167 .result = REJECT,
4168 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4169 },
Thomas Graf3f731d82016-12-05 10:30:52 +01004170 {
4171 "invalid direct packet write for LWT_IN",
4172 .insns = {
4173 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4174 offsetof(struct __sk_buff, data)),
4175 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4176 offsetof(struct __sk_buff, data_end)),
4177 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4178 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4179 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4180 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4181 BPF_MOV64_IMM(BPF_REG_0, 0),
4182 BPF_EXIT_INSN(),
4183 },
4184 .errstr = "cannot write into packet",
4185 .result = REJECT,
4186 .prog_type = BPF_PROG_TYPE_LWT_IN,
4187 },
4188 {
4189 "invalid direct packet write for LWT_OUT",
4190 .insns = {
4191 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4192 offsetof(struct __sk_buff, data)),
4193 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4194 offsetof(struct __sk_buff, data_end)),
4195 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4196 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4197 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4198 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4199 BPF_MOV64_IMM(BPF_REG_0, 0),
4200 BPF_EXIT_INSN(),
4201 },
4202 .errstr = "cannot write into packet",
4203 .result = REJECT,
4204 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4205 },
4206 {
4207 "direct packet write for LWT_XMIT",
4208 .insns = {
4209 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4210 offsetof(struct __sk_buff, data)),
4211 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4212 offsetof(struct __sk_buff, data_end)),
4213 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4215 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4216 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4217 BPF_MOV64_IMM(BPF_REG_0, 0),
4218 BPF_EXIT_INSN(),
4219 },
4220 .result = ACCEPT,
4221 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4222 },
4223 {
4224 "direct packet read for LWT_IN",
4225 .insns = {
4226 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4227 offsetof(struct __sk_buff, data)),
4228 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4229 offsetof(struct __sk_buff, data_end)),
4230 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4231 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4232 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4233 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4234 BPF_MOV64_IMM(BPF_REG_0, 0),
4235 BPF_EXIT_INSN(),
4236 },
4237 .result = ACCEPT,
4238 .prog_type = BPF_PROG_TYPE_LWT_IN,
4239 },
4240 {
4241 "direct packet read for LWT_OUT",
4242 .insns = {
4243 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4244 offsetof(struct __sk_buff, data)),
4245 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4246 offsetof(struct __sk_buff, data_end)),
4247 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4248 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4249 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4250 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4251 BPF_MOV64_IMM(BPF_REG_0, 0),
4252 BPF_EXIT_INSN(),
4253 },
4254 .result = ACCEPT,
4255 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4256 },
4257 {
4258 "direct packet read for LWT_XMIT",
4259 .insns = {
4260 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4261 offsetof(struct __sk_buff, data)),
4262 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4263 offsetof(struct __sk_buff, data_end)),
4264 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4266 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4267 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4268 BPF_MOV64_IMM(BPF_REG_0, 0),
4269 BPF_EXIT_INSN(),
4270 },
4271 .result = ACCEPT,
4272 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4273 },
4274 {
Alexei Starovoitovb1977682017-03-24 15:57:33 -07004275 "overlapping checks for direct packet access",
4276 .insns = {
4277 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4278 offsetof(struct __sk_buff, data)),
4279 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4280 offsetof(struct __sk_buff, data_end)),
4281 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4283 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
4284 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4285 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
4286 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
4287 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
4288 BPF_MOV64_IMM(BPF_REG_0, 0),
4289 BPF_EXIT_INSN(),
4290 },
4291 .result = ACCEPT,
4292 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4293 },
4294 {
Thomas Graf3f731d82016-12-05 10:30:52 +01004295 "invalid access of tc_classid for LWT_IN",
4296 .insns = {
4297 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4298 offsetof(struct __sk_buff, tc_classid)),
4299 BPF_EXIT_INSN(),
4300 },
4301 .result = REJECT,
4302 .errstr = "invalid bpf_context access",
4303 },
4304 {
4305 "invalid access of tc_classid for LWT_OUT",
4306 .insns = {
4307 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4308 offsetof(struct __sk_buff, tc_classid)),
4309 BPF_EXIT_INSN(),
4310 },
4311 .result = REJECT,
4312 .errstr = "invalid bpf_context access",
4313 },
4314 {
4315 "invalid access of tc_classid for LWT_XMIT",
4316 .insns = {
4317 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4318 offsetof(struct __sk_buff, tc_classid)),
4319 BPF_EXIT_INSN(),
4320 },
4321 .result = REJECT,
4322 .errstr = "invalid bpf_context access",
4323 },
Gianluca Borello57225692017-01-09 10:19:47 -08004324 {
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02004325 "leak pointer into ctx 1",
4326 .insns = {
4327 BPF_MOV64_IMM(BPF_REG_0, 0),
4328 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
4329 offsetof(struct __sk_buff, cb[0])),
4330 BPF_LD_MAP_FD(BPF_REG_2, 0),
4331 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
4332 offsetof(struct __sk_buff, cb[0])),
4333 BPF_EXIT_INSN(),
4334 },
4335 .fixup_map1 = { 2 },
4336 .errstr_unpriv = "R2 leaks addr into mem",
4337 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01004338 .result = REJECT,
4339 .errstr = "BPF_XADD stores into R1 context is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02004340 },
4341 {
4342 "leak pointer into ctx 2",
4343 .insns = {
4344 BPF_MOV64_IMM(BPF_REG_0, 0),
4345 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
4346 offsetof(struct __sk_buff, cb[0])),
4347 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
4348 offsetof(struct __sk_buff, cb[0])),
4349 BPF_EXIT_INSN(),
4350 },
4351 .errstr_unpriv = "R10 leaks addr into mem",
4352 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01004353 .result = REJECT,
4354 .errstr = "BPF_XADD stores into R1 context is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02004355 },
4356 {
4357 "leak pointer into ctx 3",
4358 .insns = {
4359 BPF_MOV64_IMM(BPF_REG_0, 0),
4360 BPF_LD_MAP_FD(BPF_REG_2, 0),
4361 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
4362 offsetof(struct __sk_buff, cb[0])),
4363 BPF_EXIT_INSN(),
4364 },
4365 .fixup_map1 = { 1 },
4366 .errstr_unpriv = "R2 leaks addr into ctx",
4367 .result_unpriv = REJECT,
4368 .result = ACCEPT,
4369 },
4370 {
4371 "leak pointer into map val",
4372 .insns = {
4373 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
4374 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4375 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4376 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4377 BPF_LD_MAP_FD(BPF_REG_1, 0),
4378 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4379 BPF_FUNC_map_lookup_elem),
4380 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
4381 BPF_MOV64_IMM(BPF_REG_3, 0),
4382 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
4383 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
4384 BPF_MOV64_IMM(BPF_REG_0, 0),
4385 BPF_EXIT_INSN(),
4386 },
4387 .fixup_map1 = { 4 },
4388 .errstr_unpriv = "R6 leaks addr into mem",
4389 .result_unpriv = REJECT,
4390 .result = ACCEPT,
4391 },
4392 {
Gianluca Borello57225692017-01-09 10:19:47 -08004393 "helper access to map: full range",
4394 .insns = {
4395 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4396 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4397 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4398 BPF_LD_MAP_FD(BPF_REG_1, 0),
4399 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4400 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4401 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4402 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4403 BPF_MOV64_IMM(BPF_REG_3, 0),
4404 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4405 BPF_EXIT_INSN(),
4406 },
4407 .fixup_map2 = { 3 },
4408 .result = ACCEPT,
4409 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4410 },
4411 {
4412 "helper access to map: partial range",
4413 .insns = {
4414 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4415 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4416 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4417 BPF_LD_MAP_FD(BPF_REG_1, 0),
4418 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4419 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4420 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4421 BPF_MOV64_IMM(BPF_REG_2, 8),
4422 BPF_MOV64_IMM(BPF_REG_3, 0),
4423 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4424 BPF_EXIT_INSN(),
4425 },
4426 .fixup_map2 = { 3 },
4427 .result = ACCEPT,
4428 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4429 },
4430 {
4431 "helper access to map: empty range",
4432 .insns = {
4433 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4435 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4436 BPF_LD_MAP_FD(BPF_REG_1, 0),
4437 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004438 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
4439 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4440 BPF_MOV64_IMM(BPF_REG_2, 0),
4441 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08004442 BPF_EXIT_INSN(),
4443 },
4444 .fixup_map2 = { 3 },
4445 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
4446 .result = REJECT,
4447 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4448 },
4449 {
4450 "helper access to map: out-of-bound range",
4451 .insns = {
4452 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4453 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4454 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4455 BPF_LD_MAP_FD(BPF_REG_1, 0),
4456 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4457 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4458 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4459 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
4460 BPF_MOV64_IMM(BPF_REG_3, 0),
4461 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4462 BPF_EXIT_INSN(),
4463 },
4464 .fixup_map2 = { 3 },
4465 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
4466 .result = REJECT,
4467 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4468 },
4469 {
4470 "helper access to map: negative range",
4471 .insns = {
4472 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4474 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4475 BPF_LD_MAP_FD(BPF_REG_1, 0),
4476 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4477 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4478 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4479 BPF_MOV64_IMM(BPF_REG_2, -8),
4480 BPF_MOV64_IMM(BPF_REG_3, 0),
4481 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4482 BPF_EXIT_INSN(),
4483 },
4484 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004485 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004486 .result = REJECT,
4487 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4488 },
4489 {
4490 "helper access to adjusted map (via const imm): full range",
4491 .insns = {
4492 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4493 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4494 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4495 BPF_LD_MAP_FD(BPF_REG_1, 0),
4496 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4497 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4498 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4499 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4500 offsetof(struct test_val, foo)),
4501 BPF_MOV64_IMM(BPF_REG_2,
4502 sizeof(struct test_val) -
4503 offsetof(struct test_val, foo)),
4504 BPF_MOV64_IMM(BPF_REG_3, 0),
4505 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4506 BPF_EXIT_INSN(),
4507 },
4508 .fixup_map2 = { 3 },
4509 .result = ACCEPT,
4510 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4511 },
4512 {
4513 "helper access to adjusted map (via const imm): partial range",
4514 .insns = {
4515 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4516 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4517 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4518 BPF_LD_MAP_FD(BPF_REG_1, 0),
4519 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4520 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4521 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4523 offsetof(struct test_val, foo)),
4524 BPF_MOV64_IMM(BPF_REG_2, 8),
4525 BPF_MOV64_IMM(BPF_REG_3, 0),
4526 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4527 BPF_EXIT_INSN(),
4528 },
4529 .fixup_map2 = { 3 },
4530 .result = ACCEPT,
4531 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4532 },
4533 {
4534 "helper access to adjusted map (via const imm): empty range",
4535 .insns = {
4536 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4537 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4538 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4539 BPF_LD_MAP_FD(BPF_REG_1, 0),
4540 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004541 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Gianluca Borello57225692017-01-09 10:19:47 -08004542 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4543 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4544 offsetof(struct test_val, foo)),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004545 BPF_MOV64_IMM(BPF_REG_2, 0),
4546 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08004547 BPF_EXIT_INSN(),
4548 },
4549 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004550 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
Gianluca Borello57225692017-01-09 10:19:47 -08004551 .result = REJECT,
4552 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4553 },
4554 {
4555 "helper access to adjusted map (via const imm): out-of-bound range",
4556 .insns = {
4557 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4559 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4560 BPF_LD_MAP_FD(BPF_REG_1, 0),
4561 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4562 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4563 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4565 offsetof(struct test_val, foo)),
4566 BPF_MOV64_IMM(BPF_REG_2,
4567 sizeof(struct test_val) -
4568 offsetof(struct test_val, foo) + 8),
4569 BPF_MOV64_IMM(BPF_REG_3, 0),
4570 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4571 BPF_EXIT_INSN(),
4572 },
4573 .fixup_map2 = { 3 },
4574 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4575 .result = REJECT,
4576 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4577 },
4578 {
4579 "helper access to adjusted map (via const imm): negative range (> adjustment)",
4580 .insns = {
4581 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4582 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4583 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4584 BPF_LD_MAP_FD(BPF_REG_1, 0),
4585 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4586 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4587 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4588 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4589 offsetof(struct test_val, foo)),
4590 BPF_MOV64_IMM(BPF_REG_2, -8),
4591 BPF_MOV64_IMM(BPF_REG_3, 0),
4592 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4593 BPF_EXIT_INSN(),
4594 },
4595 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004596 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004597 .result = REJECT,
4598 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4599 },
4600 {
4601 "helper access to adjusted map (via const imm): negative range (< adjustment)",
4602 .insns = {
4603 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4605 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4606 BPF_LD_MAP_FD(BPF_REG_1, 0),
4607 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4608 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4609 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4610 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4611 offsetof(struct test_val, foo)),
4612 BPF_MOV64_IMM(BPF_REG_2, -1),
4613 BPF_MOV64_IMM(BPF_REG_3, 0),
4614 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4615 BPF_EXIT_INSN(),
4616 },
4617 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004618 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004619 .result = REJECT,
4620 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4621 },
4622 {
4623 "helper access to adjusted map (via const reg): full range",
4624 .insns = {
4625 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4627 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4628 BPF_LD_MAP_FD(BPF_REG_1, 0),
4629 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4630 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4631 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4632 BPF_MOV64_IMM(BPF_REG_3,
4633 offsetof(struct test_val, foo)),
4634 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4635 BPF_MOV64_IMM(BPF_REG_2,
4636 sizeof(struct test_val) -
4637 offsetof(struct test_val, foo)),
4638 BPF_MOV64_IMM(BPF_REG_3, 0),
4639 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4640 BPF_EXIT_INSN(),
4641 },
4642 .fixup_map2 = { 3 },
4643 .result = ACCEPT,
4644 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4645 },
4646 {
4647 "helper access to adjusted map (via const reg): partial range",
4648 .insns = {
4649 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4651 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4652 BPF_LD_MAP_FD(BPF_REG_1, 0),
4653 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4654 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4655 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4656 BPF_MOV64_IMM(BPF_REG_3,
4657 offsetof(struct test_val, foo)),
4658 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4659 BPF_MOV64_IMM(BPF_REG_2, 8),
4660 BPF_MOV64_IMM(BPF_REG_3, 0),
4661 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4662 BPF_EXIT_INSN(),
4663 },
4664 .fixup_map2 = { 3 },
4665 .result = ACCEPT,
4666 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4667 },
4668 {
4669 "helper access to adjusted map (via const reg): empty range",
4670 .insns = {
4671 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4672 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4673 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4674 BPF_LD_MAP_FD(BPF_REG_1, 0),
4675 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004676 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
Gianluca Borello57225692017-01-09 10:19:47 -08004677 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4678 BPF_MOV64_IMM(BPF_REG_3, 0),
4679 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004680 BPF_MOV64_IMM(BPF_REG_2, 0),
4681 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08004682 BPF_EXIT_INSN(),
4683 },
4684 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004685 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08004686 .result = REJECT,
4687 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4688 },
4689 {
4690 "helper access to adjusted map (via const reg): out-of-bound range",
4691 .insns = {
4692 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4694 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4695 BPF_LD_MAP_FD(BPF_REG_1, 0),
4696 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4697 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4698 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4699 BPF_MOV64_IMM(BPF_REG_3,
4700 offsetof(struct test_val, foo)),
4701 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4702 BPF_MOV64_IMM(BPF_REG_2,
4703 sizeof(struct test_val) -
4704 offsetof(struct test_val, foo) + 8),
4705 BPF_MOV64_IMM(BPF_REG_3, 0),
4706 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4707 BPF_EXIT_INSN(),
4708 },
4709 .fixup_map2 = { 3 },
4710 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4711 .result = REJECT,
4712 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4713 },
4714 {
4715 "helper access to adjusted map (via const reg): negative range (> adjustment)",
4716 .insns = {
4717 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4719 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4720 BPF_LD_MAP_FD(BPF_REG_1, 0),
4721 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4723 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4724 BPF_MOV64_IMM(BPF_REG_3,
4725 offsetof(struct test_val, foo)),
4726 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4727 BPF_MOV64_IMM(BPF_REG_2, -8),
4728 BPF_MOV64_IMM(BPF_REG_3, 0),
4729 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4730 BPF_EXIT_INSN(),
4731 },
4732 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004733 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004734 .result = REJECT,
4735 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4736 },
4737 {
4738 "helper access to adjusted map (via const reg): negative range (< adjustment)",
4739 .insns = {
4740 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4741 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4742 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4743 BPF_LD_MAP_FD(BPF_REG_1, 0),
4744 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4745 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4746 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4747 BPF_MOV64_IMM(BPF_REG_3,
4748 offsetof(struct test_val, foo)),
4749 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4750 BPF_MOV64_IMM(BPF_REG_2, -1),
4751 BPF_MOV64_IMM(BPF_REG_3, 0),
4752 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4753 BPF_EXIT_INSN(),
4754 },
4755 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004756 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004757 .result = REJECT,
4758 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4759 },
4760 {
4761 "helper access to adjusted map (via variable): full range",
4762 .insns = {
4763 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4764 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4765 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4766 BPF_LD_MAP_FD(BPF_REG_1, 0),
4767 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4768 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4769 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4770 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4771 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4772 offsetof(struct test_val, foo), 4),
4773 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4774 BPF_MOV64_IMM(BPF_REG_2,
4775 sizeof(struct test_val) -
4776 offsetof(struct test_val, foo)),
4777 BPF_MOV64_IMM(BPF_REG_3, 0),
4778 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4779 BPF_EXIT_INSN(),
4780 },
4781 .fixup_map2 = { 3 },
4782 .result = ACCEPT,
4783 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4784 },
4785 {
4786 "helper access to adjusted map (via variable): partial range",
4787 .insns = {
4788 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4789 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4790 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4791 BPF_LD_MAP_FD(BPF_REG_1, 0),
4792 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4793 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4794 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4795 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4796 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4797 offsetof(struct test_val, foo), 4),
4798 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4799 BPF_MOV64_IMM(BPF_REG_2, 8),
4800 BPF_MOV64_IMM(BPF_REG_3, 0),
4801 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4802 BPF_EXIT_INSN(),
4803 },
4804 .fixup_map2 = { 3 },
4805 .result = ACCEPT,
4806 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4807 },
4808 {
4809 "helper access to adjusted map (via variable): empty range",
4810 .insns = {
4811 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4813 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4814 BPF_LD_MAP_FD(BPF_REG_1, 0),
4815 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004816 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
Gianluca Borello57225692017-01-09 10:19:47 -08004817 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4818 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4819 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004820 offsetof(struct test_val, foo), 3),
Gianluca Borello57225692017-01-09 10:19:47 -08004821 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004822 BPF_MOV64_IMM(BPF_REG_2, 0),
4823 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08004824 BPF_EXIT_INSN(),
4825 },
4826 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08004827 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08004828 .result = REJECT,
4829 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4830 },
4831 {
4832 "helper access to adjusted map (via variable): no max check",
4833 .insns = {
4834 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4835 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4836 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4837 BPF_LD_MAP_FD(BPF_REG_1, 0),
4838 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4839 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4841 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4842 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Edward Creef65b1842017-08-07 15:27:12 +01004843 BPF_MOV64_IMM(BPF_REG_2, 1),
Gianluca Borello57225692017-01-09 10:19:47 -08004844 BPF_MOV64_IMM(BPF_REG_3, 0),
4845 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4846 BPF_EXIT_INSN(),
4847 },
4848 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004849 .errstr = "R1 unbounded memory access",
Gianluca Borello57225692017-01-09 10:19:47 -08004850 .result = REJECT,
4851 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4852 },
4853 {
4854 "helper access to adjusted map (via variable): wrong max check",
4855 .insns = {
4856 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4857 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4858 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4859 BPF_LD_MAP_FD(BPF_REG_1, 0),
4860 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4861 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4862 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4863 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4864 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4865 offsetof(struct test_val, foo), 4),
4866 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4867 BPF_MOV64_IMM(BPF_REG_2,
4868 sizeof(struct test_val) -
4869 offsetof(struct test_val, foo) + 1),
4870 BPF_MOV64_IMM(BPF_REG_3, 0),
4871 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4872 BPF_EXIT_INSN(),
4873 },
4874 .fixup_map2 = { 3 },
4875 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
4876 .result = REJECT,
4877 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4878 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08004879 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02004880 "helper access to map: bounds check using <, good access",
4881 .insns = {
4882 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4883 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4884 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4885 BPF_LD_MAP_FD(BPF_REG_1, 0),
4886 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4887 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4888 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4889 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4890 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
4891 BPF_MOV64_IMM(BPF_REG_0, 0),
4892 BPF_EXIT_INSN(),
4893 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4894 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4895 BPF_MOV64_IMM(BPF_REG_0, 0),
4896 BPF_EXIT_INSN(),
4897 },
4898 .fixup_map2 = { 3 },
4899 .result = ACCEPT,
4900 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4901 },
4902 {
4903 "helper access to map: bounds check using <, bad access",
4904 .insns = {
4905 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4906 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4907 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4908 BPF_LD_MAP_FD(BPF_REG_1, 0),
4909 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4910 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4911 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4912 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4913 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
4914 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4915 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4916 BPF_MOV64_IMM(BPF_REG_0, 0),
4917 BPF_EXIT_INSN(),
4918 BPF_MOV64_IMM(BPF_REG_0, 0),
4919 BPF_EXIT_INSN(),
4920 },
4921 .fixup_map2 = { 3 },
4922 .result = REJECT,
4923 .errstr = "R1 unbounded memory access",
4924 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4925 },
4926 {
4927 "helper access to map: bounds check using <=, good access",
4928 .insns = {
4929 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4931 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4932 BPF_LD_MAP_FD(BPF_REG_1, 0),
4933 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4934 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4935 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4936 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4937 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
4938 BPF_MOV64_IMM(BPF_REG_0, 0),
4939 BPF_EXIT_INSN(),
4940 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4941 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4942 BPF_MOV64_IMM(BPF_REG_0, 0),
4943 BPF_EXIT_INSN(),
4944 },
4945 .fixup_map2 = { 3 },
4946 .result = ACCEPT,
4947 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4948 },
4949 {
4950 "helper access to map: bounds check using <=, bad access",
4951 .insns = {
4952 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4953 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4954 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4955 BPF_LD_MAP_FD(BPF_REG_1, 0),
4956 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4957 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4958 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4959 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4960 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
4961 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4962 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4963 BPF_MOV64_IMM(BPF_REG_0, 0),
4964 BPF_EXIT_INSN(),
4965 BPF_MOV64_IMM(BPF_REG_0, 0),
4966 BPF_EXIT_INSN(),
4967 },
4968 .fixup_map2 = { 3 },
4969 .result = REJECT,
4970 .errstr = "R1 unbounded memory access",
4971 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4972 },
4973 {
4974 "helper access to map: bounds check using s<, good access",
4975 .insns = {
4976 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4977 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4978 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4979 BPF_LD_MAP_FD(BPF_REG_1, 0),
4980 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4981 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4982 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4983 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4984 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
4985 BPF_MOV64_IMM(BPF_REG_0, 0),
4986 BPF_EXIT_INSN(),
4987 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
4988 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4989 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
4990 BPF_MOV64_IMM(BPF_REG_0, 0),
4991 BPF_EXIT_INSN(),
4992 },
4993 .fixup_map2 = { 3 },
4994 .result = ACCEPT,
4995 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4996 },
4997 {
4998 "helper access to map: bounds check using s<, good access 2",
4999 .insns = {
5000 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5001 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5002 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5003 BPF_LD_MAP_FD(BPF_REG_1, 0),
5004 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5005 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5006 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5007 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5008 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5009 BPF_MOV64_IMM(BPF_REG_0, 0),
5010 BPF_EXIT_INSN(),
5011 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5012 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5013 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5014 BPF_MOV64_IMM(BPF_REG_0, 0),
5015 BPF_EXIT_INSN(),
5016 },
5017 .fixup_map2 = { 3 },
5018 .result = ACCEPT,
5019 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5020 },
5021 {
5022 "helper access to map: bounds check using s<, bad access",
5023 .insns = {
5024 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5026 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5027 BPF_LD_MAP_FD(BPF_REG_1, 0),
5028 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5030 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5031 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5032 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5033 BPF_MOV64_IMM(BPF_REG_0, 0),
5034 BPF_EXIT_INSN(),
5035 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5036 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5037 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5038 BPF_MOV64_IMM(BPF_REG_0, 0),
5039 BPF_EXIT_INSN(),
5040 },
5041 .fixup_map2 = { 3 },
5042 .result = REJECT,
5043 .errstr = "R1 min value is negative",
5044 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5045 },
5046 {
5047 "helper access to map: bounds check using s<=, good access",
5048 .insns = {
5049 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5050 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5051 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5052 BPF_LD_MAP_FD(BPF_REG_1, 0),
5053 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5054 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5055 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5056 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5057 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5058 BPF_MOV64_IMM(BPF_REG_0, 0),
5059 BPF_EXIT_INSN(),
5060 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
5061 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5062 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5063 BPF_MOV64_IMM(BPF_REG_0, 0),
5064 BPF_EXIT_INSN(),
5065 },
5066 .fixup_map2 = { 3 },
5067 .result = ACCEPT,
5068 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5069 },
5070 {
5071 "helper access to map: bounds check using s<=, good access 2",
5072 .insns = {
5073 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5074 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5075 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5076 BPF_LD_MAP_FD(BPF_REG_1, 0),
5077 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5078 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5079 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5080 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5081 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5082 BPF_MOV64_IMM(BPF_REG_0, 0),
5083 BPF_EXIT_INSN(),
5084 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5085 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5086 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5087 BPF_MOV64_IMM(BPF_REG_0, 0),
5088 BPF_EXIT_INSN(),
5089 },
5090 .fixup_map2 = { 3 },
5091 .result = ACCEPT,
5092 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5093 },
5094 {
5095 "helper access to map: bounds check using s<=, bad access",
5096 .insns = {
5097 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5099 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5100 BPF_LD_MAP_FD(BPF_REG_1, 0),
5101 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5102 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5103 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5104 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5105 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5106 BPF_MOV64_IMM(BPF_REG_0, 0),
5107 BPF_EXIT_INSN(),
5108 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5109 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5110 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5111 BPF_MOV64_IMM(BPF_REG_0, 0),
5112 BPF_EXIT_INSN(),
5113 },
5114 .fixup_map2 = { 3 },
5115 .result = REJECT,
5116 .errstr = "R1 min value is negative",
5117 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5118 },
5119 {
Gianluca Borellof0318d02017-01-09 10:19:48 -08005120 "map element value is preserved across register spilling",
5121 .insns = {
5122 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5123 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5124 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5125 BPF_LD_MAP_FD(BPF_REG_1, 0),
5126 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5127 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5128 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5129 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
5131 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5132 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5133 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5134 BPF_EXIT_INSN(),
5135 },
5136 .fixup_map2 = { 3 },
5137 .errstr_unpriv = "R0 leaks addr",
5138 .result = ACCEPT,
5139 .result_unpriv = REJECT,
5140 },
5141 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005142 "map element value or null is marked on register spilling",
5143 .insns = {
5144 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5145 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5146 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5147 BPF_LD_MAP_FD(BPF_REG_1, 0),
5148 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5149 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5150 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
5151 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5152 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5153 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5154 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5155 BPF_EXIT_INSN(),
5156 },
5157 .fixup_map2 = { 3 },
5158 .errstr_unpriv = "R0 leaks addr",
5159 .result = ACCEPT,
5160 .result_unpriv = REJECT,
5161 },
5162 {
5163 "map element value store of cleared call register",
5164 .insns = {
5165 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5166 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5167 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5168 BPF_LD_MAP_FD(BPF_REG_1, 0),
5169 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5170 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
5171 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
5172 BPF_EXIT_INSN(),
5173 },
5174 .fixup_map2 = { 3 },
5175 .errstr_unpriv = "R1 !read_ok",
5176 .errstr = "R1 !read_ok",
5177 .result = REJECT,
5178 .result_unpriv = REJECT,
5179 },
5180 {
5181 "map element value with unaligned store",
5182 .insns = {
5183 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5184 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5185 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5186 BPF_LD_MAP_FD(BPF_REG_1, 0),
5187 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5188 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
5189 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
5190 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5191 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
5192 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
5193 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
5194 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
5195 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
5196 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
5197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
5198 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
5199 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
5200 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
5201 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
5202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
5203 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
5204 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
5205 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
5206 BPF_EXIT_INSN(),
5207 },
5208 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005209 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005210 .result = ACCEPT,
5211 .result_unpriv = REJECT,
5212 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5213 },
5214 {
5215 "map element value with unaligned load",
5216 .insns = {
5217 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5219 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5220 BPF_LD_MAP_FD(BPF_REG_1, 0),
5221 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5222 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5223 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5224 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
5225 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
5226 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
5227 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
5228 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
5229 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
5230 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
5231 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
5232 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
5233 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
5234 BPF_EXIT_INSN(),
5235 },
5236 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005237 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005238 .result = ACCEPT,
5239 .result_unpriv = REJECT,
5240 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
5241 },
5242 {
5243 "map element value illegal alu op, 1",
5244 .insns = {
5245 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5247 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5248 BPF_LD_MAP_FD(BPF_REG_1, 0),
5249 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5251 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
5252 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5253 BPF_EXIT_INSN(),
5254 },
5255 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08005256 .errstr = "R0 bitwise operator &= on pointer",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005257 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005258 },
5259 {
5260 "map element value illegal alu op, 2",
5261 .insns = {
5262 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5264 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5265 BPF_LD_MAP_FD(BPF_REG_1, 0),
5266 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5268 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
5269 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5270 BPF_EXIT_INSN(),
5271 },
5272 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08005273 .errstr = "R0 32-bit pointer arithmetic prohibited",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005274 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005275 },
5276 {
5277 "map element value illegal alu op, 3",
5278 .insns = {
5279 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5280 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5281 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5282 BPF_LD_MAP_FD(BPF_REG_1, 0),
5283 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5284 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5285 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
5286 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5287 BPF_EXIT_INSN(),
5288 },
5289 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08005290 .errstr = "R0 pointer arithmetic with /= operator",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005291 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005292 },
5293 {
5294 "map element value illegal alu op, 4",
5295 .insns = {
5296 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5298 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5299 BPF_LD_MAP_FD(BPF_REG_1, 0),
5300 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5301 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
5302 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
5303 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5304 BPF_EXIT_INSN(),
5305 },
5306 .fixup_map2 = { 3 },
5307 .errstr_unpriv = "R0 pointer arithmetic prohibited",
5308 .errstr = "invalid mem access 'inv'",
5309 .result = REJECT,
5310 .result_unpriv = REJECT,
5311 },
5312 {
5313 "map element value illegal alu op, 5",
5314 .insns = {
5315 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5316 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5317 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5318 BPF_LD_MAP_FD(BPF_REG_1, 0),
5319 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5320 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5321 BPF_MOV64_IMM(BPF_REG_3, 4096),
5322 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5324 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5325 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
5326 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
5327 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
5328 BPF_EXIT_INSN(),
5329 },
5330 .fixup_map2 = { 3 },
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005331 .errstr = "R0 invalid mem access 'inv'",
5332 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005333 },
5334 {
5335 "map element value is preserved across register spilling",
Gianluca Borellof0318d02017-01-09 10:19:48 -08005336 .insns = {
5337 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5339 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5340 BPF_LD_MAP_FD(BPF_REG_1, 0),
5341 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5342 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
5344 offsetof(struct test_val, foo)),
5345 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5346 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5347 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
5348 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5349 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5350 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5351 BPF_EXIT_INSN(),
5352 },
5353 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005354 .errstr_unpriv = "R0 leaks addr",
Gianluca Borellof0318d02017-01-09 10:19:48 -08005355 .result = ACCEPT,
5356 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005357 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Gianluca Borellof0318d02017-01-09 10:19:48 -08005358 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08005359 {
5360 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
5361 .insns = {
5362 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5364 BPF_MOV64_IMM(BPF_REG_0, 0),
5365 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5366 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5367 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5368 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5369 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5370 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5371 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5372 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5373 BPF_MOV64_IMM(BPF_REG_2, 16),
5374 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5375 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5376 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5377 BPF_MOV64_IMM(BPF_REG_4, 0),
5378 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5379 BPF_MOV64_IMM(BPF_REG_3, 0),
5380 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5381 BPF_MOV64_IMM(BPF_REG_0, 0),
5382 BPF_EXIT_INSN(),
5383 },
5384 .result = ACCEPT,
5385 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5386 },
5387 {
5388 "helper access to variable memory: stack, bitwise AND, zero included",
5389 .insns = {
5390 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5392 BPF_MOV64_IMM(BPF_REG_2, 16),
5393 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5394 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5395 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5396 BPF_MOV64_IMM(BPF_REG_3, 0),
5397 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5398 BPF_EXIT_INSN(),
5399 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08005400 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005401 .result = REJECT,
5402 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5403 },
5404 {
5405 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
5406 .insns = {
5407 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5408 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5409 BPF_MOV64_IMM(BPF_REG_2, 16),
5410 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5411 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5412 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
5413 BPF_MOV64_IMM(BPF_REG_4, 0),
5414 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5415 BPF_MOV64_IMM(BPF_REG_3, 0),
5416 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5417 BPF_MOV64_IMM(BPF_REG_0, 0),
5418 BPF_EXIT_INSN(),
5419 },
5420 .errstr = "invalid stack type R1 off=-64 access_size=65",
5421 .result = REJECT,
5422 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5423 },
5424 {
5425 "helper access to variable memory: stack, JMP, correct bounds",
5426 .insns = {
5427 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5428 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5429 BPF_MOV64_IMM(BPF_REG_0, 0),
5430 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5431 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5432 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5433 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5434 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5435 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5436 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5437 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5438 BPF_MOV64_IMM(BPF_REG_2, 16),
5439 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5440 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5441 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
5442 BPF_MOV64_IMM(BPF_REG_4, 0),
5443 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5444 BPF_MOV64_IMM(BPF_REG_3, 0),
5445 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5446 BPF_MOV64_IMM(BPF_REG_0, 0),
5447 BPF_EXIT_INSN(),
5448 },
5449 .result = ACCEPT,
5450 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5451 },
5452 {
5453 "helper access to variable memory: stack, JMP (signed), correct bounds",
5454 .insns = {
5455 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5457 BPF_MOV64_IMM(BPF_REG_0, 0),
5458 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5459 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5460 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5461 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5462 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5463 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5464 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5465 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5466 BPF_MOV64_IMM(BPF_REG_2, 16),
5467 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5468 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5469 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
5470 BPF_MOV64_IMM(BPF_REG_4, 0),
5471 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
5472 BPF_MOV64_IMM(BPF_REG_3, 0),
5473 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5474 BPF_MOV64_IMM(BPF_REG_0, 0),
5475 BPF_EXIT_INSN(),
5476 },
5477 .result = ACCEPT,
5478 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5479 },
5480 {
5481 "helper access to variable memory: stack, JMP, bounds + offset",
5482 .insns = {
5483 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5485 BPF_MOV64_IMM(BPF_REG_2, 16),
5486 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5487 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5488 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
5489 BPF_MOV64_IMM(BPF_REG_4, 0),
5490 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
5491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5492 BPF_MOV64_IMM(BPF_REG_3, 0),
5493 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5494 BPF_MOV64_IMM(BPF_REG_0, 0),
5495 BPF_EXIT_INSN(),
5496 },
5497 .errstr = "invalid stack type R1 off=-64 access_size=65",
5498 .result = REJECT,
5499 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5500 },
5501 {
5502 "helper access to variable memory: stack, JMP, wrong max",
5503 .insns = {
5504 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5506 BPF_MOV64_IMM(BPF_REG_2, 16),
5507 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5508 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5509 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
5510 BPF_MOV64_IMM(BPF_REG_4, 0),
5511 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5512 BPF_MOV64_IMM(BPF_REG_3, 0),
5513 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5514 BPF_MOV64_IMM(BPF_REG_0, 0),
5515 BPF_EXIT_INSN(),
5516 },
5517 .errstr = "invalid stack type R1 off=-64 access_size=65",
5518 .result = REJECT,
5519 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5520 },
5521 {
5522 "helper access to variable memory: stack, JMP, no max check",
5523 .insns = {
5524 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5525 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5526 BPF_MOV64_IMM(BPF_REG_2, 16),
5527 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5528 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5529 BPF_MOV64_IMM(BPF_REG_4, 0),
5530 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
5531 BPF_MOV64_IMM(BPF_REG_3, 0),
5532 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5533 BPF_MOV64_IMM(BPF_REG_0, 0),
5534 BPF_EXIT_INSN(),
5535 },
Edward Creef65b1842017-08-07 15:27:12 +01005536 /* because max wasn't checked, signed min is negative */
5537 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005538 .result = REJECT,
5539 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5540 },
5541 {
5542 "helper access to variable memory: stack, JMP, no min check",
5543 .insns = {
5544 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5546 BPF_MOV64_IMM(BPF_REG_2, 16),
5547 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5548 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5549 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
5550 BPF_MOV64_IMM(BPF_REG_3, 0),
5551 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5552 BPF_MOV64_IMM(BPF_REG_0, 0),
5553 BPF_EXIT_INSN(),
5554 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08005555 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005556 .result = REJECT,
5557 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5558 },
5559 {
5560 "helper access to variable memory: stack, JMP (signed), no min check",
5561 .insns = {
5562 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5563 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5564 BPF_MOV64_IMM(BPF_REG_2, 16),
5565 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
5566 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
5567 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
5568 BPF_MOV64_IMM(BPF_REG_3, 0),
5569 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5570 BPF_MOV64_IMM(BPF_REG_0, 0),
5571 BPF_EXIT_INSN(),
5572 },
5573 .errstr = "R2 min value is negative",
5574 .result = REJECT,
5575 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5576 },
5577 {
5578 "helper access to variable memory: map, JMP, correct bounds",
5579 .insns = {
5580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5582 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5583 BPF_LD_MAP_FD(BPF_REG_1, 0),
5584 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
5586 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5587 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5588 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5589 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5590 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5591 sizeof(struct test_val), 4),
5592 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005593 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005594 BPF_MOV64_IMM(BPF_REG_3, 0),
5595 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5596 BPF_MOV64_IMM(BPF_REG_0, 0),
5597 BPF_EXIT_INSN(),
5598 },
5599 .fixup_map2 = { 3 },
5600 .result = ACCEPT,
5601 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5602 },
5603 {
5604 "helper access to variable memory: map, JMP, wrong max",
5605 .insns = {
5606 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5608 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5609 BPF_LD_MAP_FD(BPF_REG_1, 0),
5610 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5611 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
5612 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5613 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5614 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5615 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5616 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5617 sizeof(struct test_val) + 1, 4),
5618 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005619 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005620 BPF_MOV64_IMM(BPF_REG_3, 0),
5621 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5622 BPF_MOV64_IMM(BPF_REG_0, 0),
5623 BPF_EXIT_INSN(),
5624 },
5625 .fixup_map2 = { 3 },
5626 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
5627 .result = REJECT,
5628 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5629 },
5630 {
5631 "helper access to variable memory: map adjusted, JMP, correct bounds",
5632 .insns = {
5633 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5635 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5636 BPF_LD_MAP_FD(BPF_REG_1, 0),
5637 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5638 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5639 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5640 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5641 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5642 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5643 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5644 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5645 sizeof(struct test_val) - 20, 4),
5646 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005647 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005648 BPF_MOV64_IMM(BPF_REG_3, 0),
5649 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5650 BPF_MOV64_IMM(BPF_REG_0, 0),
5651 BPF_EXIT_INSN(),
5652 },
5653 .fixup_map2 = { 3 },
5654 .result = ACCEPT,
5655 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5656 },
5657 {
5658 "helper access to variable memory: map adjusted, JMP, wrong max",
5659 .insns = {
5660 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5662 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5663 BPF_LD_MAP_FD(BPF_REG_1, 0),
5664 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5666 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5667 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5668 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5669 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5670 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5671 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5672 sizeof(struct test_val) - 19, 4),
5673 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005674 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005675 BPF_MOV64_IMM(BPF_REG_3, 0),
5676 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5677 BPF_MOV64_IMM(BPF_REG_0, 0),
5678 BPF_EXIT_INSN(),
5679 },
5680 .fixup_map2 = { 3 },
5681 .errstr = "R1 min value is outside of the array range",
5682 .result = REJECT,
5683 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5684 },
5685 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005686 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Edward Creef65b1842017-08-07 15:27:12 +01005687 .insns = {
5688 BPF_MOV64_IMM(BPF_REG_1, 0),
5689 BPF_MOV64_IMM(BPF_REG_2, 0),
5690 BPF_MOV64_IMM(BPF_REG_3, 0),
5691 BPF_MOV64_IMM(BPF_REG_4, 0),
5692 BPF_MOV64_IMM(BPF_REG_5, 0),
5693 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5694 BPF_EXIT_INSN(),
5695 },
5696 .result = ACCEPT,
5697 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5698 },
5699 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005700 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005701 .insns = {
5702 BPF_MOV64_IMM(BPF_REG_1, 0),
5703 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01005704 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),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005706 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5707 BPF_MOV64_IMM(BPF_REG_3, 0),
5708 BPF_MOV64_IMM(BPF_REG_4, 0),
5709 BPF_MOV64_IMM(BPF_REG_5, 0),
5710 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5711 BPF_EXIT_INSN(),
5712 },
Edward Creef65b1842017-08-07 15:27:12 +01005713 .errstr = "R1 type=inv expected=fp",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005714 .result = REJECT,
5715 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5716 },
5717 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005718 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005719 .insns = {
5720 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5721 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5722 BPF_MOV64_IMM(BPF_REG_2, 0),
5723 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
5724 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
5725 BPF_MOV64_IMM(BPF_REG_3, 0),
5726 BPF_MOV64_IMM(BPF_REG_4, 0),
5727 BPF_MOV64_IMM(BPF_REG_5, 0),
5728 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5729 BPF_EXIT_INSN(),
5730 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08005731 .result = ACCEPT,
5732 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5733 },
5734 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005735 "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08005736 .insns = {
5737 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5738 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5739 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5740 BPF_LD_MAP_FD(BPF_REG_1, 0),
5741 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5742 BPF_FUNC_map_lookup_elem),
5743 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5744 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5745 BPF_MOV64_IMM(BPF_REG_2, 0),
5746 BPF_MOV64_IMM(BPF_REG_3, 0),
5747 BPF_MOV64_IMM(BPF_REG_4, 0),
5748 BPF_MOV64_IMM(BPF_REG_5, 0),
5749 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5750 BPF_EXIT_INSN(),
5751 },
5752 .fixup_map1 = { 3 },
5753 .result = ACCEPT,
5754 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5755 },
5756 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005757 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08005758 .insns = {
5759 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5760 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5762 BPF_LD_MAP_FD(BPF_REG_1, 0),
5763 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5764 BPF_FUNC_map_lookup_elem),
5765 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5766 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5767 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
5768 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5770 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
5771 BPF_MOV64_IMM(BPF_REG_3, 0),
5772 BPF_MOV64_IMM(BPF_REG_4, 0),
5773 BPF_MOV64_IMM(BPF_REG_5, 0),
5774 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5775 BPF_EXIT_INSN(),
5776 },
5777 .fixup_map1 = { 3 },
5778 .result = ACCEPT,
5779 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5780 },
5781 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005782 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08005783 .insns = {
5784 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5785 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5786 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5787 BPF_LD_MAP_FD(BPF_REG_1, 0),
5788 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5789 BPF_FUNC_map_lookup_elem),
5790 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5791 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5792 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5793 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5794 BPF_MOV64_IMM(BPF_REG_3, 0),
5795 BPF_MOV64_IMM(BPF_REG_4, 0),
5796 BPF_MOV64_IMM(BPF_REG_5, 0),
5797 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5798 BPF_EXIT_INSN(),
5799 },
5800 .fixup_map1 = { 3 },
5801 .result = ACCEPT,
5802 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5803 },
5804 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005805 "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08005806 .insns = {
5807 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
5808 offsetof(struct __sk_buff, data)),
5809 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5810 offsetof(struct __sk_buff, data_end)),
5811 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
5812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5813 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
5814 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
5815 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
5816 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5817 BPF_MOV64_IMM(BPF_REG_3, 0),
5818 BPF_MOV64_IMM(BPF_REG_4, 0),
5819 BPF_MOV64_IMM(BPF_REG_5, 0),
5820 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5821 BPF_EXIT_INSN(),
5822 },
5823 .result = ACCEPT,
Gianluca Borello06c1c042017-01-09 10:19:49 -08005824 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5825 },
5826 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00005827 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
5828 .insns = {
5829 BPF_MOV64_IMM(BPF_REG_1, 0),
5830 BPF_MOV64_IMM(BPF_REG_2, 0),
5831 BPF_MOV64_IMM(BPF_REG_3, 0),
5832 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5833 BPF_EXIT_INSN(),
5834 },
5835 .errstr = "R1 type=inv expected=fp",
5836 .result = REJECT,
5837 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5838 },
5839 {
5840 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
5841 .insns = {
5842 BPF_MOV64_IMM(BPF_REG_1, 0),
5843 BPF_MOV64_IMM(BPF_REG_2, 1),
5844 BPF_MOV64_IMM(BPF_REG_3, 0),
5845 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5846 BPF_EXIT_INSN(),
5847 },
5848 .errstr = "R1 type=inv expected=fp",
5849 .result = REJECT,
5850 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5851 },
5852 {
5853 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5854 .insns = {
5855 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5856 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5857 BPF_MOV64_IMM(BPF_REG_2, 0),
5858 BPF_MOV64_IMM(BPF_REG_3, 0),
5859 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5860 BPF_EXIT_INSN(),
5861 },
5862 .result = ACCEPT,
5863 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5864 },
5865 {
5866 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5867 .insns = {
5868 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5869 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5871 BPF_LD_MAP_FD(BPF_REG_1, 0),
5872 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5873 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5874 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5875 BPF_MOV64_IMM(BPF_REG_2, 0),
5876 BPF_MOV64_IMM(BPF_REG_3, 0),
5877 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5878 BPF_EXIT_INSN(),
5879 },
5880 .fixup_map1 = { 3 },
5881 .result = ACCEPT,
5882 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5883 },
5884 {
5885 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5886 .insns = {
5887 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5888 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5889 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5890 BPF_LD_MAP_FD(BPF_REG_1, 0),
5891 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5892 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5893 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5894 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
5895 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5896 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5897 BPF_MOV64_IMM(BPF_REG_3, 0),
5898 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5899 BPF_EXIT_INSN(),
5900 },
5901 .fixup_map1 = { 3 },
5902 .result = ACCEPT,
5903 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5904 },
5905 {
5906 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
5907 .insns = {
5908 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5909 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5910 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5911 BPF_LD_MAP_FD(BPF_REG_1, 0),
5912 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5913 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5914 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5915 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
5916 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
5917 BPF_MOV64_IMM(BPF_REG_3, 0),
5918 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5919 BPF_EXIT_INSN(),
5920 },
5921 .fixup_map1 = { 3 },
5922 .result = ACCEPT,
5923 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5924 },
5925 {
Gianluca Borello06c1c042017-01-09 10:19:49 -08005926 "helper access to variable memory: 8 bytes leak",
5927 .insns = {
5928 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5930 BPF_MOV64_IMM(BPF_REG_0, 0),
5931 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5932 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5933 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5934 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5935 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),
5937 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5938 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01005939 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),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005941 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
5942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5943 BPF_MOV64_IMM(BPF_REG_3, 0),
5944 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5945 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5946 BPF_EXIT_INSN(),
5947 },
5948 .errstr = "invalid indirect read from stack off -64+32 size 64",
5949 .result = REJECT,
5950 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5951 },
5952 {
5953 "helper access to variable memory: 8 bytes no leak (init memory)",
5954 .insns = {
5955 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5956 BPF_MOV64_IMM(BPF_REG_0, 0),
5957 BPF_MOV64_IMM(BPF_REG_0, 0),
5958 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5959 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5960 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5961 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5962 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5963 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5964 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5965 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5967 BPF_MOV64_IMM(BPF_REG_2, 0),
5968 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
5969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
5970 BPF_MOV64_IMM(BPF_REG_3, 0),
5971 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5972 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5973 BPF_EXIT_INSN(),
5974 },
5975 .result = ACCEPT,
5976 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5977 },
Josef Bacik29200c12017-02-03 16:25:23 -05005978 {
5979 "invalid and of negative number",
5980 .insns = {
5981 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5982 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5983 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5984 BPF_LD_MAP_FD(BPF_REG_1, 0),
5985 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5986 BPF_FUNC_map_lookup_elem),
5987 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Edward Creef65b1842017-08-07 15:27:12 +01005988 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik29200c12017-02-03 16:25:23 -05005989 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
5990 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
5991 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5992 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
5993 offsetof(struct test_val, foo)),
5994 BPF_EXIT_INSN(),
5995 },
5996 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005997 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05005998 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005999 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik29200c12017-02-03 16:25:23 -05006000 },
6001 {
6002 "invalid range check",
6003 .insns = {
6004 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6005 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6006 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6007 BPF_LD_MAP_FD(BPF_REG_1, 0),
6008 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6009 BPF_FUNC_map_lookup_elem),
6010 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
6011 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6012 BPF_MOV64_IMM(BPF_REG_9, 1),
6013 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
6014 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
6015 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
6016 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
6017 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
6018 BPF_MOV32_IMM(BPF_REG_3, 1),
6019 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
6020 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
6021 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
6022 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
6023 BPF_MOV64_REG(BPF_REG_0, 0),
6024 BPF_EXIT_INSN(),
6025 },
6026 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006027 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05006028 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006029 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006030 },
6031 {
6032 "map in map access",
6033 .insns = {
6034 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6035 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6037 BPF_LD_MAP_FD(BPF_REG_1, 0),
6038 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6039 BPF_FUNC_map_lookup_elem),
6040 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6041 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6042 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6044 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6045 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6046 BPF_FUNC_map_lookup_elem),
6047 BPF_MOV64_REG(BPF_REG_0, 0),
6048 BPF_EXIT_INSN(),
6049 },
6050 .fixup_map_in_map = { 3 },
6051 .result = ACCEPT,
6052 },
6053 {
6054 "invalid inner map pointer",
6055 .insns = {
6056 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6057 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6059 BPF_LD_MAP_FD(BPF_REG_1, 0),
6060 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6061 BPF_FUNC_map_lookup_elem),
6062 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6063 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6064 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6065 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6066 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6067 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6068 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6069 BPF_FUNC_map_lookup_elem),
6070 BPF_MOV64_REG(BPF_REG_0, 0),
6071 BPF_EXIT_INSN(),
6072 },
6073 .fixup_map_in_map = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006074 .errstr = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006075 .result = REJECT,
6076 },
6077 {
6078 "forgot null checking on the inner map pointer",
6079 .insns = {
6080 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6081 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6083 BPF_LD_MAP_FD(BPF_REG_1, 0),
6084 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6085 BPF_FUNC_map_lookup_elem),
6086 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6087 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6088 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6089 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6090 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6091 BPF_FUNC_map_lookup_elem),
6092 BPF_MOV64_REG(BPF_REG_0, 0),
6093 BPF_EXIT_INSN(),
6094 },
6095 .fixup_map_in_map = { 3 },
6096 .errstr = "R1 type=map_value_or_null expected=map_ptr",
6097 .result = REJECT,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02006098 },
6099 {
6100 "ld_abs: check calling conv, r1",
6101 .insns = {
6102 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6103 BPF_MOV64_IMM(BPF_REG_1, 0),
6104 BPF_LD_ABS(BPF_W, -0x200000),
6105 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6106 BPF_EXIT_INSN(),
6107 },
6108 .errstr = "R1 !read_ok",
6109 .result = REJECT,
6110 },
6111 {
6112 "ld_abs: check calling conv, r2",
6113 .insns = {
6114 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6115 BPF_MOV64_IMM(BPF_REG_2, 0),
6116 BPF_LD_ABS(BPF_W, -0x200000),
6117 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
6118 BPF_EXIT_INSN(),
6119 },
6120 .errstr = "R2 !read_ok",
6121 .result = REJECT,
6122 },
6123 {
6124 "ld_abs: check calling conv, r3",
6125 .insns = {
6126 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6127 BPF_MOV64_IMM(BPF_REG_3, 0),
6128 BPF_LD_ABS(BPF_W, -0x200000),
6129 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
6130 BPF_EXIT_INSN(),
6131 },
6132 .errstr = "R3 !read_ok",
6133 .result = REJECT,
6134 },
6135 {
6136 "ld_abs: check calling conv, r4",
6137 .insns = {
6138 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6139 BPF_MOV64_IMM(BPF_REG_4, 0),
6140 BPF_LD_ABS(BPF_W, -0x200000),
6141 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
6142 BPF_EXIT_INSN(),
6143 },
6144 .errstr = "R4 !read_ok",
6145 .result = REJECT,
6146 },
6147 {
6148 "ld_abs: check calling conv, r5",
6149 .insns = {
6150 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6151 BPF_MOV64_IMM(BPF_REG_5, 0),
6152 BPF_LD_ABS(BPF_W, -0x200000),
6153 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
6154 BPF_EXIT_INSN(),
6155 },
6156 .errstr = "R5 !read_ok",
6157 .result = REJECT,
6158 },
6159 {
6160 "ld_abs: check calling conv, r7",
6161 .insns = {
6162 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6163 BPF_MOV64_IMM(BPF_REG_7, 0),
6164 BPF_LD_ABS(BPF_W, -0x200000),
6165 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
6166 BPF_EXIT_INSN(),
6167 },
6168 .result = ACCEPT,
6169 },
6170 {
Daniel Borkmann87ab8192017-12-14 21:07:27 +01006171 "ld_abs: tests on r6 and skb data reload helper",
6172 .insns = {
6173 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6174 BPF_LD_ABS(BPF_B, 0),
6175 BPF_LD_ABS(BPF_H, 0),
6176 BPF_LD_ABS(BPF_W, 0),
6177 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
6178 BPF_MOV64_IMM(BPF_REG_6, 0),
6179 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
6180 BPF_MOV64_IMM(BPF_REG_2, 1),
6181 BPF_MOV64_IMM(BPF_REG_3, 2),
6182 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6183 BPF_FUNC_skb_vlan_push),
6184 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
6185 BPF_LD_ABS(BPF_B, 0),
6186 BPF_LD_ABS(BPF_H, 0),
6187 BPF_LD_ABS(BPF_W, 0),
6188 BPF_MOV64_IMM(BPF_REG_0, 42),
6189 BPF_EXIT_INSN(),
6190 },
6191 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6192 .result = ACCEPT,
6193 },
6194 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02006195 "ld_ind: check calling conv, r1",
6196 .insns = {
6197 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6198 BPF_MOV64_IMM(BPF_REG_1, 1),
6199 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
6200 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6201 BPF_EXIT_INSN(),
6202 },
6203 .errstr = "R1 !read_ok",
6204 .result = REJECT,
6205 },
6206 {
6207 "ld_ind: check calling conv, r2",
6208 .insns = {
6209 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6210 BPF_MOV64_IMM(BPF_REG_2, 1),
6211 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
6212 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
6213 BPF_EXIT_INSN(),
6214 },
6215 .errstr = "R2 !read_ok",
6216 .result = REJECT,
6217 },
6218 {
6219 "ld_ind: check calling conv, r3",
6220 .insns = {
6221 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6222 BPF_MOV64_IMM(BPF_REG_3, 1),
6223 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
6224 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
6225 BPF_EXIT_INSN(),
6226 },
6227 .errstr = "R3 !read_ok",
6228 .result = REJECT,
6229 },
6230 {
6231 "ld_ind: check calling conv, r4",
6232 .insns = {
6233 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6234 BPF_MOV64_IMM(BPF_REG_4, 1),
6235 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
6236 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
6237 BPF_EXIT_INSN(),
6238 },
6239 .errstr = "R4 !read_ok",
6240 .result = REJECT,
6241 },
6242 {
6243 "ld_ind: check calling conv, r5",
6244 .insns = {
6245 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6246 BPF_MOV64_IMM(BPF_REG_5, 1),
6247 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
6248 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
6249 BPF_EXIT_INSN(),
6250 },
6251 .errstr = "R5 !read_ok",
6252 .result = REJECT,
6253 },
6254 {
6255 "ld_ind: check calling conv, r7",
6256 .insns = {
6257 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6258 BPF_MOV64_IMM(BPF_REG_7, 1),
6259 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
6260 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
6261 BPF_EXIT_INSN(),
6262 },
6263 .result = ACCEPT,
6264 },
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006265 {
6266 "check bpf_perf_event_data->sample_period byte load permitted",
6267 .insns = {
6268 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02006269#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006270 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
6271 offsetof(struct bpf_perf_event_data, sample_period)),
6272#else
6273 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
6274 offsetof(struct bpf_perf_event_data, sample_period) + 7),
6275#endif
6276 BPF_EXIT_INSN(),
6277 },
6278 .result = ACCEPT,
6279 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6280 },
6281 {
6282 "check bpf_perf_event_data->sample_period half load permitted",
6283 .insns = {
6284 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02006285#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006286 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6287 offsetof(struct bpf_perf_event_data, sample_period)),
6288#else
6289 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6290 offsetof(struct bpf_perf_event_data, sample_period) + 6),
6291#endif
6292 BPF_EXIT_INSN(),
6293 },
6294 .result = ACCEPT,
6295 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6296 },
6297 {
6298 "check bpf_perf_event_data->sample_period word load permitted",
6299 .insns = {
6300 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02006301#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006302 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6303 offsetof(struct bpf_perf_event_data, sample_period)),
6304#else
6305 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6306 offsetof(struct bpf_perf_event_data, sample_period) + 4),
6307#endif
6308 BPF_EXIT_INSN(),
6309 },
6310 .result = ACCEPT,
6311 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6312 },
6313 {
6314 "check bpf_perf_event_data->sample_period dword load permitted",
6315 .insns = {
6316 BPF_MOV64_IMM(BPF_REG_0, 0),
6317 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
6318 offsetof(struct bpf_perf_event_data, sample_period)),
6319 BPF_EXIT_INSN(),
6320 },
6321 .result = ACCEPT,
6322 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
6323 },
6324 {
6325 "check skb->data half load not permitted",
6326 .insns = {
6327 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02006328#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006329 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6330 offsetof(struct __sk_buff, data)),
6331#else
6332 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6333 offsetof(struct __sk_buff, data) + 2),
6334#endif
6335 BPF_EXIT_INSN(),
6336 },
6337 .result = REJECT,
6338 .errstr = "invalid bpf_context access",
6339 },
6340 {
6341 "check skb->tc_classid half load not permitted for lwt prog",
6342 .insns = {
6343 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02006344#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07006345 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6346 offsetof(struct __sk_buff, tc_classid)),
6347#else
6348 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
6349 offsetof(struct __sk_buff, tc_classid) + 2),
6350#endif
6351 BPF_EXIT_INSN(),
6352 },
6353 .result = REJECT,
6354 .errstr = "invalid bpf_context access",
6355 .prog_type = BPF_PROG_TYPE_LWT_IN,
6356 },
Edward Creeb712296a2017-07-21 00:00:24 +02006357 {
6358 "bounds checks mixing signed and unsigned, positive bounds",
6359 .insns = {
6360 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6361 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6362 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6363 BPF_LD_MAP_FD(BPF_REG_1, 0),
6364 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6365 BPF_FUNC_map_lookup_elem),
6366 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6367 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6368 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6369 BPF_MOV64_IMM(BPF_REG_2, 2),
6370 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
6371 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
6372 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6373 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6374 BPF_MOV64_IMM(BPF_REG_0, 0),
6375 BPF_EXIT_INSN(),
6376 },
6377 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006378 .errstr = "unbounded min value",
Edward Creeb712296a2017-07-21 00:00:24 +02006379 .result = REJECT,
Edward Creeb712296a2017-07-21 00:00:24 +02006380 },
6381 {
6382 "bounds checks mixing signed and unsigned",
6383 .insns = {
6384 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6385 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6387 BPF_LD_MAP_FD(BPF_REG_1, 0),
6388 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6389 BPF_FUNC_map_lookup_elem),
6390 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6391 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6392 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6393 BPF_MOV64_IMM(BPF_REG_2, -1),
6394 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
6395 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6396 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6397 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6398 BPF_MOV64_IMM(BPF_REG_0, 0),
6399 BPF_EXIT_INSN(),
6400 },
6401 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006402 .errstr = "unbounded min value",
Edward Creeb712296a2017-07-21 00:00:24 +02006403 .result = REJECT,
Edward Creeb712296a2017-07-21 00:00:24 +02006404 },
Daniel Borkmann86412502017-07-21 00:00:25 +02006405 {
6406 "bounds checks mixing signed and unsigned, variant 2",
6407 .insns = {
6408 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6409 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6411 BPF_LD_MAP_FD(BPF_REG_1, 0),
6412 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6413 BPF_FUNC_map_lookup_elem),
6414 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6415 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6416 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6417 BPF_MOV64_IMM(BPF_REG_2, -1),
6418 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
6419 BPF_MOV64_IMM(BPF_REG_8, 0),
6420 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
6421 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
6422 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
6423 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
6424 BPF_MOV64_IMM(BPF_REG_0, 0),
6425 BPF_EXIT_INSN(),
6426 },
6427 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006428 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006429 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006430 },
6431 {
6432 "bounds checks mixing signed and unsigned, variant 3",
6433 .insns = {
6434 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6435 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6437 BPF_LD_MAP_FD(BPF_REG_1, 0),
6438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6439 BPF_FUNC_map_lookup_elem),
6440 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6441 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6442 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6443 BPF_MOV64_IMM(BPF_REG_2, -1),
6444 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
6445 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
6446 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
6447 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
6448 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
6449 BPF_MOV64_IMM(BPF_REG_0, 0),
6450 BPF_EXIT_INSN(),
6451 },
6452 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006453 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006454 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006455 },
6456 {
6457 "bounds checks mixing signed and unsigned, variant 4",
6458 .insns = {
6459 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6460 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6462 BPF_LD_MAP_FD(BPF_REG_1, 0),
6463 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6464 BPF_FUNC_map_lookup_elem),
6465 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6466 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6467 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6468 BPF_MOV64_IMM(BPF_REG_2, 1),
6469 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
6470 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6471 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6472 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6473 BPF_MOV64_IMM(BPF_REG_0, 0),
6474 BPF_EXIT_INSN(),
6475 },
6476 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006477 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006478 },
6479 {
6480 "bounds checks mixing signed and unsigned, variant 5",
6481 .insns = {
6482 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6483 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6485 BPF_LD_MAP_FD(BPF_REG_1, 0),
6486 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6487 BPF_FUNC_map_lookup_elem),
6488 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6489 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6490 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6491 BPF_MOV64_IMM(BPF_REG_2, -1),
6492 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
6493 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
6494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
6495 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
6496 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6497 BPF_MOV64_IMM(BPF_REG_0, 0),
6498 BPF_EXIT_INSN(),
6499 },
6500 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006501 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006502 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006503 },
6504 {
6505 "bounds checks mixing signed and unsigned, variant 6",
6506 .insns = {
6507 BPF_MOV64_IMM(BPF_REG_2, 0),
6508 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
6509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
6510 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6511 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
6512 BPF_MOV64_IMM(BPF_REG_6, -1),
6513 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
6514 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
6515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
6516 BPF_MOV64_IMM(BPF_REG_5, 0),
6517 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
6518 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6519 BPF_FUNC_skb_load_bytes),
6520 BPF_MOV64_IMM(BPF_REG_0, 0),
6521 BPF_EXIT_INSN(),
6522 },
Daniel Borkmann86412502017-07-21 00:00:25 +02006523 .errstr = "R4 min value is negative, either use unsigned",
6524 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006525 },
6526 {
6527 "bounds checks mixing signed and unsigned, variant 7",
6528 .insns = {
6529 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6530 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6531 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6532 BPF_LD_MAP_FD(BPF_REG_1, 0),
6533 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6534 BPF_FUNC_map_lookup_elem),
6535 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6536 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6537 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6538 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
6539 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
6540 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6541 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6542 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6543 BPF_MOV64_IMM(BPF_REG_0, 0),
6544 BPF_EXIT_INSN(),
6545 },
6546 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006547 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006548 },
6549 {
6550 "bounds checks mixing signed and unsigned, variant 8",
6551 .insns = {
6552 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6553 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6554 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6555 BPF_LD_MAP_FD(BPF_REG_1, 0),
6556 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6557 BPF_FUNC_map_lookup_elem),
Daniel Borkmann86412502017-07-21 00:00:25 +02006558 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6559 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6560 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6561 BPF_MOV64_IMM(BPF_REG_2, -1),
6562 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6563 BPF_MOV64_IMM(BPF_REG_0, 0),
6564 BPF_EXIT_INSN(),
6565 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6566 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6567 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6568 BPF_MOV64_IMM(BPF_REG_0, 0),
6569 BPF_EXIT_INSN(),
6570 },
6571 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006572 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006573 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006574 },
6575 {
Edward Creef65b1842017-08-07 15:27:12 +01006576 "bounds checks mixing signed and unsigned, variant 9",
Daniel Borkmann86412502017-07-21 00:00:25 +02006577 .insns = {
6578 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6579 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6581 BPF_LD_MAP_FD(BPF_REG_1, 0),
6582 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6583 BPF_FUNC_map_lookup_elem),
6584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6585 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6586 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6587 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
6588 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6589 BPF_MOV64_IMM(BPF_REG_0, 0),
6590 BPF_EXIT_INSN(),
6591 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6592 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6593 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6594 BPF_MOV64_IMM(BPF_REG_0, 0),
6595 BPF_EXIT_INSN(),
6596 },
6597 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006598 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006599 },
6600 {
Edward Creef65b1842017-08-07 15:27:12 +01006601 "bounds checks mixing signed and unsigned, variant 10",
Daniel Borkmann86412502017-07-21 00:00:25 +02006602 .insns = {
6603 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6604 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6606 BPF_LD_MAP_FD(BPF_REG_1, 0),
6607 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6608 BPF_FUNC_map_lookup_elem),
6609 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6610 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6611 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6612 BPF_MOV64_IMM(BPF_REG_2, 0),
6613 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
6614 BPF_MOV64_IMM(BPF_REG_0, 0),
6615 BPF_EXIT_INSN(),
6616 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6617 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6618 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6619 BPF_MOV64_IMM(BPF_REG_0, 0),
6620 BPF_EXIT_INSN(),
6621 },
6622 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006623 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006624 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006625 },
6626 {
Edward Creef65b1842017-08-07 15:27:12 +01006627 "bounds checks mixing signed and unsigned, variant 11",
Daniel Borkmann86412502017-07-21 00:00:25 +02006628 .insns = {
6629 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6630 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6632 BPF_LD_MAP_FD(BPF_REG_1, 0),
6633 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6634 BPF_FUNC_map_lookup_elem),
6635 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6636 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6637 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6638 BPF_MOV64_IMM(BPF_REG_2, -1),
6639 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6640 /* Dead branch. */
6641 BPF_MOV64_IMM(BPF_REG_0, 0),
6642 BPF_EXIT_INSN(),
6643 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6644 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6645 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6646 BPF_MOV64_IMM(BPF_REG_0, 0),
6647 BPF_EXIT_INSN(),
6648 },
6649 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006650 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006651 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006652 },
6653 {
Edward Creef65b1842017-08-07 15:27:12 +01006654 "bounds checks mixing signed and unsigned, variant 12",
Daniel Borkmann86412502017-07-21 00:00:25 +02006655 .insns = {
6656 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6657 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6659 BPF_LD_MAP_FD(BPF_REG_1, 0),
6660 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6661 BPF_FUNC_map_lookup_elem),
6662 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6663 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6664 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6665 BPF_MOV64_IMM(BPF_REG_2, -6),
6666 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6667 BPF_MOV64_IMM(BPF_REG_0, 0),
6668 BPF_EXIT_INSN(),
6669 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6670 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6671 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6672 BPF_MOV64_IMM(BPF_REG_0, 0),
6673 BPF_EXIT_INSN(),
6674 },
6675 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006676 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006677 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006678 },
6679 {
Edward Creef65b1842017-08-07 15:27:12 +01006680 "bounds checks mixing signed and unsigned, variant 13",
Daniel Borkmann86412502017-07-21 00:00:25 +02006681 .insns = {
6682 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6683 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6684 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6685 BPF_LD_MAP_FD(BPF_REG_1, 0),
6686 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6687 BPF_FUNC_map_lookup_elem),
6688 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6689 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6690 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6691 BPF_MOV64_IMM(BPF_REG_2, 2),
6692 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6693 BPF_MOV64_IMM(BPF_REG_7, 1),
6694 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
6695 BPF_MOV64_IMM(BPF_REG_0, 0),
6696 BPF_EXIT_INSN(),
6697 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
6698 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
6699 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
6700 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6701 BPF_MOV64_IMM(BPF_REG_0, 0),
6702 BPF_EXIT_INSN(),
6703 },
6704 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006705 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006706 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006707 },
6708 {
Edward Creef65b1842017-08-07 15:27:12 +01006709 "bounds checks mixing signed and unsigned, variant 14",
Daniel Borkmann86412502017-07-21 00:00:25 +02006710 .insns = {
6711 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
6712 offsetof(struct __sk_buff, mark)),
6713 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6716 BPF_LD_MAP_FD(BPF_REG_1, 0),
6717 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6718 BPF_FUNC_map_lookup_elem),
6719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6720 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6721 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6722 BPF_MOV64_IMM(BPF_REG_2, -1),
6723 BPF_MOV64_IMM(BPF_REG_8, 2),
6724 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
6725 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
6726 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
6727 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6728 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6729 BPF_MOV64_IMM(BPF_REG_0, 0),
6730 BPF_EXIT_INSN(),
6731 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
6732 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
6733 },
6734 .fixup_map1 = { 4 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006735 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006736 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02006737 },
6738 {
Edward Creef65b1842017-08-07 15:27:12 +01006739 "bounds checks mixing signed and unsigned, variant 15",
Daniel Borkmann86412502017-07-21 00:00:25 +02006740 .insns = {
6741 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6742 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6743 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6744 BPF_LD_MAP_FD(BPF_REG_1, 0),
6745 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6746 BPF_FUNC_map_lookup_elem),
6747 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6748 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
6749 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6750 BPF_MOV64_IMM(BPF_REG_2, -6),
6751 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
6752 BPF_MOV64_IMM(BPF_REG_0, 0),
6753 BPF_EXIT_INSN(),
6754 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6755 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
6756 BPF_MOV64_IMM(BPF_REG_0, 0),
6757 BPF_EXIT_INSN(),
6758 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
6759 BPF_MOV64_IMM(BPF_REG_0, 0),
6760 BPF_EXIT_INSN(),
6761 },
6762 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08006763 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02006764 .result = REJECT,
6765 .result_unpriv = REJECT,
6766 },
Edward Cree545722c2017-07-21 14:36:57 +01006767 {
Edward Creef65b1842017-08-07 15:27:12 +01006768 "subtraction bounds (map value) variant 1",
Edward Cree545722c2017-07-21 14:36:57 +01006769 .insns = {
6770 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6771 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6773 BPF_LD_MAP_FD(BPF_REG_1, 0),
6774 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6775 BPF_FUNC_map_lookup_elem),
6776 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6777 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6778 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
6779 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
6780 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
6781 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
6782 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
6783 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6784 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6785 BPF_EXIT_INSN(),
6786 BPF_MOV64_IMM(BPF_REG_0, 0),
6787 BPF_EXIT_INSN(),
6788 },
6789 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006790 .errstr = "R0 max value is outside of the array range",
6791 .result = REJECT,
6792 },
6793 {
6794 "subtraction bounds (map value) variant 2",
6795 .insns = {
6796 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6797 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6798 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6799 BPF_LD_MAP_FD(BPF_REG_1, 0),
6800 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6801 BPF_FUNC_map_lookup_elem),
6802 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
6803 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6804 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
6805 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
6806 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
6807 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
6808 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6809 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6810 BPF_EXIT_INSN(),
6811 BPF_MOV64_IMM(BPF_REG_0, 0),
6812 BPF_EXIT_INSN(),
6813 },
6814 .fixup_map1 = { 3 },
Edward Cree545722c2017-07-21 14:36:57 +01006815 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
6816 .result = REJECT,
Edward Cree545722c2017-07-21 14:36:57 +01006817 },
Edward Cree69c4e8a2017-08-07 15:29:51 +01006818 {
Jann Horn2255f8d2017-12-18 20:12:01 -08006819 "bounds check based on zero-extended MOV",
6820 .insns = {
6821 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6822 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6824 BPF_LD_MAP_FD(BPF_REG_1, 0),
6825 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6826 BPF_FUNC_map_lookup_elem),
6827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6828 /* r2 = 0x0000'0000'ffff'ffff */
6829 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
6830 /* r2 = 0 */
6831 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
6832 /* no-op */
6833 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6834 /* access at offset 0 */
6835 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6836 /* exit */
6837 BPF_MOV64_IMM(BPF_REG_0, 0),
6838 BPF_EXIT_INSN(),
6839 },
6840 .fixup_map1 = { 3 },
6841 .result = ACCEPT
6842 },
6843 {
6844 "bounds check based on sign-extended MOV. test1",
6845 .insns = {
6846 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6847 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6849 BPF_LD_MAP_FD(BPF_REG_1, 0),
6850 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6851 BPF_FUNC_map_lookup_elem),
6852 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6853 /* r2 = 0xffff'ffff'ffff'ffff */
6854 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
6855 /* r2 = 0xffff'ffff */
6856 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
6857 /* r0 = <oob pointer> */
6858 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6859 /* access to OOB pointer */
6860 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6861 /* exit */
6862 BPF_MOV64_IMM(BPF_REG_0, 0),
6863 BPF_EXIT_INSN(),
6864 },
6865 .fixup_map1 = { 3 },
6866 .errstr = "map_value pointer and 4294967295",
6867 .result = REJECT
6868 },
6869 {
6870 "bounds check based on sign-extended MOV. test2",
6871 .insns = {
6872 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6873 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6874 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6875 BPF_LD_MAP_FD(BPF_REG_1, 0),
6876 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6877 BPF_FUNC_map_lookup_elem),
6878 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6879 /* r2 = 0xffff'ffff'ffff'ffff */
6880 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
6881 /* r2 = 0xfff'ffff */
6882 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
6883 /* r0 = <oob pointer> */
6884 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
6885 /* access to OOB pointer */
6886 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6887 /* exit */
6888 BPF_MOV64_IMM(BPF_REG_0, 0),
6889 BPF_EXIT_INSN(),
6890 },
6891 .fixup_map1 = { 3 },
6892 .errstr = "R0 min value is outside of the array range",
6893 .result = REJECT
6894 },
6895 {
6896 "bounds check based on reg_off + var_off + insn_off. test1",
6897 .insns = {
6898 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6899 offsetof(struct __sk_buff, mark)),
6900 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6901 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6902 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6903 BPF_LD_MAP_FD(BPF_REG_1, 0),
6904 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6905 BPF_FUNC_map_lookup_elem),
6906 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6907 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
6908 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
6909 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
6910 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
6911 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
6912 BPF_MOV64_IMM(BPF_REG_0, 0),
6913 BPF_EXIT_INSN(),
6914 },
6915 .fixup_map1 = { 4 },
6916 .errstr = "value_size=8 off=1073741825",
6917 .result = REJECT,
6918 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6919 },
6920 {
6921 "bounds check based on reg_off + var_off + insn_off. test2",
6922 .insns = {
6923 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6924 offsetof(struct __sk_buff, mark)),
6925 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6926 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6927 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6928 BPF_LD_MAP_FD(BPF_REG_1, 0),
6929 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6930 BPF_FUNC_map_lookup_elem),
6931 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6932 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
6933 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
6934 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
6935 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
6936 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
6937 BPF_MOV64_IMM(BPF_REG_0, 0),
6938 BPF_EXIT_INSN(),
6939 },
6940 .fixup_map1 = { 4 },
6941 .errstr = "value 1073741823",
6942 .result = REJECT,
6943 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6944 },
6945 {
6946 "bounds check after truncation of non-boundary-crossing range",
6947 .insns = {
6948 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6949 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6950 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6951 BPF_LD_MAP_FD(BPF_REG_1, 0),
6952 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6953 BPF_FUNC_map_lookup_elem),
6954 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6955 /* r1 = [0x00, 0xff] */
6956 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6957 BPF_MOV64_IMM(BPF_REG_2, 1),
6958 /* r2 = 0x10'0000'0000 */
6959 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
6960 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
6961 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
6962 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
6963 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
6964 /* r1 = [0x00, 0xff] */
6965 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
6966 /* r1 = 0 */
6967 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
6968 /* no-op */
6969 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6970 /* access at offset 0 */
6971 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
6972 /* exit */
6973 BPF_MOV64_IMM(BPF_REG_0, 0),
6974 BPF_EXIT_INSN(),
6975 },
6976 .fixup_map1 = { 3 },
6977 .result = ACCEPT
6978 },
6979 {
6980 "bounds check after truncation of boundary-crossing range (1)",
6981 .insns = {
6982 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6983 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6984 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6985 BPF_LD_MAP_FD(BPF_REG_1, 0),
6986 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6987 BPF_FUNC_map_lookup_elem),
6988 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6989 /* r1 = [0x00, 0xff] */
6990 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
6991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
6992 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
6993 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
6994 /* r1 = [0xffff'ff80, 0xffff'ffff] or
6995 * [0x0000'0000, 0x0000'007f]
6996 */
6997 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
6998 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
6999 /* r1 = [0x00, 0xff] or
7000 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7001 */
7002 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7003 /* r1 = 0 or
7004 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7005 */
7006 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7007 /* no-op or OOB pointer computation */
7008 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7009 /* potentially OOB access */
7010 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7011 /* exit */
7012 BPF_MOV64_IMM(BPF_REG_0, 0),
7013 BPF_EXIT_INSN(),
7014 },
7015 .fixup_map1 = { 3 },
7016 /* not actually fully unbounded, but the bound is very high */
7017 .errstr = "R0 unbounded memory access",
7018 .result = REJECT
7019 },
7020 {
7021 "bounds check after truncation of boundary-crossing range (2)",
7022 .insns = {
7023 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7024 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7026 BPF_LD_MAP_FD(BPF_REG_1, 0),
7027 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7028 BPF_FUNC_map_lookup_elem),
7029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7030 /* r1 = [0x00, 0xff] */
7031 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7032 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7033 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7034 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7035 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7036 * [0x0000'0000, 0x0000'007f]
7037 * difference to previous test: truncation via MOV32
7038 * instead of ALU32.
7039 */
7040 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
7041 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7042 /* r1 = [0x00, 0xff] or
7043 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7044 */
7045 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7046 /* r1 = 0 or
7047 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7048 */
7049 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7050 /* no-op or OOB pointer computation */
7051 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7052 /* potentially OOB access */
7053 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7054 /* exit */
7055 BPF_MOV64_IMM(BPF_REG_0, 0),
7056 BPF_EXIT_INSN(),
7057 },
7058 .fixup_map1 = { 3 },
7059 /* not actually fully unbounded, but the bound is very high */
7060 .errstr = "R0 unbounded memory access",
7061 .result = REJECT
7062 },
7063 {
7064 "bounds check after wrapping 32-bit addition",
7065 .insns = {
7066 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7067 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7068 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7069 BPF_LD_MAP_FD(BPF_REG_1, 0),
7070 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7071 BPF_FUNC_map_lookup_elem),
7072 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7073 /* r1 = 0x7fff'ffff */
7074 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
7075 /* r1 = 0xffff'fffe */
7076 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7077 /* r1 = 0 */
7078 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
7079 /* no-op */
7080 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7081 /* access at offset 0 */
7082 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7083 /* exit */
7084 BPF_MOV64_IMM(BPF_REG_0, 0),
7085 BPF_EXIT_INSN(),
7086 },
7087 .fixup_map1 = { 3 },
7088 .result = ACCEPT
7089 },
7090 {
7091 "bounds check after shift with oversized count operand",
7092 .insns = {
7093 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7094 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7095 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7096 BPF_LD_MAP_FD(BPF_REG_1, 0),
7097 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7098 BPF_FUNC_map_lookup_elem),
7099 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7100 BPF_MOV64_IMM(BPF_REG_2, 32),
7101 BPF_MOV64_IMM(BPF_REG_1, 1),
7102 /* r1 = (u32)1 << (u32)32 = ? */
7103 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
7104 /* r1 = [0x0000, 0xffff] */
7105 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
7106 /* computes unknown pointer, potentially OOB */
7107 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7108 /* potentially OOB access */
7109 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7110 /* exit */
7111 BPF_MOV64_IMM(BPF_REG_0, 0),
7112 BPF_EXIT_INSN(),
7113 },
7114 .fixup_map1 = { 3 },
7115 .errstr = "R0 max value is outside of the array range",
7116 .result = REJECT
7117 },
7118 {
7119 "bounds check after right shift of maybe-negative number",
7120 .insns = {
7121 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7122 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7123 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7124 BPF_LD_MAP_FD(BPF_REG_1, 0),
7125 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7126 BPF_FUNC_map_lookup_elem),
7127 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7128 /* r1 = [0x00, 0xff] */
7129 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7130 /* r1 = [-0x01, 0xfe] */
7131 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
7132 /* r1 = 0 or 0xff'ffff'ffff'ffff */
7133 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7134 /* r1 = 0 or 0xffff'ffff'ffff */
7135 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7136 /* computes unknown pointer, potentially OOB */
7137 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7138 /* potentially OOB access */
7139 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7140 /* exit */
7141 BPF_MOV64_IMM(BPF_REG_0, 0),
7142 BPF_EXIT_INSN(),
7143 },
7144 .fixup_map1 = { 3 },
7145 .errstr = "R0 unbounded memory access",
7146 .result = REJECT
7147 },
7148 {
7149 "bounds check map access with off+size signed 32bit overflow. test1",
7150 .insns = {
7151 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7152 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7153 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7154 BPF_LD_MAP_FD(BPF_REG_1, 0),
7155 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7156 BPF_FUNC_map_lookup_elem),
7157 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7158 BPF_EXIT_INSN(),
7159 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
7160 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7161 BPF_JMP_A(0),
7162 BPF_EXIT_INSN(),
7163 },
7164 .fixup_map1 = { 3 },
7165 .errstr = "map_value pointer and 2147483646",
7166 .result = REJECT
7167 },
7168 {
7169 "bounds check map access with off+size signed 32bit overflow. test2",
7170 .insns = {
7171 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7172 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7174 BPF_LD_MAP_FD(BPF_REG_1, 0),
7175 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7176 BPF_FUNC_map_lookup_elem),
7177 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7178 BPF_EXIT_INSN(),
7179 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7180 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
7182 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7183 BPF_JMP_A(0),
7184 BPF_EXIT_INSN(),
7185 },
7186 .fixup_map1 = { 3 },
7187 .errstr = "pointer offset 1073741822",
7188 .result = REJECT
7189 },
7190 {
7191 "bounds check map access with off+size signed 32bit overflow. test3",
7192 .insns = {
7193 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7194 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7196 BPF_LD_MAP_FD(BPF_REG_1, 0),
7197 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7198 BPF_FUNC_map_lookup_elem),
7199 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7200 BPF_EXIT_INSN(),
7201 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
7202 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
7203 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
7204 BPF_JMP_A(0),
7205 BPF_EXIT_INSN(),
7206 },
7207 .fixup_map1 = { 3 },
7208 .errstr = "pointer offset -1073741822",
7209 .result = REJECT
7210 },
7211 {
7212 "bounds check map access with off+size signed 32bit overflow. test4",
7213 .insns = {
7214 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7215 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7216 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7217 BPF_LD_MAP_FD(BPF_REG_1, 0),
7218 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7219 BPF_FUNC_map_lookup_elem),
7220 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
7221 BPF_EXIT_INSN(),
7222 BPF_MOV64_IMM(BPF_REG_1, 1000000),
7223 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
7224 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7225 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
7226 BPF_JMP_A(0),
7227 BPF_EXIT_INSN(),
7228 },
7229 .fixup_map1 = { 3 },
7230 .errstr = "map_value pointer and 1000000000000",
7231 .result = REJECT
7232 },
7233 {
7234 "pointer/scalar confusion in state equality check (way 1)",
7235 .insns = {
7236 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7237 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7239 BPF_LD_MAP_FD(BPF_REG_1, 0),
7240 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7241 BPF_FUNC_map_lookup_elem),
7242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
7243 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7244 BPF_JMP_A(1),
7245 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
7246 BPF_JMP_A(0),
7247 BPF_EXIT_INSN(),
7248 },
7249 .fixup_map1 = { 3 },
7250 .result = ACCEPT,
7251 .result_unpriv = REJECT,
7252 .errstr_unpriv = "R0 leaks addr as return value"
7253 },
7254 {
7255 "pointer/scalar confusion in state equality check (way 2)",
7256 .insns = {
7257 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7258 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7260 BPF_LD_MAP_FD(BPF_REG_1, 0),
7261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7262 BPF_FUNC_map_lookup_elem),
7263 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
7264 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
7265 BPF_JMP_A(1),
7266 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
7267 BPF_EXIT_INSN(),
7268 },
7269 .fixup_map1 = { 3 },
7270 .result = ACCEPT,
7271 .result_unpriv = REJECT,
7272 .errstr_unpriv = "R0 leaks addr as return value"
7273 },
7274 {
Edward Cree69c4e8a2017-08-07 15:29:51 +01007275 "variable-offset ctx access",
7276 .insns = {
7277 /* Get an unknown value */
7278 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7279 /* Make it small and 4-byte aligned */
7280 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7281 /* add it to skb. We now have either &skb->len or
7282 * &skb->pkt_type, but we don't know which
7283 */
7284 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
7285 /* dereference it */
7286 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
7287 BPF_EXIT_INSN(),
7288 },
7289 .errstr = "variable ctx access var_off=(0x0; 0x4)",
7290 .result = REJECT,
7291 .prog_type = BPF_PROG_TYPE_LWT_IN,
7292 },
7293 {
7294 "variable-offset stack access",
7295 .insns = {
7296 /* Fill the top 8 bytes of the stack */
7297 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7298 /* Get an unknown value */
7299 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7300 /* Make it small and 4-byte aligned */
7301 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7302 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
7303 /* add it to fp. We now have either fp-4 or fp-8, but
7304 * we don't know which
7305 */
7306 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
7307 /* dereference it */
7308 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
7309 BPF_EXIT_INSN(),
7310 },
7311 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
7312 .result = REJECT,
7313 .prog_type = BPF_PROG_TYPE_LWT_IN,
7314 },
Edward Creed893dc22017-08-23 15:09:46 +01007315 {
Jann Horn2255f8d2017-12-18 20:12:01 -08007316 "indirect variable-offset stack access",
7317 .insns = {
7318 /* Fill the top 8 bytes of the stack */
7319 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7320 /* Get an unknown value */
7321 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7322 /* Make it small and 4-byte aligned */
7323 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
7324 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
7325 /* add it to fp. We now have either fp-4 or fp-8, but
7326 * we don't know which
7327 */
7328 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
7329 /* dereference it indirectly */
7330 BPF_LD_MAP_FD(BPF_REG_1, 0),
7331 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7332 BPF_FUNC_map_lookup_elem),
7333 BPF_MOV64_IMM(BPF_REG_0, 0),
7334 BPF_EXIT_INSN(),
7335 },
7336 .fixup_map1 = { 5 },
7337 .errstr = "variable stack read R2",
7338 .result = REJECT,
7339 .prog_type = BPF_PROG_TYPE_LWT_IN,
7340 },
7341 {
7342 "direct stack access with 32-bit wraparound. test1",
7343 .insns = {
7344 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7346 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7347 BPF_MOV32_IMM(BPF_REG_0, 0),
7348 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7349 BPF_EXIT_INSN()
7350 },
7351 .errstr = "fp pointer and 2147483647",
7352 .result = REJECT
7353 },
7354 {
7355 "direct stack access with 32-bit wraparound. test2",
7356 .insns = {
7357 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7358 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
7359 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
7360 BPF_MOV32_IMM(BPF_REG_0, 0),
7361 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7362 BPF_EXIT_INSN()
7363 },
7364 .errstr = "fp pointer and 1073741823",
7365 .result = REJECT
7366 },
7367 {
7368 "direct stack access with 32-bit wraparound. test3",
7369 .insns = {
7370 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7371 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
7372 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
7373 BPF_MOV32_IMM(BPF_REG_0, 0),
7374 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7375 BPF_EXIT_INSN()
7376 },
7377 .errstr = "fp pointer offset 1073741822",
7378 .result = REJECT
7379 },
7380 {
Edward Creed893dc22017-08-23 15:09:46 +01007381 "liveness pruning and write screening",
7382 .insns = {
7383 /* Get an unknown value */
7384 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
7385 /* branch conditions teach us nothing about R2 */
7386 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
7387 BPF_MOV64_IMM(BPF_REG_0, 0),
7388 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
7389 BPF_MOV64_IMM(BPF_REG_0, 0),
7390 BPF_EXIT_INSN(),
7391 },
7392 .errstr = "R0 !read_ok",
7393 .result = REJECT,
7394 .prog_type = BPF_PROG_TYPE_LWT_IN,
7395 },
Alexei Starovoitovdf20cb72017-08-23 15:10:26 +01007396 {
7397 "varlen_map_value_access pruning",
7398 .insns = {
7399 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7400 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7401 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7402 BPF_LD_MAP_FD(BPF_REG_1, 0),
7403 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7404 BPF_FUNC_map_lookup_elem),
7405 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7406 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
7407 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
7408 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
7409 BPF_MOV32_IMM(BPF_REG_1, 0),
7410 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
7411 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7412 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
7413 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
7414 offsetof(struct test_val, foo)),
7415 BPF_EXIT_INSN(),
7416 },
7417 .fixup_map2 = { 3 },
7418 .errstr_unpriv = "R0 leaks addr",
7419 .errstr = "R0 unbounded memory access",
7420 .result_unpriv = REJECT,
7421 .result = REJECT,
7422 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7423 },
Edward Creee67b8a62017-09-15 14:37:38 +01007424 {
7425 "invalid 64-bit BPF_END",
7426 .insns = {
7427 BPF_MOV32_IMM(BPF_REG_0, 0),
7428 {
7429 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
7430 .dst_reg = BPF_REG_0,
7431 .src_reg = 0,
7432 .off = 0,
7433 .imm = 32,
7434 },
7435 BPF_EXIT_INSN(),
7436 },
7437 .errstr = "BPF_END uses reserved fields",
7438 .result = REJECT,
7439 },
Daniel Borkmann22c88522017-09-25 02:25:53 +02007440 {
7441 "meta access, test1",
7442 .insns = {
7443 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7444 offsetof(struct xdp_md, data_meta)),
7445 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7446 offsetof(struct xdp_md, data)),
7447 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7448 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7449 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7450 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7451 BPF_MOV64_IMM(BPF_REG_0, 0),
7452 BPF_EXIT_INSN(),
7453 },
7454 .result = ACCEPT,
7455 .prog_type = BPF_PROG_TYPE_XDP,
7456 },
7457 {
7458 "meta access, test2",
7459 .insns = {
7460 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7461 offsetof(struct xdp_md, data_meta)),
7462 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7463 offsetof(struct xdp_md, data)),
7464 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7465 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
7466 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7468 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7469 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7470 BPF_MOV64_IMM(BPF_REG_0, 0),
7471 BPF_EXIT_INSN(),
7472 },
7473 .result = REJECT,
7474 .errstr = "invalid access to packet, off=-8",
7475 .prog_type = BPF_PROG_TYPE_XDP,
7476 },
7477 {
7478 "meta access, test3",
7479 .insns = {
7480 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7481 offsetof(struct xdp_md, data_meta)),
7482 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7483 offsetof(struct xdp_md, data_end)),
7484 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7485 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7486 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7487 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7488 BPF_MOV64_IMM(BPF_REG_0, 0),
7489 BPF_EXIT_INSN(),
7490 },
7491 .result = REJECT,
7492 .errstr = "invalid access to packet",
7493 .prog_type = BPF_PROG_TYPE_XDP,
7494 },
7495 {
7496 "meta access, test4",
7497 .insns = {
7498 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7499 offsetof(struct xdp_md, data_meta)),
7500 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7501 offsetof(struct xdp_md, data_end)),
7502 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7503 offsetof(struct xdp_md, data)),
7504 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7506 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
7507 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7508 BPF_MOV64_IMM(BPF_REG_0, 0),
7509 BPF_EXIT_INSN(),
7510 },
7511 .result = REJECT,
7512 .errstr = "invalid access to packet",
7513 .prog_type = BPF_PROG_TYPE_XDP,
7514 },
7515 {
7516 "meta access, test5",
7517 .insns = {
7518 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7519 offsetof(struct xdp_md, data_meta)),
7520 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7521 offsetof(struct xdp_md, data)),
7522 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7524 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
7525 BPF_MOV64_IMM(BPF_REG_2, -8),
7526 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7527 BPF_FUNC_xdp_adjust_meta),
7528 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
7529 BPF_MOV64_IMM(BPF_REG_0, 0),
7530 BPF_EXIT_INSN(),
7531 },
7532 .result = REJECT,
7533 .errstr = "R3 !read_ok",
7534 .prog_type = BPF_PROG_TYPE_XDP,
7535 },
7536 {
7537 "meta access, test6",
7538 .insns = {
7539 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7540 offsetof(struct xdp_md, data_meta)),
7541 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7542 offsetof(struct xdp_md, data)),
7543 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7544 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7545 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7546 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7547 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
7548 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7549 BPF_MOV64_IMM(BPF_REG_0, 0),
7550 BPF_EXIT_INSN(),
7551 },
7552 .result = REJECT,
7553 .errstr = "invalid access to packet",
7554 .prog_type = BPF_PROG_TYPE_XDP,
7555 },
7556 {
7557 "meta access, test7",
7558 .insns = {
7559 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7560 offsetof(struct xdp_md, data_meta)),
7561 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7562 offsetof(struct xdp_md, data)),
7563 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
7565 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7566 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
7567 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7568 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7569 BPF_MOV64_IMM(BPF_REG_0, 0),
7570 BPF_EXIT_INSN(),
7571 },
7572 .result = ACCEPT,
7573 .prog_type = BPF_PROG_TYPE_XDP,
7574 },
7575 {
7576 "meta access, test8",
7577 .insns = {
7578 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7579 offsetof(struct xdp_md, data_meta)),
7580 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7581 offsetof(struct xdp_md, data)),
7582 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
7584 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7585 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7586 BPF_MOV64_IMM(BPF_REG_0, 0),
7587 BPF_EXIT_INSN(),
7588 },
7589 .result = ACCEPT,
7590 .prog_type = BPF_PROG_TYPE_XDP,
7591 },
7592 {
7593 "meta access, test9",
7594 .insns = {
7595 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7596 offsetof(struct xdp_md, data_meta)),
7597 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7598 offsetof(struct xdp_md, data)),
7599 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
7600 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
7601 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
7602 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
7603 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7604 BPF_MOV64_IMM(BPF_REG_0, 0),
7605 BPF_EXIT_INSN(),
7606 },
7607 .result = REJECT,
7608 .errstr = "invalid access to packet",
7609 .prog_type = BPF_PROG_TYPE_XDP,
7610 },
7611 {
7612 "meta access, test10",
7613 .insns = {
7614 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7615 offsetof(struct xdp_md, data_meta)),
7616 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7617 offsetof(struct xdp_md, data)),
7618 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7619 offsetof(struct xdp_md, data_end)),
7620 BPF_MOV64_IMM(BPF_REG_5, 42),
7621 BPF_MOV64_IMM(BPF_REG_6, 24),
7622 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
7623 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
7624 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
7625 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
7626 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
7627 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
7628 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
7629 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
7630 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
7631 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
7632 BPF_MOV64_IMM(BPF_REG_0, 0),
7633 BPF_EXIT_INSN(),
7634 },
7635 .result = REJECT,
7636 .errstr = "invalid access to packet",
7637 .prog_type = BPF_PROG_TYPE_XDP,
7638 },
7639 {
7640 "meta access, test11",
7641 .insns = {
7642 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7643 offsetof(struct xdp_md, data_meta)),
7644 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7645 offsetof(struct xdp_md, data)),
7646 BPF_MOV64_IMM(BPF_REG_5, 42),
7647 BPF_MOV64_IMM(BPF_REG_6, 24),
7648 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
7649 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
7650 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
7651 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
7652 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
7653 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
7654 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
7655 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
7656 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
7657 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
7658 BPF_MOV64_IMM(BPF_REG_0, 0),
7659 BPF_EXIT_INSN(),
7660 },
7661 .result = ACCEPT,
7662 .prog_type = BPF_PROG_TYPE_XDP,
7663 },
7664 {
7665 "meta access, test12",
7666 .insns = {
7667 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7668 offsetof(struct xdp_md, data_meta)),
7669 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7670 offsetof(struct xdp_md, data)),
7671 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
7672 offsetof(struct xdp_md, data_end)),
7673 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
7674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
7675 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
7676 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
7677 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
7678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
7679 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
7680 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
7681 BPF_MOV64_IMM(BPF_REG_0, 0),
7682 BPF_EXIT_INSN(),
7683 },
7684 .result = ACCEPT,
7685 .prog_type = BPF_PROG_TYPE_XDP,
7686 },
Alexei Starovoitov390ee7e2017-10-02 22:50:23 -07007687 {
Jakub Kicinski28e33f92017-10-16 11:16:55 -07007688 "arithmetic ops make PTR_TO_CTX unusable",
7689 .insns = {
7690 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
7691 offsetof(struct __sk_buff, data) -
7692 offsetof(struct __sk_buff, mark)),
7693 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7694 offsetof(struct __sk_buff, mark)),
7695 BPF_EXIT_INSN(),
7696 },
7697 .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
7698 .result = REJECT,
7699 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7700 },
Daniel Borkmannb37242c2017-10-21 02:34:23 +02007701 {
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08007702 "pkt_end - pkt_start is allowed",
7703 .insns = {
7704 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7705 offsetof(struct __sk_buff, data_end)),
7706 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7707 offsetof(struct __sk_buff, data)),
7708 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
7709 BPF_EXIT_INSN(),
7710 },
7711 .result = ACCEPT,
7712 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7713 },
7714 {
Daniel Borkmannb37242c2017-10-21 02:34:23 +02007715 "XDP pkt read, pkt_end mangling, bad access 1",
7716 .insns = {
7717 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7718 offsetof(struct xdp_md, data)),
7719 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7720 offsetof(struct xdp_md, data_end)),
7721 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7722 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7723 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
7724 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7725 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7726 BPF_MOV64_IMM(BPF_REG_0, 0),
7727 BPF_EXIT_INSN(),
7728 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08007729 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02007730 .result = REJECT,
7731 .prog_type = BPF_PROG_TYPE_XDP,
7732 },
7733 {
7734 "XDP pkt read, pkt_end mangling, bad access 2",
7735 .insns = {
7736 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7737 offsetof(struct xdp_md, data)),
7738 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7739 offsetof(struct xdp_md, data_end)),
7740 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7741 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7742 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
7743 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7744 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7745 BPF_MOV64_IMM(BPF_REG_0, 0),
7746 BPF_EXIT_INSN(),
7747 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08007748 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02007749 .result = REJECT,
7750 .prog_type = BPF_PROG_TYPE_XDP,
7751 },
7752 {
7753 "XDP pkt read, pkt_data' > pkt_end, good access",
7754 .insns = {
7755 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7756 offsetof(struct xdp_md, data)),
7757 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7758 offsetof(struct xdp_md, data_end)),
7759 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7760 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7761 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7762 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7763 BPF_MOV64_IMM(BPF_REG_0, 0),
7764 BPF_EXIT_INSN(),
7765 },
7766 .result = ACCEPT,
7767 .prog_type = BPF_PROG_TYPE_XDP,
7768 },
7769 {
7770 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
7771 .insns = {
7772 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7773 offsetof(struct xdp_md, data)),
7774 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7775 offsetof(struct xdp_md, data_end)),
7776 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7777 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7778 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
7779 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7780 BPF_MOV64_IMM(BPF_REG_0, 0),
7781 BPF_EXIT_INSN(),
7782 },
7783 .errstr = "R1 offset is outside of the packet",
7784 .result = REJECT,
7785 .prog_type = BPF_PROG_TYPE_XDP,
7786 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7787 },
7788 {
7789 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
7790 .insns = {
7791 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7792 offsetof(struct xdp_md, data)),
7793 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7794 offsetof(struct xdp_md, data_end)),
7795 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7796 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7797 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
7798 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7799 BPF_MOV64_IMM(BPF_REG_0, 0),
7800 BPF_EXIT_INSN(),
7801 },
7802 .errstr = "R1 offset is outside of the packet",
7803 .result = REJECT,
7804 .prog_type = BPF_PROG_TYPE_XDP,
7805 },
7806 {
7807 "XDP pkt read, pkt_end > pkt_data', good access",
7808 .insns = {
7809 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7810 offsetof(struct xdp_md, data)),
7811 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7812 offsetof(struct xdp_md, data_end)),
7813 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7814 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7815 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7816 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7817 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7818 BPF_MOV64_IMM(BPF_REG_0, 0),
7819 BPF_EXIT_INSN(),
7820 },
7821 .result = ACCEPT,
7822 .prog_type = BPF_PROG_TYPE_XDP,
7823 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7824 },
7825 {
7826 "XDP pkt read, pkt_end > pkt_data', bad access 1",
7827 .insns = {
7828 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7829 offsetof(struct xdp_md, data)),
7830 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7831 offsetof(struct xdp_md, data_end)),
7832 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7833 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7834 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7835 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7836 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7837 BPF_MOV64_IMM(BPF_REG_0, 0),
7838 BPF_EXIT_INSN(),
7839 },
7840 .errstr = "R1 offset is outside of the packet",
7841 .result = REJECT,
7842 .prog_type = BPF_PROG_TYPE_XDP,
7843 },
7844 {
7845 "XDP pkt read, pkt_end > pkt_data', bad access 2",
7846 .insns = {
7847 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7848 offsetof(struct xdp_md, data)),
7849 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7850 offsetof(struct xdp_md, data_end)),
7851 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7853 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
7854 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7855 BPF_MOV64_IMM(BPF_REG_0, 0),
7856 BPF_EXIT_INSN(),
7857 },
7858 .errstr = "R1 offset is outside of the packet",
7859 .result = REJECT,
7860 .prog_type = BPF_PROG_TYPE_XDP,
7861 },
7862 {
7863 "XDP pkt read, pkt_data' < pkt_end, good access",
7864 .insns = {
7865 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7866 offsetof(struct xdp_md, data)),
7867 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7868 offsetof(struct xdp_md, data_end)),
7869 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7871 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7872 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7873 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7874 BPF_MOV64_IMM(BPF_REG_0, 0),
7875 BPF_EXIT_INSN(),
7876 },
7877 .result = ACCEPT,
7878 .prog_type = BPF_PROG_TYPE_XDP,
7879 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7880 },
7881 {
7882 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
7883 .insns = {
7884 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7885 offsetof(struct xdp_md, data)),
7886 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7887 offsetof(struct xdp_md, data_end)),
7888 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7889 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7890 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7891 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7892 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7893 BPF_MOV64_IMM(BPF_REG_0, 0),
7894 BPF_EXIT_INSN(),
7895 },
7896 .errstr = "R1 offset is outside of the packet",
7897 .result = REJECT,
7898 .prog_type = BPF_PROG_TYPE_XDP,
7899 },
7900 {
7901 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
7902 .insns = {
7903 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7904 offsetof(struct xdp_md, data)),
7905 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7906 offsetof(struct xdp_md, data_end)),
7907 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7908 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7909 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
7910 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7911 BPF_MOV64_IMM(BPF_REG_0, 0),
7912 BPF_EXIT_INSN(),
7913 },
7914 .errstr = "R1 offset is outside of the packet",
7915 .result = REJECT,
7916 .prog_type = BPF_PROG_TYPE_XDP,
7917 },
7918 {
7919 "XDP pkt read, pkt_end < pkt_data', good access",
7920 .insns = {
7921 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7922 offsetof(struct xdp_md, data)),
7923 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7924 offsetof(struct xdp_md, data_end)),
7925 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7926 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7927 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
7928 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7929 BPF_MOV64_IMM(BPF_REG_0, 0),
7930 BPF_EXIT_INSN(),
7931 },
7932 .result = ACCEPT,
7933 .prog_type = BPF_PROG_TYPE_XDP,
7934 },
7935 {
7936 "XDP pkt read, pkt_end < pkt_data', bad access 1",
7937 .insns = {
7938 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7939 offsetof(struct xdp_md, data)),
7940 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7941 offsetof(struct xdp_md, data_end)),
7942 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7943 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7944 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
7945 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7946 BPF_MOV64_IMM(BPF_REG_0, 0),
7947 BPF_EXIT_INSN(),
7948 },
7949 .errstr = "R1 offset is outside of the packet",
7950 .result = REJECT,
7951 .prog_type = BPF_PROG_TYPE_XDP,
7952 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7953 },
7954 {
7955 "XDP pkt read, pkt_end < pkt_data', bad access 2",
7956 .insns = {
7957 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7958 offsetof(struct xdp_md, data)),
7959 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7960 offsetof(struct xdp_md, data_end)),
7961 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7962 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7963 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
7964 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7965 BPF_MOV64_IMM(BPF_REG_0, 0),
7966 BPF_EXIT_INSN(),
7967 },
7968 .errstr = "R1 offset is outside of the packet",
7969 .result = REJECT,
7970 .prog_type = BPF_PROG_TYPE_XDP,
7971 },
7972 {
7973 "XDP pkt read, pkt_data' >= pkt_end, good access",
7974 .insns = {
7975 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7976 offsetof(struct xdp_md, data)),
7977 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7978 offsetof(struct xdp_md, data_end)),
7979 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7981 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
7982 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7983 BPF_MOV64_IMM(BPF_REG_0, 0),
7984 BPF_EXIT_INSN(),
7985 },
7986 .result = ACCEPT,
7987 .prog_type = BPF_PROG_TYPE_XDP,
7988 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7989 },
7990 {
7991 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
7992 .insns = {
7993 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7994 offsetof(struct xdp_md, data)),
7995 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7996 offsetof(struct xdp_md, data_end)),
7997 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7999 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8000 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8001 BPF_MOV64_IMM(BPF_REG_0, 0),
8002 BPF_EXIT_INSN(),
8003 },
8004 .errstr = "R1 offset is outside of the packet",
8005 .result = REJECT,
8006 .prog_type = BPF_PROG_TYPE_XDP,
8007 },
8008 {
8009 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
8010 .insns = {
8011 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8012 offsetof(struct xdp_md, data)),
8013 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8014 offsetof(struct xdp_md, data_end)),
8015 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8016 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8017 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8018 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8019 BPF_MOV64_IMM(BPF_REG_0, 0),
8020 BPF_EXIT_INSN(),
8021 },
8022 .errstr = "R1 offset is outside of the packet",
8023 .result = REJECT,
8024 .prog_type = BPF_PROG_TYPE_XDP,
8025 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8026 },
8027 {
8028 "XDP pkt read, pkt_end >= pkt_data', good access",
8029 .insns = {
8030 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8031 offsetof(struct xdp_md, data)),
8032 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8033 offsetof(struct xdp_md, data_end)),
8034 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8035 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8036 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8037 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8038 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8039 BPF_MOV64_IMM(BPF_REG_0, 0),
8040 BPF_EXIT_INSN(),
8041 },
8042 .result = ACCEPT,
8043 .prog_type = BPF_PROG_TYPE_XDP,
8044 },
8045 {
8046 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
8047 .insns = {
8048 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8049 offsetof(struct xdp_md, data)),
8050 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8051 offsetof(struct xdp_md, data_end)),
8052 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8054 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8055 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8056 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8057 BPF_MOV64_IMM(BPF_REG_0, 0),
8058 BPF_EXIT_INSN(),
8059 },
8060 .errstr = "R1 offset is outside of the packet",
8061 .result = REJECT,
8062 .prog_type = BPF_PROG_TYPE_XDP,
8063 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8064 },
8065 {
8066 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
8067 .insns = {
8068 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8069 offsetof(struct xdp_md, data)),
8070 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8071 offsetof(struct xdp_md, data_end)),
8072 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8073 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8074 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8075 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8076 BPF_MOV64_IMM(BPF_REG_0, 0),
8077 BPF_EXIT_INSN(),
8078 },
8079 .errstr = "R1 offset is outside of the packet",
8080 .result = REJECT,
8081 .prog_type = BPF_PROG_TYPE_XDP,
8082 },
8083 {
8084 "XDP pkt read, pkt_data' <= pkt_end, good access",
8085 .insns = {
8086 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8087 offsetof(struct xdp_md, data)),
8088 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8089 offsetof(struct xdp_md, data_end)),
8090 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8091 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8092 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8093 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8094 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8095 BPF_MOV64_IMM(BPF_REG_0, 0),
8096 BPF_EXIT_INSN(),
8097 },
8098 .result = ACCEPT,
8099 .prog_type = BPF_PROG_TYPE_XDP,
8100 },
8101 {
8102 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
8103 .insns = {
8104 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8105 offsetof(struct xdp_md, data)),
8106 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8107 offsetof(struct xdp_md, data_end)),
8108 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8109 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8110 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8111 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8112 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8113 BPF_MOV64_IMM(BPF_REG_0, 0),
8114 BPF_EXIT_INSN(),
8115 },
8116 .errstr = "R1 offset is outside of the packet",
8117 .result = REJECT,
8118 .prog_type = BPF_PROG_TYPE_XDP,
8119 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8120 },
8121 {
8122 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
8123 .insns = {
8124 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8125 offsetof(struct xdp_md, data)),
8126 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8127 offsetof(struct xdp_md, data_end)),
8128 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8130 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8131 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8132 BPF_MOV64_IMM(BPF_REG_0, 0),
8133 BPF_EXIT_INSN(),
8134 },
8135 .errstr = "R1 offset is outside of the packet",
8136 .result = REJECT,
8137 .prog_type = BPF_PROG_TYPE_XDP,
8138 },
8139 {
8140 "XDP pkt read, pkt_end <= pkt_data', good access",
8141 .insns = {
8142 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8143 offsetof(struct xdp_md, data)),
8144 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8145 offsetof(struct xdp_md, data_end)),
8146 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8147 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8148 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8149 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8150 BPF_MOV64_IMM(BPF_REG_0, 0),
8151 BPF_EXIT_INSN(),
8152 },
8153 .result = ACCEPT,
8154 .prog_type = BPF_PROG_TYPE_XDP,
8155 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8156 },
8157 {
8158 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
8159 .insns = {
8160 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8161 offsetof(struct xdp_md, data)),
8162 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8163 offsetof(struct xdp_md, data_end)),
8164 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8165 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8166 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8167 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8168 BPF_MOV64_IMM(BPF_REG_0, 0),
8169 BPF_EXIT_INSN(),
8170 },
8171 .errstr = "R1 offset is outside of the packet",
8172 .result = REJECT,
8173 .prog_type = BPF_PROG_TYPE_XDP,
8174 },
8175 {
8176 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
8177 .insns = {
8178 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8179 offsetof(struct xdp_md, data)),
8180 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8181 offsetof(struct xdp_md, data_end)),
8182 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8184 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
8185 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8186 BPF_MOV64_IMM(BPF_REG_0, 0),
8187 BPF_EXIT_INSN(),
8188 },
8189 .errstr = "R1 offset is outside of the packet",
8190 .result = REJECT,
8191 .prog_type = BPF_PROG_TYPE_XDP,
8192 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8193 },
Daniel Borkmannb06723d2017-11-01 23:58:09 +01008194 {
Daniel Borkmann634eab12017-11-01 23:58:11 +01008195 "XDP pkt read, pkt_meta' > pkt_data, good access",
8196 .insns = {
8197 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8198 offsetof(struct xdp_md, data_meta)),
8199 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8200 offsetof(struct xdp_md, data)),
8201 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8203 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8204 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8205 BPF_MOV64_IMM(BPF_REG_0, 0),
8206 BPF_EXIT_INSN(),
8207 },
8208 .result = ACCEPT,
8209 .prog_type = BPF_PROG_TYPE_XDP,
8210 },
8211 {
8212 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
8213 .insns = {
8214 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8215 offsetof(struct xdp_md, data_meta)),
8216 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8217 offsetof(struct xdp_md, data)),
8218 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8219 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8220 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8221 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8222 BPF_MOV64_IMM(BPF_REG_0, 0),
8223 BPF_EXIT_INSN(),
8224 },
8225 .errstr = "R1 offset is outside of the packet",
8226 .result = REJECT,
8227 .prog_type = BPF_PROG_TYPE_XDP,
8228 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8229 },
8230 {
8231 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
8232 .insns = {
8233 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8234 offsetof(struct xdp_md, data_meta)),
8235 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8236 offsetof(struct xdp_md, data)),
8237 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8239 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8240 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8241 BPF_MOV64_IMM(BPF_REG_0, 0),
8242 BPF_EXIT_INSN(),
8243 },
8244 .errstr = "R1 offset is outside of the packet",
8245 .result = REJECT,
8246 .prog_type = BPF_PROG_TYPE_XDP,
8247 },
8248 {
8249 "XDP pkt read, pkt_data > pkt_meta', good access",
8250 .insns = {
8251 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8252 offsetof(struct xdp_md, data_meta)),
8253 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8254 offsetof(struct xdp_md, data)),
8255 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8256 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8257 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8258 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8259 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8260 BPF_MOV64_IMM(BPF_REG_0, 0),
8261 BPF_EXIT_INSN(),
8262 },
8263 .result = ACCEPT,
8264 .prog_type = BPF_PROG_TYPE_XDP,
8265 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8266 },
8267 {
8268 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
8269 .insns = {
8270 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8271 offsetof(struct xdp_md, data_meta)),
8272 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8273 offsetof(struct xdp_md, data)),
8274 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8275 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8276 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8277 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8278 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8279 BPF_MOV64_IMM(BPF_REG_0, 0),
8280 BPF_EXIT_INSN(),
8281 },
8282 .errstr = "R1 offset is outside of the packet",
8283 .result = REJECT,
8284 .prog_type = BPF_PROG_TYPE_XDP,
8285 },
8286 {
8287 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
8288 .insns = {
8289 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8290 offsetof(struct xdp_md, data_meta)),
8291 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8292 offsetof(struct xdp_md, data)),
8293 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8294 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8295 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8296 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8297 BPF_MOV64_IMM(BPF_REG_0, 0),
8298 BPF_EXIT_INSN(),
8299 },
8300 .errstr = "R1 offset is outside of the packet",
8301 .result = REJECT,
8302 .prog_type = BPF_PROG_TYPE_XDP,
8303 },
8304 {
8305 "XDP pkt read, pkt_meta' < pkt_data, good access",
8306 .insns = {
8307 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8308 offsetof(struct xdp_md, data_meta)),
8309 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8310 offsetof(struct xdp_md, data)),
8311 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8312 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8313 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8314 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8315 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8316 BPF_MOV64_IMM(BPF_REG_0, 0),
8317 BPF_EXIT_INSN(),
8318 },
8319 .result = ACCEPT,
8320 .prog_type = BPF_PROG_TYPE_XDP,
8321 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8322 },
8323 {
8324 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
8325 .insns = {
8326 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8327 offsetof(struct xdp_md, data_meta)),
8328 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8329 offsetof(struct xdp_md, data)),
8330 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8332 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8333 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8334 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8335 BPF_MOV64_IMM(BPF_REG_0, 0),
8336 BPF_EXIT_INSN(),
8337 },
8338 .errstr = "R1 offset is outside of the packet",
8339 .result = REJECT,
8340 .prog_type = BPF_PROG_TYPE_XDP,
8341 },
8342 {
8343 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
8344 .insns = {
8345 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8346 offsetof(struct xdp_md, data_meta)),
8347 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8348 offsetof(struct xdp_md, data)),
8349 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8350 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8351 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8352 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8353 BPF_MOV64_IMM(BPF_REG_0, 0),
8354 BPF_EXIT_INSN(),
8355 },
8356 .errstr = "R1 offset is outside of the packet",
8357 .result = REJECT,
8358 .prog_type = BPF_PROG_TYPE_XDP,
8359 },
8360 {
8361 "XDP pkt read, pkt_data < pkt_meta', good access",
8362 .insns = {
8363 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8364 offsetof(struct xdp_md, data_meta)),
8365 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8366 offsetof(struct xdp_md, data)),
8367 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8368 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8369 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8370 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8371 BPF_MOV64_IMM(BPF_REG_0, 0),
8372 BPF_EXIT_INSN(),
8373 },
8374 .result = ACCEPT,
8375 .prog_type = BPF_PROG_TYPE_XDP,
8376 },
8377 {
8378 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
8379 .insns = {
8380 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8381 offsetof(struct xdp_md, data_meta)),
8382 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8383 offsetof(struct xdp_md, data)),
8384 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8385 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8386 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8387 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8388 BPF_MOV64_IMM(BPF_REG_0, 0),
8389 BPF_EXIT_INSN(),
8390 },
8391 .errstr = "R1 offset is outside of the packet",
8392 .result = REJECT,
8393 .prog_type = BPF_PROG_TYPE_XDP,
8394 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8395 },
8396 {
8397 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
8398 .insns = {
8399 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8400 offsetof(struct xdp_md, data_meta)),
8401 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8402 offsetof(struct xdp_md, data)),
8403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8405 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
8406 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8407 BPF_MOV64_IMM(BPF_REG_0, 0),
8408 BPF_EXIT_INSN(),
8409 },
8410 .errstr = "R1 offset is outside of the packet",
8411 .result = REJECT,
8412 .prog_type = BPF_PROG_TYPE_XDP,
8413 },
8414 {
8415 "XDP pkt read, pkt_meta' >= pkt_data, good access",
8416 .insns = {
8417 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8418 offsetof(struct xdp_md, data_meta)),
8419 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8420 offsetof(struct xdp_md, data)),
8421 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8423 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8424 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8425 BPF_MOV64_IMM(BPF_REG_0, 0),
8426 BPF_EXIT_INSN(),
8427 },
8428 .result = ACCEPT,
8429 .prog_type = BPF_PROG_TYPE_XDP,
8430 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8431 },
8432 {
8433 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
8434 .insns = {
8435 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8436 offsetof(struct xdp_md, data_meta)),
8437 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8438 offsetof(struct xdp_md, data)),
8439 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8440 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8441 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8442 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8443 BPF_MOV64_IMM(BPF_REG_0, 0),
8444 BPF_EXIT_INSN(),
8445 },
8446 .errstr = "R1 offset is outside of the packet",
8447 .result = REJECT,
8448 .prog_type = BPF_PROG_TYPE_XDP,
8449 },
8450 {
8451 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
8452 .insns = {
8453 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8454 offsetof(struct xdp_md, data_meta)),
8455 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8456 offsetof(struct xdp_md, data)),
8457 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8458 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8459 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8460 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8461 BPF_MOV64_IMM(BPF_REG_0, 0),
8462 BPF_EXIT_INSN(),
8463 },
8464 .errstr = "R1 offset is outside of the packet",
8465 .result = REJECT,
8466 .prog_type = BPF_PROG_TYPE_XDP,
8467 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8468 },
8469 {
8470 "XDP pkt read, pkt_data >= pkt_meta', good access",
8471 .insns = {
8472 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8473 offsetof(struct xdp_md, data_meta)),
8474 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8475 offsetof(struct xdp_md, data)),
8476 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8478 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8479 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8480 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8481 BPF_MOV64_IMM(BPF_REG_0, 0),
8482 BPF_EXIT_INSN(),
8483 },
8484 .result = ACCEPT,
8485 .prog_type = BPF_PROG_TYPE_XDP,
8486 },
8487 {
8488 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
8489 .insns = {
8490 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8491 offsetof(struct xdp_md, data_meta)),
8492 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8493 offsetof(struct xdp_md, data)),
8494 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8495 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8496 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8497 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8498 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8499 BPF_MOV64_IMM(BPF_REG_0, 0),
8500 BPF_EXIT_INSN(),
8501 },
8502 .errstr = "R1 offset is outside of the packet",
8503 .result = REJECT,
8504 .prog_type = BPF_PROG_TYPE_XDP,
8505 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8506 },
8507 {
8508 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
8509 .insns = {
8510 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8511 offsetof(struct xdp_md, data_meta)),
8512 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8513 offsetof(struct xdp_md, data)),
8514 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8516 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8517 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8518 BPF_MOV64_IMM(BPF_REG_0, 0),
8519 BPF_EXIT_INSN(),
8520 },
8521 .errstr = "R1 offset is outside of the packet",
8522 .result = REJECT,
8523 .prog_type = BPF_PROG_TYPE_XDP,
8524 },
8525 {
8526 "XDP pkt read, pkt_meta' <= pkt_data, good access",
8527 .insns = {
8528 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8529 offsetof(struct xdp_md, data_meta)),
8530 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8531 offsetof(struct xdp_md, data)),
8532 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8534 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8535 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8536 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8537 BPF_MOV64_IMM(BPF_REG_0, 0),
8538 BPF_EXIT_INSN(),
8539 },
8540 .result = ACCEPT,
8541 .prog_type = BPF_PROG_TYPE_XDP,
8542 },
8543 {
8544 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
8545 .insns = {
8546 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8547 offsetof(struct xdp_md, data_meta)),
8548 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8549 offsetof(struct xdp_md, data)),
8550 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8552 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8553 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8554 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8555 BPF_MOV64_IMM(BPF_REG_0, 0),
8556 BPF_EXIT_INSN(),
8557 },
8558 .errstr = "R1 offset is outside of the packet",
8559 .result = REJECT,
8560 .prog_type = BPF_PROG_TYPE_XDP,
8561 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8562 },
8563 {
8564 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
8565 .insns = {
8566 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8567 offsetof(struct xdp_md, data_meta)),
8568 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8569 offsetof(struct xdp_md, data)),
8570 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8571 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8572 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8573 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8574 BPF_MOV64_IMM(BPF_REG_0, 0),
8575 BPF_EXIT_INSN(),
8576 },
8577 .errstr = "R1 offset is outside of the packet",
8578 .result = REJECT,
8579 .prog_type = BPF_PROG_TYPE_XDP,
8580 },
8581 {
8582 "XDP pkt read, pkt_data <= pkt_meta', good access",
8583 .insns = {
8584 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8585 offsetof(struct xdp_md, data_meta)),
8586 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8587 offsetof(struct xdp_md, data)),
8588 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8590 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8591 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8592 BPF_MOV64_IMM(BPF_REG_0, 0),
8593 BPF_EXIT_INSN(),
8594 },
8595 .result = ACCEPT,
8596 .prog_type = BPF_PROG_TYPE_XDP,
8597 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8598 },
8599 {
8600 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
8601 .insns = {
8602 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8603 offsetof(struct xdp_md, data_meta)),
8604 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8605 offsetof(struct xdp_md, data)),
8606 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8608 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8609 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8610 BPF_MOV64_IMM(BPF_REG_0, 0),
8611 BPF_EXIT_INSN(),
8612 },
8613 .errstr = "R1 offset is outside of the packet",
8614 .result = REJECT,
8615 .prog_type = BPF_PROG_TYPE_XDP,
8616 },
8617 {
8618 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
8619 .insns = {
8620 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8621 offsetof(struct xdp_md, data_meta)),
8622 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8623 offsetof(struct xdp_md, data)),
8624 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8625 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8626 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
8627 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8628 BPF_MOV64_IMM(BPF_REG_0, 0),
8629 BPF_EXIT_INSN(),
8630 },
8631 .errstr = "R1 offset is outside of the packet",
8632 .result = REJECT,
8633 .prog_type = BPF_PROG_TYPE_XDP,
8634 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8635 },
8636 {
Daniel Borkmannb06723d2017-11-01 23:58:09 +01008637 "bpf_exit with invalid return code. test1",
8638 .insns = {
8639 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8640 BPF_EXIT_INSN(),
8641 },
8642 .errstr = "R0 has value (0x0; 0xffffffff)",
8643 .result = REJECT,
8644 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8645 },
8646 {
8647 "bpf_exit with invalid return code. test2",
8648 .insns = {
8649 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8650 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
8651 BPF_EXIT_INSN(),
8652 },
8653 .result = ACCEPT,
8654 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8655 },
8656 {
8657 "bpf_exit with invalid return code. test3",
8658 .insns = {
8659 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8660 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
8661 BPF_EXIT_INSN(),
8662 },
8663 .errstr = "R0 has value (0x0; 0x3)",
8664 .result = REJECT,
8665 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8666 },
8667 {
8668 "bpf_exit with invalid return code. test4",
8669 .insns = {
8670 BPF_MOV64_IMM(BPF_REG_0, 1),
8671 BPF_EXIT_INSN(),
8672 },
8673 .result = ACCEPT,
8674 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8675 },
8676 {
8677 "bpf_exit with invalid return code. test5",
8678 .insns = {
8679 BPF_MOV64_IMM(BPF_REG_0, 2),
8680 BPF_EXIT_INSN(),
8681 },
8682 .errstr = "R0 has value (0x2; 0x0)",
8683 .result = REJECT,
8684 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8685 },
8686 {
8687 "bpf_exit with invalid return code. test6",
8688 .insns = {
8689 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8690 BPF_EXIT_INSN(),
8691 },
8692 .errstr = "R0 is not a known value (ctx)",
8693 .result = REJECT,
8694 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8695 },
8696 {
8697 "bpf_exit with invalid return code. test7",
8698 .insns = {
8699 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8700 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
8701 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
8702 BPF_EXIT_INSN(),
8703 },
8704 .errstr = "R0 has unknown scalar value",
8705 .result = REJECT,
8706 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8707 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008708};
8709
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008710static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008711{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008712 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008713
8714 for (len = MAX_INSNS - 1; len > 0; --len)
8715 if (fp[len].code != 0 || fp[len].imm != 0)
8716 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008717 return len + 1;
8718}
8719
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008720static int create_map(uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008721{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008722 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008723
Mickaël Salaünf4874d02017-02-10 00:21:43 +01008724 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008725 size_value, max_elem, BPF_F_NO_PREALLOC);
8726 if (fd < 0)
8727 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -07008728
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008729 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07008730}
8731
8732static int create_prog_array(void)
8733{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008734 int fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07008735
Mickaël Salaünf4874d02017-02-10 00:21:43 +01008736 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008737 sizeof(int), 4, 0);
8738 if (fd < 0)
8739 printf("Failed to create prog array '%s'!\n", strerror(errno));
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008740
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008741 return fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008742}
8743
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008744static int create_map_in_map(void)
8745{
8746 int inner_map_fd, outer_map_fd;
8747
8748 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
8749 sizeof(int), 1, 0);
8750 if (inner_map_fd < 0) {
8751 printf("Failed to create array '%s'!\n", strerror(errno));
8752 return inner_map_fd;
8753 }
8754
Martin KaFai Lau88cda1c2017-09-27 14:37:54 -07008755 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008756 sizeof(int), inner_map_fd, 1, 0);
8757 if (outer_map_fd < 0)
8758 printf("Failed to create array of maps '%s'!\n",
8759 strerror(errno));
8760
8761 close(inner_map_fd);
8762
8763 return outer_map_fd;
8764}
8765
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008766static char bpf_vlog[32768];
8767
8768static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008769 int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008770{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008771 int *fixup_map1 = test->fixup_map1;
8772 int *fixup_map2 = test->fixup_map2;
8773 int *fixup_prog = test->fixup_prog;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008774 int *fixup_map_in_map = test->fixup_map_in_map;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008775
8776 /* Allocating HTs with 1 elem is fine here, since we only test
8777 * for verifier and not do a runtime lookup, so the only thing
8778 * that really matters is value size in this case.
8779 */
8780 if (*fixup_map1) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008781 map_fds[0] = create_map(sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008782 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008783 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008784 fixup_map1++;
8785 } while (*fixup_map1);
8786 }
8787
8788 if (*fixup_map2) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008789 map_fds[1] = create_map(sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008790 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008791 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008792 fixup_map2++;
8793 } while (*fixup_map2);
8794 }
8795
8796 if (*fixup_prog) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008797 map_fds[2] = create_prog_array();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008798 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008799 prog[*fixup_prog].imm = map_fds[2];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008800 fixup_prog++;
8801 } while (*fixup_prog);
8802 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008803
8804 if (*fixup_map_in_map) {
8805 map_fds[3] = create_map_in_map();
8806 do {
8807 prog[*fixup_map_in_map].imm = map_fds[3];
8808 fixup_map_in_map++;
8809 } while (*fixup_map_in_map);
8810 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008811}
8812
8813static void do_test_single(struct bpf_test *test, bool unpriv,
8814 int *passes, int *errors)
8815{
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02008816 int fd_prog, expected_ret, reject_from_alignment;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008817 struct bpf_insn *prog = test->insns;
8818 int prog_len = probe_filter_length(prog);
8819 int prog_type = test->prog_type;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008820 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008821 const char *expected_err;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008822 int i;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008823
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008824 for (i = 0; i < MAX_NR_MAPS; i++)
8825 map_fds[i] = -1;
8826
8827 do_test_fixup(test, prog, map_fds);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008828
Daniel Borkmann614d0d72017-05-25 01:05:09 +02008829 fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
8830 prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmannd6554902017-07-21 00:00:22 +02008831 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008832
8833 expected_ret = unpriv && test->result_unpriv != UNDEF ?
8834 test->result_unpriv : test->result;
8835 expected_err = unpriv && test->errstr_unpriv ?
8836 test->errstr_unpriv : test->errstr;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02008837
8838 reject_from_alignment = fd_prog < 0 &&
8839 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
8840 strstr(bpf_vlog, "Unknown alignment.");
8841#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
8842 if (reject_from_alignment) {
8843 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
8844 strerror(errno));
8845 goto fail_log;
8846 }
8847#endif
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008848 if (expected_ret == ACCEPT) {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02008849 if (fd_prog < 0 && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008850 printf("FAIL\nFailed to load prog '%s'!\n",
8851 strerror(errno));
8852 goto fail_log;
8853 }
8854 } else {
8855 if (fd_prog >= 0) {
8856 printf("FAIL\nUnexpected success to load!\n");
8857 goto fail_log;
8858 }
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02008859 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008860 printf("FAIL\nUnexpected error message!\n");
8861 goto fail_log;
8862 }
8863 }
8864
8865 (*passes)++;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02008866 printf("OK%s\n", reject_from_alignment ?
8867 " (NOTE: reject due to unknown alignment)" : "");
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008868close_fds:
8869 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07008870 for (i = 0; i < MAX_NR_MAPS; i++)
8871 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008872 sched_yield();
8873 return;
8874fail_log:
8875 (*errors)++;
8876 printf("%s", bpf_vlog);
8877 goto close_fds;
8878}
8879
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008880static bool is_admin(void)
8881{
8882 cap_t caps;
8883 cap_flag_value_t sysadmin = CAP_CLEAR;
8884 const cap_value_t cap_val = CAP_SYS_ADMIN;
8885
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08008886#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008887 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
8888 perror("cap_get_flag");
8889 return false;
8890 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08008891#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008892 caps = cap_get_proc();
8893 if (!caps) {
8894 perror("cap_get_proc");
8895 return false;
8896 }
8897 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
8898 perror("cap_get_flag");
8899 if (cap_free(caps))
8900 perror("cap_free");
8901 return (sysadmin == CAP_SET);
8902}
8903
8904static int set_admin(bool admin)
8905{
8906 cap_t caps;
8907 const cap_value_t cap_val = CAP_SYS_ADMIN;
8908 int ret = -1;
8909
8910 caps = cap_get_proc();
8911 if (!caps) {
8912 perror("cap_get_proc");
8913 return -1;
8914 }
8915 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
8916 admin ? CAP_SET : CAP_CLEAR)) {
8917 perror("cap_set_flag");
8918 goto out;
8919 }
8920 if (cap_set_proc(caps)) {
8921 perror("cap_set_proc");
8922 goto out;
8923 }
8924 ret = 0;
8925out:
8926 if (cap_free(caps))
8927 perror("cap_free");
8928 return ret;
8929}
8930
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008931static int do_test(bool unpriv, unsigned int from, unsigned int to)
8932{
8933 int i, passes = 0, errors = 0;
8934
8935 for (i = from; i < to; i++) {
8936 struct bpf_test *test = &tests[i];
8937
8938 /* Program types that are not supported by non-root we
8939 * skip right away.
8940 */
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008941 if (!test->prog_type) {
8942 if (!unpriv)
8943 set_admin(false);
8944 printf("#%d/u %s ", i, test->descr);
8945 do_test_single(test, true, &passes, &errors);
8946 if (!unpriv)
8947 set_admin(true);
8948 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008949
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008950 if (!unpriv) {
8951 printf("#%d/p %s ", i, test->descr);
8952 do_test_single(test, false, &passes, &errors);
8953 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008954 }
8955
8956 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
Jesper Dangaard Brouerefe5f9c2017-06-13 15:17:19 +02008957 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008958}
8959
8960int main(int argc, char **argv)
8961{
8962 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
8963 struct rlimit rlim = { 1 << 20, 1 << 20 };
8964 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +01008965 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008966
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008967 if (argc == 3) {
8968 unsigned int l = atoi(argv[argc - 2]);
8969 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008970
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008971 if (l < to && u < to) {
8972 from = l;
8973 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008974 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008975 } else if (argc == 2) {
8976 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -07008977
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008978 if (t < to) {
8979 from = t;
8980 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07008981 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008982 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008983
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02008984 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
8985 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07008986}