blob: 876b8785fd83cda11a57cf92c5ad429092e8849b [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
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080011#include <asm/types.h>
12#include <linux/types.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010013#include <stdint.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070014#include <stdio.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010015#include <stdlib.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070016#include <unistd.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070017#include <errno.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070018#include <string.h>
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -070019#include <stddef.h>
Alexei Starovoitovbf508872015-10-07 22:23:23 -070020#include <stdbool.h>
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020021#include <sched.h>
22
Mickaël Salaünd02d8982017-02-10 00:21:37 +010023#include <sys/capability.h>
Alexei Starovoitovbf508872015-10-07 22:23:23 -070024#include <sys/resource.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070025
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020026#include <linux/unistd.h>
27#include <linux/filter.h>
28#include <linux/bpf_perf_event.h>
29#include <linux/bpf.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070030
Mickaël Salaün2ee89fb2017-02-10 00:21:38 +010031#include <bpf/bpf.h>
32
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020033#ifdef HAVE_GENHDR
34# include "autoconf.h"
35#else
36# if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
37# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
38# endif
39#endif
40
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020041#include "../../../include/linux/filter.h"
42
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020043#ifndef ARRAY_SIZE
44# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
45#endif
46
47#define MAX_INSNS 512
48#define MAX_FIXUPS 8
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070049#define MAX_NR_MAPS 4
Alexei Starovoitovbf508872015-10-07 22:23:23 -070050
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020051#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
Daniel Borkmann614d0d72017-05-25 01:05:09 +020052#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020053
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070054struct bpf_test {
55 const char *descr;
56 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020057 int fixup_map1[MAX_FIXUPS];
58 int fixup_map2[MAX_FIXUPS];
59 int fixup_prog[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070060 int fixup_map_in_map[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070061 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070062 const char *errstr_unpriv;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070063 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070064 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070065 ACCEPT,
66 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070067 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070068 enum bpf_prog_type prog_type;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020069 uint8_t flags;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070070};
71
Josef Bacik48461132016-09-28 10:54:32 -040072/* Note we want this to be 64 bit aligned so that the end of our array is
73 * actually the end of the structure.
74 */
75#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040076
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020077struct test_val {
78 unsigned int index;
79 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040080};
81
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070082static struct bpf_test tests[] = {
83 {
84 "add+sub+mul",
85 .insns = {
86 BPF_MOV64_IMM(BPF_REG_1, 1),
87 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
88 BPF_MOV64_IMM(BPF_REG_2, 3),
89 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
90 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
91 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
92 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
93 BPF_EXIT_INSN(),
94 },
95 .result = ACCEPT,
96 },
97 {
98 "unreachable",
99 .insns = {
100 BPF_EXIT_INSN(),
101 BPF_EXIT_INSN(),
102 },
103 .errstr = "unreachable",
104 .result = REJECT,
105 },
106 {
107 "unreachable2",
108 .insns = {
109 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
110 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
111 BPF_EXIT_INSN(),
112 },
113 .errstr = "unreachable",
114 .result = REJECT,
115 },
116 {
117 "out of range jump",
118 .insns = {
119 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
120 BPF_EXIT_INSN(),
121 },
122 .errstr = "jump out of range",
123 .result = REJECT,
124 },
125 {
126 "out of range jump2",
127 .insns = {
128 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
129 BPF_EXIT_INSN(),
130 },
131 .errstr = "jump out of range",
132 .result = REJECT,
133 },
134 {
135 "test1 ld_imm64",
136 .insns = {
137 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
138 BPF_LD_IMM64(BPF_REG_0, 0),
139 BPF_LD_IMM64(BPF_REG_0, 0),
140 BPF_LD_IMM64(BPF_REG_0, 1),
141 BPF_LD_IMM64(BPF_REG_0, 1),
142 BPF_MOV64_IMM(BPF_REG_0, 2),
143 BPF_EXIT_INSN(),
144 },
145 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700146 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700147 .result = REJECT,
148 },
149 {
150 "test2 ld_imm64",
151 .insns = {
152 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
153 BPF_LD_IMM64(BPF_REG_0, 0),
154 BPF_LD_IMM64(BPF_REG_0, 0),
155 BPF_LD_IMM64(BPF_REG_0, 1),
156 BPF_LD_IMM64(BPF_REG_0, 1),
157 BPF_EXIT_INSN(),
158 },
159 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700160 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700161 .result = REJECT,
162 },
163 {
164 "test3 ld_imm64",
165 .insns = {
166 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
167 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
168 BPF_LD_IMM64(BPF_REG_0, 0),
169 BPF_LD_IMM64(BPF_REG_0, 0),
170 BPF_LD_IMM64(BPF_REG_0, 1),
171 BPF_LD_IMM64(BPF_REG_0, 1),
172 BPF_EXIT_INSN(),
173 },
174 .errstr = "invalid bpf_ld_imm64 insn",
175 .result = REJECT,
176 },
177 {
178 "test4 ld_imm64",
179 .insns = {
180 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
181 BPF_EXIT_INSN(),
182 },
183 .errstr = "invalid bpf_ld_imm64 insn",
184 .result = REJECT,
185 },
186 {
187 "test5 ld_imm64",
188 .insns = {
189 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
190 },
191 .errstr = "invalid bpf_ld_imm64 insn",
192 .result = REJECT,
193 },
194 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200195 "test6 ld_imm64",
196 .insns = {
197 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
198 BPF_RAW_INSN(0, 0, 0, 0, 0),
199 BPF_EXIT_INSN(),
200 },
201 .result = ACCEPT,
202 },
203 {
204 "test7 ld_imm64",
205 .insns = {
206 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
207 BPF_RAW_INSN(0, 0, 0, 0, 1),
208 BPF_EXIT_INSN(),
209 },
210 .result = ACCEPT,
211 },
212 {
213 "test8 ld_imm64",
214 .insns = {
215 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
216 BPF_RAW_INSN(0, 0, 0, 0, 1),
217 BPF_EXIT_INSN(),
218 },
219 .errstr = "uses reserved fields",
220 .result = REJECT,
221 },
222 {
223 "test9 ld_imm64",
224 .insns = {
225 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
226 BPF_RAW_INSN(0, 0, 0, 1, 1),
227 BPF_EXIT_INSN(),
228 },
229 .errstr = "invalid bpf_ld_imm64 insn",
230 .result = REJECT,
231 },
232 {
233 "test10 ld_imm64",
234 .insns = {
235 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
236 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
237 BPF_EXIT_INSN(),
238 },
239 .errstr = "invalid bpf_ld_imm64 insn",
240 .result = REJECT,
241 },
242 {
243 "test11 ld_imm64",
244 .insns = {
245 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
246 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
247 BPF_EXIT_INSN(),
248 },
249 .errstr = "invalid bpf_ld_imm64 insn",
250 .result = REJECT,
251 },
252 {
253 "test12 ld_imm64",
254 .insns = {
255 BPF_MOV64_IMM(BPF_REG_1, 0),
256 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
257 BPF_RAW_INSN(0, 0, 0, 0, 1),
258 BPF_EXIT_INSN(),
259 },
260 .errstr = "not pointing to valid bpf_map",
261 .result = REJECT,
262 },
263 {
264 "test13 ld_imm64",
265 .insns = {
266 BPF_MOV64_IMM(BPF_REG_1, 0),
267 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
268 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
269 BPF_EXIT_INSN(),
270 },
271 .errstr = "invalid bpf_ld_imm64 insn",
272 .result = REJECT,
273 },
274 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700275 "no bpf_exit",
276 .insns = {
277 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
278 },
279 .errstr = "jump out of range",
280 .result = REJECT,
281 },
282 {
283 "loop (back-edge)",
284 .insns = {
285 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
286 BPF_EXIT_INSN(),
287 },
288 .errstr = "back-edge",
289 .result = REJECT,
290 },
291 {
292 "loop2 (back-edge)",
293 .insns = {
294 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
295 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
296 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
297 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
298 BPF_EXIT_INSN(),
299 },
300 .errstr = "back-edge",
301 .result = REJECT,
302 },
303 {
304 "conditional loop",
305 .insns = {
306 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
307 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
308 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
309 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
310 BPF_EXIT_INSN(),
311 },
312 .errstr = "back-edge",
313 .result = REJECT,
314 },
315 {
316 "read uninitialized register",
317 .insns = {
318 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
319 BPF_EXIT_INSN(),
320 },
321 .errstr = "R2 !read_ok",
322 .result = REJECT,
323 },
324 {
325 "read invalid register",
326 .insns = {
327 BPF_MOV64_REG(BPF_REG_0, -1),
328 BPF_EXIT_INSN(),
329 },
330 .errstr = "R15 is invalid",
331 .result = REJECT,
332 },
333 {
334 "program doesn't init R0 before exit",
335 .insns = {
336 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
337 BPF_EXIT_INSN(),
338 },
339 .errstr = "R0 !read_ok",
340 .result = REJECT,
341 },
342 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700343 "program doesn't init R0 before exit in all branches",
344 .insns = {
345 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
346 BPF_MOV64_IMM(BPF_REG_0, 1),
347 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
348 BPF_EXIT_INSN(),
349 },
350 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700351 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700352 .result = REJECT,
353 },
354 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700355 "stack out of bounds",
356 .insns = {
357 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
358 BPF_EXIT_INSN(),
359 },
360 .errstr = "invalid stack",
361 .result = REJECT,
362 },
363 {
364 "invalid call insn1",
365 .insns = {
366 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
367 BPF_EXIT_INSN(),
368 },
369 .errstr = "BPF_CALL uses reserved",
370 .result = REJECT,
371 },
372 {
373 "invalid call insn2",
374 .insns = {
375 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
376 BPF_EXIT_INSN(),
377 },
378 .errstr = "BPF_CALL uses reserved",
379 .result = REJECT,
380 },
381 {
382 "invalid function call",
383 .insns = {
384 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
385 BPF_EXIT_INSN(),
386 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100387 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700388 .result = REJECT,
389 },
390 {
391 "uninitialized stack1",
392 .insns = {
393 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
395 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200396 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
397 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700398 BPF_EXIT_INSN(),
399 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200400 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700401 .errstr = "invalid indirect read from stack",
402 .result = REJECT,
403 },
404 {
405 "uninitialized stack2",
406 .insns = {
407 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
408 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
409 BPF_EXIT_INSN(),
410 },
411 .errstr = "invalid read from stack",
412 .result = REJECT,
413 },
414 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200415 "invalid fp arithmetic",
416 /* If this gets ever changed, make sure JITs can deal with it. */
417 .insns = {
418 BPF_MOV64_IMM(BPF_REG_0, 0),
419 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
420 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
421 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
422 BPF_EXIT_INSN(),
423 },
Edward Creef65b1842017-08-07 15:27:12 +0100424 .errstr_unpriv = "R1 subtraction from stack pointer",
Daniel Borkmann728a8532017-04-27 01:39:32 +0200425 .result_unpriv = REJECT,
426 .errstr = "R1 invalid mem access",
427 .result = REJECT,
428 },
429 {
430 "non-invalid fp arithmetic",
431 .insns = {
432 BPF_MOV64_IMM(BPF_REG_0, 0),
433 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
434 BPF_EXIT_INSN(),
435 },
436 .result = ACCEPT,
437 },
438 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200439 "invalid argument register",
440 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200441 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
442 BPF_FUNC_get_cgroup_classid),
443 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
444 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200445 BPF_EXIT_INSN(),
446 },
447 .errstr = "R1 !read_ok",
448 .result = REJECT,
449 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
450 },
451 {
452 "non-invalid argument register",
453 .insns = {
454 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200455 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
456 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200457 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200458 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
459 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200460 BPF_EXIT_INSN(),
461 },
462 .result = ACCEPT,
463 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
464 },
465 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700466 "check valid spill/fill",
467 .insns = {
468 /* spill R1(ctx) into stack */
469 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700470 /* fill it back into R2 */
471 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700472 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100473 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
474 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700475 BPF_EXIT_INSN(),
476 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700477 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700478 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700479 .result_unpriv = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700480 },
481 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200482 "check valid spill/fill, skb mark",
483 .insns = {
484 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
485 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
486 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
487 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
488 offsetof(struct __sk_buff, mark)),
489 BPF_EXIT_INSN(),
490 },
491 .result = ACCEPT,
492 .result_unpriv = ACCEPT,
493 },
494 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700495 "check corrupted spill/fill",
496 .insns = {
497 /* spill R1(ctx) into stack */
498 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700499 /* mess up with R1 pointer on stack */
500 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700501 /* fill back into R0 should fail */
502 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700503 BPF_EXIT_INSN(),
504 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700505 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700506 .errstr = "corrupted spill",
507 .result = REJECT,
508 },
509 {
510 "invalid src register in STX",
511 .insns = {
512 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
513 BPF_EXIT_INSN(),
514 },
515 .errstr = "R15 is invalid",
516 .result = REJECT,
517 },
518 {
519 "invalid dst register in STX",
520 .insns = {
521 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
522 BPF_EXIT_INSN(),
523 },
524 .errstr = "R14 is invalid",
525 .result = REJECT,
526 },
527 {
528 "invalid dst register in ST",
529 .insns = {
530 BPF_ST_MEM(BPF_B, 14, -1, -1),
531 BPF_EXIT_INSN(),
532 },
533 .errstr = "R14 is invalid",
534 .result = REJECT,
535 },
536 {
537 "invalid src register in LDX",
538 .insns = {
539 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
540 BPF_EXIT_INSN(),
541 },
542 .errstr = "R12 is invalid",
543 .result = REJECT,
544 },
545 {
546 "invalid dst register in LDX",
547 .insns = {
548 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
549 BPF_EXIT_INSN(),
550 },
551 .errstr = "R11 is invalid",
552 .result = REJECT,
553 },
554 {
555 "junk insn",
556 .insns = {
557 BPF_RAW_INSN(0, 0, 0, 0, 0),
558 BPF_EXIT_INSN(),
559 },
560 .errstr = "invalid BPF_LD_IMM",
561 .result = REJECT,
562 },
563 {
564 "junk insn2",
565 .insns = {
566 BPF_RAW_INSN(1, 0, 0, 0, 0),
567 BPF_EXIT_INSN(),
568 },
569 .errstr = "BPF_LDX uses reserved fields",
570 .result = REJECT,
571 },
572 {
573 "junk insn3",
574 .insns = {
575 BPF_RAW_INSN(-1, 0, 0, 0, 0),
576 BPF_EXIT_INSN(),
577 },
578 .errstr = "invalid BPF_ALU opcode f0",
579 .result = REJECT,
580 },
581 {
582 "junk insn4",
583 .insns = {
584 BPF_RAW_INSN(-1, -1, -1, -1, -1),
585 BPF_EXIT_INSN(),
586 },
587 .errstr = "invalid BPF_ALU opcode f0",
588 .result = REJECT,
589 },
590 {
591 "junk insn5",
592 .insns = {
593 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
594 BPF_EXIT_INSN(),
595 },
596 .errstr = "BPF_ALU uses reserved fields",
597 .result = REJECT,
598 },
599 {
600 "misaligned read from stack",
601 .insns = {
602 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
603 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
604 BPF_EXIT_INSN(),
605 },
Edward Creef65b1842017-08-07 15:27:12 +0100606 .errstr = "misaligned stack access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700607 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +0100608 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700609 },
610 {
611 "invalid map_fd for function call",
612 .insns = {
613 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
614 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
615 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
616 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200617 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
618 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700619 BPF_EXIT_INSN(),
620 },
621 .errstr = "fd 0 is not pointing to valid bpf_map",
622 .result = REJECT,
623 },
624 {
625 "don't check return value before access",
626 .insns = {
627 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
628 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
629 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
630 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200631 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
632 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700633 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
634 BPF_EXIT_INSN(),
635 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200636 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700637 .errstr = "R0 invalid mem access 'map_value_or_null'",
638 .result = REJECT,
639 },
640 {
641 "access memory with incorrect alignment",
642 .insns = {
643 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
644 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
645 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
646 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200647 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
648 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700649 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
650 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
651 BPF_EXIT_INSN(),
652 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200653 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +0100654 .errstr = "misaligned value access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700655 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +0100656 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700657 },
658 {
659 "sometimes access memory with incorrect alignment",
660 .insns = {
661 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
662 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
664 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200665 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
666 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700667 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
668 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
669 BPF_EXIT_INSN(),
670 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
671 BPF_EXIT_INSN(),
672 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200673 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700674 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700675 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700676 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +0100677 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700678 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700679 {
680 "jump test 1",
681 .insns = {
682 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
683 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
685 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
687 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
688 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
689 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
690 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
691 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
692 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
693 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
694 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
695 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
696 BPF_MOV64_IMM(BPF_REG_0, 0),
697 BPF_EXIT_INSN(),
698 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700699 .errstr_unpriv = "R1 pointer comparison",
700 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700701 .result = ACCEPT,
702 },
703 {
704 "jump test 2",
705 .insns = {
706 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
707 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
708 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
709 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
710 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
711 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
712 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
713 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
714 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
715 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
716 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
717 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
718 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
720 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
721 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
723 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
724 BPF_MOV64_IMM(BPF_REG_0, 0),
725 BPF_EXIT_INSN(),
726 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700727 .errstr_unpriv = "R1 pointer comparison",
728 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700729 .result = ACCEPT,
730 },
731 {
732 "jump test 3",
733 .insns = {
734 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
735 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
736 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
738 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
739 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
740 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
741 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
742 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
743 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
744 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
746 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
747 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
748 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
749 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
750 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
751 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
752 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
753 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
754 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
755 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
756 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
757 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
758 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200759 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
760 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700761 BPF_EXIT_INSN(),
762 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200763 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700764 .errstr_unpriv = "R1 pointer comparison",
765 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700766 .result = ACCEPT,
767 },
768 {
769 "jump test 4",
770 .insns = {
771 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
772 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
773 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
774 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
775 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
776 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
777 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
778 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
779 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
780 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
781 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
782 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
783 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
784 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
785 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
786 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
787 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
788 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
789 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
790 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
791 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
792 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
793 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
794 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
795 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
796 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
797 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
798 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
799 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
800 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
801 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
802 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
803 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
804 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
805 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
806 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
807 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
808 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
809 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
810 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
811 BPF_MOV64_IMM(BPF_REG_0, 0),
812 BPF_EXIT_INSN(),
813 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700814 .errstr_unpriv = "R1 pointer comparison",
815 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700816 .result = ACCEPT,
817 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700818 {
819 "jump test 5",
820 .insns = {
821 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
822 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
823 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
824 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
825 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
826 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
827 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
828 BPF_MOV64_IMM(BPF_REG_0, 0),
829 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
830 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
831 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
832 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
833 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
834 BPF_MOV64_IMM(BPF_REG_0, 0),
835 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
836 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
837 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
838 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
839 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
840 BPF_MOV64_IMM(BPF_REG_0, 0),
841 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
842 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
843 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
844 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
845 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
846 BPF_MOV64_IMM(BPF_REG_0, 0),
847 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
848 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
849 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
850 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
851 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
852 BPF_MOV64_IMM(BPF_REG_0, 0),
853 BPF_EXIT_INSN(),
854 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700855 .errstr_unpriv = "R1 pointer comparison",
856 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700857 .result = ACCEPT,
858 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700859 {
860 "access skb fields ok",
861 .insns = {
862 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
863 offsetof(struct __sk_buff, len)),
864 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
865 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
866 offsetof(struct __sk_buff, mark)),
867 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
868 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
869 offsetof(struct __sk_buff, pkt_type)),
870 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
871 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
872 offsetof(struct __sk_buff, queue_mapping)),
873 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -0700874 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
875 offsetof(struct __sk_buff, protocol)),
876 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
877 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
878 offsetof(struct __sk_buff, vlan_present)),
879 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
880 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
881 offsetof(struct __sk_buff, vlan_tci)),
882 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Daniel Borkmannb1d9fc42017-04-19 23:01:17 +0200883 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
884 offsetof(struct __sk_buff, napi_id)),
885 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700886 BPF_EXIT_INSN(),
887 },
888 .result = ACCEPT,
889 },
890 {
891 "access skb fields bad1",
892 .insns = {
893 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
894 BPF_EXIT_INSN(),
895 },
896 .errstr = "invalid bpf_context access",
897 .result = REJECT,
898 },
899 {
900 "access skb fields bad2",
901 .insns = {
902 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
903 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
904 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
906 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200907 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
908 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700909 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
910 BPF_EXIT_INSN(),
911 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
912 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
913 offsetof(struct __sk_buff, pkt_type)),
914 BPF_EXIT_INSN(),
915 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200916 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700917 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700918 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700919 .result = REJECT,
920 },
921 {
922 "access skb fields bad3",
923 .insns = {
924 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
925 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
926 offsetof(struct __sk_buff, pkt_type)),
927 BPF_EXIT_INSN(),
928 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
929 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
931 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200932 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
933 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700934 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
935 BPF_EXIT_INSN(),
936 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
937 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
938 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200939 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700940 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700941 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700942 .result = REJECT,
943 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700944 {
945 "access skb fields bad4",
946 .insns = {
947 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
948 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
949 offsetof(struct __sk_buff, len)),
950 BPF_MOV64_IMM(BPF_REG_0, 0),
951 BPF_EXIT_INSN(),
952 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
953 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
955 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200956 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
957 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700958 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
959 BPF_EXIT_INSN(),
960 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
961 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
962 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200963 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700964 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700965 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700966 .result = REJECT,
967 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700968 {
969 "check skb->mark is not writeable by sockets",
970 .insns = {
971 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
972 offsetof(struct __sk_buff, mark)),
973 BPF_EXIT_INSN(),
974 },
975 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700976 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700977 .result = REJECT,
978 },
979 {
980 "check skb->tc_index is not writeable by sockets",
981 .insns = {
982 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
983 offsetof(struct __sk_buff, tc_index)),
984 BPF_EXIT_INSN(),
985 },
986 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700987 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700988 .result = REJECT,
989 },
990 {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100991 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700992 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100993 BPF_MOV64_IMM(BPF_REG_0, 0),
994 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
995 offsetof(struct __sk_buff, cb[0])),
996 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
997 offsetof(struct __sk_buff, cb[0]) + 1),
998 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
999 offsetof(struct __sk_buff, cb[0]) + 2),
1000 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1001 offsetof(struct __sk_buff, cb[0]) + 3),
1002 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1003 offsetof(struct __sk_buff, cb[1])),
1004 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1005 offsetof(struct __sk_buff, cb[1]) + 1),
1006 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1007 offsetof(struct __sk_buff, cb[1]) + 2),
1008 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1009 offsetof(struct __sk_buff, cb[1]) + 3),
1010 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1011 offsetof(struct __sk_buff, cb[2])),
1012 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1013 offsetof(struct __sk_buff, cb[2]) + 1),
1014 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1015 offsetof(struct __sk_buff, cb[2]) + 2),
1016 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1017 offsetof(struct __sk_buff, cb[2]) + 3),
1018 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1019 offsetof(struct __sk_buff, cb[3])),
1020 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1021 offsetof(struct __sk_buff, cb[3]) + 1),
1022 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1023 offsetof(struct __sk_buff, cb[3]) + 2),
1024 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1025 offsetof(struct __sk_buff, cb[3]) + 3),
1026 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1027 offsetof(struct __sk_buff, cb[4])),
1028 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1029 offsetof(struct __sk_buff, cb[4]) + 1),
1030 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1031 offsetof(struct __sk_buff, cb[4]) + 2),
1032 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1033 offsetof(struct __sk_buff, cb[4]) + 3),
1034 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1035 offsetof(struct __sk_buff, cb[0])),
1036 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1037 offsetof(struct __sk_buff, cb[0]) + 1),
1038 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1039 offsetof(struct __sk_buff, cb[0]) + 2),
1040 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1041 offsetof(struct __sk_buff, cb[0]) + 3),
1042 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1043 offsetof(struct __sk_buff, cb[1])),
1044 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1045 offsetof(struct __sk_buff, cb[1]) + 1),
1046 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1047 offsetof(struct __sk_buff, cb[1]) + 2),
1048 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1049 offsetof(struct __sk_buff, cb[1]) + 3),
1050 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1051 offsetof(struct __sk_buff, cb[2])),
1052 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1053 offsetof(struct __sk_buff, cb[2]) + 1),
1054 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1055 offsetof(struct __sk_buff, cb[2]) + 2),
1056 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1057 offsetof(struct __sk_buff, cb[2]) + 3),
1058 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1059 offsetof(struct __sk_buff, cb[3])),
1060 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1061 offsetof(struct __sk_buff, cb[3]) + 1),
1062 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1063 offsetof(struct __sk_buff, cb[3]) + 2),
1064 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1065 offsetof(struct __sk_buff, cb[3]) + 3),
1066 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1067 offsetof(struct __sk_buff, cb[4])),
1068 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1069 offsetof(struct __sk_buff, cb[4]) + 1),
1070 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1071 offsetof(struct __sk_buff, cb[4]) + 2),
1072 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1073 offsetof(struct __sk_buff, cb[4]) + 3),
1074 BPF_EXIT_INSN(),
1075 },
1076 .result = ACCEPT,
1077 },
1078 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001079 "__sk_buff->hash, offset 0, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001080 .insns = {
1081 BPF_MOV64_IMM(BPF_REG_0, 0),
1082 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001083 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001084 BPF_EXIT_INSN(),
1085 },
1086 .errstr = "invalid bpf_context access",
1087 .result = REJECT,
1088 },
1089 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001090 "__sk_buff->tc_index, offset 3, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001091 .insns = {
1092 BPF_MOV64_IMM(BPF_REG_0, 0),
1093 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001094 offsetof(struct __sk_buff, tc_index) + 3),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001095 BPF_EXIT_INSN(),
1096 },
1097 .errstr = "invalid bpf_context access",
1098 .result = REJECT,
1099 },
1100 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001101 "check skb->hash byte load permitted",
1102 .insns = {
1103 BPF_MOV64_IMM(BPF_REG_0, 0),
1104#ifdef __LITTLE_ENDIAN
1105 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1106 offsetof(struct __sk_buff, hash)),
1107#else
1108 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1109 offsetof(struct __sk_buff, hash) + 3),
1110#endif
1111 BPF_EXIT_INSN(),
1112 },
1113 .result = ACCEPT,
1114 },
1115 {
1116 "check skb->hash byte load not permitted 1",
1117 .insns = {
1118 BPF_MOV64_IMM(BPF_REG_0, 0),
1119 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1120 offsetof(struct __sk_buff, hash) + 1),
1121 BPF_EXIT_INSN(),
1122 },
1123 .errstr = "invalid bpf_context access",
1124 .result = REJECT,
1125 },
1126 {
1127 "check skb->hash byte load not permitted 2",
1128 .insns = {
1129 BPF_MOV64_IMM(BPF_REG_0, 0),
1130 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1131 offsetof(struct __sk_buff, hash) + 2),
1132 BPF_EXIT_INSN(),
1133 },
1134 .errstr = "invalid bpf_context access",
1135 .result = REJECT,
1136 },
1137 {
1138 "check skb->hash byte load not permitted 3",
1139 .insns = {
1140 BPF_MOV64_IMM(BPF_REG_0, 0),
1141#ifdef __LITTLE_ENDIAN
1142 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1143 offsetof(struct __sk_buff, hash) + 3),
1144#else
1145 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1146 offsetof(struct __sk_buff, hash)),
1147#endif
1148 BPF_EXIT_INSN(),
1149 },
1150 .errstr = "invalid bpf_context access",
1151 .result = REJECT,
1152 },
1153 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001154 "check cb access: byte, wrong type",
1155 .insns = {
1156 BPF_MOV64_IMM(BPF_REG_0, 0),
1157 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001158 offsetof(struct __sk_buff, cb[0])),
1159 BPF_EXIT_INSN(),
1160 },
1161 .errstr = "invalid bpf_context access",
1162 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001163 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1164 },
1165 {
1166 "check cb access: half",
1167 .insns = {
1168 BPF_MOV64_IMM(BPF_REG_0, 0),
1169 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1170 offsetof(struct __sk_buff, cb[0])),
1171 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1172 offsetof(struct __sk_buff, cb[0]) + 2),
1173 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1174 offsetof(struct __sk_buff, cb[1])),
1175 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1176 offsetof(struct __sk_buff, cb[1]) + 2),
1177 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1178 offsetof(struct __sk_buff, cb[2])),
1179 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1180 offsetof(struct __sk_buff, cb[2]) + 2),
1181 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1182 offsetof(struct __sk_buff, cb[3])),
1183 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1184 offsetof(struct __sk_buff, cb[3]) + 2),
1185 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1186 offsetof(struct __sk_buff, cb[4])),
1187 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1188 offsetof(struct __sk_buff, cb[4]) + 2),
1189 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1190 offsetof(struct __sk_buff, cb[0])),
1191 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1192 offsetof(struct __sk_buff, cb[0]) + 2),
1193 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1194 offsetof(struct __sk_buff, cb[1])),
1195 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1196 offsetof(struct __sk_buff, cb[1]) + 2),
1197 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1198 offsetof(struct __sk_buff, cb[2])),
1199 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1200 offsetof(struct __sk_buff, cb[2]) + 2),
1201 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1202 offsetof(struct __sk_buff, cb[3])),
1203 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1204 offsetof(struct __sk_buff, cb[3]) + 2),
1205 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1206 offsetof(struct __sk_buff, cb[4])),
1207 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1208 offsetof(struct __sk_buff, cb[4]) + 2),
1209 BPF_EXIT_INSN(),
1210 },
1211 .result = ACCEPT,
1212 },
1213 {
1214 "check cb access: half, unaligned",
1215 .insns = {
1216 BPF_MOV64_IMM(BPF_REG_0, 0),
1217 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1218 offsetof(struct __sk_buff, cb[0]) + 1),
1219 BPF_EXIT_INSN(),
1220 },
Edward Creef65b1842017-08-07 15:27:12 +01001221 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001222 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001223 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001224 },
1225 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001226 "check __sk_buff->hash, offset 0, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001227 .insns = {
1228 BPF_MOV64_IMM(BPF_REG_0, 0),
1229 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001230 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001231 BPF_EXIT_INSN(),
1232 },
1233 .errstr = "invalid bpf_context access",
1234 .result = REJECT,
1235 },
1236 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001237 "check __sk_buff->tc_index, offset 2, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001238 .insns = {
1239 BPF_MOV64_IMM(BPF_REG_0, 0),
1240 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001241 offsetof(struct __sk_buff, tc_index) + 2),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001242 BPF_EXIT_INSN(),
1243 },
1244 .errstr = "invalid bpf_context access",
1245 .result = REJECT,
1246 },
1247 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001248 "check skb->hash half load permitted",
1249 .insns = {
1250 BPF_MOV64_IMM(BPF_REG_0, 0),
1251#ifdef __LITTLE_ENDIAN
1252 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1253 offsetof(struct __sk_buff, hash)),
1254#else
1255 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1256 offsetof(struct __sk_buff, hash) + 2),
1257#endif
1258 BPF_EXIT_INSN(),
1259 },
1260 .result = ACCEPT,
1261 },
1262 {
1263 "check skb->hash half load not permitted",
1264 .insns = {
1265 BPF_MOV64_IMM(BPF_REG_0, 0),
1266#ifdef __LITTLE_ENDIAN
1267 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1268 offsetof(struct __sk_buff, hash) + 2),
1269#else
1270 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1271 offsetof(struct __sk_buff, hash)),
1272#endif
1273 BPF_EXIT_INSN(),
1274 },
1275 .errstr = "invalid bpf_context access",
1276 .result = REJECT,
1277 },
1278 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001279 "check cb access: half, wrong type",
1280 .insns = {
1281 BPF_MOV64_IMM(BPF_REG_0, 0),
1282 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1283 offsetof(struct __sk_buff, cb[0])),
1284 BPF_EXIT_INSN(),
1285 },
1286 .errstr = "invalid bpf_context access",
1287 .result = REJECT,
1288 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1289 },
1290 {
1291 "check cb access: word",
1292 .insns = {
1293 BPF_MOV64_IMM(BPF_REG_0, 0),
1294 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1295 offsetof(struct __sk_buff, cb[0])),
1296 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1297 offsetof(struct __sk_buff, cb[1])),
1298 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1299 offsetof(struct __sk_buff, cb[2])),
1300 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1301 offsetof(struct __sk_buff, cb[3])),
1302 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1303 offsetof(struct __sk_buff, cb[4])),
1304 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1305 offsetof(struct __sk_buff, cb[0])),
1306 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1307 offsetof(struct __sk_buff, cb[1])),
1308 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1309 offsetof(struct __sk_buff, cb[2])),
1310 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1311 offsetof(struct __sk_buff, cb[3])),
1312 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1313 offsetof(struct __sk_buff, cb[4])),
1314 BPF_EXIT_INSN(),
1315 },
1316 .result = ACCEPT,
1317 },
1318 {
1319 "check cb access: word, unaligned 1",
1320 .insns = {
1321 BPF_MOV64_IMM(BPF_REG_0, 0),
1322 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1323 offsetof(struct __sk_buff, cb[0]) + 2),
1324 BPF_EXIT_INSN(),
1325 },
Edward Creef65b1842017-08-07 15:27:12 +01001326 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001327 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001328 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001329 },
1330 {
1331 "check cb access: word, unaligned 2",
1332 .insns = {
1333 BPF_MOV64_IMM(BPF_REG_0, 0),
1334 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1335 offsetof(struct __sk_buff, cb[4]) + 1),
1336 BPF_EXIT_INSN(),
1337 },
Edward Creef65b1842017-08-07 15:27:12 +01001338 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001339 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001340 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001341 },
1342 {
1343 "check cb access: word, unaligned 3",
1344 .insns = {
1345 BPF_MOV64_IMM(BPF_REG_0, 0),
1346 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1347 offsetof(struct __sk_buff, cb[4]) + 2),
1348 BPF_EXIT_INSN(),
1349 },
Edward Creef65b1842017-08-07 15:27:12 +01001350 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001351 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001352 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001353 },
1354 {
1355 "check cb access: word, unaligned 4",
1356 .insns = {
1357 BPF_MOV64_IMM(BPF_REG_0, 0),
1358 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1359 offsetof(struct __sk_buff, cb[4]) + 3),
1360 BPF_EXIT_INSN(),
1361 },
Edward Creef65b1842017-08-07 15:27:12 +01001362 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001363 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001364 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001365 },
1366 {
1367 "check cb access: double",
1368 .insns = {
1369 BPF_MOV64_IMM(BPF_REG_0, 0),
1370 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1371 offsetof(struct __sk_buff, cb[0])),
1372 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1373 offsetof(struct __sk_buff, cb[2])),
1374 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1375 offsetof(struct __sk_buff, cb[0])),
1376 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1377 offsetof(struct __sk_buff, cb[2])),
1378 BPF_EXIT_INSN(),
1379 },
1380 .result = ACCEPT,
1381 },
1382 {
1383 "check cb access: double, unaligned 1",
1384 .insns = {
1385 BPF_MOV64_IMM(BPF_REG_0, 0),
1386 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1387 offsetof(struct __sk_buff, cb[1])),
1388 BPF_EXIT_INSN(),
1389 },
Edward Creef65b1842017-08-07 15:27:12 +01001390 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001391 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001392 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001393 },
1394 {
1395 "check cb access: double, unaligned 2",
1396 .insns = {
1397 BPF_MOV64_IMM(BPF_REG_0, 0),
1398 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1399 offsetof(struct __sk_buff, cb[3])),
1400 BPF_EXIT_INSN(),
1401 },
Edward Creef65b1842017-08-07 15:27:12 +01001402 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001403 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001404 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001405 },
1406 {
1407 "check cb access: double, oob 1",
1408 .insns = {
1409 BPF_MOV64_IMM(BPF_REG_0, 0),
1410 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1411 offsetof(struct __sk_buff, cb[4])),
1412 BPF_EXIT_INSN(),
1413 },
1414 .errstr = "invalid bpf_context access",
1415 .result = REJECT,
1416 },
1417 {
1418 "check cb access: double, oob 2",
1419 .insns = {
1420 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001421 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1422 offsetof(struct __sk_buff, cb[4])),
1423 BPF_EXIT_INSN(),
1424 },
1425 .errstr = "invalid bpf_context access",
1426 .result = REJECT,
1427 },
1428 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001429 "check __sk_buff->ifindex dw store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001430 .insns = {
1431 BPF_MOV64_IMM(BPF_REG_0, 0),
Yonghong Song31fd8582017-06-13 15:52:13 -07001432 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1433 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001434 BPF_EXIT_INSN(),
1435 },
1436 .errstr = "invalid bpf_context access",
1437 .result = REJECT,
1438 },
1439 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001440 "check __sk_buff->ifindex dw load not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001441 .insns = {
1442 BPF_MOV64_IMM(BPF_REG_0, 0),
1443 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
Yonghong Song31fd8582017-06-13 15:52:13 -07001444 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001445 BPF_EXIT_INSN(),
1446 },
1447 .errstr = "invalid bpf_context access",
1448 .result = REJECT,
1449 },
1450 {
1451 "check cb access: double, wrong type",
1452 .insns = {
1453 BPF_MOV64_IMM(BPF_REG_0, 0),
1454 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1455 offsetof(struct __sk_buff, cb[0])),
1456 BPF_EXIT_INSN(),
1457 },
1458 .errstr = "invalid bpf_context access",
1459 .result = REJECT,
1460 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001461 },
1462 {
1463 "check out of range skb->cb access",
1464 .insns = {
1465 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001466 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001467 BPF_EXIT_INSN(),
1468 },
1469 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001470 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001471 .result = REJECT,
1472 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
1473 },
1474 {
1475 "write skb fields from socket prog",
1476 .insns = {
1477 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1478 offsetof(struct __sk_buff, cb[4])),
1479 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1480 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1481 offsetof(struct __sk_buff, mark)),
1482 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1483 offsetof(struct __sk_buff, tc_index)),
1484 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1485 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1486 offsetof(struct __sk_buff, cb[0])),
1487 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1488 offsetof(struct __sk_buff, cb[2])),
1489 BPF_EXIT_INSN(),
1490 },
1491 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001492 .errstr_unpriv = "R1 leaks addr",
1493 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001494 },
1495 {
1496 "write skb fields from tc_cls_act prog",
1497 .insns = {
1498 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1499 offsetof(struct __sk_buff, cb[0])),
1500 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1501 offsetof(struct __sk_buff, mark)),
1502 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1503 offsetof(struct __sk_buff, tc_index)),
1504 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1505 offsetof(struct __sk_buff, tc_index)),
1506 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1507 offsetof(struct __sk_buff, cb[3])),
1508 BPF_EXIT_INSN(),
1509 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001510 .errstr_unpriv = "",
1511 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001512 .result = ACCEPT,
1513 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1514 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001515 {
1516 "PTR_TO_STACK store/load",
1517 .insns = {
1518 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1519 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1520 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1521 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1522 BPF_EXIT_INSN(),
1523 },
1524 .result = ACCEPT,
1525 },
1526 {
1527 "PTR_TO_STACK store/load - bad alignment on off",
1528 .insns = {
1529 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1530 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1531 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1532 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1533 BPF_EXIT_INSN(),
1534 },
1535 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001536 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
1537 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001538 },
1539 {
1540 "PTR_TO_STACK store/load - bad alignment on reg",
1541 .insns = {
1542 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1543 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1544 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1545 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1546 BPF_EXIT_INSN(),
1547 },
1548 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001549 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
1550 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001551 },
1552 {
1553 "PTR_TO_STACK store/load - out of bounds low",
1554 .insns = {
1555 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1557 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1558 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1559 BPF_EXIT_INSN(),
1560 },
1561 .result = REJECT,
1562 .errstr = "invalid stack off=-79992 size=8",
1563 },
1564 {
1565 "PTR_TO_STACK store/load - out of bounds high",
1566 .insns = {
1567 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1568 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1569 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1570 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1571 BPF_EXIT_INSN(),
1572 },
1573 .result = REJECT,
1574 .errstr = "invalid stack off=0 size=8",
1575 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001576 {
1577 "unpriv: return pointer",
1578 .insns = {
1579 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1580 BPF_EXIT_INSN(),
1581 },
1582 .result = ACCEPT,
1583 .result_unpriv = REJECT,
1584 .errstr_unpriv = "R0 leaks addr",
1585 },
1586 {
1587 "unpriv: add const to pointer",
1588 .insns = {
1589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1590 BPF_MOV64_IMM(BPF_REG_0, 0),
1591 BPF_EXIT_INSN(),
1592 },
1593 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001594 },
1595 {
1596 "unpriv: add pointer to pointer",
1597 .insns = {
1598 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1599 BPF_MOV64_IMM(BPF_REG_0, 0),
1600 BPF_EXIT_INSN(),
1601 },
1602 .result = ACCEPT,
1603 .result_unpriv = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001604 .errstr_unpriv = "R1 pointer += pointer",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001605 },
1606 {
1607 "unpriv: neg pointer",
1608 .insns = {
1609 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1610 BPF_MOV64_IMM(BPF_REG_0, 0),
1611 BPF_EXIT_INSN(),
1612 },
1613 .result = ACCEPT,
1614 .result_unpriv = REJECT,
1615 .errstr_unpriv = "R1 pointer arithmetic",
1616 },
1617 {
1618 "unpriv: cmp pointer with const",
1619 .insns = {
1620 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1621 BPF_MOV64_IMM(BPF_REG_0, 0),
1622 BPF_EXIT_INSN(),
1623 },
1624 .result = ACCEPT,
1625 .result_unpriv = REJECT,
1626 .errstr_unpriv = "R1 pointer comparison",
1627 },
1628 {
1629 "unpriv: cmp pointer with pointer",
1630 .insns = {
1631 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1632 BPF_MOV64_IMM(BPF_REG_0, 0),
1633 BPF_EXIT_INSN(),
1634 },
1635 .result = ACCEPT,
1636 .result_unpriv = REJECT,
1637 .errstr_unpriv = "R10 pointer comparison",
1638 },
1639 {
1640 "unpriv: check that printk is disallowed",
1641 .insns = {
1642 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1643 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1645 BPF_MOV64_IMM(BPF_REG_2, 8),
1646 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001647 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1648 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001649 BPF_MOV64_IMM(BPF_REG_0, 0),
1650 BPF_EXIT_INSN(),
1651 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01001652 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001653 .result_unpriv = REJECT,
1654 .result = ACCEPT,
1655 },
1656 {
1657 "unpriv: pass pointer to helper function",
1658 .insns = {
1659 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1660 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1662 BPF_LD_MAP_FD(BPF_REG_1, 0),
1663 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1664 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001665 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1666 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001667 BPF_MOV64_IMM(BPF_REG_0, 0),
1668 BPF_EXIT_INSN(),
1669 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001670 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001671 .errstr_unpriv = "R4 leaks addr",
1672 .result_unpriv = REJECT,
1673 .result = ACCEPT,
1674 },
1675 {
1676 "unpriv: indirectly pass pointer on stack to helper function",
1677 .insns = {
1678 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1679 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1681 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001682 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1683 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001684 BPF_MOV64_IMM(BPF_REG_0, 0),
1685 BPF_EXIT_INSN(),
1686 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001687 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001688 .errstr = "invalid indirect read from stack off -8+0 size 8",
1689 .result = REJECT,
1690 },
1691 {
1692 "unpriv: mangle pointer on stack 1",
1693 .insns = {
1694 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1695 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1696 BPF_MOV64_IMM(BPF_REG_0, 0),
1697 BPF_EXIT_INSN(),
1698 },
1699 .errstr_unpriv = "attempt to corrupt spilled",
1700 .result_unpriv = REJECT,
1701 .result = ACCEPT,
1702 },
1703 {
1704 "unpriv: mangle pointer on stack 2",
1705 .insns = {
1706 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1707 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1708 BPF_MOV64_IMM(BPF_REG_0, 0),
1709 BPF_EXIT_INSN(),
1710 },
1711 .errstr_unpriv = "attempt to corrupt spilled",
1712 .result_unpriv = REJECT,
1713 .result = ACCEPT,
1714 },
1715 {
1716 "unpriv: read pointer from stack in small chunks",
1717 .insns = {
1718 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1719 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1720 BPF_MOV64_IMM(BPF_REG_0, 0),
1721 BPF_EXIT_INSN(),
1722 },
1723 .errstr = "invalid size",
1724 .result = REJECT,
1725 },
1726 {
1727 "unpriv: write pointer into ctx",
1728 .insns = {
1729 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1730 BPF_MOV64_IMM(BPF_REG_0, 0),
1731 BPF_EXIT_INSN(),
1732 },
1733 .errstr_unpriv = "R1 leaks addr",
1734 .result_unpriv = REJECT,
1735 .errstr = "invalid bpf_context access",
1736 .result = REJECT,
1737 },
1738 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001739 "unpriv: spill/fill of ctx",
1740 .insns = {
1741 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1742 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1743 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1744 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1745 BPF_MOV64_IMM(BPF_REG_0, 0),
1746 BPF_EXIT_INSN(),
1747 },
1748 .result = ACCEPT,
1749 },
1750 {
1751 "unpriv: spill/fill of ctx 2",
1752 .insns = {
1753 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1754 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1755 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1756 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001757 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1758 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001759 BPF_EXIT_INSN(),
1760 },
1761 .result = ACCEPT,
1762 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1763 },
1764 {
1765 "unpriv: spill/fill of ctx 3",
1766 .insns = {
1767 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1768 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1769 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1770 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1771 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001772 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1773 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001774 BPF_EXIT_INSN(),
1775 },
1776 .result = REJECT,
1777 .errstr = "R1 type=fp expected=ctx",
1778 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1779 },
1780 {
1781 "unpriv: spill/fill of ctx 4",
1782 .insns = {
1783 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1784 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1785 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1786 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001787 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
1788 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001789 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001790 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1791 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001792 BPF_EXIT_INSN(),
1793 },
1794 .result = REJECT,
1795 .errstr = "R1 type=inv expected=ctx",
1796 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1797 },
1798 {
1799 "unpriv: spill/fill of different pointers stx",
1800 .insns = {
1801 BPF_MOV64_IMM(BPF_REG_3, 42),
1802 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1803 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1804 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1805 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1807 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1808 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1809 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1810 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1811 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
1812 offsetof(struct __sk_buff, mark)),
1813 BPF_MOV64_IMM(BPF_REG_0, 0),
1814 BPF_EXIT_INSN(),
1815 },
1816 .result = REJECT,
1817 .errstr = "same insn cannot be used with different pointers",
1818 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1819 },
1820 {
1821 "unpriv: spill/fill of different pointers ldx",
1822 .insns = {
1823 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1825 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1826 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1827 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
1828 -(__s32)offsetof(struct bpf_perf_event_data,
1829 sample_period) - 8),
1830 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1831 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1832 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1833 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1834 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
1835 offsetof(struct bpf_perf_event_data,
1836 sample_period)),
1837 BPF_MOV64_IMM(BPF_REG_0, 0),
1838 BPF_EXIT_INSN(),
1839 },
1840 .result = REJECT,
1841 .errstr = "same insn cannot be used with different pointers",
1842 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
1843 },
1844 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001845 "unpriv: write pointer into map elem value",
1846 .insns = {
1847 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1848 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1850 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001851 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1852 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001853 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1854 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1855 BPF_EXIT_INSN(),
1856 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001857 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001858 .errstr_unpriv = "R0 leaks addr",
1859 .result_unpriv = REJECT,
1860 .result = ACCEPT,
1861 },
1862 {
1863 "unpriv: partial copy of pointer",
1864 .insns = {
1865 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1866 BPF_MOV64_IMM(BPF_REG_0, 0),
1867 BPF_EXIT_INSN(),
1868 },
1869 .errstr_unpriv = "R10 partial copy",
1870 .result_unpriv = REJECT,
1871 .result = ACCEPT,
1872 },
1873 {
1874 "unpriv: pass pointer to tail_call",
1875 .insns = {
1876 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1877 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001878 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1879 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001880 BPF_MOV64_IMM(BPF_REG_0, 0),
1881 BPF_EXIT_INSN(),
1882 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001883 .fixup_prog = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001884 .errstr_unpriv = "R3 leaks addr into helper",
1885 .result_unpriv = REJECT,
1886 .result = ACCEPT,
1887 },
1888 {
1889 "unpriv: cmp map pointer with zero",
1890 .insns = {
1891 BPF_MOV64_IMM(BPF_REG_1, 0),
1892 BPF_LD_MAP_FD(BPF_REG_1, 0),
1893 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1894 BPF_MOV64_IMM(BPF_REG_0, 0),
1895 BPF_EXIT_INSN(),
1896 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001897 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001898 .errstr_unpriv = "R1 pointer comparison",
1899 .result_unpriv = REJECT,
1900 .result = ACCEPT,
1901 },
1902 {
1903 "unpriv: write into frame pointer",
1904 .insns = {
1905 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1906 BPF_MOV64_IMM(BPF_REG_0, 0),
1907 BPF_EXIT_INSN(),
1908 },
1909 .errstr = "frame pointer is read only",
1910 .result = REJECT,
1911 },
1912 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001913 "unpriv: spill/fill frame pointer",
1914 .insns = {
1915 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1916 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1917 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1918 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
1919 BPF_MOV64_IMM(BPF_REG_0, 0),
1920 BPF_EXIT_INSN(),
1921 },
1922 .errstr = "frame pointer is read only",
1923 .result = REJECT,
1924 },
1925 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001926 "unpriv: cmp of frame pointer",
1927 .insns = {
1928 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1929 BPF_MOV64_IMM(BPF_REG_0, 0),
1930 BPF_EXIT_INSN(),
1931 },
1932 .errstr_unpriv = "R10 pointer comparison",
1933 .result_unpriv = REJECT,
1934 .result = ACCEPT,
1935 },
1936 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02001937 "unpriv: adding of fp",
1938 .insns = {
1939 BPF_MOV64_IMM(BPF_REG_0, 0),
1940 BPF_MOV64_IMM(BPF_REG_1, 0),
1941 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1942 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
1943 BPF_EXIT_INSN(),
1944 },
Edward Creef65b1842017-08-07 15:27:12 +01001945 .result = ACCEPT,
Daniel Borkmann728a8532017-04-27 01:39:32 +02001946 },
1947 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001948 "unpriv: cmp of stack pointer",
1949 .insns = {
1950 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1951 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1952 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1953 BPF_MOV64_IMM(BPF_REG_0, 0),
1954 BPF_EXIT_INSN(),
1955 },
1956 .errstr_unpriv = "R2 pointer comparison",
1957 .result_unpriv = REJECT,
1958 .result = ACCEPT,
1959 },
1960 {
Yonghong Song332270f2017-04-29 22:52:42 -07001961 "stack pointer arithmetic",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001962 .insns = {
Yonghong Song332270f2017-04-29 22:52:42 -07001963 BPF_MOV64_IMM(BPF_REG_1, 4),
1964 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1965 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
1967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
1968 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
1969 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
1970 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
1971 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
1972 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
1973 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001974 BPF_MOV64_IMM(BPF_REG_0, 0),
1975 BPF_EXIT_INSN(),
1976 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001977 .result = ACCEPT,
1978 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001979 {
1980 "raw_stack: no skb_load_bytes",
1981 .insns = {
1982 BPF_MOV64_IMM(BPF_REG_2, 4),
1983 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1984 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1985 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1986 BPF_MOV64_IMM(BPF_REG_4, 8),
1987 /* Call to skb_load_bytes() omitted. */
1988 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1989 BPF_EXIT_INSN(),
1990 },
1991 .result = REJECT,
1992 .errstr = "invalid read from stack off -8+0 size 8",
1993 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1994 },
1995 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001996 "raw_stack: skb_load_bytes, negative len",
1997 .insns = {
1998 BPF_MOV64_IMM(BPF_REG_2, 4),
1999 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2000 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2001 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2002 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002003 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2004 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002005 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2006 BPF_EXIT_INSN(),
2007 },
2008 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002009 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002010 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2011 },
2012 {
2013 "raw_stack: skb_load_bytes, negative len 2",
2014 .insns = {
2015 BPF_MOV64_IMM(BPF_REG_2, 4),
2016 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2017 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2018 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2019 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002020 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2021 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002022 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2023 BPF_EXIT_INSN(),
2024 },
2025 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002026 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002027 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2028 },
2029 {
2030 "raw_stack: skb_load_bytes, zero len",
2031 .insns = {
2032 BPF_MOV64_IMM(BPF_REG_2, 4),
2033 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2034 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2035 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2036 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002037 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2038 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002039 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2040 BPF_EXIT_INSN(),
2041 },
2042 .result = REJECT,
2043 .errstr = "invalid stack type R3",
2044 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2045 },
2046 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002047 "raw_stack: skb_load_bytes, no init",
2048 .insns = {
2049 BPF_MOV64_IMM(BPF_REG_2, 4),
2050 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2052 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2053 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002054 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2055 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002056 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2057 BPF_EXIT_INSN(),
2058 },
2059 .result = ACCEPT,
2060 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2061 },
2062 {
2063 "raw_stack: skb_load_bytes, init",
2064 .insns = {
2065 BPF_MOV64_IMM(BPF_REG_2, 4),
2066 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2067 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2068 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
2069 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2070 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002071 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2072 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002073 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2074 BPF_EXIT_INSN(),
2075 },
2076 .result = ACCEPT,
2077 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2078 },
2079 {
2080 "raw_stack: skb_load_bytes, spilled regs around bounds",
2081 .insns = {
2082 BPF_MOV64_IMM(BPF_REG_2, 4),
2083 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2084 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002085 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2086 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002087 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2088 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002089 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2090 BPF_FUNC_skb_load_bytes),
2091 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2092 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002093 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2094 offsetof(struct __sk_buff, mark)),
2095 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2096 offsetof(struct __sk_buff, priority)),
2097 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2098 BPF_EXIT_INSN(),
2099 },
2100 .result = ACCEPT,
2101 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2102 },
2103 {
2104 "raw_stack: skb_load_bytes, spilled regs corruption",
2105 .insns = {
2106 BPF_MOV64_IMM(BPF_REG_2, 4),
2107 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2108 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002109 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002110 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2111 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002112 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2113 BPF_FUNC_skb_load_bytes),
2114 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002115 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2116 offsetof(struct __sk_buff, mark)),
2117 BPF_EXIT_INSN(),
2118 },
2119 .result = REJECT,
2120 .errstr = "R0 invalid mem access 'inv'",
2121 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2122 },
2123 {
2124 "raw_stack: skb_load_bytes, spilled regs corruption 2",
2125 .insns = {
2126 BPF_MOV64_IMM(BPF_REG_2, 4),
2127 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2128 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002129 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2130 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2131 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002132 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2133 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002134 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2135 BPF_FUNC_skb_load_bytes),
2136 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2137 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2138 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002139 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2140 offsetof(struct __sk_buff, mark)),
2141 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2142 offsetof(struct __sk_buff, priority)),
2143 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2144 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
2145 offsetof(struct __sk_buff, pkt_type)),
2146 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2147 BPF_EXIT_INSN(),
2148 },
2149 .result = REJECT,
2150 .errstr = "R3 invalid mem access 'inv'",
2151 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2152 },
2153 {
2154 "raw_stack: skb_load_bytes, spilled regs + data",
2155 .insns = {
2156 BPF_MOV64_IMM(BPF_REG_2, 4),
2157 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2158 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002159 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2160 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2161 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002162 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2163 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002164 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2165 BPF_FUNC_skb_load_bytes),
2166 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2167 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2168 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002169 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2170 offsetof(struct __sk_buff, mark)),
2171 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2172 offsetof(struct __sk_buff, priority)),
2173 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2174 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2175 BPF_EXIT_INSN(),
2176 },
2177 .result = ACCEPT,
2178 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2179 },
2180 {
2181 "raw_stack: skb_load_bytes, invalid access 1",
2182 .insns = {
2183 BPF_MOV64_IMM(BPF_REG_2, 4),
2184 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2186 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2187 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2189 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002190 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2191 BPF_EXIT_INSN(),
2192 },
2193 .result = REJECT,
2194 .errstr = "invalid stack type R3 off=-513 access_size=8",
2195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2196 },
2197 {
2198 "raw_stack: skb_load_bytes, invalid access 2",
2199 .insns = {
2200 BPF_MOV64_IMM(BPF_REG_2, 4),
2201 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2203 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2204 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002205 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2206 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002207 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2208 BPF_EXIT_INSN(),
2209 },
2210 .result = REJECT,
2211 .errstr = "invalid stack type R3 off=-1 access_size=8",
2212 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2213 },
2214 {
2215 "raw_stack: skb_load_bytes, invalid access 3",
2216 .insns = {
2217 BPF_MOV64_IMM(BPF_REG_2, 4),
2218 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2219 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2220 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2221 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2223 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002224 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2225 BPF_EXIT_INSN(),
2226 },
2227 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002228 .errstr = "R4 min value is negative",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002229 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2230 },
2231 {
2232 "raw_stack: skb_load_bytes, invalid access 4",
2233 .insns = {
2234 BPF_MOV64_IMM(BPF_REG_2, 4),
2235 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2236 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2237 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2238 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002239 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2240 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002241 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2242 BPF_EXIT_INSN(),
2243 },
2244 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002245 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002246 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2247 },
2248 {
2249 "raw_stack: skb_load_bytes, invalid access 5",
2250 .insns = {
2251 BPF_MOV64_IMM(BPF_REG_2, 4),
2252 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2253 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2254 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2255 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002256 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2257 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002258 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2259 BPF_EXIT_INSN(),
2260 },
2261 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002262 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002263 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2264 },
2265 {
2266 "raw_stack: skb_load_bytes, invalid access 6",
2267 .insns = {
2268 BPF_MOV64_IMM(BPF_REG_2, 4),
2269 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2271 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2272 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002273 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2274 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002275 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2276 BPF_EXIT_INSN(),
2277 },
2278 .result = REJECT,
2279 .errstr = "invalid stack type R3 off=-512 access_size=0",
2280 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2281 },
2282 {
2283 "raw_stack: skb_load_bytes, large access",
2284 .insns = {
2285 BPF_MOV64_IMM(BPF_REG_2, 4),
2286 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2287 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2288 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2289 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002290 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2291 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002292 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2293 BPF_EXIT_INSN(),
2294 },
2295 .result = ACCEPT,
2296 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2297 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002298 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002299 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002300 .insns = {
2301 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2302 offsetof(struct __sk_buff, data)),
2303 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2304 offsetof(struct __sk_buff, data_end)),
2305 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2307 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2308 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2309 BPF_MOV64_IMM(BPF_REG_0, 0),
2310 BPF_EXIT_INSN(),
2311 },
2312 .result = ACCEPT,
2313 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2314 },
2315 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002316 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002317 .insns = {
2318 BPF_MOV64_IMM(BPF_REG_0, 1),
2319 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2320 offsetof(struct __sk_buff, data_end)),
2321 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2322 offsetof(struct __sk_buff, data)),
2323 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2324 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2325 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2326 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2327 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2328 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2329 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2330 offsetof(struct __sk_buff, data)),
2331 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
2332 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
Edward Cree1f9ab382017-08-07 15:29:11 +01002333 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
2334 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002335 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2336 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2337 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2338 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2339 offsetof(struct __sk_buff, data_end)),
2340 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2341 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2342 BPF_MOV64_IMM(BPF_REG_0, 0),
2343 BPF_EXIT_INSN(),
2344 },
2345 .result = ACCEPT,
2346 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2347 },
2348 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002349 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002350 .insns = {
2351 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2352 offsetof(struct __sk_buff, data)),
2353 BPF_MOV64_IMM(BPF_REG_0, 0),
2354 BPF_EXIT_INSN(),
2355 },
2356 .errstr = "invalid bpf_context access off=76",
2357 .result = REJECT,
2358 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2359 },
2360 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002361 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002362 .insns = {
2363 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2364 offsetof(struct __sk_buff, data)),
2365 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2366 offsetof(struct __sk_buff, data_end)),
2367 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2368 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2369 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2370 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2371 BPF_MOV64_IMM(BPF_REG_0, 0),
2372 BPF_EXIT_INSN(),
2373 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002374 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002375 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2376 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002377 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02002378 "direct packet access: test5 (pkt_end >= reg, good access)",
2379 .insns = {
2380 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2381 offsetof(struct __sk_buff, data)),
2382 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2383 offsetof(struct __sk_buff, data_end)),
2384 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2385 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2386 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2387 BPF_MOV64_IMM(BPF_REG_0, 1),
2388 BPF_EXIT_INSN(),
2389 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2390 BPF_MOV64_IMM(BPF_REG_0, 0),
2391 BPF_EXIT_INSN(),
2392 },
2393 .result = ACCEPT,
2394 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2395 },
2396 {
2397 "direct packet access: test6 (pkt_end >= reg, bad access)",
2398 .insns = {
2399 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2400 offsetof(struct __sk_buff, data)),
2401 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2402 offsetof(struct __sk_buff, data_end)),
2403 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2405 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2406 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2407 BPF_MOV64_IMM(BPF_REG_0, 1),
2408 BPF_EXIT_INSN(),
2409 BPF_MOV64_IMM(BPF_REG_0, 0),
2410 BPF_EXIT_INSN(),
2411 },
2412 .errstr = "invalid access to packet",
2413 .result = REJECT,
2414 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2415 },
2416 {
2417 "direct packet access: test7 (pkt_end >= reg, both accesses)",
2418 .insns = {
2419 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2420 offsetof(struct __sk_buff, data)),
2421 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2422 offsetof(struct __sk_buff, data_end)),
2423 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2425 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2426 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2427 BPF_MOV64_IMM(BPF_REG_0, 1),
2428 BPF_EXIT_INSN(),
2429 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2430 BPF_MOV64_IMM(BPF_REG_0, 0),
2431 BPF_EXIT_INSN(),
2432 },
2433 .errstr = "invalid access to packet",
2434 .result = REJECT,
2435 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2436 },
2437 {
2438 "direct packet access: test8 (double test, variant 1)",
2439 .insns = {
2440 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2441 offsetof(struct __sk_buff, data)),
2442 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2443 offsetof(struct __sk_buff, data_end)),
2444 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2445 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2446 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2447 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2448 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2449 BPF_MOV64_IMM(BPF_REG_0, 1),
2450 BPF_EXIT_INSN(),
2451 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2452 BPF_MOV64_IMM(BPF_REG_0, 0),
2453 BPF_EXIT_INSN(),
2454 },
2455 .result = ACCEPT,
2456 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2457 },
2458 {
2459 "direct packet access: test9 (double test, variant 2)",
2460 .insns = {
2461 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2462 offsetof(struct __sk_buff, data)),
2463 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2464 offsetof(struct __sk_buff, data_end)),
2465 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2466 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2467 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2468 BPF_MOV64_IMM(BPF_REG_0, 1),
2469 BPF_EXIT_INSN(),
2470 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2471 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2472 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2473 BPF_MOV64_IMM(BPF_REG_0, 0),
2474 BPF_EXIT_INSN(),
2475 },
2476 .result = ACCEPT,
2477 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2478 },
2479 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002480 "direct packet access: test10 (write invalid)",
2481 .insns = {
2482 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2483 offsetof(struct __sk_buff, data)),
2484 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2485 offsetof(struct __sk_buff, data_end)),
2486 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2487 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2488 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2489 BPF_MOV64_IMM(BPF_REG_0, 0),
2490 BPF_EXIT_INSN(),
2491 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2492 BPF_MOV64_IMM(BPF_REG_0, 0),
2493 BPF_EXIT_INSN(),
2494 },
2495 .errstr = "invalid access to packet",
2496 .result = REJECT,
2497 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2498 },
2499 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01002500 "direct packet access: test11 (shift, good access)",
2501 .insns = {
2502 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2503 offsetof(struct __sk_buff, data)),
2504 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2505 offsetof(struct __sk_buff, data_end)),
2506 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2507 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2508 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2509 BPF_MOV64_IMM(BPF_REG_3, 144),
2510 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2511 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2512 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2513 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2514 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2515 BPF_MOV64_IMM(BPF_REG_0, 1),
2516 BPF_EXIT_INSN(),
2517 BPF_MOV64_IMM(BPF_REG_0, 0),
2518 BPF_EXIT_INSN(),
2519 },
2520 .result = ACCEPT,
2521 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2522 },
2523 {
2524 "direct packet access: test12 (and, good access)",
2525 .insns = {
2526 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2527 offsetof(struct __sk_buff, data)),
2528 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2529 offsetof(struct __sk_buff, data_end)),
2530 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2531 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2532 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2533 BPF_MOV64_IMM(BPF_REG_3, 144),
2534 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2536 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2537 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2538 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2539 BPF_MOV64_IMM(BPF_REG_0, 1),
2540 BPF_EXIT_INSN(),
2541 BPF_MOV64_IMM(BPF_REG_0, 0),
2542 BPF_EXIT_INSN(),
2543 },
2544 .result = ACCEPT,
2545 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2546 },
2547 {
2548 "direct packet access: test13 (branches, good access)",
2549 .insns = {
2550 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2551 offsetof(struct __sk_buff, data)),
2552 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2553 offsetof(struct __sk_buff, data_end)),
2554 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2556 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2557 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2558 offsetof(struct __sk_buff, mark)),
2559 BPF_MOV64_IMM(BPF_REG_4, 1),
2560 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2561 BPF_MOV64_IMM(BPF_REG_3, 14),
2562 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2563 BPF_MOV64_IMM(BPF_REG_3, 24),
2564 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2566 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2567 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2568 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2569 BPF_MOV64_IMM(BPF_REG_0, 1),
2570 BPF_EXIT_INSN(),
2571 BPF_MOV64_IMM(BPF_REG_0, 0),
2572 BPF_EXIT_INSN(),
2573 },
2574 .result = ACCEPT,
2575 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2576 },
2577 {
William Tu63dfef72017-02-04 08:37:29 -08002578 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2579 .insns = {
2580 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2581 offsetof(struct __sk_buff, data)),
2582 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2583 offsetof(struct __sk_buff, data_end)),
2584 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2585 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2586 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2587 BPF_MOV64_IMM(BPF_REG_5, 12),
2588 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2589 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2590 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2591 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2592 BPF_MOV64_IMM(BPF_REG_0, 1),
2593 BPF_EXIT_INSN(),
2594 BPF_MOV64_IMM(BPF_REG_0, 0),
2595 BPF_EXIT_INSN(),
2596 },
2597 .result = ACCEPT,
2598 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2599 },
2600 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02002601 "direct packet access: test15 (spill with xadd)",
2602 .insns = {
2603 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2604 offsetof(struct __sk_buff, data)),
2605 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2606 offsetof(struct __sk_buff, data_end)),
2607 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2608 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2609 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2610 BPF_MOV64_IMM(BPF_REG_5, 4096),
2611 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2612 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2613 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2614 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
2615 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
2616 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
2617 BPF_MOV64_IMM(BPF_REG_0, 0),
2618 BPF_EXIT_INSN(),
2619 },
2620 .errstr = "R2 invalid mem access 'inv'",
2621 .result = REJECT,
2622 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2623 },
2624 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02002625 "direct packet access: test16 (arith on data_end)",
2626 .insns = {
2627 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2628 offsetof(struct __sk_buff, data)),
2629 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2630 offsetof(struct __sk_buff, data_end)),
2631 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2632 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2633 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
2634 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2635 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2636 BPF_MOV64_IMM(BPF_REG_0, 0),
2637 BPF_EXIT_INSN(),
2638 },
2639 .errstr = "invalid access to packet",
2640 .result = REJECT,
2641 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2642 },
2643 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02002644 "direct packet access: test17 (pruning, alignment)",
2645 .insns = {
2646 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2647 offsetof(struct __sk_buff, data)),
2648 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2649 offsetof(struct __sk_buff, data_end)),
2650 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2651 offsetof(struct __sk_buff, mark)),
2652 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2653 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
2654 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
2655 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2656 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
2657 BPF_MOV64_IMM(BPF_REG_0, 0),
2658 BPF_EXIT_INSN(),
2659 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
2660 BPF_JMP_A(-6),
2661 },
Edward Creef65b1842017-08-07 15:27:12 +01002662 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02002663 .result = REJECT,
2664 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2665 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
2666 },
2667 {
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002668 "direct packet access: test18 (imm += pkt_ptr, 1)",
2669 .insns = {
2670 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2671 offsetof(struct __sk_buff, data)),
2672 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2673 offsetof(struct __sk_buff, data_end)),
2674 BPF_MOV64_IMM(BPF_REG_0, 8),
2675 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2676 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2677 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2678 BPF_MOV64_IMM(BPF_REG_0, 0),
2679 BPF_EXIT_INSN(),
2680 },
2681 .result = ACCEPT,
2682 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2683 },
2684 {
2685 "direct packet access: test19 (imm += pkt_ptr, 2)",
2686 .insns = {
2687 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2688 offsetof(struct __sk_buff, data)),
2689 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2690 offsetof(struct __sk_buff, data_end)),
2691 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2692 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2693 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2694 BPF_MOV64_IMM(BPF_REG_4, 4),
2695 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
2696 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
2697 BPF_MOV64_IMM(BPF_REG_0, 0),
2698 BPF_EXIT_INSN(),
2699 },
2700 .result = ACCEPT,
2701 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2702 },
2703 {
2704 "direct packet access: test20 (x += pkt_ptr, 1)",
2705 .insns = {
2706 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2707 offsetof(struct __sk_buff, data)),
2708 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2709 offsetof(struct __sk_buff, data_end)),
2710 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
2711 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
2712 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01002713 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002714 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2715 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
2716 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01002717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002718 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
2719 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
2720 BPF_MOV64_IMM(BPF_REG_0, 0),
2721 BPF_EXIT_INSN(),
2722 },
2723 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2724 .result = ACCEPT,
2725 },
2726 {
2727 "direct packet access: test21 (x += pkt_ptr, 2)",
2728 .insns = {
2729 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2730 offsetof(struct __sk_buff, data)),
2731 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2732 offsetof(struct __sk_buff, data_end)),
2733 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2735 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
2736 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
2737 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
2738 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01002739 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002740 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
2741 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01002742 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002743 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
2744 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
2745 BPF_MOV64_IMM(BPF_REG_0, 0),
2746 BPF_EXIT_INSN(),
2747 },
2748 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2749 .result = ACCEPT,
2750 },
2751 {
2752 "direct packet access: test22 (x += pkt_ptr, 3)",
2753 .insns = {
2754 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2755 offsetof(struct __sk_buff, data)),
2756 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2757 offsetof(struct __sk_buff, data_end)),
2758 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2759 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2760 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
2761 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
2762 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
2763 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
2764 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
2765 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
2766 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
2767 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01002768 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002769 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
2770 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
2771 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
2772 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2773 BPF_MOV64_IMM(BPF_REG_2, 1),
2774 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
2775 BPF_MOV64_IMM(BPF_REG_0, 0),
2776 BPF_EXIT_INSN(),
2777 },
2778 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2779 .result = ACCEPT,
2780 },
2781 {
2782 "direct packet access: test23 (x += pkt_ptr, 4)",
2783 .insns = {
2784 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2785 offsetof(struct __sk_buff, data)),
2786 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2787 offsetof(struct __sk_buff, data_end)),
2788 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
2789 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
2790 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
2791 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
2792 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2793 BPF_MOV64_IMM(BPF_REG_0, 31),
2794 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
2795 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2796 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
2797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
2798 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2799 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
2800 BPF_MOV64_IMM(BPF_REG_0, 0),
2801 BPF_EXIT_INSN(),
2802 },
2803 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2804 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002805 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002806 },
2807 {
2808 "direct packet access: test24 (x += pkt_ptr, 5)",
2809 .insns = {
2810 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2811 offsetof(struct __sk_buff, data)),
2812 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2813 offsetof(struct __sk_buff, data_end)),
2814 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
2815 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
2816 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
2817 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
2818 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
2819 BPF_MOV64_IMM(BPF_REG_0, 64),
2820 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
2821 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2822 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
Edward Cree1f9ab382017-08-07 15:29:11 +01002823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02002824 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2825 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
2826 BPF_MOV64_IMM(BPF_REG_0, 0),
2827 BPF_EXIT_INSN(),
2828 },
2829 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2830 .result = ACCEPT,
2831 },
2832 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002833 "helper access to packet: test1, valid packet_ptr range",
2834 .insns = {
2835 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2836 offsetof(struct xdp_md, data)),
2837 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2838 offsetof(struct xdp_md, data_end)),
2839 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2840 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2841 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2842 BPF_LD_MAP_FD(BPF_REG_1, 0),
2843 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2844 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002845 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2846 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002847 BPF_MOV64_IMM(BPF_REG_0, 0),
2848 BPF_EXIT_INSN(),
2849 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002850 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002851 .result_unpriv = ACCEPT,
2852 .result = ACCEPT,
2853 .prog_type = BPF_PROG_TYPE_XDP,
2854 },
2855 {
2856 "helper access to packet: test2, unchecked packet_ptr",
2857 .insns = {
2858 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2859 offsetof(struct xdp_md, data)),
2860 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002861 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2862 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002863 BPF_MOV64_IMM(BPF_REG_0, 0),
2864 BPF_EXIT_INSN(),
2865 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002866 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002867 .result = REJECT,
2868 .errstr = "invalid access to packet",
2869 .prog_type = BPF_PROG_TYPE_XDP,
2870 },
2871 {
2872 "helper access to packet: test3, variable add",
2873 .insns = {
2874 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2875 offsetof(struct xdp_md, data)),
2876 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2877 offsetof(struct xdp_md, data_end)),
2878 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2879 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2880 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2881 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2882 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2883 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2884 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2885 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2886 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2887 BPF_LD_MAP_FD(BPF_REG_1, 0),
2888 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002889 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2890 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002891 BPF_MOV64_IMM(BPF_REG_0, 0),
2892 BPF_EXIT_INSN(),
2893 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002894 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002895 .result = ACCEPT,
2896 .prog_type = BPF_PROG_TYPE_XDP,
2897 },
2898 {
2899 "helper access to packet: test4, packet_ptr with bad range",
2900 .insns = {
2901 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2902 offsetof(struct xdp_md, data)),
2903 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2904 offsetof(struct xdp_md, data_end)),
2905 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2906 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2907 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2908 BPF_MOV64_IMM(BPF_REG_0, 0),
2909 BPF_EXIT_INSN(),
2910 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002911 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2912 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002913 BPF_MOV64_IMM(BPF_REG_0, 0),
2914 BPF_EXIT_INSN(),
2915 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002916 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002917 .result = REJECT,
2918 .errstr = "invalid access to packet",
2919 .prog_type = BPF_PROG_TYPE_XDP,
2920 },
2921 {
2922 "helper access to packet: test5, packet_ptr with too short range",
2923 .insns = {
2924 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2925 offsetof(struct xdp_md, data)),
2926 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2927 offsetof(struct xdp_md, data_end)),
2928 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2929 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2931 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2932 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002933 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2934 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002935 BPF_MOV64_IMM(BPF_REG_0, 0),
2936 BPF_EXIT_INSN(),
2937 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002938 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002939 .result = REJECT,
2940 .errstr = "invalid access to packet",
2941 .prog_type = BPF_PROG_TYPE_XDP,
2942 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002943 {
2944 "helper access to packet: test6, cls valid packet_ptr range",
2945 .insns = {
2946 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2947 offsetof(struct __sk_buff, data)),
2948 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2949 offsetof(struct __sk_buff, data_end)),
2950 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2951 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2952 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2953 BPF_LD_MAP_FD(BPF_REG_1, 0),
2954 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2955 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002956 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2957 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002958 BPF_MOV64_IMM(BPF_REG_0, 0),
2959 BPF_EXIT_INSN(),
2960 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002961 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002962 .result = ACCEPT,
2963 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2964 },
2965 {
2966 "helper access to packet: test7, cls unchecked packet_ptr",
2967 .insns = {
2968 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2969 offsetof(struct __sk_buff, data)),
2970 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002971 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2972 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002973 BPF_MOV64_IMM(BPF_REG_0, 0),
2974 BPF_EXIT_INSN(),
2975 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002976 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002977 .result = REJECT,
2978 .errstr = "invalid access to packet",
2979 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2980 },
2981 {
2982 "helper access to packet: test8, cls variable add",
2983 .insns = {
2984 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2985 offsetof(struct __sk_buff, data)),
2986 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2987 offsetof(struct __sk_buff, data_end)),
2988 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2989 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2990 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2991 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2992 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2993 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2994 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2995 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2996 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2997 BPF_LD_MAP_FD(BPF_REG_1, 0),
2998 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3000 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003001 BPF_MOV64_IMM(BPF_REG_0, 0),
3002 BPF_EXIT_INSN(),
3003 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003004 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003005 .result = ACCEPT,
3006 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3007 },
3008 {
3009 "helper access to packet: test9, cls packet_ptr with bad range",
3010 .insns = {
3011 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3012 offsetof(struct __sk_buff, data)),
3013 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3014 offsetof(struct __sk_buff, data_end)),
3015 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3016 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3017 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3018 BPF_MOV64_IMM(BPF_REG_0, 0),
3019 BPF_EXIT_INSN(),
3020 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3022 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003023 BPF_MOV64_IMM(BPF_REG_0, 0),
3024 BPF_EXIT_INSN(),
3025 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003026 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003027 .result = REJECT,
3028 .errstr = "invalid access to packet",
3029 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3030 },
3031 {
3032 "helper access to packet: test10, cls packet_ptr with too short range",
3033 .insns = {
3034 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3035 offsetof(struct __sk_buff, data)),
3036 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3037 offsetof(struct __sk_buff, data_end)),
3038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3039 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3040 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
3041 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
3042 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003043 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3044 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003045 BPF_MOV64_IMM(BPF_REG_0, 0),
3046 BPF_EXIT_INSN(),
3047 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003048 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003049 .result = REJECT,
3050 .errstr = "invalid access to packet",
3051 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3052 },
3053 {
3054 "helper access to packet: test11, cls unsuitable helper 1",
3055 .insns = {
3056 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3057 offsetof(struct __sk_buff, data)),
3058 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3059 offsetof(struct __sk_buff, data_end)),
3060 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3061 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3062 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
3063 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
3064 BPF_MOV64_IMM(BPF_REG_2, 0),
3065 BPF_MOV64_IMM(BPF_REG_4, 42),
3066 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003067 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3068 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003069 BPF_MOV64_IMM(BPF_REG_0, 0),
3070 BPF_EXIT_INSN(),
3071 },
3072 .result = REJECT,
3073 .errstr = "helper access to the packet",
3074 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3075 },
3076 {
3077 "helper access to packet: test12, cls unsuitable helper 2",
3078 .insns = {
3079 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3080 offsetof(struct __sk_buff, data)),
3081 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3082 offsetof(struct __sk_buff, data_end)),
3083 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3084 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
3085 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
3086 BPF_MOV64_IMM(BPF_REG_2, 0),
3087 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003088 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3089 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003090 BPF_MOV64_IMM(BPF_REG_0, 0),
3091 BPF_EXIT_INSN(),
3092 },
3093 .result = REJECT,
3094 .errstr = "helper access to the packet",
3095 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3096 },
3097 {
3098 "helper access to packet: test13, cls helper ok",
3099 .insns = {
3100 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3101 offsetof(struct __sk_buff, data)),
3102 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3103 offsetof(struct __sk_buff, data_end)),
3104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3105 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3106 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3107 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3108 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3109 BPF_MOV64_IMM(BPF_REG_2, 4),
3110 BPF_MOV64_IMM(BPF_REG_3, 0),
3111 BPF_MOV64_IMM(BPF_REG_4, 0),
3112 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003113 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3114 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003115 BPF_MOV64_IMM(BPF_REG_0, 0),
3116 BPF_EXIT_INSN(),
3117 },
3118 .result = ACCEPT,
3119 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3120 },
3121 {
Edward Creef65b1842017-08-07 15:27:12 +01003122 "helper access to packet: test14, cls helper ok sub",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003123 .insns = {
3124 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3125 offsetof(struct __sk_buff, data)),
3126 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3127 offsetof(struct __sk_buff, data_end)),
3128 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3129 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3131 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3132 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
3133 BPF_MOV64_IMM(BPF_REG_2, 4),
3134 BPF_MOV64_IMM(BPF_REG_3, 0),
3135 BPF_MOV64_IMM(BPF_REG_4, 0),
3136 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003137 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3138 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003139 BPF_MOV64_IMM(BPF_REG_0, 0),
3140 BPF_EXIT_INSN(),
3141 },
Edward Creef65b1842017-08-07 15:27:12 +01003142 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003143 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3144 },
3145 {
Edward Creef65b1842017-08-07 15:27:12 +01003146 "helper access to packet: test15, cls helper fail sub",
3147 .insns = {
3148 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3149 offsetof(struct __sk_buff, data)),
3150 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3151 offsetof(struct __sk_buff, data_end)),
3152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3153 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3155 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3156 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
3157 BPF_MOV64_IMM(BPF_REG_2, 4),
3158 BPF_MOV64_IMM(BPF_REG_3, 0),
3159 BPF_MOV64_IMM(BPF_REG_4, 0),
3160 BPF_MOV64_IMM(BPF_REG_5, 0),
3161 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3162 BPF_FUNC_csum_diff),
3163 BPF_MOV64_IMM(BPF_REG_0, 0),
3164 BPF_EXIT_INSN(),
3165 },
3166 .result = REJECT,
3167 .errstr = "invalid access to packet",
3168 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3169 },
3170 {
3171 "helper access to packet: test16, cls helper fail range 1",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003172 .insns = {
3173 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3174 offsetof(struct __sk_buff, data)),
3175 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3176 offsetof(struct __sk_buff, data_end)),
3177 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3178 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3179 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3180 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3181 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3182 BPF_MOV64_IMM(BPF_REG_2, 8),
3183 BPF_MOV64_IMM(BPF_REG_3, 0),
3184 BPF_MOV64_IMM(BPF_REG_4, 0),
3185 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003186 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3187 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003188 BPF_MOV64_IMM(BPF_REG_0, 0),
3189 BPF_EXIT_INSN(),
3190 },
3191 .result = REJECT,
3192 .errstr = "invalid access to packet",
3193 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3194 },
3195 {
Edward Creef65b1842017-08-07 15:27:12 +01003196 "helper access to packet: test17, cls helper fail range 2",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003197 .insns = {
3198 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3199 offsetof(struct __sk_buff, data)),
3200 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3201 offsetof(struct __sk_buff, data_end)),
3202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3203 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3205 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3206 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3207 BPF_MOV64_IMM(BPF_REG_2, -9),
3208 BPF_MOV64_IMM(BPF_REG_3, 0),
3209 BPF_MOV64_IMM(BPF_REG_4, 0),
3210 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003211 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3212 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003213 BPF_MOV64_IMM(BPF_REG_0, 0),
3214 BPF_EXIT_INSN(),
3215 },
3216 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003217 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003218 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3219 },
3220 {
Edward Creef65b1842017-08-07 15:27:12 +01003221 "helper access to packet: test18, cls helper fail range 3",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003222 .insns = {
3223 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3224 offsetof(struct __sk_buff, data)),
3225 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3226 offsetof(struct __sk_buff, data_end)),
3227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3228 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3230 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3231 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3232 BPF_MOV64_IMM(BPF_REG_2, ~0),
3233 BPF_MOV64_IMM(BPF_REG_3, 0),
3234 BPF_MOV64_IMM(BPF_REG_4, 0),
3235 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3237 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003238 BPF_MOV64_IMM(BPF_REG_0, 0),
3239 BPF_EXIT_INSN(),
3240 },
3241 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003242 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003243 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3244 },
3245 {
Edward Creef65b1842017-08-07 15:27:12 +01003246 "helper access to packet: test19, cls helper fail range zero",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003247 .insns = {
3248 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3249 offsetof(struct __sk_buff, data)),
3250 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3251 offsetof(struct __sk_buff, data_end)),
3252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3253 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3255 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3256 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3257 BPF_MOV64_IMM(BPF_REG_2, 0),
3258 BPF_MOV64_IMM(BPF_REG_3, 0),
3259 BPF_MOV64_IMM(BPF_REG_4, 0),
3260 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3262 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003263 BPF_MOV64_IMM(BPF_REG_0, 0),
3264 BPF_EXIT_INSN(),
3265 },
3266 .result = REJECT,
3267 .errstr = "invalid access to packet",
3268 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3269 },
3270 {
Edward Creef65b1842017-08-07 15:27:12 +01003271 "helper access to packet: test20, pkt end as input",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003272 .insns = {
3273 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3274 offsetof(struct __sk_buff, data)),
3275 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3276 offsetof(struct __sk_buff, data_end)),
3277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3278 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3280 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3281 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
3282 BPF_MOV64_IMM(BPF_REG_2, 4),
3283 BPF_MOV64_IMM(BPF_REG_3, 0),
3284 BPF_MOV64_IMM(BPF_REG_4, 0),
3285 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003286 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3287 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003288 BPF_MOV64_IMM(BPF_REG_0, 0),
3289 BPF_EXIT_INSN(),
3290 },
3291 .result = REJECT,
3292 .errstr = "R1 type=pkt_end expected=fp",
3293 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3294 },
3295 {
Edward Creef65b1842017-08-07 15:27:12 +01003296 "helper access to packet: test21, wrong reg",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003297 .insns = {
3298 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
3299 offsetof(struct __sk_buff, data)),
3300 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3301 offsetof(struct __sk_buff, data_end)),
3302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
3303 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
3304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
3305 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
3306 BPF_MOV64_IMM(BPF_REG_2, 4),
3307 BPF_MOV64_IMM(BPF_REG_3, 0),
3308 BPF_MOV64_IMM(BPF_REG_4, 0),
3309 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003310 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3311 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003312 BPF_MOV64_IMM(BPF_REG_0, 0),
3313 BPF_EXIT_INSN(),
3314 },
3315 .result = REJECT,
3316 .errstr = "invalid access to packet",
3317 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3318 },
Josef Bacik48461132016-09-28 10:54:32 -04003319 {
3320 "valid map access into an array with a constant",
3321 .insns = {
3322 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3323 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3324 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3325 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003326 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3327 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003328 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003329 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3330 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003331 BPF_EXIT_INSN(),
3332 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003333 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003334 .errstr_unpriv = "R0 leaks addr",
3335 .result_unpriv = REJECT,
3336 .result = ACCEPT,
3337 },
3338 {
3339 "valid map access into an array with a register",
3340 .insns = {
3341 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3342 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3344 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003345 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3346 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003347 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3348 BPF_MOV64_IMM(BPF_REG_1, 4),
3349 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3350 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003351 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3352 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003353 BPF_EXIT_INSN(),
3354 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003355 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003356 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003357 .result_unpriv = REJECT,
3358 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003359 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003360 },
3361 {
3362 "valid map access into an array with a variable",
3363 .insns = {
3364 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3365 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3367 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003368 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3369 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003370 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3371 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3372 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
3373 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3374 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003375 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3376 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003377 BPF_EXIT_INSN(),
3378 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003379 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003380 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003381 .result_unpriv = REJECT,
3382 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003383 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003384 },
3385 {
3386 "valid map access into an array with a signed variable",
3387 .insns = {
3388 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3389 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3391 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003392 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3393 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003394 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
3395 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3396 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
3397 BPF_MOV32_IMM(BPF_REG_1, 0),
3398 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3399 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3400 BPF_MOV32_IMM(BPF_REG_1, 0),
3401 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3402 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003403 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3404 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003405 BPF_EXIT_INSN(),
3406 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003407 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003408 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003409 .result_unpriv = REJECT,
3410 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003411 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003412 },
3413 {
3414 "invalid map access into an array with a constant",
3415 .insns = {
3416 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3417 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3418 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3419 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003420 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3421 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003422 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3423 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
3424 offsetof(struct test_val, foo)),
3425 BPF_EXIT_INSN(),
3426 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003427 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003428 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
3429 .result = REJECT,
3430 },
3431 {
3432 "invalid map access into an array with a register",
3433 .insns = {
3434 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3435 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3437 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3439 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003440 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3441 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3442 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3443 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003444 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3445 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003446 BPF_EXIT_INSN(),
3447 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003448 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003449 .errstr = "R0 min value is outside of the array range",
3450 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003451 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003452 },
3453 {
3454 "invalid map access into an array with a variable",
3455 .insns = {
3456 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3457 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3458 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3459 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003460 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3461 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003462 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3463 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3464 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3465 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003466 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3467 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003468 BPF_EXIT_INSN(),
3469 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003470 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003471 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
Josef Bacik48461132016-09-28 10:54:32 -04003472 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003473 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003474 },
3475 {
3476 "invalid map access into an array with no floor check",
3477 .insns = {
3478 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3479 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3481 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003482 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3483 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003484 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
Edward Creef65b1842017-08-07 15:27:12 +01003485 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik48461132016-09-28 10:54:32 -04003486 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3487 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3488 BPF_MOV32_IMM(BPF_REG_1, 0),
3489 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3490 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003491 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3492 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003493 BPF_EXIT_INSN(),
3494 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003495 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003496 .errstr_unpriv = "R0 leaks addr",
3497 .errstr = "R0 unbounded memory access",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003498 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003499 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003500 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003501 },
3502 {
3503 "invalid map access into an array with a invalid max check",
3504 .insns = {
3505 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3506 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3507 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3508 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3510 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003511 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3512 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3513 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3514 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3515 BPF_MOV32_IMM(BPF_REG_1, 0),
3516 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3517 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003518 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3519 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003520 BPF_EXIT_INSN(),
3521 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003522 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003523 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04003524 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003525 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003526 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003527 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003528 },
3529 {
3530 "invalid map access into an array with a invalid max check",
3531 .insns = {
3532 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3535 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3537 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003538 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3539 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3540 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3541 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3542 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3543 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003544 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3545 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003546 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3547 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003548 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3549 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003550 BPF_EXIT_INSN(),
3551 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003552 .fixup_map2 = { 3, 11 },
Edward Creef65b1842017-08-07 15:27:12 +01003553 .errstr_unpriv = "R0 pointer += pointer",
3554 .errstr = "R0 invalid mem access 'inv'",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003555 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003556 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003557 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003558 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02003559 {
3560 "multiple registers share map_lookup_elem result",
3561 .insns = {
3562 BPF_MOV64_IMM(BPF_REG_1, 10),
3563 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3564 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3566 BPF_LD_MAP_FD(BPF_REG_1, 0),
3567 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3568 BPF_FUNC_map_lookup_elem),
3569 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3570 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3571 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3572 BPF_EXIT_INSN(),
3573 },
3574 .fixup_map1 = { 4 },
3575 .result = ACCEPT,
3576 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3577 },
3578 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003579 "alu ops on ptr_to_map_value_or_null, 1",
3580 .insns = {
3581 BPF_MOV64_IMM(BPF_REG_1, 10),
3582 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3583 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3584 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3585 BPF_LD_MAP_FD(BPF_REG_1, 0),
3586 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3587 BPF_FUNC_map_lookup_elem),
3588 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
3590 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
3591 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3592 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3593 BPF_EXIT_INSN(),
3594 },
3595 .fixup_map1 = { 4 },
3596 .errstr = "R4 invalid mem access",
3597 .result = REJECT,
3598 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3599 },
3600 {
3601 "alu ops on ptr_to_map_value_or_null, 2",
3602 .insns = {
3603 BPF_MOV64_IMM(BPF_REG_1, 10),
3604 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3605 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3606 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3607 BPF_LD_MAP_FD(BPF_REG_1, 0),
3608 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3609 BPF_FUNC_map_lookup_elem),
3610 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3611 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
3612 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3613 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3614 BPF_EXIT_INSN(),
3615 },
3616 .fixup_map1 = { 4 },
3617 .errstr = "R4 invalid mem access",
3618 .result = REJECT,
3619 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3620 },
3621 {
3622 "alu ops on ptr_to_map_value_or_null, 3",
3623 .insns = {
3624 BPF_MOV64_IMM(BPF_REG_1, 10),
3625 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3626 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3627 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3628 BPF_LD_MAP_FD(BPF_REG_1, 0),
3629 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3630 BPF_FUNC_map_lookup_elem),
3631 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3632 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
3633 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3634 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3635 BPF_EXIT_INSN(),
3636 },
3637 .fixup_map1 = { 4 },
3638 .errstr = "R4 invalid mem access",
3639 .result = REJECT,
3640 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3641 },
3642 {
Thomas Graf57a09bf2016-10-18 19:51:19 +02003643 "invalid memory access with multiple map_lookup_elem calls",
3644 .insns = {
3645 BPF_MOV64_IMM(BPF_REG_1, 10),
3646 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3649 BPF_LD_MAP_FD(BPF_REG_1, 0),
3650 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3651 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3652 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3653 BPF_FUNC_map_lookup_elem),
3654 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3655 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3656 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3657 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3658 BPF_FUNC_map_lookup_elem),
3659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3660 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3661 BPF_EXIT_INSN(),
3662 },
3663 .fixup_map1 = { 4 },
3664 .result = REJECT,
3665 .errstr = "R4 !read_ok",
3666 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3667 },
3668 {
3669 "valid indirect map_lookup_elem access with 2nd lookup in branch",
3670 .insns = {
3671 BPF_MOV64_IMM(BPF_REG_1, 10),
3672 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3673 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3675 BPF_LD_MAP_FD(BPF_REG_1, 0),
3676 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3677 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3679 BPF_FUNC_map_lookup_elem),
3680 BPF_MOV64_IMM(BPF_REG_2, 10),
3681 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
3682 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3683 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3684 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3685 BPF_FUNC_map_lookup_elem),
3686 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3687 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3688 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3689 BPF_EXIT_INSN(),
3690 },
3691 .fixup_map1 = { 4 },
3692 .result = ACCEPT,
3693 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3694 },
Josef Bacike9548902016-11-29 12:35:19 -05003695 {
3696 "invalid map access from else condition",
3697 .insns = {
3698 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3699 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3700 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3701 BPF_LD_MAP_FD(BPF_REG_1, 0),
3702 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
3703 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3704 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3705 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
3706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
3707 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3708 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3709 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
3710 BPF_EXIT_INSN(),
3711 },
3712 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01003713 .errstr = "R0 unbounded memory access",
Josef Bacike9548902016-11-29 12:35:19 -05003714 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003715 .errstr_unpriv = "R0 leaks addr",
Josef Bacike9548902016-11-29 12:35:19 -05003716 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003717 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacike9548902016-11-29 12:35:19 -05003718 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08003719 {
3720 "constant register |= constant should keep constant type",
3721 .insns = {
3722 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3723 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3724 BPF_MOV64_IMM(BPF_REG_2, 34),
3725 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
3726 BPF_MOV64_IMM(BPF_REG_3, 0),
3727 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3728 BPF_EXIT_INSN(),
3729 },
3730 .result = ACCEPT,
3731 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3732 },
3733 {
3734 "constant register |= constant should not bypass stack boundary checks",
3735 .insns = {
3736 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3738 BPF_MOV64_IMM(BPF_REG_2, 34),
3739 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
3740 BPF_MOV64_IMM(BPF_REG_3, 0),
3741 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3742 BPF_EXIT_INSN(),
3743 },
3744 .errstr = "invalid stack type R1 off=-48 access_size=58",
3745 .result = REJECT,
3746 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3747 },
3748 {
3749 "constant register |= constant register should keep constant type",
3750 .insns = {
3751 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3752 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3753 BPF_MOV64_IMM(BPF_REG_2, 34),
3754 BPF_MOV64_IMM(BPF_REG_4, 13),
3755 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3756 BPF_MOV64_IMM(BPF_REG_3, 0),
3757 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3758 BPF_EXIT_INSN(),
3759 },
3760 .result = ACCEPT,
3761 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3762 },
3763 {
3764 "constant register |= constant register should not bypass stack boundary checks",
3765 .insns = {
3766 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3767 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3768 BPF_MOV64_IMM(BPF_REG_2, 34),
3769 BPF_MOV64_IMM(BPF_REG_4, 24),
3770 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3771 BPF_MOV64_IMM(BPF_REG_3, 0),
3772 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3773 BPF_EXIT_INSN(),
3774 },
3775 .errstr = "invalid stack type R1 off=-48 access_size=58",
3776 .result = REJECT,
3777 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3778 },
Thomas Graf3f731d82016-12-05 10:30:52 +01003779 {
3780 "invalid direct packet write for LWT_IN",
3781 .insns = {
3782 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3783 offsetof(struct __sk_buff, data)),
3784 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3785 offsetof(struct __sk_buff, data_end)),
3786 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3788 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3789 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3790 BPF_MOV64_IMM(BPF_REG_0, 0),
3791 BPF_EXIT_INSN(),
3792 },
3793 .errstr = "cannot write into packet",
3794 .result = REJECT,
3795 .prog_type = BPF_PROG_TYPE_LWT_IN,
3796 },
3797 {
3798 "invalid direct packet write for LWT_OUT",
3799 .insns = {
3800 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3801 offsetof(struct __sk_buff, data)),
3802 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3803 offsetof(struct __sk_buff, data_end)),
3804 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3805 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3806 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3807 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3808 BPF_MOV64_IMM(BPF_REG_0, 0),
3809 BPF_EXIT_INSN(),
3810 },
3811 .errstr = "cannot write into packet",
3812 .result = REJECT,
3813 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3814 },
3815 {
3816 "direct packet write for LWT_XMIT",
3817 .insns = {
3818 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3819 offsetof(struct __sk_buff, data)),
3820 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3821 offsetof(struct __sk_buff, data_end)),
3822 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3824 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3825 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3826 BPF_MOV64_IMM(BPF_REG_0, 0),
3827 BPF_EXIT_INSN(),
3828 },
3829 .result = ACCEPT,
3830 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3831 },
3832 {
3833 "direct packet read for LWT_IN",
3834 .insns = {
3835 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3836 offsetof(struct __sk_buff, data)),
3837 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3838 offsetof(struct __sk_buff, data_end)),
3839 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3840 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3841 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3842 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3843 BPF_MOV64_IMM(BPF_REG_0, 0),
3844 BPF_EXIT_INSN(),
3845 },
3846 .result = ACCEPT,
3847 .prog_type = BPF_PROG_TYPE_LWT_IN,
3848 },
3849 {
3850 "direct packet read for LWT_OUT",
3851 .insns = {
3852 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3853 offsetof(struct __sk_buff, data)),
3854 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3855 offsetof(struct __sk_buff, data_end)),
3856 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3857 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3858 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3859 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3860 BPF_MOV64_IMM(BPF_REG_0, 0),
3861 BPF_EXIT_INSN(),
3862 },
3863 .result = ACCEPT,
3864 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3865 },
3866 {
3867 "direct packet read for LWT_XMIT",
3868 .insns = {
3869 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3870 offsetof(struct __sk_buff, data)),
3871 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3872 offsetof(struct __sk_buff, data_end)),
3873 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3874 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3875 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3876 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3877 BPF_MOV64_IMM(BPF_REG_0, 0),
3878 BPF_EXIT_INSN(),
3879 },
3880 .result = ACCEPT,
3881 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3882 },
3883 {
Alexei Starovoitovb1977682017-03-24 15:57:33 -07003884 "overlapping checks for direct packet access",
3885 .insns = {
3886 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3887 offsetof(struct __sk_buff, data)),
3888 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3889 offsetof(struct __sk_buff, data_end)),
3890 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3891 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3892 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
3893 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3894 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
3895 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
3896 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
3897 BPF_MOV64_IMM(BPF_REG_0, 0),
3898 BPF_EXIT_INSN(),
3899 },
3900 .result = ACCEPT,
3901 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3902 },
3903 {
Thomas Graf3f731d82016-12-05 10:30:52 +01003904 "invalid access of tc_classid for LWT_IN",
3905 .insns = {
3906 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3907 offsetof(struct __sk_buff, tc_classid)),
3908 BPF_EXIT_INSN(),
3909 },
3910 .result = REJECT,
3911 .errstr = "invalid bpf_context access",
3912 },
3913 {
3914 "invalid access of tc_classid for LWT_OUT",
3915 .insns = {
3916 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3917 offsetof(struct __sk_buff, tc_classid)),
3918 BPF_EXIT_INSN(),
3919 },
3920 .result = REJECT,
3921 .errstr = "invalid bpf_context access",
3922 },
3923 {
3924 "invalid access of tc_classid for LWT_XMIT",
3925 .insns = {
3926 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3927 offsetof(struct __sk_buff, tc_classid)),
3928 BPF_EXIT_INSN(),
3929 },
3930 .result = REJECT,
3931 .errstr = "invalid bpf_context access",
3932 },
Gianluca Borello57225692017-01-09 10:19:47 -08003933 {
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02003934 "leak pointer into ctx 1",
3935 .insns = {
3936 BPF_MOV64_IMM(BPF_REG_0, 0),
3937 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
3938 offsetof(struct __sk_buff, cb[0])),
3939 BPF_LD_MAP_FD(BPF_REG_2, 0),
3940 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
3941 offsetof(struct __sk_buff, cb[0])),
3942 BPF_EXIT_INSN(),
3943 },
3944 .fixup_map1 = { 2 },
3945 .errstr_unpriv = "R2 leaks addr into mem",
3946 .result_unpriv = REJECT,
3947 .result = ACCEPT,
3948 },
3949 {
3950 "leak pointer into ctx 2",
3951 .insns = {
3952 BPF_MOV64_IMM(BPF_REG_0, 0),
3953 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
3954 offsetof(struct __sk_buff, cb[0])),
3955 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
3956 offsetof(struct __sk_buff, cb[0])),
3957 BPF_EXIT_INSN(),
3958 },
3959 .errstr_unpriv = "R10 leaks addr into mem",
3960 .result_unpriv = REJECT,
3961 .result = ACCEPT,
3962 },
3963 {
3964 "leak pointer into ctx 3",
3965 .insns = {
3966 BPF_MOV64_IMM(BPF_REG_0, 0),
3967 BPF_LD_MAP_FD(BPF_REG_2, 0),
3968 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
3969 offsetof(struct __sk_buff, cb[0])),
3970 BPF_EXIT_INSN(),
3971 },
3972 .fixup_map1 = { 1 },
3973 .errstr_unpriv = "R2 leaks addr into ctx",
3974 .result_unpriv = REJECT,
3975 .result = ACCEPT,
3976 },
3977 {
3978 "leak pointer into map val",
3979 .insns = {
3980 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
3981 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3982 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3983 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3984 BPF_LD_MAP_FD(BPF_REG_1, 0),
3985 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3986 BPF_FUNC_map_lookup_elem),
3987 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
3988 BPF_MOV64_IMM(BPF_REG_3, 0),
3989 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
3990 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3991 BPF_MOV64_IMM(BPF_REG_0, 0),
3992 BPF_EXIT_INSN(),
3993 },
3994 .fixup_map1 = { 4 },
3995 .errstr_unpriv = "R6 leaks addr into mem",
3996 .result_unpriv = REJECT,
3997 .result = ACCEPT,
3998 },
3999 {
Gianluca Borello57225692017-01-09 10:19:47 -08004000 "helper access to map: full range",
4001 .insns = {
4002 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4003 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4004 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4005 BPF_LD_MAP_FD(BPF_REG_1, 0),
4006 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4007 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4008 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4009 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4010 BPF_MOV64_IMM(BPF_REG_3, 0),
4011 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4012 BPF_EXIT_INSN(),
4013 },
4014 .fixup_map2 = { 3 },
4015 .result = ACCEPT,
4016 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4017 },
4018 {
4019 "helper access to map: partial range",
4020 .insns = {
4021 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4022 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4023 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4024 BPF_LD_MAP_FD(BPF_REG_1, 0),
4025 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4026 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4027 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4028 BPF_MOV64_IMM(BPF_REG_2, 8),
4029 BPF_MOV64_IMM(BPF_REG_3, 0),
4030 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4031 BPF_EXIT_INSN(),
4032 },
4033 .fixup_map2 = { 3 },
4034 .result = ACCEPT,
4035 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4036 },
4037 {
4038 "helper access to map: empty range",
4039 .insns = {
4040 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4042 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4043 BPF_LD_MAP_FD(BPF_REG_1, 0),
4044 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4045 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4046 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4047 BPF_MOV64_IMM(BPF_REG_2, 0),
4048 BPF_MOV64_IMM(BPF_REG_3, 0),
4049 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4050 BPF_EXIT_INSN(),
4051 },
4052 .fixup_map2 = { 3 },
4053 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
4054 .result = REJECT,
4055 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4056 },
4057 {
4058 "helper access to map: out-of-bound range",
4059 .insns = {
4060 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4061 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4062 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4063 BPF_LD_MAP_FD(BPF_REG_1, 0),
4064 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4065 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4066 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4067 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
4068 BPF_MOV64_IMM(BPF_REG_3, 0),
4069 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4070 BPF_EXIT_INSN(),
4071 },
4072 .fixup_map2 = { 3 },
4073 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
4074 .result = REJECT,
4075 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4076 },
4077 {
4078 "helper access to map: negative range",
4079 .insns = {
4080 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4082 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4083 BPF_LD_MAP_FD(BPF_REG_1, 0),
4084 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4085 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4086 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4087 BPF_MOV64_IMM(BPF_REG_2, -8),
4088 BPF_MOV64_IMM(BPF_REG_3, 0),
4089 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4090 BPF_EXIT_INSN(),
4091 },
4092 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004093 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004094 .result = REJECT,
4095 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4096 },
4097 {
4098 "helper access to adjusted map (via const imm): full range",
4099 .insns = {
4100 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4101 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4102 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4103 BPF_LD_MAP_FD(BPF_REG_1, 0),
4104 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4105 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4106 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4107 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4108 offsetof(struct test_val, foo)),
4109 BPF_MOV64_IMM(BPF_REG_2,
4110 sizeof(struct test_val) -
4111 offsetof(struct test_val, foo)),
4112 BPF_MOV64_IMM(BPF_REG_3, 0),
4113 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4114 BPF_EXIT_INSN(),
4115 },
4116 .fixup_map2 = { 3 },
4117 .result = ACCEPT,
4118 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4119 },
4120 {
4121 "helper access to adjusted map (via const imm): partial range",
4122 .insns = {
4123 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4124 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4125 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4126 BPF_LD_MAP_FD(BPF_REG_1, 0),
4127 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4128 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4129 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4131 offsetof(struct test_val, foo)),
4132 BPF_MOV64_IMM(BPF_REG_2, 8),
4133 BPF_MOV64_IMM(BPF_REG_3, 0),
4134 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4135 BPF_EXIT_INSN(),
4136 },
4137 .fixup_map2 = { 3 },
4138 .result = ACCEPT,
4139 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4140 },
4141 {
4142 "helper access to adjusted map (via const imm): empty range",
4143 .insns = {
4144 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4145 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4146 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4147 BPF_LD_MAP_FD(BPF_REG_1, 0),
4148 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4149 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4150 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4151 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4152 offsetof(struct test_val, foo)),
4153 BPF_MOV64_IMM(BPF_REG_2, 0),
4154 BPF_MOV64_IMM(BPF_REG_3, 0),
4155 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4156 BPF_EXIT_INSN(),
4157 },
4158 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004159 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
Gianluca Borello57225692017-01-09 10:19:47 -08004160 .result = REJECT,
4161 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4162 },
4163 {
4164 "helper access to adjusted map (via const imm): out-of-bound range",
4165 .insns = {
4166 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4167 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4168 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4169 BPF_LD_MAP_FD(BPF_REG_1, 0),
4170 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4171 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4172 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4174 offsetof(struct test_val, foo)),
4175 BPF_MOV64_IMM(BPF_REG_2,
4176 sizeof(struct test_val) -
4177 offsetof(struct test_val, foo) + 8),
4178 BPF_MOV64_IMM(BPF_REG_3, 0),
4179 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4180 BPF_EXIT_INSN(),
4181 },
4182 .fixup_map2 = { 3 },
4183 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4184 .result = REJECT,
4185 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4186 },
4187 {
4188 "helper access to adjusted map (via const imm): negative range (> adjustment)",
4189 .insns = {
4190 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4191 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4192 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4193 BPF_LD_MAP_FD(BPF_REG_1, 0),
4194 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4195 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4196 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4198 offsetof(struct test_val, foo)),
4199 BPF_MOV64_IMM(BPF_REG_2, -8),
4200 BPF_MOV64_IMM(BPF_REG_3, 0),
4201 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4202 BPF_EXIT_INSN(),
4203 },
4204 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004205 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004206 .result = REJECT,
4207 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4208 },
4209 {
4210 "helper access to adjusted map (via const imm): negative range (< adjustment)",
4211 .insns = {
4212 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4213 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4214 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4215 BPF_LD_MAP_FD(BPF_REG_1, 0),
4216 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4217 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4218 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4219 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
4220 offsetof(struct test_val, foo)),
4221 BPF_MOV64_IMM(BPF_REG_2, -1),
4222 BPF_MOV64_IMM(BPF_REG_3, 0),
4223 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4224 BPF_EXIT_INSN(),
4225 },
4226 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004227 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004228 .result = REJECT,
4229 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4230 },
4231 {
4232 "helper access to adjusted map (via const reg): full range",
4233 .insns = {
4234 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4235 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4236 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4237 BPF_LD_MAP_FD(BPF_REG_1, 0),
4238 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4239 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4240 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4241 BPF_MOV64_IMM(BPF_REG_3,
4242 offsetof(struct test_val, foo)),
4243 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4244 BPF_MOV64_IMM(BPF_REG_2,
4245 sizeof(struct test_val) -
4246 offsetof(struct test_val, foo)),
4247 BPF_MOV64_IMM(BPF_REG_3, 0),
4248 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4249 BPF_EXIT_INSN(),
4250 },
4251 .fixup_map2 = { 3 },
4252 .result = ACCEPT,
4253 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4254 },
4255 {
4256 "helper access to adjusted map (via const reg): partial range",
4257 .insns = {
4258 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4260 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4261 BPF_LD_MAP_FD(BPF_REG_1, 0),
4262 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4265 BPF_MOV64_IMM(BPF_REG_3,
4266 offsetof(struct test_val, foo)),
4267 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4268 BPF_MOV64_IMM(BPF_REG_2, 8),
4269 BPF_MOV64_IMM(BPF_REG_3, 0),
4270 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4271 BPF_EXIT_INSN(),
4272 },
4273 .fixup_map2 = { 3 },
4274 .result = ACCEPT,
4275 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4276 },
4277 {
4278 "helper access to adjusted map (via const reg): empty range",
4279 .insns = {
4280 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4282 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4283 BPF_LD_MAP_FD(BPF_REG_1, 0),
4284 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4285 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4286 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4287 BPF_MOV64_IMM(BPF_REG_3, 0),
4288 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4289 BPF_MOV64_IMM(BPF_REG_2, 0),
4290 BPF_MOV64_IMM(BPF_REG_3, 0),
4291 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4292 BPF_EXIT_INSN(),
4293 },
4294 .fixup_map2 = { 3 },
4295 .errstr = "R1 min value is outside of the array range",
4296 .result = REJECT,
4297 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4298 },
4299 {
4300 "helper access to adjusted map (via const reg): out-of-bound range",
4301 .insns = {
4302 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4304 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4305 BPF_LD_MAP_FD(BPF_REG_1, 0),
4306 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4307 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4308 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4309 BPF_MOV64_IMM(BPF_REG_3,
4310 offsetof(struct test_val, foo)),
4311 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4312 BPF_MOV64_IMM(BPF_REG_2,
4313 sizeof(struct test_val) -
4314 offsetof(struct test_val, foo) + 8),
4315 BPF_MOV64_IMM(BPF_REG_3, 0),
4316 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4317 BPF_EXIT_INSN(),
4318 },
4319 .fixup_map2 = { 3 },
4320 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
4321 .result = REJECT,
4322 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4323 },
4324 {
4325 "helper access to adjusted map (via const reg): negative range (> adjustment)",
4326 .insns = {
4327 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4328 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4329 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4330 BPF_LD_MAP_FD(BPF_REG_1, 0),
4331 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4332 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4333 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4334 BPF_MOV64_IMM(BPF_REG_3,
4335 offsetof(struct test_val, foo)),
4336 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4337 BPF_MOV64_IMM(BPF_REG_2, -8),
4338 BPF_MOV64_IMM(BPF_REG_3, 0),
4339 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4340 BPF_EXIT_INSN(),
4341 },
4342 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004343 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004344 .result = REJECT,
4345 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4346 },
4347 {
4348 "helper access to adjusted map (via const reg): negative range (< adjustment)",
4349 .insns = {
4350 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4351 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4352 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4353 BPF_LD_MAP_FD(BPF_REG_1, 0),
4354 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4355 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4356 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4357 BPF_MOV64_IMM(BPF_REG_3,
4358 offsetof(struct test_val, foo)),
4359 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4360 BPF_MOV64_IMM(BPF_REG_2, -1),
4361 BPF_MOV64_IMM(BPF_REG_3, 0),
4362 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4363 BPF_EXIT_INSN(),
4364 },
4365 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004366 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08004367 .result = REJECT,
4368 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4369 },
4370 {
4371 "helper access to adjusted map (via variable): full range",
4372 .insns = {
4373 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4374 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4375 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4376 BPF_LD_MAP_FD(BPF_REG_1, 0),
4377 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4378 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4380 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4381 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4382 offsetof(struct test_val, foo), 4),
4383 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4384 BPF_MOV64_IMM(BPF_REG_2,
4385 sizeof(struct test_val) -
4386 offsetof(struct test_val, foo)),
4387 BPF_MOV64_IMM(BPF_REG_3, 0),
4388 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4389 BPF_EXIT_INSN(),
4390 },
4391 .fixup_map2 = { 3 },
4392 .result = ACCEPT,
4393 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4394 },
4395 {
4396 "helper access to adjusted map (via variable): partial range",
4397 .insns = {
4398 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4400 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4401 BPF_LD_MAP_FD(BPF_REG_1, 0),
4402 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4403 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4404 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4405 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4406 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4407 offsetof(struct test_val, foo), 4),
4408 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4409 BPF_MOV64_IMM(BPF_REG_2, 8),
4410 BPF_MOV64_IMM(BPF_REG_3, 0),
4411 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4412 BPF_EXIT_INSN(),
4413 },
4414 .fixup_map2 = { 3 },
4415 .result = ACCEPT,
4416 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4417 },
4418 {
4419 "helper access to adjusted map (via variable): empty range",
4420 .insns = {
4421 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4423 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4424 BPF_LD_MAP_FD(BPF_REG_1, 0),
4425 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4426 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4427 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4428 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4429 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4430 offsetof(struct test_val, foo), 4),
4431 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4432 BPF_MOV64_IMM(BPF_REG_2, 0),
4433 BPF_MOV64_IMM(BPF_REG_3, 0),
4434 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4435 BPF_EXIT_INSN(),
4436 },
4437 .fixup_map2 = { 3 },
4438 .errstr = "R1 min value is outside of the array range",
4439 .result = REJECT,
4440 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4441 },
4442 {
4443 "helper access to adjusted map (via variable): no max check",
4444 .insns = {
4445 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4446 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4447 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4448 BPF_LD_MAP_FD(BPF_REG_1, 0),
4449 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4450 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4451 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4452 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4453 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Edward Creef65b1842017-08-07 15:27:12 +01004454 BPF_MOV64_IMM(BPF_REG_2, 1),
Gianluca Borello57225692017-01-09 10:19:47 -08004455 BPF_MOV64_IMM(BPF_REG_3, 0),
4456 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4457 BPF_EXIT_INSN(),
4458 },
4459 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004460 .errstr = "R1 unbounded memory access",
Gianluca Borello57225692017-01-09 10:19:47 -08004461 .result = REJECT,
4462 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4463 },
4464 {
4465 "helper access to adjusted map (via variable): wrong max check",
4466 .insns = {
4467 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4468 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4469 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4470 BPF_LD_MAP_FD(BPF_REG_1, 0),
4471 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4472 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4473 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4474 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
4475 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
4476 offsetof(struct test_val, foo), 4),
4477 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
4478 BPF_MOV64_IMM(BPF_REG_2,
4479 sizeof(struct test_val) -
4480 offsetof(struct test_val, foo) + 1),
4481 BPF_MOV64_IMM(BPF_REG_3, 0),
4482 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4483 BPF_EXIT_INSN(),
4484 },
4485 .fixup_map2 = { 3 },
4486 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
4487 .result = REJECT,
4488 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4489 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08004490 {
4491 "map element value is preserved across register spilling",
4492 .insns = {
4493 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4495 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4496 BPF_LD_MAP_FD(BPF_REG_1, 0),
4497 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4498 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4499 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4500 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4501 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
4502 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4503 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4504 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4505 BPF_EXIT_INSN(),
4506 },
4507 .fixup_map2 = { 3 },
4508 .errstr_unpriv = "R0 leaks addr",
4509 .result = ACCEPT,
4510 .result_unpriv = REJECT,
4511 },
4512 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004513 "map element value or null is marked on register spilling",
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_MOV64_REG(BPF_REG_1, BPF_REG_10),
4521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
4522 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4523 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4524 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4525 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4526 BPF_EXIT_INSN(),
4527 },
4528 .fixup_map2 = { 3 },
4529 .errstr_unpriv = "R0 leaks addr",
4530 .result = ACCEPT,
4531 .result_unpriv = REJECT,
4532 },
4533 {
4534 "map element value store of cleared call register",
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),
4541 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4542 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
4543 BPF_EXIT_INSN(),
4544 },
4545 .fixup_map2 = { 3 },
4546 .errstr_unpriv = "R1 !read_ok",
4547 .errstr = "R1 !read_ok",
4548 .result = REJECT,
4549 .result_unpriv = REJECT,
4550 },
4551 {
4552 "map element value with unaligned store",
4553 .insns = {
4554 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4556 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4557 BPF_LD_MAP_FD(BPF_REG_1, 0),
4558 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4559 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
4560 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4561 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4562 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
4563 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
4564 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4565 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
4566 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
4567 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
4568 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
4569 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
4570 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
4571 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
4572 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
4573 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
4574 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
4575 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
4576 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
4577 BPF_EXIT_INSN(),
4578 },
4579 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004580 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004581 .result = ACCEPT,
4582 .result_unpriv = REJECT,
4583 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4584 },
4585 {
4586 "map element value with unaligned load",
4587 .insns = {
4588 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4590 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4591 BPF_LD_MAP_FD(BPF_REG_1, 0),
4592 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4593 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4594 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4595 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
4596 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4597 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4598 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
4599 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4600 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
4601 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
4602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
4603 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4604 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
4605 BPF_EXIT_INSN(),
4606 },
4607 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004608 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004609 .result = ACCEPT,
4610 .result_unpriv = REJECT,
4611 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4612 },
4613 {
4614 "map element value illegal alu op, 1",
4615 .insns = {
4616 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4617 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4618 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4619 BPF_LD_MAP_FD(BPF_REG_1, 0),
4620 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4621 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4622 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
4623 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4624 BPF_EXIT_INSN(),
4625 },
4626 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004627 .errstr_unpriv = "R0 bitwise operator &= on pointer",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004628 .errstr = "invalid mem access 'inv'",
4629 .result = REJECT,
4630 .result_unpriv = REJECT,
4631 },
4632 {
4633 "map element value illegal alu op, 2",
4634 .insns = {
4635 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4636 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4637 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4638 BPF_LD_MAP_FD(BPF_REG_1, 0),
4639 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4640 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4641 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
4642 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4643 BPF_EXIT_INSN(),
4644 },
4645 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004646 .errstr_unpriv = "R0 32-bit pointer arithmetic prohibited",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004647 .errstr = "invalid mem access 'inv'",
4648 .result = REJECT,
4649 .result_unpriv = REJECT,
4650 },
4651 {
4652 "map element value illegal alu op, 3",
4653 .insns = {
4654 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4655 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4656 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4657 BPF_LD_MAP_FD(BPF_REG_1, 0),
4658 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4660 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
4661 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4662 BPF_EXIT_INSN(),
4663 },
4664 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004665 .errstr_unpriv = "R0 pointer arithmetic with /= operator",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004666 .errstr = "invalid mem access 'inv'",
4667 .result = REJECT,
4668 .result_unpriv = REJECT,
4669 },
4670 {
4671 "map element value illegal alu op, 4",
4672 .insns = {
4673 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4675 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4676 BPF_LD_MAP_FD(BPF_REG_1, 0),
4677 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4678 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4679 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
4680 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4681 BPF_EXIT_INSN(),
4682 },
4683 .fixup_map2 = { 3 },
4684 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4685 .errstr = "invalid mem access 'inv'",
4686 .result = REJECT,
4687 .result_unpriv = REJECT,
4688 },
4689 {
4690 "map element value illegal alu op, 5",
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, 7),
4698 BPF_MOV64_IMM(BPF_REG_3, 4096),
4699 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4700 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4701 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
4702 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
4703 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
4704 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4705 BPF_EXIT_INSN(),
4706 },
4707 .fixup_map2 = { 3 },
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004708 .errstr = "R0 invalid mem access 'inv'",
4709 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004710 },
4711 {
4712 "map element value is preserved across register spilling",
Gianluca Borellof0318d02017-01-09 10:19:48 -08004713 .insns = {
4714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4716 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4717 BPF_LD_MAP_FD(BPF_REG_1, 0),
4718 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
4721 offsetof(struct test_val, foo)),
4722 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4723 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4724 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
4725 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4726 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4727 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4728 BPF_EXIT_INSN(),
4729 },
4730 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004731 .errstr_unpriv = "R0 leaks addr",
Gianluca Borellof0318d02017-01-09 10:19:48 -08004732 .result = ACCEPT,
4733 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004734 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Gianluca Borellof0318d02017-01-09 10:19:48 -08004735 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08004736 {
4737 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
4738 .insns = {
4739 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4740 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4741 BPF_MOV64_IMM(BPF_REG_0, 0),
4742 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4743 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4744 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4745 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4746 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4747 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4748 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4749 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4750 BPF_MOV64_IMM(BPF_REG_2, 16),
4751 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4752 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4753 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4754 BPF_MOV64_IMM(BPF_REG_4, 0),
4755 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4756 BPF_MOV64_IMM(BPF_REG_3, 0),
4757 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4758 BPF_MOV64_IMM(BPF_REG_0, 0),
4759 BPF_EXIT_INSN(),
4760 },
4761 .result = ACCEPT,
4762 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4763 },
4764 {
4765 "helper access to variable memory: stack, bitwise AND, zero included",
4766 .insns = {
4767 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4768 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4769 BPF_MOV64_IMM(BPF_REG_2, 16),
4770 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4771 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4772 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4773 BPF_MOV64_IMM(BPF_REG_3, 0),
4774 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4775 BPF_EXIT_INSN(),
4776 },
4777 .errstr = "invalid stack type R1 off=-64 access_size=0",
4778 .result = REJECT,
4779 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4780 },
4781 {
4782 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
4783 .insns = {
4784 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4785 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4786 BPF_MOV64_IMM(BPF_REG_2, 16),
4787 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4788 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4789 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
4790 BPF_MOV64_IMM(BPF_REG_4, 0),
4791 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4792 BPF_MOV64_IMM(BPF_REG_3, 0),
4793 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4794 BPF_MOV64_IMM(BPF_REG_0, 0),
4795 BPF_EXIT_INSN(),
4796 },
4797 .errstr = "invalid stack type R1 off=-64 access_size=65",
4798 .result = REJECT,
4799 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4800 },
4801 {
4802 "helper access to variable memory: stack, JMP, correct bounds",
4803 .insns = {
4804 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4805 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4806 BPF_MOV64_IMM(BPF_REG_0, 0),
4807 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4808 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4809 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4810 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4811 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4812 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4813 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4814 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4815 BPF_MOV64_IMM(BPF_REG_2, 16),
4816 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4817 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4818 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
4819 BPF_MOV64_IMM(BPF_REG_4, 0),
4820 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4821 BPF_MOV64_IMM(BPF_REG_3, 0),
4822 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4823 BPF_MOV64_IMM(BPF_REG_0, 0),
4824 BPF_EXIT_INSN(),
4825 },
4826 .result = ACCEPT,
4827 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4828 },
4829 {
4830 "helper access to variable memory: stack, JMP (signed), correct bounds",
4831 .insns = {
4832 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4833 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4834 BPF_MOV64_IMM(BPF_REG_0, 0),
4835 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4836 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4837 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4838 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4839 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4840 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4841 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4842 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4843 BPF_MOV64_IMM(BPF_REG_2, 16),
4844 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4845 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4846 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
4847 BPF_MOV64_IMM(BPF_REG_4, 0),
4848 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
4849 BPF_MOV64_IMM(BPF_REG_3, 0),
4850 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4851 BPF_MOV64_IMM(BPF_REG_0, 0),
4852 BPF_EXIT_INSN(),
4853 },
4854 .result = ACCEPT,
4855 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4856 },
4857 {
4858 "helper access to variable memory: stack, JMP, bounds + offset",
4859 .insns = {
4860 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4861 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4862 BPF_MOV64_IMM(BPF_REG_2, 16),
4863 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4864 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4865 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
4866 BPF_MOV64_IMM(BPF_REG_4, 0),
4867 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
4868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4869 BPF_MOV64_IMM(BPF_REG_3, 0),
4870 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4871 BPF_MOV64_IMM(BPF_REG_0, 0),
4872 BPF_EXIT_INSN(),
4873 },
4874 .errstr = "invalid stack type R1 off=-64 access_size=65",
4875 .result = REJECT,
4876 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4877 },
4878 {
4879 "helper access to variable memory: stack, JMP, wrong max",
4880 .insns = {
4881 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4883 BPF_MOV64_IMM(BPF_REG_2, 16),
4884 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4885 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4886 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
4887 BPF_MOV64_IMM(BPF_REG_4, 0),
4888 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4889 BPF_MOV64_IMM(BPF_REG_3, 0),
4890 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4891 BPF_MOV64_IMM(BPF_REG_0, 0),
4892 BPF_EXIT_INSN(),
4893 },
4894 .errstr = "invalid stack type R1 off=-64 access_size=65",
4895 .result = REJECT,
4896 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4897 },
4898 {
4899 "helper access to variable memory: stack, JMP, no max check",
4900 .insns = {
4901 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4902 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4903 BPF_MOV64_IMM(BPF_REG_2, 16),
4904 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4905 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4906 BPF_MOV64_IMM(BPF_REG_4, 0),
4907 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4908 BPF_MOV64_IMM(BPF_REG_3, 0),
4909 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4910 BPF_MOV64_IMM(BPF_REG_0, 0),
4911 BPF_EXIT_INSN(),
4912 },
Edward Creef65b1842017-08-07 15:27:12 +01004913 /* because max wasn't checked, signed min is negative */
4914 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
Gianluca Borello06c1c042017-01-09 10:19:49 -08004915 .result = REJECT,
4916 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4917 },
4918 {
4919 "helper access to variable memory: stack, JMP, no min check",
4920 .insns = {
4921 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4923 BPF_MOV64_IMM(BPF_REG_2, 16),
4924 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4925 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4926 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
4927 BPF_MOV64_IMM(BPF_REG_3, 0),
4928 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4929 BPF_MOV64_IMM(BPF_REG_0, 0),
4930 BPF_EXIT_INSN(),
4931 },
4932 .errstr = "invalid stack type R1 off=-64 access_size=0",
4933 .result = REJECT,
4934 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4935 },
4936 {
4937 "helper access to variable memory: stack, JMP (signed), no min check",
4938 .insns = {
4939 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4941 BPF_MOV64_IMM(BPF_REG_2, 16),
4942 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4943 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4944 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
4945 BPF_MOV64_IMM(BPF_REG_3, 0),
4946 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4947 BPF_MOV64_IMM(BPF_REG_0, 0),
4948 BPF_EXIT_INSN(),
4949 },
4950 .errstr = "R2 min value is negative",
4951 .result = REJECT,
4952 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4953 },
4954 {
4955 "helper access to variable memory: map, JMP, correct bounds",
4956 .insns = {
4957 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4959 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4960 BPF_LD_MAP_FD(BPF_REG_1, 0),
4961 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4962 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4963 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4964 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4965 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4966 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4967 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4968 sizeof(struct test_val), 4),
4969 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02004970 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004971 BPF_MOV64_IMM(BPF_REG_3, 0),
4972 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4973 BPF_MOV64_IMM(BPF_REG_0, 0),
4974 BPF_EXIT_INSN(),
4975 },
4976 .fixup_map2 = { 3 },
4977 .result = ACCEPT,
4978 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4979 },
4980 {
4981 "helper access to variable memory: map, JMP, wrong max",
4982 .insns = {
4983 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4984 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4985 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4986 BPF_LD_MAP_FD(BPF_REG_1, 0),
4987 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4988 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4989 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4990 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4991 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4992 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4993 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4994 sizeof(struct test_val) + 1, 4),
4995 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02004996 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004997 BPF_MOV64_IMM(BPF_REG_3, 0),
4998 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4999 BPF_MOV64_IMM(BPF_REG_0, 0),
5000 BPF_EXIT_INSN(),
5001 },
5002 .fixup_map2 = { 3 },
5003 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
5004 .result = REJECT,
5005 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5006 },
5007 {
5008 "helper access to variable memory: map adjusted, JMP, correct bounds",
5009 .insns = {
5010 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5012 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5013 BPF_LD_MAP_FD(BPF_REG_1, 0),
5014 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5015 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5016 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5017 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5018 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5019 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5020 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5021 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5022 sizeof(struct test_val) - 20, 4),
5023 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005024 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005025 BPF_MOV64_IMM(BPF_REG_3, 0),
5026 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5027 BPF_MOV64_IMM(BPF_REG_0, 0),
5028 BPF_EXIT_INSN(),
5029 },
5030 .fixup_map2 = { 3 },
5031 .result = ACCEPT,
5032 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5033 },
5034 {
5035 "helper access to variable memory: map adjusted, JMP, wrong max",
5036 .insns = {
5037 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5039 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5040 BPF_LD_MAP_FD(BPF_REG_1, 0),
5041 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5042 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
5043 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
5045 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5046 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5047 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
5048 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
5049 sizeof(struct test_val) - 19, 4),
5050 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02005051 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005052 BPF_MOV64_IMM(BPF_REG_3, 0),
5053 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5054 BPF_MOV64_IMM(BPF_REG_0, 0),
5055 BPF_EXIT_INSN(),
5056 },
5057 .fixup_map2 = { 3 },
5058 .errstr = "R1 min value is outside of the array range",
5059 .result = REJECT,
5060 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5061 },
5062 {
Edward Creef65b1842017-08-07 15:27:12 +01005063 "helper access to variable memory: size = 0 allowed on NULL",
5064 .insns = {
5065 BPF_MOV64_IMM(BPF_REG_1, 0),
5066 BPF_MOV64_IMM(BPF_REG_2, 0),
5067 BPF_MOV64_IMM(BPF_REG_3, 0),
5068 BPF_MOV64_IMM(BPF_REG_4, 0),
5069 BPF_MOV64_IMM(BPF_REG_5, 0),
5070 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5071 BPF_EXIT_INSN(),
5072 },
5073 .result = ACCEPT,
5074 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5075 },
5076 {
Gianluca Borello06c1c042017-01-09 10:19:49 -08005077 "helper access to variable memory: size > 0 not allowed on NULL",
5078 .insns = {
5079 BPF_MOV64_IMM(BPF_REG_1, 0),
5080 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01005081 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5082 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005083 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
5084 BPF_MOV64_IMM(BPF_REG_3, 0),
5085 BPF_MOV64_IMM(BPF_REG_4, 0),
5086 BPF_MOV64_IMM(BPF_REG_5, 0),
5087 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5088 BPF_EXIT_INSN(),
5089 },
Edward Creef65b1842017-08-07 15:27:12 +01005090 .errstr = "R1 type=inv expected=fp",
Gianluca Borello06c1c042017-01-09 10:19:49 -08005091 .result = REJECT,
5092 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5093 },
5094 {
5095 "helper access to variable memory: size = 0 not allowed on != NULL",
5096 .insns = {
5097 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
5099 BPF_MOV64_IMM(BPF_REG_2, 0),
5100 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
5101 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
5102 BPF_MOV64_IMM(BPF_REG_3, 0),
5103 BPF_MOV64_IMM(BPF_REG_4, 0),
5104 BPF_MOV64_IMM(BPF_REG_5, 0),
5105 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
5106 BPF_EXIT_INSN(),
5107 },
5108 .errstr = "invalid stack type R1 off=-8 access_size=0",
5109 .result = REJECT,
5110 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5111 },
5112 {
5113 "helper access to variable memory: 8 bytes leak",
5114 .insns = {
5115 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5117 BPF_MOV64_IMM(BPF_REG_0, 0),
5118 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5119 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5120 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5121 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5122 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5123 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5124 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5125 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01005126 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
5127 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08005128 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
5129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5130 BPF_MOV64_IMM(BPF_REG_3, 0),
5131 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5132 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5133 BPF_EXIT_INSN(),
5134 },
5135 .errstr = "invalid indirect read from stack off -64+32 size 64",
5136 .result = REJECT,
5137 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5138 },
5139 {
5140 "helper access to variable memory: 8 bytes no leak (init memory)",
5141 .insns = {
5142 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5143 BPF_MOV64_IMM(BPF_REG_0, 0),
5144 BPF_MOV64_IMM(BPF_REG_0, 0),
5145 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
5146 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
5147 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
5148 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
5149 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
5150 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
5151 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
5152 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
5153 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
5154 BPF_MOV64_IMM(BPF_REG_2, 0),
5155 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
5156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
5157 BPF_MOV64_IMM(BPF_REG_3, 0),
5158 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5159 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5160 BPF_EXIT_INSN(),
5161 },
5162 .result = ACCEPT,
5163 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5164 },
Josef Bacik29200c12017-02-03 16:25:23 -05005165 {
5166 "invalid and of negative number",
5167 .insns = {
5168 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5169 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5170 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5171 BPF_LD_MAP_FD(BPF_REG_1, 0),
5172 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5173 BPF_FUNC_map_lookup_elem),
5174 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Edward Creef65b1842017-08-07 15:27:12 +01005175 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik29200c12017-02-03 16:25:23 -05005176 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
5177 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
5178 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5179 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
5180 offsetof(struct test_val, foo)),
5181 BPF_EXIT_INSN(),
5182 },
5183 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005184 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05005185 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005186 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik29200c12017-02-03 16:25:23 -05005187 },
5188 {
5189 "invalid range check",
5190 .insns = {
5191 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5192 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5193 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5194 BPF_LD_MAP_FD(BPF_REG_1, 0),
5195 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5196 BPF_FUNC_map_lookup_elem),
5197 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
5198 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5199 BPF_MOV64_IMM(BPF_REG_9, 1),
5200 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
5201 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
5202 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
5203 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
5204 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
5205 BPF_MOV32_IMM(BPF_REG_3, 1),
5206 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
5207 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
5208 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
5209 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
5210 BPF_MOV64_REG(BPF_REG_0, 0),
5211 BPF_EXIT_INSN(),
5212 },
5213 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005214 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05005215 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005216 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07005217 },
5218 {
5219 "map in map access",
5220 .insns = {
5221 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5222 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5223 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5224 BPF_LD_MAP_FD(BPF_REG_1, 0),
5225 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5226 BPF_FUNC_map_lookup_elem),
5227 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5228 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5229 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5230 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5231 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5232 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5233 BPF_FUNC_map_lookup_elem),
5234 BPF_MOV64_REG(BPF_REG_0, 0),
5235 BPF_EXIT_INSN(),
5236 },
5237 .fixup_map_in_map = { 3 },
5238 .result = ACCEPT,
5239 },
5240 {
5241 "invalid inner map pointer",
5242 .insns = {
5243 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5244 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5245 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5246 BPF_LD_MAP_FD(BPF_REG_1, 0),
5247 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5248 BPF_FUNC_map_lookup_elem),
5249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5250 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5251 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5253 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
5255 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5256 BPF_FUNC_map_lookup_elem),
5257 BPF_MOV64_REG(BPF_REG_0, 0),
5258 BPF_EXIT_INSN(),
5259 },
5260 .fixup_map_in_map = { 3 },
5261 .errstr = "R1 type=inv expected=map_ptr",
Edward Creef65b1842017-08-07 15:27:12 +01005262 .errstr_unpriv = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07005263 .result = REJECT,
5264 },
5265 {
5266 "forgot null checking on the inner map pointer",
5267 .insns = {
5268 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5269 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5271 BPF_LD_MAP_FD(BPF_REG_1, 0),
5272 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5273 BPF_FUNC_map_lookup_elem),
5274 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
5275 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5276 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5277 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5278 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5279 BPF_FUNC_map_lookup_elem),
5280 BPF_MOV64_REG(BPF_REG_0, 0),
5281 BPF_EXIT_INSN(),
5282 },
5283 .fixup_map_in_map = { 3 },
5284 .errstr = "R1 type=map_value_or_null expected=map_ptr",
5285 .result = REJECT,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02005286 },
5287 {
5288 "ld_abs: check calling conv, r1",
5289 .insns = {
5290 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5291 BPF_MOV64_IMM(BPF_REG_1, 0),
5292 BPF_LD_ABS(BPF_W, -0x200000),
5293 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5294 BPF_EXIT_INSN(),
5295 },
5296 .errstr = "R1 !read_ok",
5297 .result = REJECT,
5298 },
5299 {
5300 "ld_abs: check calling conv, r2",
5301 .insns = {
5302 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5303 BPF_MOV64_IMM(BPF_REG_2, 0),
5304 BPF_LD_ABS(BPF_W, -0x200000),
5305 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5306 BPF_EXIT_INSN(),
5307 },
5308 .errstr = "R2 !read_ok",
5309 .result = REJECT,
5310 },
5311 {
5312 "ld_abs: check calling conv, r3",
5313 .insns = {
5314 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5315 BPF_MOV64_IMM(BPF_REG_3, 0),
5316 BPF_LD_ABS(BPF_W, -0x200000),
5317 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
5318 BPF_EXIT_INSN(),
5319 },
5320 .errstr = "R3 !read_ok",
5321 .result = REJECT,
5322 },
5323 {
5324 "ld_abs: check calling conv, r4",
5325 .insns = {
5326 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5327 BPF_MOV64_IMM(BPF_REG_4, 0),
5328 BPF_LD_ABS(BPF_W, -0x200000),
5329 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
5330 BPF_EXIT_INSN(),
5331 },
5332 .errstr = "R4 !read_ok",
5333 .result = REJECT,
5334 },
5335 {
5336 "ld_abs: check calling conv, r5",
5337 .insns = {
5338 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5339 BPF_MOV64_IMM(BPF_REG_5, 0),
5340 BPF_LD_ABS(BPF_W, -0x200000),
5341 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
5342 BPF_EXIT_INSN(),
5343 },
5344 .errstr = "R5 !read_ok",
5345 .result = REJECT,
5346 },
5347 {
5348 "ld_abs: check calling conv, r7",
5349 .insns = {
5350 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5351 BPF_MOV64_IMM(BPF_REG_7, 0),
5352 BPF_LD_ABS(BPF_W, -0x200000),
5353 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
5354 BPF_EXIT_INSN(),
5355 },
5356 .result = ACCEPT,
5357 },
5358 {
5359 "ld_ind: check calling conv, r1",
5360 .insns = {
5361 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5362 BPF_MOV64_IMM(BPF_REG_1, 1),
5363 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
5364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5365 BPF_EXIT_INSN(),
5366 },
5367 .errstr = "R1 !read_ok",
5368 .result = REJECT,
5369 },
5370 {
5371 "ld_ind: check calling conv, r2",
5372 .insns = {
5373 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5374 BPF_MOV64_IMM(BPF_REG_2, 1),
5375 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
5376 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5377 BPF_EXIT_INSN(),
5378 },
5379 .errstr = "R2 !read_ok",
5380 .result = REJECT,
5381 },
5382 {
5383 "ld_ind: check calling conv, r3",
5384 .insns = {
5385 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5386 BPF_MOV64_IMM(BPF_REG_3, 1),
5387 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
5388 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
5389 BPF_EXIT_INSN(),
5390 },
5391 .errstr = "R3 !read_ok",
5392 .result = REJECT,
5393 },
5394 {
5395 "ld_ind: check calling conv, r4",
5396 .insns = {
5397 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5398 BPF_MOV64_IMM(BPF_REG_4, 1),
5399 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
5400 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
5401 BPF_EXIT_INSN(),
5402 },
5403 .errstr = "R4 !read_ok",
5404 .result = REJECT,
5405 },
5406 {
5407 "ld_ind: check calling conv, r5",
5408 .insns = {
5409 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5410 BPF_MOV64_IMM(BPF_REG_5, 1),
5411 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
5412 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
5413 BPF_EXIT_INSN(),
5414 },
5415 .errstr = "R5 !read_ok",
5416 .result = REJECT,
5417 },
5418 {
5419 "ld_ind: check calling conv, r7",
5420 .insns = {
5421 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5422 BPF_MOV64_IMM(BPF_REG_7, 1),
5423 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
5424 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
5425 BPF_EXIT_INSN(),
5426 },
5427 .result = ACCEPT,
5428 },
Yonghong Song18f3d6b2017-06-13 15:52:14 -07005429 {
5430 "check bpf_perf_event_data->sample_period byte load permitted",
5431 .insns = {
5432 BPF_MOV64_IMM(BPF_REG_0, 0),
5433#ifdef __LITTLE_ENDIAN
5434 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
5435 offsetof(struct bpf_perf_event_data, sample_period)),
5436#else
5437 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
5438 offsetof(struct bpf_perf_event_data, sample_period) + 7),
5439#endif
5440 BPF_EXIT_INSN(),
5441 },
5442 .result = ACCEPT,
5443 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
5444 },
5445 {
5446 "check bpf_perf_event_data->sample_period half load permitted",
5447 .insns = {
5448 BPF_MOV64_IMM(BPF_REG_0, 0),
5449#ifdef __LITTLE_ENDIAN
5450 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5451 offsetof(struct bpf_perf_event_data, sample_period)),
5452#else
5453 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5454 offsetof(struct bpf_perf_event_data, sample_period) + 6),
5455#endif
5456 BPF_EXIT_INSN(),
5457 },
5458 .result = ACCEPT,
5459 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
5460 },
5461 {
5462 "check bpf_perf_event_data->sample_period word load permitted",
5463 .insns = {
5464 BPF_MOV64_IMM(BPF_REG_0, 0),
5465#ifdef __LITTLE_ENDIAN
5466 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5467 offsetof(struct bpf_perf_event_data, sample_period)),
5468#else
5469 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5470 offsetof(struct bpf_perf_event_data, sample_period) + 4),
5471#endif
5472 BPF_EXIT_INSN(),
5473 },
5474 .result = ACCEPT,
5475 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
5476 },
5477 {
5478 "check bpf_perf_event_data->sample_period dword load permitted",
5479 .insns = {
5480 BPF_MOV64_IMM(BPF_REG_0, 0),
5481 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
5482 offsetof(struct bpf_perf_event_data, sample_period)),
5483 BPF_EXIT_INSN(),
5484 },
5485 .result = ACCEPT,
5486 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
5487 },
5488 {
5489 "check skb->data half load not permitted",
5490 .insns = {
5491 BPF_MOV64_IMM(BPF_REG_0, 0),
5492#ifdef __LITTLE_ENDIAN
5493 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5494 offsetof(struct __sk_buff, data)),
5495#else
5496 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5497 offsetof(struct __sk_buff, data) + 2),
5498#endif
5499 BPF_EXIT_INSN(),
5500 },
5501 .result = REJECT,
5502 .errstr = "invalid bpf_context access",
5503 },
5504 {
5505 "check skb->tc_classid half load not permitted for lwt prog",
5506 .insns = {
5507 BPF_MOV64_IMM(BPF_REG_0, 0),
5508#ifdef __LITTLE_ENDIAN
5509 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5510 offsetof(struct __sk_buff, tc_classid)),
5511#else
5512 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
5513 offsetof(struct __sk_buff, tc_classid) + 2),
5514#endif
5515 BPF_EXIT_INSN(),
5516 },
5517 .result = REJECT,
5518 .errstr = "invalid bpf_context access",
5519 .prog_type = BPF_PROG_TYPE_LWT_IN,
5520 },
Edward Creeb7122962017-07-21 00:00:24 +02005521 {
5522 "bounds checks mixing signed and unsigned, positive bounds",
5523 .insns = {
5524 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5525 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5526 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5527 BPF_LD_MAP_FD(BPF_REG_1, 0),
5528 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5529 BPF_FUNC_map_lookup_elem),
5530 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5531 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5532 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5533 BPF_MOV64_IMM(BPF_REG_2, 2),
5534 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
5535 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
5536 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5537 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5538 BPF_MOV64_IMM(BPF_REG_0, 0),
5539 BPF_EXIT_INSN(),
5540 },
5541 .fixup_map1 = { 3 },
Edward Creeb7122962017-07-21 00:00:24 +02005542 .errstr = "R0 min value is negative",
5543 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02005544 },
5545 {
5546 "bounds checks mixing signed and unsigned",
5547 .insns = {
5548 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5549 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5550 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5551 BPF_LD_MAP_FD(BPF_REG_1, 0),
5552 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5553 BPF_FUNC_map_lookup_elem),
5554 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5555 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5556 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5557 BPF_MOV64_IMM(BPF_REG_2, -1),
5558 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
5559 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5560 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5561 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5562 BPF_MOV64_IMM(BPF_REG_0, 0),
5563 BPF_EXIT_INSN(),
5564 },
5565 .fixup_map1 = { 3 },
Edward Creeb7122962017-07-21 00:00:24 +02005566 .errstr = "R0 min value is negative",
5567 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02005568 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005569 {
5570 "bounds checks mixing signed and unsigned, variant 2",
5571 .insns = {
5572 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5573 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5574 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5575 BPF_LD_MAP_FD(BPF_REG_1, 0),
5576 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5577 BPF_FUNC_map_lookup_elem),
5578 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5579 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5580 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5581 BPF_MOV64_IMM(BPF_REG_2, -1),
5582 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
5583 BPF_MOV64_IMM(BPF_REG_8, 0),
5584 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
5585 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
5586 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
5587 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
5588 BPF_MOV64_IMM(BPF_REG_0, 0),
5589 BPF_EXIT_INSN(),
5590 },
5591 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005592 .errstr = "R8 invalid mem access 'inv'",
5593 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005594 },
5595 {
5596 "bounds checks mixing signed and unsigned, variant 3",
5597 .insns = {
5598 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5599 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5600 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5601 BPF_LD_MAP_FD(BPF_REG_1, 0),
5602 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5603 BPF_FUNC_map_lookup_elem),
5604 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
5605 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5606 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5607 BPF_MOV64_IMM(BPF_REG_2, -1),
5608 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
5609 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
5610 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
5611 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
5612 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
5613 BPF_MOV64_IMM(BPF_REG_0, 0),
5614 BPF_EXIT_INSN(),
5615 },
5616 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005617 .errstr = "R8 invalid mem access 'inv'",
5618 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005619 },
5620 {
5621 "bounds checks mixing signed and unsigned, variant 4",
5622 .insns = {
5623 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5624 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5625 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5626 BPF_LD_MAP_FD(BPF_REG_1, 0),
5627 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5628 BPF_FUNC_map_lookup_elem),
5629 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5630 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5631 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5632 BPF_MOV64_IMM(BPF_REG_2, 1),
5633 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
5634 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5635 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5636 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5637 BPF_MOV64_IMM(BPF_REG_0, 0),
5638 BPF_EXIT_INSN(),
5639 },
5640 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005641 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005642 },
5643 {
5644 "bounds checks mixing signed and unsigned, variant 5",
5645 .insns = {
5646 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5649 BPF_LD_MAP_FD(BPF_REG_1, 0),
5650 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5651 BPF_FUNC_map_lookup_elem),
5652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5653 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5654 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5655 BPF_MOV64_IMM(BPF_REG_2, -1),
5656 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
5657 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
5658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
5659 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
5660 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5661 BPF_MOV64_IMM(BPF_REG_0, 0),
5662 BPF_EXIT_INSN(),
5663 },
5664 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005665 .errstr = "R0 min value is negative",
Daniel Borkmann86412502017-07-21 00:00:25 +02005666 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005667 },
5668 {
5669 "bounds checks mixing signed and unsigned, variant 6",
5670 .insns = {
5671 BPF_MOV64_IMM(BPF_REG_2, 0),
5672 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
5673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
5674 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5675 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
5676 BPF_MOV64_IMM(BPF_REG_6, -1),
5677 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
5678 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
5679 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
5680 BPF_MOV64_IMM(BPF_REG_5, 0),
5681 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
5682 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5683 BPF_FUNC_skb_load_bytes),
5684 BPF_MOV64_IMM(BPF_REG_0, 0),
5685 BPF_EXIT_INSN(),
5686 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005687 .errstr = "R4 min value is negative, either use unsigned",
5688 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005689 },
5690 {
5691 "bounds checks mixing signed and unsigned, variant 7",
5692 .insns = {
5693 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5694 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5696 BPF_LD_MAP_FD(BPF_REG_1, 0),
5697 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5698 BPF_FUNC_map_lookup_elem),
5699 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5700 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5701 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5702 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
5703 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
5704 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5705 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5706 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5707 BPF_MOV64_IMM(BPF_REG_0, 0),
5708 BPF_EXIT_INSN(),
5709 },
5710 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005711 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005712 },
5713 {
5714 "bounds checks mixing signed and unsigned, variant 8",
5715 .insns = {
5716 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5717 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5719 BPF_LD_MAP_FD(BPF_REG_1, 0),
5720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5721 BPF_FUNC_map_lookup_elem),
Daniel Borkmann86412502017-07-21 00:00:25 +02005722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5723 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5724 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5725 BPF_MOV64_IMM(BPF_REG_2, -1),
5726 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
5727 BPF_MOV64_IMM(BPF_REG_0, 0),
5728 BPF_EXIT_INSN(),
5729 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5730 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5731 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5732 BPF_MOV64_IMM(BPF_REG_0, 0),
5733 BPF_EXIT_INSN(),
5734 },
5735 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005736 .errstr = "R0 min value is negative",
5737 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005738 },
5739 {
Edward Creef65b1842017-08-07 15:27:12 +01005740 "bounds checks mixing signed and unsigned, variant 9",
Daniel Borkmann86412502017-07-21 00:00:25 +02005741 .insns = {
5742 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5743 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5745 BPF_LD_MAP_FD(BPF_REG_1, 0),
5746 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5747 BPF_FUNC_map_lookup_elem),
5748 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
5749 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5750 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5751 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
5752 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
5753 BPF_MOV64_IMM(BPF_REG_0, 0),
5754 BPF_EXIT_INSN(),
5755 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5756 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5757 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5758 BPF_MOV64_IMM(BPF_REG_0, 0),
5759 BPF_EXIT_INSN(),
5760 },
5761 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005762 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005763 },
5764 {
Edward Creef65b1842017-08-07 15:27:12 +01005765 "bounds checks mixing signed and unsigned, variant 10",
Daniel Borkmann86412502017-07-21 00:00:25 +02005766 .insns = {
5767 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5768 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5770 BPF_LD_MAP_FD(BPF_REG_1, 0),
5771 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5772 BPF_FUNC_map_lookup_elem),
5773 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5774 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5775 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5776 BPF_MOV64_IMM(BPF_REG_2, 0),
5777 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
5778 BPF_MOV64_IMM(BPF_REG_0, 0),
5779 BPF_EXIT_INSN(),
5780 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5781 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5782 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5783 BPF_MOV64_IMM(BPF_REG_0, 0),
5784 BPF_EXIT_INSN(),
5785 },
5786 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005787 .errstr = "R0 min value is negative",
5788 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005789 },
5790 {
Edward Creef65b1842017-08-07 15:27:12 +01005791 "bounds checks mixing signed and unsigned, variant 11",
Daniel Borkmann86412502017-07-21 00:00:25 +02005792 .insns = {
5793 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5794 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5796 BPF_LD_MAP_FD(BPF_REG_1, 0),
5797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5798 BPF_FUNC_map_lookup_elem),
5799 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5800 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5801 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5802 BPF_MOV64_IMM(BPF_REG_2, -1),
5803 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
5804 /* Dead branch. */
5805 BPF_MOV64_IMM(BPF_REG_0, 0),
5806 BPF_EXIT_INSN(),
5807 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5808 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5809 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5810 BPF_MOV64_IMM(BPF_REG_0, 0),
5811 BPF_EXIT_INSN(),
5812 },
5813 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005814 .errstr = "R0 min value is negative",
5815 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005816 },
5817 {
Edward Creef65b1842017-08-07 15:27:12 +01005818 "bounds checks mixing signed and unsigned, variant 12",
Daniel Borkmann86412502017-07-21 00:00:25 +02005819 .insns = {
5820 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5821 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5823 BPF_LD_MAP_FD(BPF_REG_1, 0),
5824 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5825 BPF_FUNC_map_lookup_elem),
5826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5827 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5828 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5829 BPF_MOV64_IMM(BPF_REG_2, -6),
5830 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
5831 BPF_MOV64_IMM(BPF_REG_0, 0),
5832 BPF_EXIT_INSN(),
5833 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5834 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5835 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5836 BPF_MOV64_IMM(BPF_REG_0, 0),
5837 BPF_EXIT_INSN(),
5838 },
5839 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005840 .errstr = "R0 min value is negative",
5841 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005842 },
5843 {
Edward Creef65b1842017-08-07 15:27:12 +01005844 "bounds checks mixing signed and unsigned, variant 13",
Daniel Borkmann86412502017-07-21 00:00:25 +02005845 .insns = {
5846 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5847 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5849 BPF_LD_MAP_FD(BPF_REG_1, 0),
5850 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5851 BPF_FUNC_map_lookup_elem),
5852 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5853 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5854 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5855 BPF_MOV64_IMM(BPF_REG_2, 2),
5856 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
5857 BPF_MOV64_IMM(BPF_REG_7, 1),
5858 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
5859 BPF_MOV64_IMM(BPF_REG_0, 0),
5860 BPF_EXIT_INSN(),
5861 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
5862 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
5863 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
5864 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5865 BPF_MOV64_IMM(BPF_REG_0, 0),
5866 BPF_EXIT_INSN(),
5867 },
5868 .fixup_map1 = { 3 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005869 .errstr = "R0 min value is negative",
5870 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005871 },
5872 {
Edward Creef65b1842017-08-07 15:27:12 +01005873 "bounds checks mixing signed and unsigned, variant 14",
Daniel Borkmann86412502017-07-21 00:00:25 +02005874 .insns = {
5875 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
5876 offsetof(struct __sk_buff, mark)),
5877 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5878 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5879 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5880 BPF_LD_MAP_FD(BPF_REG_1, 0),
5881 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5882 BPF_FUNC_map_lookup_elem),
5883 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
5884 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5885 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5886 BPF_MOV64_IMM(BPF_REG_2, -1),
5887 BPF_MOV64_IMM(BPF_REG_8, 2),
5888 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
5889 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
5890 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
5891 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5892 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5893 BPF_MOV64_IMM(BPF_REG_0, 0),
5894 BPF_EXIT_INSN(),
5895 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
5896 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
5897 },
5898 .fixup_map1 = { 4 },
Daniel Borkmann86412502017-07-21 00:00:25 +02005899 .errstr = "R0 min value is negative",
5900 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02005901 },
5902 {
Edward Creef65b1842017-08-07 15:27:12 +01005903 "bounds checks mixing signed and unsigned, variant 15",
Daniel Borkmann86412502017-07-21 00:00:25 +02005904 .insns = {
5905 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5906 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5907 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5908 BPF_LD_MAP_FD(BPF_REG_1, 0),
5909 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5910 BPF_FUNC_map_lookup_elem),
5911 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5912 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
5913 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
5914 BPF_MOV64_IMM(BPF_REG_2, -6),
5915 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
5916 BPF_MOV64_IMM(BPF_REG_0, 0),
5917 BPF_EXIT_INSN(),
5918 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5919 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
5920 BPF_MOV64_IMM(BPF_REG_0, 0),
5921 BPF_EXIT_INSN(),
5922 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
5923 BPF_MOV64_IMM(BPF_REG_0, 0),
5924 BPF_EXIT_INSN(),
5925 },
5926 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005927 .errstr_unpriv = "R0 pointer comparison prohibited",
Daniel Borkmann86412502017-07-21 00:00:25 +02005928 .errstr = "R0 min value is negative",
5929 .result = REJECT,
5930 .result_unpriv = REJECT,
5931 },
Edward Cree545722c2017-07-21 14:36:57 +01005932 {
Edward Creef65b1842017-08-07 15:27:12 +01005933 "subtraction bounds (map value) variant 1",
Edward Cree545722c2017-07-21 14:36:57 +01005934 .insns = {
5935 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5936 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5937 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5938 BPF_LD_MAP_FD(BPF_REG_1, 0),
5939 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5940 BPF_FUNC_map_lookup_elem),
5941 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
5942 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
5943 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
5944 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
5945 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
5946 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
5947 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
5948 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5949 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
5950 BPF_EXIT_INSN(),
5951 BPF_MOV64_IMM(BPF_REG_0, 0),
5952 BPF_EXIT_INSN(),
5953 },
5954 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005955 .errstr = "R0 max value is outside of the array range",
5956 .result = REJECT,
5957 },
5958 {
5959 "subtraction bounds (map value) variant 2",
5960 .insns = {
5961 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5962 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5963 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5964 BPF_LD_MAP_FD(BPF_REG_1, 0),
5965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5966 BPF_FUNC_map_lookup_elem),
5967 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
5968 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
5969 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
5970 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
5971 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
5972 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
5973 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5974 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
5975 BPF_EXIT_INSN(),
5976 BPF_MOV64_IMM(BPF_REG_0, 0),
5977 BPF_EXIT_INSN(),
5978 },
5979 .fixup_map1 = { 3 },
Edward Cree545722c2017-07-21 14:36:57 +01005980 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
5981 .result = REJECT,
Edward Cree545722c2017-07-21 14:36:57 +01005982 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005983};
5984
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005985static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005986{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005987 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005988
5989 for (len = MAX_INSNS - 1; len > 0; --len)
5990 if (fp[len].code != 0 || fp[len].imm != 0)
5991 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005992 return len + 1;
5993}
5994
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005995static int create_map(uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005996{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005997 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005998
Mickaël Salaünf4874d02017-02-10 00:21:43 +01005999 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006000 size_value, max_elem, BPF_F_NO_PREALLOC);
6001 if (fd < 0)
6002 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -07006003
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006004 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07006005}
6006
6007static int create_prog_array(void)
6008{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006009 int fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07006010
Mickaël Salaünf4874d02017-02-10 00:21:43 +01006011 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006012 sizeof(int), 4, 0);
6013 if (fd < 0)
6014 printf("Failed to create prog array '%s'!\n", strerror(errno));
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006015
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006016 return fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006017}
6018
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006019static int create_map_in_map(void)
6020{
6021 int inner_map_fd, outer_map_fd;
6022
6023 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
6024 sizeof(int), 1, 0);
6025 if (inner_map_fd < 0) {
6026 printf("Failed to create array '%s'!\n", strerror(errno));
6027 return inner_map_fd;
6028 }
6029
6030 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS,
6031 sizeof(int), inner_map_fd, 1, 0);
6032 if (outer_map_fd < 0)
6033 printf("Failed to create array of maps '%s'!\n",
6034 strerror(errno));
6035
6036 close(inner_map_fd);
6037
6038 return outer_map_fd;
6039}
6040
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006041static char bpf_vlog[32768];
6042
6043static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006044 int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006045{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006046 int *fixup_map1 = test->fixup_map1;
6047 int *fixup_map2 = test->fixup_map2;
6048 int *fixup_prog = test->fixup_prog;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006049 int *fixup_map_in_map = test->fixup_map_in_map;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006050
6051 /* Allocating HTs with 1 elem is fine here, since we only test
6052 * for verifier and not do a runtime lookup, so the only thing
6053 * that really matters is value size in this case.
6054 */
6055 if (*fixup_map1) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006056 map_fds[0] = create_map(sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006057 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006058 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006059 fixup_map1++;
6060 } while (*fixup_map1);
6061 }
6062
6063 if (*fixup_map2) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006064 map_fds[1] = create_map(sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006065 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006066 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006067 fixup_map2++;
6068 } while (*fixup_map2);
6069 }
6070
6071 if (*fixup_prog) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006072 map_fds[2] = create_prog_array();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006073 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006074 prog[*fixup_prog].imm = map_fds[2];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006075 fixup_prog++;
6076 } while (*fixup_prog);
6077 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006078
6079 if (*fixup_map_in_map) {
6080 map_fds[3] = create_map_in_map();
6081 do {
6082 prog[*fixup_map_in_map].imm = map_fds[3];
6083 fixup_map_in_map++;
6084 } while (*fixup_map_in_map);
6085 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006086}
6087
6088static void do_test_single(struct bpf_test *test, bool unpriv,
6089 int *passes, int *errors)
6090{
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006091 int fd_prog, expected_ret, reject_from_alignment;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006092 struct bpf_insn *prog = test->insns;
6093 int prog_len = probe_filter_length(prog);
6094 int prog_type = test->prog_type;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006095 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006096 const char *expected_err;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006097 int i;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006098
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006099 for (i = 0; i < MAX_NR_MAPS; i++)
6100 map_fds[i] = -1;
6101
6102 do_test_fixup(test, prog, map_fds);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006103
Daniel Borkmann614d0d72017-05-25 01:05:09 +02006104 fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
6105 prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmannd6554902017-07-21 00:00:22 +02006106 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006107
6108 expected_ret = unpriv && test->result_unpriv != UNDEF ?
6109 test->result_unpriv : test->result;
6110 expected_err = unpriv && test->errstr_unpriv ?
6111 test->errstr_unpriv : test->errstr;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006112
6113 reject_from_alignment = fd_prog < 0 &&
6114 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
6115 strstr(bpf_vlog, "Unknown alignment.");
6116#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
6117 if (reject_from_alignment) {
6118 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
6119 strerror(errno));
6120 goto fail_log;
6121 }
6122#endif
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006123 if (expected_ret == ACCEPT) {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006124 if (fd_prog < 0 && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006125 printf("FAIL\nFailed to load prog '%s'!\n",
6126 strerror(errno));
6127 goto fail_log;
6128 }
6129 } else {
6130 if (fd_prog >= 0) {
6131 printf("FAIL\nUnexpected success to load!\n");
6132 goto fail_log;
6133 }
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006134 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006135 printf("FAIL\nUnexpected error message!\n");
6136 goto fail_log;
6137 }
6138 }
6139
6140 (*passes)++;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006141 printf("OK%s\n", reject_from_alignment ?
6142 " (NOTE: reject due to unknown alignment)" : "");
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006143close_fds:
6144 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006145 for (i = 0; i < MAX_NR_MAPS; i++)
6146 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006147 sched_yield();
6148 return;
6149fail_log:
6150 (*errors)++;
6151 printf("%s", bpf_vlog);
6152 goto close_fds;
6153}
6154
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006155static bool is_admin(void)
6156{
6157 cap_t caps;
6158 cap_flag_value_t sysadmin = CAP_CLEAR;
6159 const cap_value_t cap_val = CAP_SYS_ADMIN;
6160
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08006161#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006162 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
6163 perror("cap_get_flag");
6164 return false;
6165 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08006166#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006167 caps = cap_get_proc();
6168 if (!caps) {
6169 perror("cap_get_proc");
6170 return false;
6171 }
6172 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
6173 perror("cap_get_flag");
6174 if (cap_free(caps))
6175 perror("cap_free");
6176 return (sysadmin == CAP_SET);
6177}
6178
6179static int set_admin(bool admin)
6180{
6181 cap_t caps;
6182 const cap_value_t cap_val = CAP_SYS_ADMIN;
6183 int ret = -1;
6184
6185 caps = cap_get_proc();
6186 if (!caps) {
6187 perror("cap_get_proc");
6188 return -1;
6189 }
6190 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
6191 admin ? CAP_SET : CAP_CLEAR)) {
6192 perror("cap_set_flag");
6193 goto out;
6194 }
6195 if (cap_set_proc(caps)) {
6196 perror("cap_set_proc");
6197 goto out;
6198 }
6199 ret = 0;
6200out:
6201 if (cap_free(caps))
6202 perror("cap_free");
6203 return ret;
6204}
6205
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006206static int do_test(bool unpriv, unsigned int from, unsigned int to)
6207{
6208 int i, passes = 0, errors = 0;
6209
6210 for (i = from; i < to; i++) {
6211 struct bpf_test *test = &tests[i];
6212
6213 /* Program types that are not supported by non-root we
6214 * skip right away.
6215 */
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006216 if (!test->prog_type) {
6217 if (!unpriv)
6218 set_admin(false);
6219 printf("#%d/u %s ", i, test->descr);
6220 do_test_single(test, true, &passes, &errors);
6221 if (!unpriv)
6222 set_admin(true);
6223 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006224
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006225 if (!unpriv) {
6226 printf("#%d/p %s ", i, test->descr);
6227 do_test_single(test, false, &passes, &errors);
6228 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006229 }
6230
6231 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
Jesper Dangaard Brouerefe5f9c2017-06-13 15:17:19 +02006232 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006233}
6234
6235int main(int argc, char **argv)
6236{
6237 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
6238 struct rlimit rlim = { 1 << 20, 1 << 20 };
6239 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +01006240 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006241
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006242 if (argc == 3) {
6243 unsigned int l = atoi(argv[argc - 2]);
6244 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006245
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006246 if (l < to && u < to) {
6247 from = l;
6248 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006249 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006250 } else if (argc == 2) {
6251 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -07006252
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006253 if (t < to) {
6254 from = t;
6255 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07006256 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006257 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006258
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02006259 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
6260 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006261}