blob: 95a8d5f3ab80d9c3dd65e35dea74fab558adb21d [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)
52
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070053struct bpf_test {
54 const char *descr;
55 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020056 int fixup_map1[MAX_FIXUPS];
57 int fixup_map2[MAX_FIXUPS];
58 int fixup_prog[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070059 int fixup_map_in_map[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070060 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070061 const char *errstr_unpriv;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070062 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070063 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070064 ACCEPT,
65 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070066 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070067 enum bpf_prog_type prog_type;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020068 uint8_t flags;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070069};
70
Josef Bacik48461132016-09-28 10:54:32 -040071/* Note we want this to be 64 bit aligned so that the end of our array is
72 * actually the end of the structure.
73 */
74#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040075
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020076struct test_val {
77 unsigned int index;
78 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040079};
80
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070081static struct bpf_test tests[] = {
82 {
83 "add+sub+mul",
84 .insns = {
85 BPF_MOV64_IMM(BPF_REG_1, 1),
86 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
87 BPF_MOV64_IMM(BPF_REG_2, 3),
88 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
89 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
90 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
91 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
92 BPF_EXIT_INSN(),
93 },
94 .result = ACCEPT,
95 },
96 {
97 "unreachable",
98 .insns = {
99 BPF_EXIT_INSN(),
100 BPF_EXIT_INSN(),
101 },
102 .errstr = "unreachable",
103 .result = REJECT,
104 },
105 {
106 "unreachable2",
107 .insns = {
108 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
109 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
110 BPF_EXIT_INSN(),
111 },
112 .errstr = "unreachable",
113 .result = REJECT,
114 },
115 {
116 "out of range jump",
117 .insns = {
118 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
119 BPF_EXIT_INSN(),
120 },
121 .errstr = "jump out of range",
122 .result = REJECT,
123 },
124 {
125 "out of range jump2",
126 .insns = {
127 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
128 BPF_EXIT_INSN(),
129 },
130 .errstr = "jump out of range",
131 .result = REJECT,
132 },
133 {
134 "test1 ld_imm64",
135 .insns = {
136 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
137 BPF_LD_IMM64(BPF_REG_0, 0),
138 BPF_LD_IMM64(BPF_REG_0, 0),
139 BPF_LD_IMM64(BPF_REG_0, 1),
140 BPF_LD_IMM64(BPF_REG_0, 1),
141 BPF_MOV64_IMM(BPF_REG_0, 2),
142 BPF_EXIT_INSN(),
143 },
144 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700145 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700146 .result = REJECT,
147 },
148 {
149 "test2 ld_imm64",
150 .insns = {
151 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
152 BPF_LD_IMM64(BPF_REG_0, 0),
153 BPF_LD_IMM64(BPF_REG_0, 0),
154 BPF_LD_IMM64(BPF_REG_0, 1),
155 BPF_LD_IMM64(BPF_REG_0, 1),
156 BPF_EXIT_INSN(),
157 },
158 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700159 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700160 .result = REJECT,
161 },
162 {
163 "test3 ld_imm64",
164 .insns = {
165 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
166 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
167 BPF_LD_IMM64(BPF_REG_0, 0),
168 BPF_LD_IMM64(BPF_REG_0, 0),
169 BPF_LD_IMM64(BPF_REG_0, 1),
170 BPF_LD_IMM64(BPF_REG_0, 1),
171 BPF_EXIT_INSN(),
172 },
173 .errstr = "invalid bpf_ld_imm64 insn",
174 .result = REJECT,
175 },
176 {
177 "test4 ld_imm64",
178 .insns = {
179 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
180 BPF_EXIT_INSN(),
181 },
182 .errstr = "invalid bpf_ld_imm64 insn",
183 .result = REJECT,
184 },
185 {
186 "test5 ld_imm64",
187 .insns = {
188 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
189 },
190 .errstr = "invalid bpf_ld_imm64 insn",
191 .result = REJECT,
192 },
193 {
194 "no bpf_exit",
195 .insns = {
196 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
197 },
198 .errstr = "jump out of range",
199 .result = REJECT,
200 },
201 {
202 "loop (back-edge)",
203 .insns = {
204 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
205 BPF_EXIT_INSN(),
206 },
207 .errstr = "back-edge",
208 .result = REJECT,
209 },
210 {
211 "loop2 (back-edge)",
212 .insns = {
213 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
214 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
215 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
216 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
217 BPF_EXIT_INSN(),
218 },
219 .errstr = "back-edge",
220 .result = REJECT,
221 },
222 {
223 "conditional loop",
224 .insns = {
225 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
226 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
227 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
228 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
229 BPF_EXIT_INSN(),
230 },
231 .errstr = "back-edge",
232 .result = REJECT,
233 },
234 {
235 "read uninitialized register",
236 .insns = {
237 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
238 BPF_EXIT_INSN(),
239 },
240 .errstr = "R2 !read_ok",
241 .result = REJECT,
242 },
243 {
244 "read invalid register",
245 .insns = {
246 BPF_MOV64_REG(BPF_REG_0, -1),
247 BPF_EXIT_INSN(),
248 },
249 .errstr = "R15 is invalid",
250 .result = REJECT,
251 },
252 {
253 "program doesn't init R0 before exit",
254 .insns = {
255 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
256 BPF_EXIT_INSN(),
257 },
258 .errstr = "R0 !read_ok",
259 .result = REJECT,
260 },
261 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700262 "program doesn't init R0 before exit in all branches",
263 .insns = {
264 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
265 BPF_MOV64_IMM(BPF_REG_0, 1),
266 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
267 BPF_EXIT_INSN(),
268 },
269 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700270 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700271 .result = REJECT,
272 },
273 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700274 "stack out of bounds",
275 .insns = {
276 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
277 BPF_EXIT_INSN(),
278 },
279 .errstr = "invalid stack",
280 .result = REJECT,
281 },
282 {
283 "invalid call insn1",
284 .insns = {
285 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
286 BPF_EXIT_INSN(),
287 },
288 .errstr = "BPF_CALL uses reserved",
289 .result = REJECT,
290 },
291 {
292 "invalid call insn2",
293 .insns = {
294 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
295 BPF_EXIT_INSN(),
296 },
297 .errstr = "BPF_CALL uses reserved",
298 .result = REJECT,
299 },
300 {
301 "invalid function call",
302 .insns = {
303 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
304 BPF_EXIT_INSN(),
305 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100306 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700307 .result = REJECT,
308 },
309 {
310 "uninitialized stack1",
311 .insns = {
312 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
313 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
314 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200315 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
316 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700317 BPF_EXIT_INSN(),
318 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200319 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700320 .errstr = "invalid indirect read from stack",
321 .result = REJECT,
322 },
323 {
324 "uninitialized stack2",
325 .insns = {
326 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
327 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
328 BPF_EXIT_INSN(),
329 },
330 .errstr = "invalid read from stack",
331 .result = REJECT,
332 },
333 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200334 "invalid argument register",
335 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200336 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
337 BPF_FUNC_get_cgroup_classid),
338 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
339 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200340 BPF_EXIT_INSN(),
341 },
342 .errstr = "R1 !read_ok",
343 .result = REJECT,
344 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
345 },
346 {
347 "non-invalid argument register",
348 .insns = {
349 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200350 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
351 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200352 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200353 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
354 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200355 BPF_EXIT_INSN(),
356 },
357 .result = ACCEPT,
358 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
359 },
360 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700361 "check valid spill/fill",
362 .insns = {
363 /* spill R1(ctx) into stack */
364 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700365 /* fill it back into R2 */
366 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700367 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100368 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
369 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700370 BPF_EXIT_INSN(),
371 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700372 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700373 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700374 .result_unpriv = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700375 },
376 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200377 "check valid spill/fill, skb mark",
378 .insns = {
379 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
380 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
381 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
382 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
383 offsetof(struct __sk_buff, mark)),
384 BPF_EXIT_INSN(),
385 },
386 .result = ACCEPT,
387 .result_unpriv = ACCEPT,
388 },
389 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700390 "check corrupted spill/fill",
391 .insns = {
392 /* spill R1(ctx) into stack */
393 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700394 /* mess up with R1 pointer on stack */
395 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700396 /* fill back into R0 should fail */
397 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700398 BPF_EXIT_INSN(),
399 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700400 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700401 .errstr = "corrupted spill",
402 .result = REJECT,
403 },
404 {
405 "invalid src register in STX",
406 .insns = {
407 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
408 BPF_EXIT_INSN(),
409 },
410 .errstr = "R15 is invalid",
411 .result = REJECT,
412 },
413 {
414 "invalid dst register in STX",
415 .insns = {
416 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
417 BPF_EXIT_INSN(),
418 },
419 .errstr = "R14 is invalid",
420 .result = REJECT,
421 },
422 {
423 "invalid dst register in ST",
424 .insns = {
425 BPF_ST_MEM(BPF_B, 14, -1, -1),
426 BPF_EXIT_INSN(),
427 },
428 .errstr = "R14 is invalid",
429 .result = REJECT,
430 },
431 {
432 "invalid src register in LDX",
433 .insns = {
434 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
435 BPF_EXIT_INSN(),
436 },
437 .errstr = "R12 is invalid",
438 .result = REJECT,
439 },
440 {
441 "invalid dst register in LDX",
442 .insns = {
443 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
444 BPF_EXIT_INSN(),
445 },
446 .errstr = "R11 is invalid",
447 .result = REJECT,
448 },
449 {
450 "junk insn",
451 .insns = {
452 BPF_RAW_INSN(0, 0, 0, 0, 0),
453 BPF_EXIT_INSN(),
454 },
455 .errstr = "invalid BPF_LD_IMM",
456 .result = REJECT,
457 },
458 {
459 "junk insn2",
460 .insns = {
461 BPF_RAW_INSN(1, 0, 0, 0, 0),
462 BPF_EXIT_INSN(),
463 },
464 .errstr = "BPF_LDX uses reserved fields",
465 .result = REJECT,
466 },
467 {
468 "junk insn3",
469 .insns = {
470 BPF_RAW_INSN(-1, 0, 0, 0, 0),
471 BPF_EXIT_INSN(),
472 },
473 .errstr = "invalid BPF_ALU opcode f0",
474 .result = REJECT,
475 },
476 {
477 "junk insn4",
478 .insns = {
479 BPF_RAW_INSN(-1, -1, -1, -1, -1),
480 BPF_EXIT_INSN(),
481 },
482 .errstr = "invalid BPF_ALU opcode f0",
483 .result = REJECT,
484 },
485 {
486 "junk insn5",
487 .insns = {
488 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
489 BPF_EXIT_INSN(),
490 },
491 .errstr = "BPF_ALU uses reserved fields",
492 .result = REJECT,
493 },
494 {
495 "misaligned read from stack",
496 .insns = {
497 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
498 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
499 BPF_EXIT_INSN(),
500 },
501 .errstr = "misaligned access",
502 .result = REJECT,
503 },
504 {
505 "invalid map_fd for function call",
506 .insns = {
507 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
508 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
510 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200511 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
512 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700513 BPF_EXIT_INSN(),
514 },
515 .errstr = "fd 0 is not pointing to valid bpf_map",
516 .result = REJECT,
517 },
518 {
519 "don't check return value before access",
520 .insns = {
521 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
522 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
524 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200525 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
526 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700527 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
528 BPF_EXIT_INSN(),
529 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200530 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700531 .errstr = "R0 invalid mem access 'map_value_or_null'",
532 .result = REJECT,
533 },
534 {
535 "access memory with incorrect alignment",
536 .insns = {
537 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
538 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
539 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
540 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200541 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
542 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700543 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
544 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
545 BPF_EXIT_INSN(),
546 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200547 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700548 .errstr = "misaligned access",
549 .result = REJECT,
550 },
551 {
552 "sometimes access memory with incorrect alignment",
553 .insns = {
554 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
555 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
557 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200558 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
559 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
561 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
562 BPF_EXIT_INSN(),
563 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
564 BPF_EXIT_INSN(),
565 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200566 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700567 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700568 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700569 .result = REJECT,
570 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700571 {
572 "jump test 1",
573 .insns = {
574 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
575 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
576 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
577 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
578 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
579 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
580 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
581 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
582 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
583 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
585 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
586 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
587 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
588 BPF_MOV64_IMM(BPF_REG_0, 0),
589 BPF_EXIT_INSN(),
590 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700591 .errstr_unpriv = "R1 pointer comparison",
592 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700593 .result = ACCEPT,
594 },
595 {
596 "jump test 2",
597 .insns = {
598 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
599 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
600 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
601 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
602 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
603 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
604 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
605 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
606 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
607 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
608 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
609 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
610 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
611 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
612 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
613 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
614 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
615 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
616 BPF_MOV64_IMM(BPF_REG_0, 0),
617 BPF_EXIT_INSN(),
618 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700619 .errstr_unpriv = "R1 pointer comparison",
620 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700621 .result = ACCEPT,
622 },
623 {
624 "jump test 3",
625 .insns = {
626 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
627 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
628 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
629 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
630 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
631 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
632 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
633 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
634 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
635 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
636 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
638 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
639 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
640 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
641 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
642 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
643 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
644 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
645 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
646 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
647 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
648 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
649 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
650 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200651 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
652 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700653 BPF_EXIT_INSN(),
654 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200655 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700656 .errstr_unpriv = "R1 pointer comparison",
657 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700658 .result = ACCEPT,
659 },
660 {
661 "jump test 4",
662 .insns = {
663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
664 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
666 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
667 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
669 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
670 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
672 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
673 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
674 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
675 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
676 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
677 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
678 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
679 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
680 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
681 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
683 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
685 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
687 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
688 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
689 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
690 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
691 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
692 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
693 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
694 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
695 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
696 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
697 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
698 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
699 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
700 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
701 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
702 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
703 BPF_MOV64_IMM(BPF_REG_0, 0),
704 BPF_EXIT_INSN(),
705 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700706 .errstr_unpriv = "R1 pointer comparison",
707 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700708 .result = ACCEPT,
709 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700710 {
711 "jump test 5",
712 .insns = {
713 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
714 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
715 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
716 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
717 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
718 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
719 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
720 BPF_MOV64_IMM(BPF_REG_0, 0),
721 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
722 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
723 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
724 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
725 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
726 BPF_MOV64_IMM(BPF_REG_0, 0),
727 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
728 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
729 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
730 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
731 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
732 BPF_MOV64_IMM(BPF_REG_0, 0),
733 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
734 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
735 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
736 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
737 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
738 BPF_MOV64_IMM(BPF_REG_0, 0),
739 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
740 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
741 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
742 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
743 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
744 BPF_MOV64_IMM(BPF_REG_0, 0),
745 BPF_EXIT_INSN(),
746 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700747 .errstr_unpriv = "R1 pointer comparison",
748 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700749 .result = ACCEPT,
750 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700751 {
752 "access skb fields ok",
753 .insns = {
754 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
755 offsetof(struct __sk_buff, len)),
756 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
757 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
758 offsetof(struct __sk_buff, mark)),
759 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
760 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
761 offsetof(struct __sk_buff, pkt_type)),
762 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
763 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
764 offsetof(struct __sk_buff, queue_mapping)),
765 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -0700766 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
767 offsetof(struct __sk_buff, protocol)),
768 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
769 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
770 offsetof(struct __sk_buff, vlan_present)),
771 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
772 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
773 offsetof(struct __sk_buff, vlan_tci)),
774 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Daniel Borkmannb1d9fc42017-04-19 23:01:17 +0200775 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
776 offsetof(struct __sk_buff, napi_id)),
777 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700778 BPF_EXIT_INSN(),
779 },
780 .result = ACCEPT,
781 },
782 {
783 "access skb fields bad1",
784 .insns = {
785 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
786 BPF_EXIT_INSN(),
787 },
788 .errstr = "invalid bpf_context access",
789 .result = REJECT,
790 },
791 {
792 "access skb fields bad2",
793 .insns = {
794 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
795 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
796 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
798 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200799 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
800 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700801 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
802 BPF_EXIT_INSN(),
803 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
804 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
805 offsetof(struct __sk_buff, pkt_type)),
806 BPF_EXIT_INSN(),
807 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200808 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700809 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700810 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700811 .result = REJECT,
812 },
813 {
814 "access skb fields bad3",
815 .insns = {
816 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
817 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
818 offsetof(struct __sk_buff, pkt_type)),
819 BPF_EXIT_INSN(),
820 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
821 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
823 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200824 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
825 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700826 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
827 BPF_EXIT_INSN(),
828 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
829 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
830 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200831 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700832 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700833 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700834 .result = REJECT,
835 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700836 {
837 "access skb fields bad4",
838 .insns = {
839 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
840 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
841 offsetof(struct __sk_buff, len)),
842 BPF_MOV64_IMM(BPF_REG_0, 0),
843 BPF_EXIT_INSN(),
844 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
845 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
846 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
847 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200848 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
849 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700850 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
851 BPF_EXIT_INSN(),
852 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
853 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
854 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200855 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700856 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700857 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700858 .result = REJECT,
859 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700860 {
861 "check skb->mark is not writeable by sockets",
862 .insns = {
863 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
864 offsetof(struct __sk_buff, mark)),
865 BPF_EXIT_INSN(),
866 },
867 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700868 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700869 .result = REJECT,
870 },
871 {
872 "check skb->tc_index is not writeable by sockets",
873 .insns = {
874 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
875 offsetof(struct __sk_buff, tc_index)),
876 BPF_EXIT_INSN(),
877 },
878 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700879 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700880 .result = REJECT,
881 },
882 {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100883 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700884 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100885 BPF_MOV64_IMM(BPF_REG_0, 0),
886 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
887 offsetof(struct __sk_buff, cb[0])),
888 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
889 offsetof(struct __sk_buff, cb[0]) + 1),
890 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
891 offsetof(struct __sk_buff, cb[0]) + 2),
892 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
893 offsetof(struct __sk_buff, cb[0]) + 3),
894 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
895 offsetof(struct __sk_buff, cb[1])),
896 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
897 offsetof(struct __sk_buff, cb[1]) + 1),
898 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
899 offsetof(struct __sk_buff, cb[1]) + 2),
900 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
901 offsetof(struct __sk_buff, cb[1]) + 3),
902 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
903 offsetof(struct __sk_buff, cb[2])),
904 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
905 offsetof(struct __sk_buff, cb[2]) + 1),
906 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
907 offsetof(struct __sk_buff, cb[2]) + 2),
908 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
909 offsetof(struct __sk_buff, cb[2]) + 3),
910 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
911 offsetof(struct __sk_buff, cb[3])),
912 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
913 offsetof(struct __sk_buff, cb[3]) + 1),
914 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
915 offsetof(struct __sk_buff, cb[3]) + 2),
916 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
917 offsetof(struct __sk_buff, cb[3]) + 3),
918 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
919 offsetof(struct __sk_buff, cb[4])),
920 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
921 offsetof(struct __sk_buff, cb[4]) + 1),
922 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
923 offsetof(struct __sk_buff, cb[4]) + 2),
924 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
925 offsetof(struct __sk_buff, cb[4]) + 3),
926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
927 offsetof(struct __sk_buff, cb[0])),
928 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
929 offsetof(struct __sk_buff, cb[0]) + 1),
930 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
931 offsetof(struct __sk_buff, cb[0]) + 2),
932 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
933 offsetof(struct __sk_buff, cb[0]) + 3),
934 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
935 offsetof(struct __sk_buff, cb[1])),
936 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
937 offsetof(struct __sk_buff, cb[1]) + 1),
938 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
939 offsetof(struct __sk_buff, cb[1]) + 2),
940 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
941 offsetof(struct __sk_buff, cb[1]) + 3),
942 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
943 offsetof(struct __sk_buff, cb[2])),
944 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
945 offsetof(struct __sk_buff, cb[2]) + 1),
946 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
947 offsetof(struct __sk_buff, cb[2]) + 2),
948 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
949 offsetof(struct __sk_buff, cb[2]) + 3),
950 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
951 offsetof(struct __sk_buff, cb[3])),
952 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
953 offsetof(struct __sk_buff, cb[3]) + 1),
954 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
955 offsetof(struct __sk_buff, cb[3]) + 2),
956 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
957 offsetof(struct __sk_buff, cb[3]) + 3),
958 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
959 offsetof(struct __sk_buff, cb[4])),
960 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
961 offsetof(struct __sk_buff, cb[4]) + 1),
962 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
963 offsetof(struct __sk_buff, cb[4]) + 2),
964 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
965 offsetof(struct __sk_buff, cb[4]) + 3),
966 BPF_EXIT_INSN(),
967 },
968 .result = ACCEPT,
969 },
970 {
971 "check cb access: byte, oob 1",
972 .insns = {
973 BPF_MOV64_IMM(BPF_REG_0, 0),
974 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
975 offsetof(struct __sk_buff, cb[4]) + 4),
976 BPF_EXIT_INSN(),
977 },
978 .errstr = "invalid bpf_context access",
979 .result = REJECT,
980 },
981 {
982 "check cb access: byte, oob 2",
983 .insns = {
984 BPF_MOV64_IMM(BPF_REG_0, 0),
985 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
986 offsetof(struct __sk_buff, cb[0]) - 1),
987 BPF_EXIT_INSN(),
988 },
989 .errstr = "invalid bpf_context access",
990 .result = REJECT,
991 },
992 {
993 "check cb access: byte, oob 3",
994 .insns = {
995 BPF_MOV64_IMM(BPF_REG_0, 0),
996 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
997 offsetof(struct __sk_buff, cb[4]) + 4),
998 BPF_EXIT_INSN(),
999 },
1000 .errstr = "invalid bpf_context access",
1001 .result = REJECT,
1002 },
1003 {
1004 "check cb access: byte, oob 4",
1005 .insns = {
1006 BPF_MOV64_IMM(BPF_REG_0, 0),
1007 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1008 offsetof(struct __sk_buff, cb[0]) - 1),
1009 BPF_EXIT_INSN(),
1010 },
1011 .errstr = "invalid bpf_context access",
1012 .result = REJECT,
1013 },
1014 {
1015 "check cb access: byte, wrong type",
1016 .insns = {
1017 BPF_MOV64_IMM(BPF_REG_0, 0),
1018 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001019 offsetof(struct __sk_buff, cb[0])),
1020 BPF_EXIT_INSN(),
1021 },
1022 .errstr = "invalid bpf_context access",
1023 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001024 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1025 },
1026 {
1027 "check cb access: half",
1028 .insns = {
1029 BPF_MOV64_IMM(BPF_REG_0, 0),
1030 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1031 offsetof(struct __sk_buff, cb[0])),
1032 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1033 offsetof(struct __sk_buff, cb[0]) + 2),
1034 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1035 offsetof(struct __sk_buff, cb[1])),
1036 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1037 offsetof(struct __sk_buff, cb[1]) + 2),
1038 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1039 offsetof(struct __sk_buff, cb[2])),
1040 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1041 offsetof(struct __sk_buff, cb[2]) + 2),
1042 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1043 offsetof(struct __sk_buff, cb[3])),
1044 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1045 offsetof(struct __sk_buff, cb[3]) + 2),
1046 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1047 offsetof(struct __sk_buff, cb[4])),
1048 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1049 offsetof(struct __sk_buff, cb[4]) + 2),
1050 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1051 offsetof(struct __sk_buff, cb[0])),
1052 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1053 offsetof(struct __sk_buff, cb[0]) + 2),
1054 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1055 offsetof(struct __sk_buff, cb[1])),
1056 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1057 offsetof(struct __sk_buff, cb[1]) + 2),
1058 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1059 offsetof(struct __sk_buff, cb[2])),
1060 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1061 offsetof(struct __sk_buff, cb[2]) + 2),
1062 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1063 offsetof(struct __sk_buff, cb[3])),
1064 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1065 offsetof(struct __sk_buff, cb[3]) + 2),
1066 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1067 offsetof(struct __sk_buff, cb[4])),
1068 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1069 offsetof(struct __sk_buff, cb[4]) + 2),
1070 BPF_EXIT_INSN(),
1071 },
1072 .result = ACCEPT,
1073 },
1074 {
1075 "check cb access: half, unaligned",
1076 .insns = {
1077 BPF_MOV64_IMM(BPF_REG_0, 0),
1078 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1079 offsetof(struct __sk_buff, cb[0]) + 1),
1080 BPF_EXIT_INSN(),
1081 },
1082 .errstr = "misaligned access",
1083 .result = REJECT,
1084 },
1085 {
1086 "check cb access: half, oob 1",
1087 .insns = {
1088 BPF_MOV64_IMM(BPF_REG_0, 0),
1089 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1090 offsetof(struct __sk_buff, cb[4]) + 4),
1091 BPF_EXIT_INSN(),
1092 },
1093 .errstr = "invalid bpf_context access",
1094 .result = REJECT,
1095 },
1096 {
1097 "check cb access: half, oob 2",
1098 .insns = {
1099 BPF_MOV64_IMM(BPF_REG_0, 0),
1100 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1101 offsetof(struct __sk_buff, cb[0]) - 2),
1102 BPF_EXIT_INSN(),
1103 },
1104 .errstr = "invalid bpf_context access",
1105 .result = REJECT,
1106 },
1107 {
1108 "check cb access: half, oob 3",
1109 .insns = {
1110 BPF_MOV64_IMM(BPF_REG_0, 0),
1111 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1112 offsetof(struct __sk_buff, cb[4]) + 4),
1113 BPF_EXIT_INSN(),
1114 },
1115 .errstr = "invalid bpf_context access",
1116 .result = REJECT,
1117 },
1118 {
1119 "check cb access: half, oob 4",
1120 .insns = {
1121 BPF_MOV64_IMM(BPF_REG_0, 0),
1122 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1123 offsetof(struct __sk_buff, cb[0]) - 2),
1124 BPF_EXIT_INSN(),
1125 },
1126 .errstr = "invalid bpf_context access",
1127 .result = REJECT,
1128 },
1129 {
1130 "check cb access: half, wrong type",
1131 .insns = {
1132 BPF_MOV64_IMM(BPF_REG_0, 0),
1133 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1134 offsetof(struct __sk_buff, cb[0])),
1135 BPF_EXIT_INSN(),
1136 },
1137 .errstr = "invalid bpf_context access",
1138 .result = REJECT,
1139 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1140 },
1141 {
1142 "check cb access: word",
1143 .insns = {
1144 BPF_MOV64_IMM(BPF_REG_0, 0),
1145 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1146 offsetof(struct __sk_buff, cb[0])),
1147 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1148 offsetof(struct __sk_buff, cb[1])),
1149 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1150 offsetof(struct __sk_buff, cb[2])),
1151 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1152 offsetof(struct __sk_buff, cb[3])),
1153 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1154 offsetof(struct __sk_buff, cb[4])),
1155 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1156 offsetof(struct __sk_buff, cb[0])),
1157 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1158 offsetof(struct __sk_buff, cb[1])),
1159 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1160 offsetof(struct __sk_buff, cb[2])),
1161 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1162 offsetof(struct __sk_buff, cb[3])),
1163 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1164 offsetof(struct __sk_buff, cb[4])),
1165 BPF_EXIT_INSN(),
1166 },
1167 .result = ACCEPT,
1168 },
1169 {
1170 "check cb access: word, unaligned 1",
1171 .insns = {
1172 BPF_MOV64_IMM(BPF_REG_0, 0),
1173 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1174 offsetof(struct __sk_buff, cb[0]) + 2),
1175 BPF_EXIT_INSN(),
1176 },
1177 .errstr = "misaligned access",
1178 .result = REJECT,
1179 },
1180 {
1181 "check cb access: word, unaligned 2",
1182 .insns = {
1183 BPF_MOV64_IMM(BPF_REG_0, 0),
1184 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1185 offsetof(struct __sk_buff, cb[4]) + 1),
1186 BPF_EXIT_INSN(),
1187 },
1188 .errstr = "misaligned access",
1189 .result = REJECT,
1190 },
1191 {
1192 "check cb access: word, unaligned 3",
1193 .insns = {
1194 BPF_MOV64_IMM(BPF_REG_0, 0),
1195 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1196 offsetof(struct __sk_buff, cb[4]) + 2),
1197 BPF_EXIT_INSN(),
1198 },
1199 .errstr = "misaligned access",
1200 .result = REJECT,
1201 },
1202 {
1203 "check cb access: word, unaligned 4",
1204 .insns = {
1205 BPF_MOV64_IMM(BPF_REG_0, 0),
1206 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1207 offsetof(struct __sk_buff, cb[4]) + 3),
1208 BPF_EXIT_INSN(),
1209 },
1210 .errstr = "misaligned access",
1211 .result = REJECT,
1212 },
1213 {
1214 "check cb access: double",
1215 .insns = {
1216 BPF_MOV64_IMM(BPF_REG_0, 0),
1217 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1218 offsetof(struct __sk_buff, cb[0])),
1219 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1220 offsetof(struct __sk_buff, cb[2])),
1221 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1222 offsetof(struct __sk_buff, cb[0])),
1223 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1224 offsetof(struct __sk_buff, cb[2])),
1225 BPF_EXIT_INSN(),
1226 },
1227 .result = ACCEPT,
1228 },
1229 {
1230 "check cb access: double, unaligned 1",
1231 .insns = {
1232 BPF_MOV64_IMM(BPF_REG_0, 0),
1233 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1234 offsetof(struct __sk_buff, cb[1])),
1235 BPF_EXIT_INSN(),
1236 },
1237 .errstr = "misaligned access",
1238 .result = REJECT,
1239 },
1240 {
1241 "check cb access: double, unaligned 2",
1242 .insns = {
1243 BPF_MOV64_IMM(BPF_REG_0, 0),
1244 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1245 offsetof(struct __sk_buff, cb[3])),
1246 BPF_EXIT_INSN(),
1247 },
1248 .errstr = "misaligned access",
1249 .result = REJECT,
1250 },
1251 {
1252 "check cb access: double, oob 1",
1253 .insns = {
1254 BPF_MOV64_IMM(BPF_REG_0, 0),
1255 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1256 offsetof(struct __sk_buff, cb[4])),
1257 BPF_EXIT_INSN(),
1258 },
1259 .errstr = "invalid bpf_context access",
1260 .result = REJECT,
1261 },
1262 {
1263 "check cb access: double, oob 2",
1264 .insns = {
1265 BPF_MOV64_IMM(BPF_REG_0, 0),
1266 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1267 offsetof(struct __sk_buff, cb[4]) + 8),
1268 BPF_EXIT_INSN(),
1269 },
1270 .errstr = "invalid bpf_context access",
1271 .result = REJECT,
1272 },
1273 {
1274 "check cb access: double, oob 3",
1275 .insns = {
1276 BPF_MOV64_IMM(BPF_REG_0, 0),
1277 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1278 offsetof(struct __sk_buff, cb[0]) - 8),
1279 BPF_EXIT_INSN(),
1280 },
1281 .errstr = "invalid bpf_context access",
1282 .result = REJECT,
1283 },
1284 {
1285 "check cb access: double, oob 4",
1286 .insns = {
1287 BPF_MOV64_IMM(BPF_REG_0, 0),
1288 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1289 offsetof(struct __sk_buff, cb[4])),
1290 BPF_EXIT_INSN(),
1291 },
1292 .errstr = "invalid bpf_context access",
1293 .result = REJECT,
1294 },
1295 {
1296 "check cb access: double, oob 5",
1297 .insns = {
1298 BPF_MOV64_IMM(BPF_REG_0, 0),
1299 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1300 offsetof(struct __sk_buff, cb[4]) + 8),
1301 BPF_EXIT_INSN(),
1302 },
1303 .errstr = "invalid bpf_context access",
1304 .result = REJECT,
1305 },
1306 {
1307 "check cb access: double, oob 6",
1308 .insns = {
1309 BPF_MOV64_IMM(BPF_REG_0, 0),
1310 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1311 offsetof(struct __sk_buff, cb[0]) - 8),
1312 BPF_EXIT_INSN(),
1313 },
1314 .errstr = "invalid bpf_context access",
1315 .result = REJECT,
1316 },
1317 {
1318 "check cb access: double, wrong type",
1319 .insns = {
1320 BPF_MOV64_IMM(BPF_REG_0, 0),
1321 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1322 offsetof(struct __sk_buff, cb[0])),
1323 BPF_EXIT_INSN(),
1324 },
1325 .errstr = "invalid bpf_context access",
1326 .result = REJECT,
1327 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001328 },
1329 {
1330 "check out of range skb->cb access",
1331 .insns = {
1332 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001333 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001334 BPF_EXIT_INSN(),
1335 },
1336 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001337 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001338 .result = REJECT,
1339 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
1340 },
1341 {
1342 "write skb fields from socket prog",
1343 .insns = {
1344 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1345 offsetof(struct __sk_buff, cb[4])),
1346 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1347 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1348 offsetof(struct __sk_buff, mark)),
1349 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1350 offsetof(struct __sk_buff, tc_index)),
1351 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1352 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1353 offsetof(struct __sk_buff, cb[0])),
1354 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1355 offsetof(struct __sk_buff, cb[2])),
1356 BPF_EXIT_INSN(),
1357 },
1358 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001359 .errstr_unpriv = "R1 leaks addr",
1360 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001361 },
1362 {
1363 "write skb fields from tc_cls_act prog",
1364 .insns = {
1365 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1366 offsetof(struct __sk_buff, cb[0])),
1367 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1368 offsetof(struct __sk_buff, mark)),
1369 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1370 offsetof(struct __sk_buff, tc_index)),
1371 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1372 offsetof(struct __sk_buff, tc_index)),
1373 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1374 offsetof(struct __sk_buff, cb[3])),
1375 BPF_EXIT_INSN(),
1376 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001377 .errstr_unpriv = "",
1378 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001379 .result = ACCEPT,
1380 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1381 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001382 {
1383 "PTR_TO_STACK store/load",
1384 .insns = {
1385 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1387 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1388 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1389 BPF_EXIT_INSN(),
1390 },
1391 .result = ACCEPT,
1392 },
1393 {
1394 "PTR_TO_STACK store/load - bad alignment on off",
1395 .insns = {
1396 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1397 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1398 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1399 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1400 BPF_EXIT_INSN(),
1401 },
1402 .result = REJECT,
1403 .errstr = "misaligned access off -6 size 8",
1404 },
1405 {
1406 "PTR_TO_STACK store/load - bad alignment on reg",
1407 .insns = {
1408 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1409 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1410 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1411 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1412 BPF_EXIT_INSN(),
1413 },
1414 .result = REJECT,
1415 .errstr = "misaligned access off -2 size 8",
1416 },
1417 {
1418 "PTR_TO_STACK store/load - out of bounds low",
1419 .insns = {
1420 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1422 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1423 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1424 BPF_EXIT_INSN(),
1425 },
1426 .result = REJECT,
1427 .errstr = "invalid stack off=-79992 size=8",
1428 },
1429 {
1430 "PTR_TO_STACK store/load - out of bounds high",
1431 .insns = {
1432 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1433 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1434 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1435 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1436 BPF_EXIT_INSN(),
1437 },
1438 .result = REJECT,
1439 .errstr = "invalid stack off=0 size=8",
1440 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001441 {
1442 "unpriv: return pointer",
1443 .insns = {
1444 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1445 BPF_EXIT_INSN(),
1446 },
1447 .result = ACCEPT,
1448 .result_unpriv = REJECT,
1449 .errstr_unpriv = "R0 leaks addr",
1450 },
1451 {
1452 "unpriv: add const to pointer",
1453 .insns = {
1454 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1455 BPF_MOV64_IMM(BPF_REG_0, 0),
1456 BPF_EXIT_INSN(),
1457 },
1458 .result = ACCEPT,
1459 .result_unpriv = REJECT,
1460 .errstr_unpriv = "R1 pointer arithmetic",
1461 },
1462 {
1463 "unpriv: add pointer to pointer",
1464 .insns = {
1465 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1466 BPF_MOV64_IMM(BPF_REG_0, 0),
1467 BPF_EXIT_INSN(),
1468 },
1469 .result = ACCEPT,
1470 .result_unpriv = REJECT,
1471 .errstr_unpriv = "R1 pointer arithmetic",
1472 },
1473 {
1474 "unpriv: neg pointer",
1475 .insns = {
1476 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1477 BPF_MOV64_IMM(BPF_REG_0, 0),
1478 BPF_EXIT_INSN(),
1479 },
1480 .result = ACCEPT,
1481 .result_unpriv = REJECT,
1482 .errstr_unpriv = "R1 pointer arithmetic",
1483 },
1484 {
1485 "unpriv: cmp pointer with const",
1486 .insns = {
1487 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1488 BPF_MOV64_IMM(BPF_REG_0, 0),
1489 BPF_EXIT_INSN(),
1490 },
1491 .result = ACCEPT,
1492 .result_unpriv = REJECT,
1493 .errstr_unpriv = "R1 pointer comparison",
1494 },
1495 {
1496 "unpriv: cmp pointer with pointer",
1497 .insns = {
1498 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1499 BPF_MOV64_IMM(BPF_REG_0, 0),
1500 BPF_EXIT_INSN(),
1501 },
1502 .result = ACCEPT,
1503 .result_unpriv = REJECT,
1504 .errstr_unpriv = "R10 pointer comparison",
1505 },
1506 {
1507 "unpriv: check that printk is disallowed",
1508 .insns = {
1509 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1510 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1511 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1512 BPF_MOV64_IMM(BPF_REG_2, 8),
1513 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001514 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1515 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001516 BPF_MOV64_IMM(BPF_REG_0, 0),
1517 BPF_EXIT_INSN(),
1518 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01001519 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001520 .result_unpriv = REJECT,
1521 .result = ACCEPT,
1522 },
1523 {
1524 "unpriv: pass pointer to helper function",
1525 .insns = {
1526 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1527 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1528 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1529 BPF_LD_MAP_FD(BPF_REG_1, 0),
1530 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1531 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001532 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1533 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001534 BPF_MOV64_IMM(BPF_REG_0, 0),
1535 BPF_EXIT_INSN(),
1536 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001537 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001538 .errstr_unpriv = "R4 leaks addr",
1539 .result_unpriv = REJECT,
1540 .result = ACCEPT,
1541 },
1542 {
1543 "unpriv: indirectly pass pointer on stack to helper function",
1544 .insns = {
1545 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1546 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1547 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1548 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001549 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1550 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001551 BPF_MOV64_IMM(BPF_REG_0, 0),
1552 BPF_EXIT_INSN(),
1553 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001554 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001555 .errstr = "invalid indirect read from stack off -8+0 size 8",
1556 .result = REJECT,
1557 },
1558 {
1559 "unpriv: mangle pointer on stack 1",
1560 .insns = {
1561 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1562 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1563 BPF_MOV64_IMM(BPF_REG_0, 0),
1564 BPF_EXIT_INSN(),
1565 },
1566 .errstr_unpriv = "attempt to corrupt spilled",
1567 .result_unpriv = REJECT,
1568 .result = ACCEPT,
1569 },
1570 {
1571 "unpriv: mangle pointer on stack 2",
1572 .insns = {
1573 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1574 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1575 BPF_MOV64_IMM(BPF_REG_0, 0),
1576 BPF_EXIT_INSN(),
1577 },
1578 .errstr_unpriv = "attempt to corrupt spilled",
1579 .result_unpriv = REJECT,
1580 .result = ACCEPT,
1581 },
1582 {
1583 "unpriv: read pointer from stack in small chunks",
1584 .insns = {
1585 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1586 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1587 BPF_MOV64_IMM(BPF_REG_0, 0),
1588 BPF_EXIT_INSN(),
1589 },
1590 .errstr = "invalid size",
1591 .result = REJECT,
1592 },
1593 {
1594 "unpriv: write pointer into ctx",
1595 .insns = {
1596 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1597 BPF_MOV64_IMM(BPF_REG_0, 0),
1598 BPF_EXIT_INSN(),
1599 },
1600 .errstr_unpriv = "R1 leaks addr",
1601 .result_unpriv = REJECT,
1602 .errstr = "invalid bpf_context access",
1603 .result = REJECT,
1604 },
1605 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001606 "unpriv: spill/fill of ctx",
1607 .insns = {
1608 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1610 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1611 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1612 BPF_MOV64_IMM(BPF_REG_0, 0),
1613 BPF_EXIT_INSN(),
1614 },
1615 .result = ACCEPT,
1616 },
1617 {
1618 "unpriv: spill/fill of ctx 2",
1619 .insns = {
1620 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1621 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1622 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1623 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001624 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1625 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001626 BPF_EXIT_INSN(),
1627 },
1628 .result = ACCEPT,
1629 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1630 },
1631 {
1632 "unpriv: spill/fill of ctx 3",
1633 .insns = {
1634 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1635 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1636 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1637 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1638 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001639 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1640 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001641 BPF_EXIT_INSN(),
1642 },
1643 .result = REJECT,
1644 .errstr = "R1 type=fp expected=ctx",
1645 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1646 },
1647 {
1648 "unpriv: spill/fill of ctx 4",
1649 .insns = {
1650 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1651 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1652 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1653 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001654 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
1655 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001656 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001657 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1658 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001659 BPF_EXIT_INSN(),
1660 },
1661 .result = REJECT,
1662 .errstr = "R1 type=inv expected=ctx",
1663 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1664 },
1665 {
1666 "unpriv: spill/fill of different pointers stx",
1667 .insns = {
1668 BPF_MOV64_IMM(BPF_REG_3, 42),
1669 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1670 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1672 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1674 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1675 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1676 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1677 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1678 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
1679 offsetof(struct __sk_buff, mark)),
1680 BPF_MOV64_IMM(BPF_REG_0, 0),
1681 BPF_EXIT_INSN(),
1682 },
1683 .result = REJECT,
1684 .errstr = "same insn cannot be used with different pointers",
1685 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1686 },
1687 {
1688 "unpriv: spill/fill of different pointers ldx",
1689 .insns = {
1690 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1691 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1692 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1693 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
1695 -(__s32)offsetof(struct bpf_perf_event_data,
1696 sample_period) - 8),
1697 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1698 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1699 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1700 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1701 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
1702 offsetof(struct bpf_perf_event_data,
1703 sample_period)),
1704 BPF_MOV64_IMM(BPF_REG_0, 0),
1705 BPF_EXIT_INSN(),
1706 },
1707 .result = REJECT,
1708 .errstr = "same insn cannot be used with different pointers",
1709 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
1710 },
1711 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001712 "unpriv: write pointer into map elem value",
1713 .insns = {
1714 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1715 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1716 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1717 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001718 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1719 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001720 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1721 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1722 BPF_EXIT_INSN(),
1723 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001724 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001725 .errstr_unpriv = "R0 leaks addr",
1726 .result_unpriv = REJECT,
1727 .result = ACCEPT,
1728 },
1729 {
1730 "unpriv: partial copy of pointer",
1731 .insns = {
1732 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1733 BPF_MOV64_IMM(BPF_REG_0, 0),
1734 BPF_EXIT_INSN(),
1735 },
1736 .errstr_unpriv = "R10 partial copy",
1737 .result_unpriv = REJECT,
1738 .result = ACCEPT,
1739 },
1740 {
1741 "unpriv: pass pointer to tail_call",
1742 .insns = {
1743 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1744 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001745 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1746 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001747 BPF_MOV64_IMM(BPF_REG_0, 0),
1748 BPF_EXIT_INSN(),
1749 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001750 .fixup_prog = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001751 .errstr_unpriv = "R3 leaks addr into helper",
1752 .result_unpriv = REJECT,
1753 .result = ACCEPT,
1754 },
1755 {
1756 "unpriv: cmp map pointer with zero",
1757 .insns = {
1758 BPF_MOV64_IMM(BPF_REG_1, 0),
1759 BPF_LD_MAP_FD(BPF_REG_1, 0),
1760 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1761 BPF_MOV64_IMM(BPF_REG_0, 0),
1762 BPF_EXIT_INSN(),
1763 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001764 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001765 .errstr_unpriv = "R1 pointer comparison",
1766 .result_unpriv = REJECT,
1767 .result = ACCEPT,
1768 },
1769 {
1770 "unpriv: write into frame pointer",
1771 .insns = {
1772 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1773 BPF_MOV64_IMM(BPF_REG_0, 0),
1774 BPF_EXIT_INSN(),
1775 },
1776 .errstr = "frame pointer is read only",
1777 .result = REJECT,
1778 },
1779 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001780 "unpriv: spill/fill frame pointer",
1781 .insns = {
1782 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1784 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1785 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
1786 BPF_MOV64_IMM(BPF_REG_0, 0),
1787 BPF_EXIT_INSN(),
1788 },
1789 .errstr = "frame pointer is read only",
1790 .result = REJECT,
1791 },
1792 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001793 "unpriv: cmp of frame pointer",
1794 .insns = {
1795 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1796 BPF_MOV64_IMM(BPF_REG_0, 0),
1797 BPF_EXIT_INSN(),
1798 },
1799 .errstr_unpriv = "R10 pointer comparison",
1800 .result_unpriv = REJECT,
1801 .result = ACCEPT,
1802 },
1803 {
1804 "unpriv: cmp of stack pointer",
1805 .insns = {
1806 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1808 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1809 BPF_MOV64_IMM(BPF_REG_0, 0),
1810 BPF_EXIT_INSN(),
1811 },
1812 .errstr_unpriv = "R2 pointer comparison",
1813 .result_unpriv = REJECT,
1814 .result = ACCEPT,
1815 },
1816 {
1817 "unpriv: obfuscate stack pointer",
1818 .insns = {
1819 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1821 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1822 BPF_MOV64_IMM(BPF_REG_0, 0),
1823 BPF_EXIT_INSN(),
1824 },
1825 .errstr_unpriv = "R2 pointer arithmetic",
1826 .result_unpriv = REJECT,
1827 .result = ACCEPT,
1828 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001829 {
1830 "raw_stack: no skb_load_bytes",
1831 .insns = {
1832 BPF_MOV64_IMM(BPF_REG_2, 4),
1833 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1834 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1835 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1836 BPF_MOV64_IMM(BPF_REG_4, 8),
1837 /* Call to skb_load_bytes() omitted. */
1838 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1839 BPF_EXIT_INSN(),
1840 },
1841 .result = REJECT,
1842 .errstr = "invalid read from stack off -8+0 size 8",
1843 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1844 },
1845 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001846 "raw_stack: skb_load_bytes, negative len",
1847 .insns = {
1848 BPF_MOV64_IMM(BPF_REG_2, 4),
1849 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1851 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1852 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001853 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1854 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001855 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1856 BPF_EXIT_INSN(),
1857 },
1858 .result = REJECT,
1859 .errstr = "invalid stack type R3",
1860 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1861 },
1862 {
1863 "raw_stack: skb_load_bytes, negative len 2",
1864 .insns = {
1865 BPF_MOV64_IMM(BPF_REG_2, 4),
1866 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1867 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1868 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1869 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001870 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1871 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001872 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1873 BPF_EXIT_INSN(),
1874 },
1875 .result = REJECT,
1876 .errstr = "invalid stack type R3",
1877 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1878 },
1879 {
1880 "raw_stack: skb_load_bytes, zero len",
1881 .insns = {
1882 BPF_MOV64_IMM(BPF_REG_2, 4),
1883 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1885 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1886 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001887 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1888 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001889 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1890 BPF_EXIT_INSN(),
1891 },
1892 .result = REJECT,
1893 .errstr = "invalid stack type R3",
1894 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1895 },
1896 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001897 "raw_stack: skb_load_bytes, no init",
1898 .insns = {
1899 BPF_MOV64_IMM(BPF_REG_2, 4),
1900 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1901 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1902 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1903 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001904 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1905 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001906 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1907 BPF_EXIT_INSN(),
1908 },
1909 .result = ACCEPT,
1910 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1911 },
1912 {
1913 "raw_stack: skb_load_bytes, init",
1914 .insns = {
1915 BPF_MOV64_IMM(BPF_REG_2, 4),
1916 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1917 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1918 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1919 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1920 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001921 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1922 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001923 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1924 BPF_EXIT_INSN(),
1925 },
1926 .result = ACCEPT,
1927 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1928 },
1929 {
1930 "raw_stack: skb_load_bytes, spilled regs around bounds",
1931 .insns = {
1932 BPF_MOV64_IMM(BPF_REG_2, 4),
1933 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1934 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001935 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1936 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001937 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1938 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001939 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1940 BPF_FUNC_skb_load_bytes),
1941 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1942 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001943 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1944 offsetof(struct __sk_buff, mark)),
1945 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1946 offsetof(struct __sk_buff, priority)),
1947 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1948 BPF_EXIT_INSN(),
1949 },
1950 .result = ACCEPT,
1951 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1952 },
1953 {
1954 "raw_stack: skb_load_bytes, spilled regs corruption",
1955 .insns = {
1956 BPF_MOV64_IMM(BPF_REG_2, 4),
1957 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001959 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001960 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1961 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1963 BPF_FUNC_skb_load_bytes),
1964 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001965 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1966 offsetof(struct __sk_buff, mark)),
1967 BPF_EXIT_INSN(),
1968 },
1969 .result = REJECT,
1970 .errstr = "R0 invalid mem access 'inv'",
1971 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1972 },
1973 {
1974 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1975 .insns = {
1976 BPF_MOV64_IMM(BPF_REG_2, 4),
1977 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1978 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001979 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1980 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1981 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001982 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1983 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001984 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1985 BPF_FUNC_skb_load_bytes),
1986 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1987 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
1988 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001989 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1990 offsetof(struct __sk_buff, mark)),
1991 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1992 offsetof(struct __sk_buff, priority)),
1993 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1994 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1995 offsetof(struct __sk_buff, pkt_type)),
1996 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1997 BPF_EXIT_INSN(),
1998 },
1999 .result = REJECT,
2000 .errstr = "R3 invalid mem access 'inv'",
2001 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2002 },
2003 {
2004 "raw_stack: skb_load_bytes, spilled regs + data",
2005 .insns = {
2006 BPF_MOV64_IMM(BPF_REG_2, 4),
2007 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2008 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002009 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
2010 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2011 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002012 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2013 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002014 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2015 BPF_FUNC_skb_load_bytes),
2016 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2017 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2018 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002019 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2020 offsetof(struct __sk_buff, mark)),
2021 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2022 offsetof(struct __sk_buff, priority)),
2023 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2024 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2025 BPF_EXIT_INSN(),
2026 },
2027 .result = ACCEPT,
2028 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2029 },
2030 {
2031 "raw_stack: skb_load_bytes, invalid access 1",
2032 .insns = {
2033 BPF_MOV64_IMM(BPF_REG_2, 4),
2034 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2035 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2036 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2037 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002038 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2039 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002040 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2041 BPF_EXIT_INSN(),
2042 },
2043 .result = REJECT,
2044 .errstr = "invalid stack type R3 off=-513 access_size=8",
2045 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2046 },
2047 {
2048 "raw_stack: skb_load_bytes, invalid access 2",
2049 .insns = {
2050 BPF_MOV64_IMM(BPF_REG_2, 4),
2051 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2053 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2054 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002055 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2056 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002057 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2058 BPF_EXIT_INSN(),
2059 },
2060 .result = REJECT,
2061 .errstr = "invalid stack type R3 off=-1 access_size=8",
2062 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2063 },
2064 {
2065 "raw_stack: skb_load_bytes, invalid access 3",
2066 .insns = {
2067 BPF_MOV64_IMM(BPF_REG_2, 4),
2068 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2069 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2070 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2071 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002072 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2073 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002074 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2075 BPF_EXIT_INSN(),
2076 },
2077 .result = REJECT,
2078 .errstr = "invalid stack type R3 off=-1 access_size=-1",
2079 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2080 },
2081 {
2082 "raw_stack: skb_load_bytes, invalid access 4",
2083 .insns = {
2084 BPF_MOV64_IMM(BPF_REG_2, 4),
2085 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2086 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2087 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2088 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002089 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2090 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002091 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2092 BPF_EXIT_INSN(),
2093 },
2094 .result = REJECT,
2095 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
2096 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2097 },
2098 {
2099 "raw_stack: skb_load_bytes, invalid access 5",
2100 .insns = {
2101 BPF_MOV64_IMM(BPF_REG_2, 4),
2102 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2104 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2105 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002106 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2107 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002108 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2109 BPF_EXIT_INSN(),
2110 },
2111 .result = REJECT,
2112 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
2113 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2114 },
2115 {
2116 "raw_stack: skb_load_bytes, invalid access 6",
2117 .insns = {
2118 BPF_MOV64_IMM(BPF_REG_2, 4),
2119 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2120 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2121 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2122 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002123 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2124 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002125 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2126 BPF_EXIT_INSN(),
2127 },
2128 .result = REJECT,
2129 .errstr = "invalid stack type R3 off=-512 access_size=0",
2130 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2131 },
2132 {
2133 "raw_stack: skb_load_bytes, large access",
2134 .insns = {
2135 BPF_MOV64_IMM(BPF_REG_2, 4),
2136 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2137 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2138 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2139 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002140 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2141 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002142 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2143 BPF_EXIT_INSN(),
2144 },
2145 .result = ACCEPT,
2146 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2147 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002148 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002149 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002150 .insns = {
2151 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2152 offsetof(struct __sk_buff, data)),
2153 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2154 offsetof(struct __sk_buff, data_end)),
2155 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2157 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2158 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2159 BPF_MOV64_IMM(BPF_REG_0, 0),
2160 BPF_EXIT_INSN(),
2161 },
2162 .result = ACCEPT,
2163 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2164 },
2165 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002166 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002167 .insns = {
2168 BPF_MOV64_IMM(BPF_REG_0, 1),
2169 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2170 offsetof(struct __sk_buff, data_end)),
2171 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2172 offsetof(struct __sk_buff, data)),
2173 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2175 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2176 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2177 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2178 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2179 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2180 offsetof(struct __sk_buff, data)),
2181 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
2182 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
2183 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
2184 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
2185 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2186 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2187 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2188 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2189 offsetof(struct __sk_buff, data_end)),
2190 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2191 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2192 BPF_MOV64_IMM(BPF_REG_0, 0),
2193 BPF_EXIT_INSN(),
2194 },
2195 .result = ACCEPT,
2196 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2197 },
2198 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002199 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002200 .insns = {
2201 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2202 offsetof(struct __sk_buff, data)),
2203 BPF_MOV64_IMM(BPF_REG_0, 0),
2204 BPF_EXIT_INSN(),
2205 },
2206 .errstr = "invalid bpf_context access off=76",
2207 .result = REJECT,
2208 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2209 },
2210 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002211 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002212 .insns = {
2213 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2214 offsetof(struct __sk_buff, data)),
2215 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2216 offsetof(struct __sk_buff, data_end)),
2217 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2219 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2220 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2221 BPF_MOV64_IMM(BPF_REG_0, 0),
2222 BPF_EXIT_INSN(),
2223 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002224 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002225 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2226 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002227 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02002228 "direct packet access: test5 (pkt_end >= reg, good access)",
2229 .insns = {
2230 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2231 offsetof(struct __sk_buff, data)),
2232 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2233 offsetof(struct __sk_buff, data_end)),
2234 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2235 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2236 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2237 BPF_MOV64_IMM(BPF_REG_0, 1),
2238 BPF_EXIT_INSN(),
2239 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2240 BPF_MOV64_IMM(BPF_REG_0, 0),
2241 BPF_EXIT_INSN(),
2242 },
2243 .result = ACCEPT,
2244 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2245 },
2246 {
2247 "direct packet access: test6 (pkt_end >= reg, bad access)",
2248 .insns = {
2249 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2250 offsetof(struct __sk_buff, data)),
2251 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2252 offsetof(struct __sk_buff, data_end)),
2253 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2255 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2256 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2257 BPF_MOV64_IMM(BPF_REG_0, 1),
2258 BPF_EXIT_INSN(),
2259 BPF_MOV64_IMM(BPF_REG_0, 0),
2260 BPF_EXIT_INSN(),
2261 },
2262 .errstr = "invalid access to packet",
2263 .result = REJECT,
2264 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2265 },
2266 {
2267 "direct packet access: test7 (pkt_end >= reg, both accesses)",
2268 .insns = {
2269 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2270 offsetof(struct __sk_buff, data)),
2271 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2272 offsetof(struct __sk_buff, data_end)),
2273 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2274 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2275 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2276 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2277 BPF_MOV64_IMM(BPF_REG_0, 1),
2278 BPF_EXIT_INSN(),
2279 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2280 BPF_MOV64_IMM(BPF_REG_0, 0),
2281 BPF_EXIT_INSN(),
2282 },
2283 .errstr = "invalid access to packet",
2284 .result = REJECT,
2285 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2286 },
2287 {
2288 "direct packet access: test8 (double test, variant 1)",
2289 .insns = {
2290 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2291 offsetof(struct __sk_buff, data)),
2292 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2293 offsetof(struct __sk_buff, data_end)),
2294 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2295 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2296 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2297 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2298 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2299 BPF_MOV64_IMM(BPF_REG_0, 1),
2300 BPF_EXIT_INSN(),
2301 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2302 BPF_MOV64_IMM(BPF_REG_0, 0),
2303 BPF_EXIT_INSN(),
2304 },
2305 .result = ACCEPT,
2306 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2307 },
2308 {
2309 "direct packet access: test9 (double test, variant 2)",
2310 .insns = {
2311 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2312 offsetof(struct __sk_buff, data)),
2313 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2314 offsetof(struct __sk_buff, data_end)),
2315 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2316 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2317 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2318 BPF_MOV64_IMM(BPF_REG_0, 1),
2319 BPF_EXIT_INSN(),
2320 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2321 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2322 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2323 BPF_MOV64_IMM(BPF_REG_0, 0),
2324 BPF_EXIT_INSN(),
2325 },
2326 .result = ACCEPT,
2327 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2328 },
2329 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002330 "direct packet access: test10 (write invalid)",
2331 .insns = {
2332 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2333 offsetof(struct __sk_buff, data)),
2334 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2335 offsetof(struct __sk_buff, data_end)),
2336 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2337 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2338 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2339 BPF_MOV64_IMM(BPF_REG_0, 0),
2340 BPF_EXIT_INSN(),
2341 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2342 BPF_MOV64_IMM(BPF_REG_0, 0),
2343 BPF_EXIT_INSN(),
2344 },
2345 .errstr = "invalid access to packet",
2346 .result = REJECT,
2347 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2348 },
2349 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01002350 "direct packet access: test11 (shift, good access)",
2351 .insns = {
2352 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2353 offsetof(struct __sk_buff, data)),
2354 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2355 offsetof(struct __sk_buff, data_end)),
2356 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2357 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2358 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2359 BPF_MOV64_IMM(BPF_REG_3, 144),
2360 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2362 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2363 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2364 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2365 BPF_MOV64_IMM(BPF_REG_0, 1),
2366 BPF_EXIT_INSN(),
2367 BPF_MOV64_IMM(BPF_REG_0, 0),
2368 BPF_EXIT_INSN(),
2369 },
2370 .result = ACCEPT,
2371 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2372 },
2373 {
2374 "direct packet access: test12 (and, good access)",
2375 .insns = {
2376 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2377 offsetof(struct __sk_buff, data)),
2378 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2379 offsetof(struct __sk_buff, data_end)),
2380 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2381 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2382 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2383 BPF_MOV64_IMM(BPF_REG_3, 144),
2384 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2385 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2386 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2387 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2388 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2389 BPF_MOV64_IMM(BPF_REG_0, 1),
2390 BPF_EXIT_INSN(),
2391 BPF_MOV64_IMM(BPF_REG_0, 0),
2392 BPF_EXIT_INSN(),
2393 },
2394 .result = ACCEPT,
2395 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2396 },
2397 {
2398 "direct packet access: test13 (branches, good access)",
2399 .insns = {
2400 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2401 offsetof(struct __sk_buff, data)),
2402 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2403 offsetof(struct __sk_buff, data_end)),
2404 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2405 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2406 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2407 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2408 offsetof(struct __sk_buff, mark)),
2409 BPF_MOV64_IMM(BPF_REG_4, 1),
2410 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2411 BPF_MOV64_IMM(BPF_REG_3, 14),
2412 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2413 BPF_MOV64_IMM(BPF_REG_3, 24),
2414 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2415 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2416 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2417 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2418 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2419 BPF_MOV64_IMM(BPF_REG_0, 1),
2420 BPF_EXIT_INSN(),
2421 BPF_MOV64_IMM(BPF_REG_0, 0),
2422 BPF_EXIT_INSN(),
2423 },
2424 .result = ACCEPT,
2425 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2426 },
2427 {
William Tu63dfef72017-02-04 08:37:29 -08002428 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2429 .insns = {
2430 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2431 offsetof(struct __sk_buff, data)),
2432 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2433 offsetof(struct __sk_buff, data_end)),
2434 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2435 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2436 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2437 BPF_MOV64_IMM(BPF_REG_5, 12),
2438 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2439 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2440 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2441 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2442 BPF_MOV64_IMM(BPF_REG_0, 1),
2443 BPF_EXIT_INSN(),
2444 BPF_MOV64_IMM(BPF_REG_0, 0),
2445 BPF_EXIT_INSN(),
2446 },
2447 .result = ACCEPT,
2448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2449 },
2450 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02002451 "direct packet access: test15 (spill with xadd)",
2452 .insns = {
2453 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2454 offsetof(struct __sk_buff, data)),
2455 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2456 offsetof(struct __sk_buff, data_end)),
2457 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2458 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2459 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2460 BPF_MOV64_IMM(BPF_REG_5, 4096),
2461 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2462 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2463 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2464 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
2465 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
2466 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
2467 BPF_MOV64_IMM(BPF_REG_0, 0),
2468 BPF_EXIT_INSN(),
2469 },
2470 .errstr = "R2 invalid mem access 'inv'",
2471 .result = REJECT,
2472 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2473 },
2474 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002475 "helper access to packet: test1, valid packet_ptr range",
2476 .insns = {
2477 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2478 offsetof(struct xdp_md, data)),
2479 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2480 offsetof(struct xdp_md, data_end)),
2481 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2482 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2483 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2484 BPF_LD_MAP_FD(BPF_REG_1, 0),
2485 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2486 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002487 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2488 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002489 BPF_MOV64_IMM(BPF_REG_0, 0),
2490 BPF_EXIT_INSN(),
2491 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002492 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002493 .result_unpriv = ACCEPT,
2494 .result = ACCEPT,
2495 .prog_type = BPF_PROG_TYPE_XDP,
2496 },
2497 {
2498 "helper access to packet: test2, unchecked packet_ptr",
2499 .insns = {
2500 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2501 offsetof(struct xdp_md, data)),
2502 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002503 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2504 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002505 BPF_MOV64_IMM(BPF_REG_0, 0),
2506 BPF_EXIT_INSN(),
2507 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002508 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002509 .result = REJECT,
2510 .errstr = "invalid access to packet",
2511 .prog_type = BPF_PROG_TYPE_XDP,
2512 },
2513 {
2514 "helper access to packet: test3, variable add",
2515 .insns = {
2516 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2517 offsetof(struct xdp_md, data)),
2518 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2519 offsetof(struct xdp_md, data_end)),
2520 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2522 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2523 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2524 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2525 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2526 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2527 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2528 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2529 BPF_LD_MAP_FD(BPF_REG_1, 0),
2530 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002531 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2532 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002533 BPF_MOV64_IMM(BPF_REG_0, 0),
2534 BPF_EXIT_INSN(),
2535 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002536 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002537 .result = ACCEPT,
2538 .prog_type = BPF_PROG_TYPE_XDP,
2539 },
2540 {
2541 "helper access to packet: test4, packet_ptr with bad range",
2542 .insns = {
2543 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2544 offsetof(struct xdp_md, data)),
2545 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2546 offsetof(struct xdp_md, data_end)),
2547 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2548 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2549 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2550 BPF_MOV64_IMM(BPF_REG_0, 0),
2551 BPF_EXIT_INSN(),
2552 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002553 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2554 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002555 BPF_MOV64_IMM(BPF_REG_0, 0),
2556 BPF_EXIT_INSN(),
2557 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002558 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002559 .result = REJECT,
2560 .errstr = "invalid access to packet",
2561 .prog_type = BPF_PROG_TYPE_XDP,
2562 },
2563 {
2564 "helper access to packet: test5, packet_ptr with too short range",
2565 .insns = {
2566 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2567 offsetof(struct xdp_md, data)),
2568 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2569 offsetof(struct xdp_md, data_end)),
2570 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2571 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2573 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2574 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002575 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2576 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002577 BPF_MOV64_IMM(BPF_REG_0, 0),
2578 BPF_EXIT_INSN(),
2579 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002580 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002581 .result = REJECT,
2582 .errstr = "invalid access to packet",
2583 .prog_type = BPF_PROG_TYPE_XDP,
2584 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002585 {
2586 "helper access to packet: test6, cls valid packet_ptr range",
2587 .insns = {
2588 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2589 offsetof(struct __sk_buff, data)),
2590 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2591 offsetof(struct __sk_buff, data_end)),
2592 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2594 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2595 BPF_LD_MAP_FD(BPF_REG_1, 0),
2596 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2597 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002598 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2599 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002600 BPF_MOV64_IMM(BPF_REG_0, 0),
2601 BPF_EXIT_INSN(),
2602 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002603 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002604 .result = ACCEPT,
2605 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2606 },
2607 {
2608 "helper access to packet: test7, cls unchecked packet_ptr",
2609 .insns = {
2610 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2611 offsetof(struct __sk_buff, data)),
2612 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002613 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2614 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002615 BPF_MOV64_IMM(BPF_REG_0, 0),
2616 BPF_EXIT_INSN(),
2617 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002618 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002619 .result = REJECT,
2620 .errstr = "invalid access to packet",
2621 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2622 },
2623 {
2624 "helper access to packet: test8, cls variable add",
2625 .insns = {
2626 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2627 offsetof(struct __sk_buff, data)),
2628 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2629 offsetof(struct __sk_buff, data_end)),
2630 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2632 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2633 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2634 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2635 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2636 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2638 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2639 BPF_LD_MAP_FD(BPF_REG_1, 0),
2640 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002641 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2642 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002643 BPF_MOV64_IMM(BPF_REG_0, 0),
2644 BPF_EXIT_INSN(),
2645 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002646 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002647 .result = ACCEPT,
2648 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2649 },
2650 {
2651 "helper access to packet: test9, cls packet_ptr with bad range",
2652 .insns = {
2653 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2654 offsetof(struct __sk_buff, data)),
2655 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2656 offsetof(struct __sk_buff, data_end)),
2657 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2659 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2660 BPF_MOV64_IMM(BPF_REG_0, 0),
2661 BPF_EXIT_INSN(),
2662 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002663 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2664 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002665 BPF_MOV64_IMM(BPF_REG_0, 0),
2666 BPF_EXIT_INSN(),
2667 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002668 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002669 .result = REJECT,
2670 .errstr = "invalid access to packet",
2671 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2672 },
2673 {
2674 "helper access to packet: test10, cls packet_ptr with too short range",
2675 .insns = {
2676 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2677 offsetof(struct __sk_buff, data)),
2678 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2679 offsetof(struct __sk_buff, data_end)),
2680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2681 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2682 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2683 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2684 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002685 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2686 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002687 BPF_MOV64_IMM(BPF_REG_0, 0),
2688 BPF_EXIT_INSN(),
2689 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002690 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002691 .result = REJECT,
2692 .errstr = "invalid access to packet",
2693 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2694 },
2695 {
2696 "helper access to packet: test11, cls unsuitable helper 1",
2697 .insns = {
2698 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2699 offsetof(struct __sk_buff, data)),
2700 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2701 offsetof(struct __sk_buff, data_end)),
2702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2703 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2704 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
2705 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
2706 BPF_MOV64_IMM(BPF_REG_2, 0),
2707 BPF_MOV64_IMM(BPF_REG_4, 42),
2708 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002709 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2710 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002711 BPF_MOV64_IMM(BPF_REG_0, 0),
2712 BPF_EXIT_INSN(),
2713 },
2714 .result = REJECT,
2715 .errstr = "helper access to the packet",
2716 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2717 },
2718 {
2719 "helper access to packet: test12, cls unsuitable helper 2",
2720 .insns = {
2721 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2722 offsetof(struct __sk_buff, data)),
2723 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2724 offsetof(struct __sk_buff, data_end)),
2725 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
2727 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
2728 BPF_MOV64_IMM(BPF_REG_2, 0),
2729 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002730 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2731 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002732 BPF_MOV64_IMM(BPF_REG_0, 0),
2733 BPF_EXIT_INSN(),
2734 },
2735 .result = REJECT,
2736 .errstr = "helper access to the packet",
2737 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2738 },
2739 {
2740 "helper access to packet: test13, cls helper ok",
2741 .insns = {
2742 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2743 offsetof(struct __sk_buff, data)),
2744 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2745 offsetof(struct __sk_buff, data_end)),
2746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2747 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2748 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2749 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2750 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2751 BPF_MOV64_IMM(BPF_REG_2, 4),
2752 BPF_MOV64_IMM(BPF_REG_3, 0),
2753 BPF_MOV64_IMM(BPF_REG_4, 0),
2754 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002755 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2756 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002757 BPF_MOV64_IMM(BPF_REG_0, 0),
2758 BPF_EXIT_INSN(),
2759 },
2760 .result = ACCEPT,
2761 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2762 },
2763 {
2764 "helper access to packet: test14, cls helper fail sub",
2765 .insns = {
2766 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2767 offsetof(struct __sk_buff, data)),
2768 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2769 offsetof(struct __sk_buff, data_end)),
2770 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2771 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2773 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2774 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2775 BPF_MOV64_IMM(BPF_REG_2, 4),
2776 BPF_MOV64_IMM(BPF_REG_3, 0),
2777 BPF_MOV64_IMM(BPF_REG_4, 0),
2778 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002779 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2780 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002781 BPF_MOV64_IMM(BPF_REG_0, 0),
2782 BPF_EXIT_INSN(),
2783 },
2784 .result = REJECT,
2785 .errstr = "type=inv expected=fp",
2786 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2787 },
2788 {
2789 "helper access to packet: test15, cls helper fail range 1",
2790 .insns = {
2791 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2792 offsetof(struct __sk_buff, data)),
2793 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2794 offsetof(struct __sk_buff, data_end)),
2795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2796 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2798 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2799 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2800 BPF_MOV64_IMM(BPF_REG_2, 8),
2801 BPF_MOV64_IMM(BPF_REG_3, 0),
2802 BPF_MOV64_IMM(BPF_REG_4, 0),
2803 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002804 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2805 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002806 BPF_MOV64_IMM(BPF_REG_0, 0),
2807 BPF_EXIT_INSN(),
2808 },
2809 .result = REJECT,
2810 .errstr = "invalid access to packet",
2811 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2812 },
2813 {
2814 "helper access to packet: test16, cls helper fail range 2",
2815 .insns = {
2816 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2817 offsetof(struct __sk_buff, data)),
2818 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2819 offsetof(struct __sk_buff, data_end)),
2820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2821 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2823 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2824 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2825 BPF_MOV64_IMM(BPF_REG_2, -9),
2826 BPF_MOV64_IMM(BPF_REG_3, 0),
2827 BPF_MOV64_IMM(BPF_REG_4, 0),
2828 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002829 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2830 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002831 BPF_MOV64_IMM(BPF_REG_0, 0),
2832 BPF_EXIT_INSN(),
2833 },
2834 .result = REJECT,
2835 .errstr = "invalid access to packet",
2836 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2837 },
2838 {
2839 "helper access to packet: test17, cls helper fail range 3",
2840 .insns = {
2841 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2842 offsetof(struct __sk_buff, data)),
2843 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2844 offsetof(struct __sk_buff, data_end)),
2845 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2846 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2847 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2848 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2849 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2850 BPF_MOV64_IMM(BPF_REG_2, ~0),
2851 BPF_MOV64_IMM(BPF_REG_3, 0),
2852 BPF_MOV64_IMM(BPF_REG_4, 0),
2853 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002854 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2855 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002856 BPF_MOV64_IMM(BPF_REG_0, 0),
2857 BPF_EXIT_INSN(),
2858 },
2859 .result = REJECT,
2860 .errstr = "invalid access to packet",
2861 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2862 },
2863 {
2864 "helper access to packet: test18, cls helper fail range zero",
2865 .insns = {
2866 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2867 offsetof(struct __sk_buff, data)),
2868 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2869 offsetof(struct __sk_buff, data_end)),
2870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2871 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2872 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2873 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2874 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2875 BPF_MOV64_IMM(BPF_REG_2, 0),
2876 BPF_MOV64_IMM(BPF_REG_3, 0),
2877 BPF_MOV64_IMM(BPF_REG_4, 0),
2878 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002879 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2880 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002881 BPF_MOV64_IMM(BPF_REG_0, 0),
2882 BPF_EXIT_INSN(),
2883 },
2884 .result = REJECT,
2885 .errstr = "invalid access to packet",
2886 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2887 },
2888 {
2889 "helper access to packet: test19, pkt end as input",
2890 .insns = {
2891 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2892 offsetof(struct __sk_buff, data)),
2893 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2894 offsetof(struct __sk_buff, data_end)),
2895 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2896 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2898 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2899 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2900 BPF_MOV64_IMM(BPF_REG_2, 4),
2901 BPF_MOV64_IMM(BPF_REG_3, 0),
2902 BPF_MOV64_IMM(BPF_REG_4, 0),
2903 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002904 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2905 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002906 BPF_MOV64_IMM(BPF_REG_0, 0),
2907 BPF_EXIT_INSN(),
2908 },
2909 .result = REJECT,
2910 .errstr = "R1 type=pkt_end expected=fp",
2911 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2912 },
2913 {
2914 "helper access to packet: test20, wrong reg",
2915 .insns = {
2916 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2917 offsetof(struct __sk_buff, data)),
2918 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2919 offsetof(struct __sk_buff, data_end)),
2920 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2921 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2923 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2924 BPF_MOV64_IMM(BPF_REG_2, 4),
2925 BPF_MOV64_IMM(BPF_REG_3, 0),
2926 BPF_MOV64_IMM(BPF_REG_4, 0),
2927 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002928 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2929 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002930 BPF_MOV64_IMM(BPF_REG_0, 0),
2931 BPF_EXIT_INSN(),
2932 },
2933 .result = REJECT,
2934 .errstr = "invalid access to packet",
2935 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2936 },
Josef Bacik48461132016-09-28 10:54:32 -04002937 {
2938 "valid map access into an array with a constant",
2939 .insns = {
2940 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2943 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002944 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2945 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002946 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002947 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2948 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002949 BPF_EXIT_INSN(),
2950 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002951 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04002952 .errstr_unpriv = "R0 leaks addr",
2953 .result_unpriv = REJECT,
2954 .result = ACCEPT,
2955 },
2956 {
2957 "valid map access into an array with a register",
2958 .insns = {
2959 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2960 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2961 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2962 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002963 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2964 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002965 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2966 BPF_MOV64_IMM(BPF_REG_1, 4),
2967 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2968 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002969 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2970 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002971 BPF_EXIT_INSN(),
2972 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002973 .fixup_map2 = { 3 },
2974 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04002975 .result_unpriv = REJECT,
2976 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02002977 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04002978 },
2979 {
2980 "valid map access into an array with a variable",
2981 .insns = {
2982 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2983 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2984 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2985 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002986 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2987 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002988 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2989 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2990 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2991 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2992 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002993 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2994 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002995 BPF_EXIT_INSN(),
2996 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002997 .fixup_map2 = { 3 },
2998 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04002999 .result_unpriv = REJECT,
3000 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003001 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003002 },
3003 {
3004 "valid map access into an array with a signed variable",
3005 .insns = {
3006 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3007 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3008 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3009 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003010 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3011 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003012 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
3013 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3014 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
3015 BPF_MOV32_IMM(BPF_REG_1, 0),
3016 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3017 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3018 BPF_MOV32_IMM(BPF_REG_1, 0),
3019 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3020 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003021 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3022 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003023 BPF_EXIT_INSN(),
3024 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003025 .fixup_map2 = { 3 },
3026 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003027 .result_unpriv = REJECT,
3028 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003029 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003030 },
3031 {
3032 "invalid map access into an array with a constant",
3033 .insns = {
3034 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3035 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3037 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003038 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3039 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003040 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3041 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
3042 offsetof(struct test_val, foo)),
3043 BPF_EXIT_INSN(),
3044 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003045 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003046 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
3047 .result = REJECT,
3048 },
3049 {
3050 "invalid map access into an array with a register",
3051 .insns = {
3052 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3053 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3054 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3055 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003056 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3057 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003058 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3059 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3060 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3061 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003062 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3063 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003064 BPF_EXIT_INSN(),
3065 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003066 .fixup_map2 = { 3 },
3067 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003068 .errstr = "R0 min value is outside of the array range",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003069 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003070 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003071 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003072 },
3073 {
3074 "invalid map access into an array with a variable",
3075 .insns = {
3076 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3077 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3079 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003080 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3081 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003082 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3083 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3084 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3085 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003086 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3087 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003088 BPF_EXIT_INSN(),
3089 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003090 .fixup_map2 = { 3 },
3091 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003092 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003093 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003094 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003095 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003096 },
3097 {
3098 "invalid map access into an array with no floor check",
3099 .insns = {
3100 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3101 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3103 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003104 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3105 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003106 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3107 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3108 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3109 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3110 BPF_MOV32_IMM(BPF_REG_1, 0),
3111 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3112 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003113 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3114 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003115 BPF_EXIT_INSN(),
3116 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003117 .fixup_map2 = { 3 },
3118 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003119 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003120 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003121 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003122 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003123 },
3124 {
3125 "invalid map access into an array with a invalid max check",
3126 .insns = {
3127 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3128 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3130 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003131 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3132 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003133 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3134 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3135 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3136 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3137 BPF_MOV32_IMM(BPF_REG_1, 0),
3138 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3139 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003140 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3141 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003142 BPF_EXIT_INSN(),
3143 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003144 .fixup_map2 = { 3 },
3145 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003146 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003147 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003148 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003149 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003150 },
3151 {
3152 "invalid map access into an array with a invalid max check",
3153 .insns = {
3154 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3155 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3157 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003158 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3159 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003160 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3161 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3162 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3163 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3165 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003166 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3167 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003168 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3169 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003170 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3171 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003172 BPF_EXIT_INSN(),
3173 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003174 .fixup_map2 = { 3, 11 },
3175 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003176 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003177 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003178 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003179 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04003180 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02003181 {
3182 "multiple registers share map_lookup_elem result",
3183 .insns = {
3184 BPF_MOV64_IMM(BPF_REG_1, 10),
3185 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3186 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3187 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3188 BPF_LD_MAP_FD(BPF_REG_1, 0),
3189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3190 BPF_FUNC_map_lookup_elem),
3191 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3192 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3193 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3194 BPF_EXIT_INSN(),
3195 },
3196 .fixup_map1 = { 4 },
3197 .result = ACCEPT,
3198 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3199 },
3200 {
3201 "invalid memory access with multiple map_lookup_elem calls",
3202 .insns = {
3203 BPF_MOV64_IMM(BPF_REG_1, 10),
3204 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3205 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3207 BPF_LD_MAP_FD(BPF_REG_1, 0),
3208 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3209 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3210 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3211 BPF_FUNC_map_lookup_elem),
3212 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3213 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3214 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3215 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3216 BPF_FUNC_map_lookup_elem),
3217 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3218 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3219 BPF_EXIT_INSN(),
3220 },
3221 .fixup_map1 = { 4 },
3222 .result = REJECT,
3223 .errstr = "R4 !read_ok",
3224 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3225 },
3226 {
3227 "valid indirect map_lookup_elem access with 2nd lookup in branch",
3228 .insns = {
3229 BPF_MOV64_IMM(BPF_REG_1, 10),
3230 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3231 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3232 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3233 BPF_LD_MAP_FD(BPF_REG_1, 0),
3234 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3235 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3237 BPF_FUNC_map_lookup_elem),
3238 BPF_MOV64_IMM(BPF_REG_2, 10),
3239 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
3240 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3241 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3243 BPF_FUNC_map_lookup_elem),
3244 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3245 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3246 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3247 BPF_EXIT_INSN(),
3248 },
3249 .fixup_map1 = { 4 },
3250 .result = ACCEPT,
3251 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3252 },
Josef Bacike9548902016-11-29 12:35:19 -05003253 {
Daniel Borkmanna08dd0d2016-12-15 01:30:06 +01003254 "multiple registers share map_lookup_elem bad reg type",
3255 .insns = {
3256 BPF_MOV64_IMM(BPF_REG_1, 10),
3257 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3258 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3260 BPF_LD_MAP_FD(BPF_REG_1, 0),
3261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3262 BPF_FUNC_map_lookup_elem),
3263 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
3264 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
3265 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3266 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3268 BPF_MOV64_IMM(BPF_REG_1, 1),
3269 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3270 BPF_MOV64_IMM(BPF_REG_1, 2),
3271 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1),
3272 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 0),
3273 BPF_MOV64_IMM(BPF_REG_1, 3),
3274 BPF_EXIT_INSN(),
3275 },
3276 .fixup_map1 = { 4 },
3277 .result = REJECT,
3278 .errstr = "R3 invalid mem access 'inv'",
3279 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3280 },
3281 {
Josef Bacike9548902016-11-29 12:35:19 -05003282 "invalid map access from else condition",
3283 .insns = {
3284 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3285 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3286 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3287 BPF_LD_MAP_FD(BPF_REG_1, 0),
3288 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
3289 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3290 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3291 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
3292 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
3293 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3294 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3295 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
3296 BPF_EXIT_INSN(),
3297 },
3298 .fixup_map2 = { 3 },
3299 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
3300 .result = REJECT,
3301 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3302 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003303 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacike9548902016-11-29 12:35:19 -05003304 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08003305 {
3306 "constant register |= constant should keep constant type",
3307 .insns = {
3308 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3309 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3310 BPF_MOV64_IMM(BPF_REG_2, 34),
3311 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
3312 BPF_MOV64_IMM(BPF_REG_3, 0),
3313 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3314 BPF_EXIT_INSN(),
3315 },
3316 .result = ACCEPT,
3317 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3318 },
3319 {
3320 "constant register |= constant should not bypass stack boundary checks",
3321 .insns = {
3322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3324 BPF_MOV64_IMM(BPF_REG_2, 34),
3325 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
3326 BPF_MOV64_IMM(BPF_REG_3, 0),
3327 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3328 BPF_EXIT_INSN(),
3329 },
3330 .errstr = "invalid stack type R1 off=-48 access_size=58",
3331 .result = REJECT,
3332 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3333 },
3334 {
3335 "constant register |= constant register should keep constant type",
3336 .insns = {
3337 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3339 BPF_MOV64_IMM(BPF_REG_2, 34),
3340 BPF_MOV64_IMM(BPF_REG_4, 13),
3341 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3342 BPF_MOV64_IMM(BPF_REG_3, 0),
3343 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3344 BPF_EXIT_INSN(),
3345 },
3346 .result = ACCEPT,
3347 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3348 },
3349 {
3350 "constant register |= constant register should not bypass stack boundary checks",
3351 .insns = {
3352 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3354 BPF_MOV64_IMM(BPF_REG_2, 34),
3355 BPF_MOV64_IMM(BPF_REG_4, 24),
3356 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3357 BPF_MOV64_IMM(BPF_REG_3, 0),
3358 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3359 BPF_EXIT_INSN(),
3360 },
3361 .errstr = "invalid stack type R1 off=-48 access_size=58",
3362 .result = REJECT,
3363 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3364 },
Thomas Graf3f731d82016-12-05 10:30:52 +01003365 {
3366 "invalid direct packet write for LWT_IN",
3367 .insns = {
3368 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3369 offsetof(struct __sk_buff, data)),
3370 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3371 offsetof(struct __sk_buff, data_end)),
3372 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3373 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3374 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3375 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3376 BPF_MOV64_IMM(BPF_REG_0, 0),
3377 BPF_EXIT_INSN(),
3378 },
3379 .errstr = "cannot write into packet",
3380 .result = REJECT,
3381 .prog_type = BPF_PROG_TYPE_LWT_IN,
3382 },
3383 {
3384 "invalid direct packet write for LWT_OUT",
3385 .insns = {
3386 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3387 offsetof(struct __sk_buff, data)),
3388 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3389 offsetof(struct __sk_buff, data_end)),
3390 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3392 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3393 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3394 BPF_MOV64_IMM(BPF_REG_0, 0),
3395 BPF_EXIT_INSN(),
3396 },
3397 .errstr = "cannot write into packet",
3398 .result = REJECT,
3399 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3400 },
3401 {
3402 "direct packet write for LWT_XMIT",
3403 .insns = {
3404 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3405 offsetof(struct __sk_buff, data)),
3406 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3407 offsetof(struct __sk_buff, data_end)),
3408 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3409 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3410 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3411 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3412 BPF_MOV64_IMM(BPF_REG_0, 0),
3413 BPF_EXIT_INSN(),
3414 },
3415 .result = ACCEPT,
3416 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3417 },
3418 {
3419 "direct packet read for LWT_IN",
3420 .insns = {
3421 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3422 offsetof(struct __sk_buff, data)),
3423 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3424 offsetof(struct __sk_buff, data_end)),
3425 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3426 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3427 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3428 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3429 BPF_MOV64_IMM(BPF_REG_0, 0),
3430 BPF_EXIT_INSN(),
3431 },
3432 .result = ACCEPT,
3433 .prog_type = BPF_PROG_TYPE_LWT_IN,
3434 },
3435 {
3436 "direct packet read for LWT_OUT",
3437 .insns = {
3438 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3439 offsetof(struct __sk_buff, data)),
3440 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3441 offsetof(struct __sk_buff, data_end)),
3442 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3444 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3445 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3446 BPF_MOV64_IMM(BPF_REG_0, 0),
3447 BPF_EXIT_INSN(),
3448 },
3449 .result = ACCEPT,
3450 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3451 },
3452 {
3453 "direct packet read for LWT_XMIT",
3454 .insns = {
3455 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3456 offsetof(struct __sk_buff, data)),
3457 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3458 offsetof(struct __sk_buff, data_end)),
3459 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3461 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3462 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3463 BPF_MOV64_IMM(BPF_REG_0, 0),
3464 BPF_EXIT_INSN(),
3465 },
3466 .result = ACCEPT,
3467 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3468 },
3469 {
Alexei Starovoitovb1977682017-03-24 15:57:33 -07003470 "overlapping checks for direct packet access",
3471 .insns = {
3472 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3473 offsetof(struct __sk_buff, data)),
3474 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3475 offsetof(struct __sk_buff, data_end)),
3476 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3478 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
3479 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
3481 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
3482 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
3483 BPF_MOV64_IMM(BPF_REG_0, 0),
3484 BPF_EXIT_INSN(),
3485 },
3486 .result = ACCEPT,
3487 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3488 },
3489 {
Thomas Graf3f731d82016-12-05 10:30:52 +01003490 "invalid access of tc_classid for LWT_IN",
3491 .insns = {
3492 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3493 offsetof(struct __sk_buff, tc_classid)),
3494 BPF_EXIT_INSN(),
3495 },
3496 .result = REJECT,
3497 .errstr = "invalid bpf_context access",
3498 },
3499 {
3500 "invalid access of tc_classid for LWT_OUT",
3501 .insns = {
3502 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3503 offsetof(struct __sk_buff, tc_classid)),
3504 BPF_EXIT_INSN(),
3505 },
3506 .result = REJECT,
3507 .errstr = "invalid bpf_context access",
3508 },
3509 {
3510 "invalid access of tc_classid for LWT_XMIT",
3511 .insns = {
3512 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3513 offsetof(struct __sk_buff, tc_classid)),
3514 BPF_EXIT_INSN(),
3515 },
3516 .result = REJECT,
3517 .errstr = "invalid bpf_context access",
3518 },
Gianluca Borello57225692017-01-09 10:19:47 -08003519 {
3520 "helper access to map: full range",
3521 .insns = {
3522 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3524 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3525 BPF_LD_MAP_FD(BPF_REG_1, 0),
3526 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3527 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3528 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3529 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
3530 BPF_MOV64_IMM(BPF_REG_3, 0),
3531 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3532 BPF_EXIT_INSN(),
3533 },
3534 .fixup_map2 = { 3 },
3535 .result = ACCEPT,
3536 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3537 },
3538 {
3539 "helper access to map: partial range",
3540 .insns = {
3541 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3542 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3543 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3544 BPF_LD_MAP_FD(BPF_REG_1, 0),
3545 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3546 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3547 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3548 BPF_MOV64_IMM(BPF_REG_2, 8),
3549 BPF_MOV64_IMM(BPF_REG_3, 0),
3550 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3551 BPF_EXIT_INSN(),
3552 },
3553 .fixup_map2 = { 3 },
3554 .result = ACCEPT,
3555 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3556 },
3557 {
3558 "helper access to map: empty range",
3559 .insns = {
3560 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3561 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3562 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3563 BPF_LD_MAP_FD(BPF_REG_1, 0),
3564 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3565 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3566 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3567 BPF_MOV64_IMM(BPF_REG_2, 0),
3568 BPF_MOV64_IMM(BPF_REG_3, 0),
3569 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3570 BPF_EXIT_INSN(),
3571 },
3572 .fixup_map2 = { 3 },
3573 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
3574 .result = REJECT,
3575 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3576 },
3577 {
3578 "helper access to map: out-of-bound range",
3579 .insns = {
3580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3582 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3583 BPF_LD_MAP_FD(BPF_REG_1, 0),
3584 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3586 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3587 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
3588 BPF_MOV64_IMM(BPF_REG_3, 0),
3589 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3590 BPF_EXIT_INSN(),
3591 },
3592 .fixup_map2 = { 3 },
3593 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
3594 .result = REJECT,
3595 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3596 },
3597 {
3598 "helper access to map: negative range",
3599 .insns = {
3600 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3601 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3602 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3603 BPF_LD_MAP_FD(BPF_REG_1, 0),
3604 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3605 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3606 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3607 BPF_MOV64_IMM(BPF_REG_2, -8),
3608 BPF_MOV64_IMM(BPF_REG_3, 0),
3609 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3610 BPF_EXIT_INSN(),
3611 },
3612 .fixup_map2 = { 3 },
3613 .errstr = "invalid access to map value, value_size=48 off=0 size=-8",
3614 .result = REJECT,
3615 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3616 },
3617 {
3618 "helper access to adjusted map (via const imm): full range",
3619 .insns = {
3620 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3621 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3622 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3623 BPF_LD_MAP_FD(BPF_REG_1, 0),
3624 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3625 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3626 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3627 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3628 offsetof(struct test_val, foo)),
3629 BPF_MOV64_IMM(BPF_REG_2,
3630 sizeof(struct test_val) -
3631 offsetof(struct test_val, foo)),
3632 BPF_MOV64_IMM(BPF_REG_3, 0),
3633 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3634 BPF_EXIT_INSN(),
3635 },
3636 .fixup_map2 = { 3 },
3637 .result = ACCEPT,
3638 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3639 },
3640 {
3641 "helper access to adjusted map (via const imm): partial range",
3642 .insns = {
3643 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3645 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3646 BPF_LD_MAP_FD(BPF_REG_1, 0),
3647 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3648 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3649 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3651 offsetof(struct test_val, foo)),
3652 BPF_MOV64_IMM(BPF_REG_2, 8),
3653 BPF_MOV64_IMM(BPF_REG_3, 0),
3654 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3655 BPF_EXIT_INSN(),
3656 },
3657 .fixup_map2 = { 3 },
3658 .result = ACCEPT,
3659 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3660 },
3661 {
3662 "helper access to adjusted map (via const imm): empty range",
3663 .insns = {
3664 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3665 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3666 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3667 BPF_LD_MAP_FD(BPF_REG_1, 0),
3668 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3669 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3670 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3671 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3672 offsetof(struct test_val, foo)),
3673 BPF_MOV64_IMM(BPF_REG_2, 0),
3674 BPF_MOV64_IMM(BPF_REG_3, 0),
3675 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3676 BPF_EXIT_INSN(),
3677 },
3678 .fixup_map2 = { 3 },
3679 .errstr = "R1 min value is outside of the array range",
3680 .result = REJECT,
3681 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3682 },
3683 {
3684 "helper access to adjusted map (via const imm): out-of-bound range",
3685 .insns = {
3686 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3687 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3688 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3689 BPF_LD_MAP_FD(BPF_REG_1, 0),
3690 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3691 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3692 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3694 offsetof(struct test_val, foo)),
3695 BPF_MOV64_IMM(BPF_REG_2,
3696 sizeof(struct test_val) -
3697 offsetof(struct test_val, foo) + 8),
3698 BPF_MOV64_IMM(BPF_REG_3, 0),
3699 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3700 BPF_EXIT_INSN(),
3701 },
3702 .fixup_map2 = { 3 },
3703 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3704 .result = REJECT,
3705 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3706 },
3707 {
3708 "helper access to adjusted map (via const imm): negative range (> adjustment)",
3709 .insns = {
3710 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3711 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3712 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3713 BPF_LD_MAP_FD(BPF_REG_1, 0),
3714 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3715 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3716 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3718 offsetof(struct test_val, foo)),
3719 BPF_MOV64_IMM(BPF_REG_2, -8),
3720 BPF_MOV64_IMM(BPF_REG_3, 0),
3721 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3722 BPF_EXIT_INSN(),
3723 },
3724 .fixup_map2 = { 3 },
3725 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3726 .result = REJECT,
3727 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3728 },
3729 {
3730 "helper access to adjusted map (via const imm): negative range (< adjustment)",
3731 .insns = {
3732 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3733 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3734 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3735 BPF_LD_MAP_FD(BPF_REG_1, 0),
3736 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3737 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3738 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3739 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3740 offsetof(struct test_val, foo)),
3741 BPF_MOV64_IMM(BPF_REG_2, -1),
3742 BPF_MOV64_IMM(BPF_REG_3, 0),
3743 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3744 BPF_EXIT_INSN(),
3745 },
3746 .fixup_map2 = { 3 },
3747 .errstr = "R1 min value is outside of the array range",
3748 .result = REJECT,
3749 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3750 },
3751 {
3752 "helper access to adjusted map (via const reg): full range",
3753 .insns = {
3754 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3755 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3756 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3757 BPF_LD_MAP_FD(BPF_REG_1, 0),
3758 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3759 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3760 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3761 BPF_MOV64_IMM(BPF_REG_3,
3762 offsetof(struct test_val, foo)),
3763 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3764 BPF_MOV64_IMM(BPF_REG_2,
3765 sizeof(struct test_val) -
3766 offsetof(struct test_val, foo)),
3767 BPF_MOV64_IMM(BPF_REG_3, 0),
3768 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3769 BPF_EXIT_INSN(),
3770 },
3771 .fixup_map2 = { 3 },
3772 .result = ACCEPT,
3773 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3774 },
3775 {
3776 "helper access to adjusted map (via const reg): partial range",
3777 .insns = {
3778 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3780 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3781 BPF_LD_MAP_FD(BPF_REG_1, 0),
3782 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3783 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3784 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3785 BPF_MOV64_IMM(BPF_REG_3,
3786 offsetof(struct test_val, foo)),
3787 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3788 BPF_MOV64_IMM(BPF_REG_2, 8),
3789 BPF_MOV64_IMM(BPF_REG_3, 0),
3790 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3791 BPF_EXIT_INSN(),
3792 },
3793 .fixup_map2 = { 3 },
3794 .result = ACCEPT,
3795 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3796 },
3797 {
3798 "helper access to adjusted map (via const reg): empty range",
3799 .insns = {
3800 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3801 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3802 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3803 BPF_LD_MAP_FD(BPF_REG_1, 0),
3804 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3805 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3806 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3807 BPF_MOV64_IMM(BPF_REG_3, 0),
3808 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3809 BPF_MOV64_IMM(BPF_REG_2, 0),
3810 BPF_MOV64_IMM(BPF_REG_3, 0),
3811 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3812 BPF_EXIT_INSN(),
3813 },
3814 .fixup_map2 = { 3 },
3815 .errstr = "R1 min value is outside of the array range",
3816 .result = REJECT,
3817 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3818 },
3819 {
3820 "helper access to adjusted map (via const reg): out-of-bound range",
3821 .insns = {
3822 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3824 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3825 BPF_LD_MAP_FD(BPF_REG_1, 0),
3826 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3827 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3828 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3829 BPF_MOV64_IMM(BPF_REG_3,
3830 offsetof(struct test_val, foo)),
3831 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3832 BPF_MOV64_IMM(BPF_REG_2,
3833 sizeof(struct test_val) -
3834 offsetof(struct test_val, foo) + 8),
3835 BPF_MOV64_IMM(BPF_REG_3, 0),
3836 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3837 BPF_EXIT_INSN(),
3838 },
3839 .fixup_map2 = { 3 },
3840 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3841 .result = REJECT,
3842 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3843 },
3844 {
3845 "helper access to adjusted map (via const reg): negative range (> adjustment)",
3846 .insns = {
3847 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3849 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3850 BPF_LD_MAP_FD(BPF_REG_1, 0),
3851 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3852 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3853 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3854 BPF_MOV64_IMM(BPF_REG_3,
3855 offsetof(struct test_val, foo)),
3856 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3857 BPF_MOV64_IMM(BPF_REG_2, -8),
3858 BPF_MOV64_IMM(BPF_REG_3, 0),
3859 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3860 BPF_EXIT_INSN(),
3861 },
3862 .fixup_map2 = { 3 },
3863 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3864 .result = REJECT,
3865 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3866 },
3867 {
3868 "helper access to adjusted map (via const reg): negative range (< adjustment)",
3869 .insns = {
3870 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3871 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3872 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3873 BPF_LD_MAP_FD(BPF_REG_1, 0),
3874 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3875 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3876 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3877 BPF_MOV64_IMM(BPF_REG_3,
3878 offsetof(struct test_val, foo)),
3879 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3880 BPF_MOV64_IMM(BPF_REG_2, -1),
3881 BPF_MOV64_IMM(BPF_REG_3, 0),
3882 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3883 BPF_EXIT_INSN(),
3884 },
3885 .fixup_map2 = { 3 },
3886 .errstr = "R1 min value is outside of the array range",
3887 .result = REJECT,
3888 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3889 },
3890 {
3891 "helper access to adjusted map (via variable): full range",
3892 .insns = {
3893 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3894 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3895 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3896 BPF_LD_MAP_FD(BPF_REG_1, 0),
3897 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3898 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3899 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3900 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3901 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3902 offsetof(struct test_val, foo), 4),
3903 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3904 BPF_MOV64_IMM(BPF_REG_2,
3905 sizeof(struct test_val) -
3906 offsetof(struct test_val, foo)),
3907 BPF_MOV64_IMM(BPF_REG_3, 0),
3908 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3909 BPF_EXIT_INSN(),
3910 },
3911 .fixup_map2 = { 3 },
3912 .result = ACCEPT,
3913 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3914 },
3915 {
3916 "helper access to adjusted map (via variable): partial range",
3917 .insns = {
3918 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3919 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3920 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3921 BPF_LD_MAP_FD(BPF_REG_1, 0),
3922 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3923 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3924 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3925 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3926 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3927 offsetof(struct test_val, foo), 4),
3928 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3929 BPF_MOV64_IMM(BPF_REG_2, 8),
3930 BPF_MOV64_IMM(BPF_REG_3, 0),
3931 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3932 BPF_EXIT_INSN(),
3933 },
3934 .fixup_map2 = { 3 },
3935 .result = ACCEPT,
3936 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3937 },
3938 {
3939 "helper access to adjusted map (via variable): empty range",
3940 .insns = {
3941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3943 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3944 BPF_LD_MAP_FD(BPF_REG_1, 0),
3945 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3946 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3947 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3948 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3949 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3950 offsetof(struct test_val, foo), 4),
3951 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3952 BPF_MOV64_IMM(BPF_REG_2, 0),
3953 BPF_MOV64_IMM(BPF_REG_3, 0),
3954 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3955 BPF_EXIT_INSN(),
3956 },
3957 .fixup_map2 = { 3 },
3958 .errstr = "R1 min value is outside of the array range",
3959 .result = REJECT,
3960 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3961 },
3962 {
3963 "helper access to adjusted map (via variable): no max check",
3964 .insns = {
3965 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3967 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3968 BPF_LD_MAP_FD(BPF_REG_1, 0),
3969 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3970 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3971 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3972 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3973 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3974 BPF_MOV64_IMM(BPF_REG_2, 0),
3975 BPF_MOV64_IMM(BPF_REG_3, 0),
3976 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3977 BPF_EXIT_INSN(),
3978 },
3979 .fixup_map2 = { 3 },
3980 .errstr = "R1 min value is negative, either use unsigned index or do a if (index >=0) check",
3981 .result = REJECT,
3982 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3983 },
3984 {
3985 "helper access to adjusted map (via variable): wrong max check",
3986 .insns = {
3987 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3988 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3989 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3990 BPF_LD_MAP_FD(BPF_REG_1, 0),
3991 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3992 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3993 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3994 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3995 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3996 offsetof(struct test_val, foo), 4),
3997 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3998 BPF_MOV64_IMM(BPF_REG_2,
3999 sizeof(struct test_val) -
4000 offsetof(struct test_val, foo) + 1),
4001 BPF_MOV64_IMM(BPF_REG_3, 0),
4002 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4003 BPF_EXIT_INSN(),
4004 },
4005 .fixup_map2 = { 3 },
4006 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
4007 .result = REJECT,
4008 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4009 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08004010 {
4011 "map element value is preserved across register spilling",
4012 .insns = {
4013 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4014 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4015 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4016 BPF_LD_MAP_FD(BPF_REG_1, 0),
4017 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4018 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4019 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4020 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4021 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
4022 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4023 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4024 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4025 BPF_EXIT_INSN(),
4026 },
4027 .fixup_map2 = { 3 },
4028 .errstr_unpriv = "R0 leaks addr",
4029 .result = ACCEPT,
4030 .result_unpriv = REJECT,
4031 },
4032 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004033 "map element value or null is marked on register spilling",
4034 .insns = {
4035 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4037 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4038 BPF_LD_MAP_FD(BPF_REG_1, 0),
4039 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4040 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
4042 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4043 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4044 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4045 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4046 BPF_EXIT_INSN(),
4047 },
4048 .fixup_map2 = { 3 },
4049 .errstr_unpriv = "R0 leaks addr",
4050 .result = ACCEPT,
4051 .result_unpriv = REJECT,
4052 },
4053 {
4054 "map element value store of cleared call register",
4055 .insns = {
4056 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4058 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4059 BPF_LD_MAP_FD(BPF_REG_1, 0),
4060 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4061 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4062 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
4063 BPF_EXIT_INSN(),
4064 },
4065 .fixup_map2 = { 3 },
4066 .errstr_unpriv = "R1 !read_ok",
4067 .errstr = "R1 !read_ok",
4068 .result = REJECT,
4069 .result_unpriv = REJECT,
4070 },
4071 {
4072 "map element value with unaligned store",
4073 .insns = {
4074 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4075 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4076 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4077 BPF_LD_MAP_FD(BPF_REG_1, 0),
4078 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4079 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
4080 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4081 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4082 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
4083 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
4084 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4085 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
4086 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
4087 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
4088 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
4089 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
4090 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
4091 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
4092 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
4093 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
4094 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
4095 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
4096 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
4097 BPF_EXIT_INSN(),
4098 },
4099 .fixup_map2 = { 3 },
4100 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4101 .result = ACCEPT,
4102 .result_unpriv = REJECT,
4103 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4104 },
4105 {
4106 "map element value with unaligned load",
4107 .insns = {
4108 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4109 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4110 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4111 BPF_LD_MAP_FD(BPF_REG_1, 0),
4112 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4113 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4114 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4115 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
4116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4117 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4118 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
4119 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4120 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
4121 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
4122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
4123 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4124 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
4125 BPF_EXIT_INSN(),
4126 },
4127 .fixup_map2 = { 3 },
4128 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4129 .result = ACCEPT,
4130 .result_unpriv = REJECT,
4131 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4132 },
4133 {
4134 "map element value illegal alu op, 1",
4135 .insns = {
4136 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4137 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4138 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4139 BPF_LD_MAP_FD(BPF_REG_1, 0),
4140 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4141 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4142 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
4143 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4144 BPF_EXIT_INSN(),
4145 },
4146 .fixup_map2 = { 3 },
4147 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4148 .errstr = "invalid mem access 'inv'",
4149 .result = REJECT,
4150 .result_unpriv = REJECT,
4151 },
4152 {
4153 "map element value illegal alu op, 2",
4154 .insns = {
4155 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4157 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4158 BPF_LD_MAP_FD(BPF_REG_1, 0),
4159 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4160 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4161 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
4162 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4163 BPF_EXIT_INSN(),
4164 },
4165 .fixup_map2 = { 3 },
4166 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4167 .errstr = "invalid mem access 'inv'",
4168 .result = REJECT,
4169 .result_unpriv = REJECT,
4170 },
4171 {
4172 "map element value illegal alu op, 3",
4173 .insns = {
4174 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4175 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4176 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4177 BPF_LD_MAP_FD(BPF_REG_1, 0),
4178 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4179 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4180 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
4181 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4182 BPF_EXIT_INSN(),
4183 },
4184 .fixup_map2 = { 3 },
4185 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4186 .errstr = "invalid mem access 'inv'",
4187 .result = REJECT,
4188 .result_unpriv = REJECT,
4189 },
4190 {
4191 "map element value illegal alu op, 4",
4192 .insns = {
4193 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4195 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4196 BPF_LD_MAP_FD(BPF_REG_1, 0),
4197 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4198 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4199 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
4200 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4201 BPF_EXIT_INSN(),
4202 },
4203 .fixup_map2 = { 3 },
4204 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4205 .errstr = "invalid mem access 'inv'",
4206 .result = REJECT,
4207 .result_unpriv = REJECT,
4208 },
4209 {
4210 "map element value illegal alu op, 5",
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, 7),
4218 BPF_MOV64_IMM(BPF_REG_3, 4096),
4219 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4220 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4221 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
4222 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
4223 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
4224 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4225 BPF_EXIT_INSN(),
4226 },
4227 .fixup_map2 = { 3 },
4228 .errstr_unpriv = "R0 invalid mem access 'inv'",
4229 .errstr = "R0 invalid mem access 'inv'",
4230 .result = REJECT,
4231 .result_unpriv = REJECT,
4232 },
4233 {
4234 "map element value is preserved across register spilling",
Gianluca Borellof0318d02017-01-09 10:19:48 -08004235 .insns = {
4236 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4237 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4238 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4239 BPF_LD_MAP_FD(BPF_REG_1, 0),
4240 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4242 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
4243 offsetof(struct test_val, foo)),
4244 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4245 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
4247 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4248 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4249 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4250 BPF_EXIT_INSN(),
4251 },
4252 .fixup_map2 = { 3 },
4253 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4254 .result = ACCEPT,
4255 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004256 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Gianluca Borellof0318d02017-01-09 10:19:48 -08004257 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08004258 {
4259 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
4260 .insns = {
4261 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4262 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4263 BPF_MOV64_IMM(BPF_REG_0, 0),
4264 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4265 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4266 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4267 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4268 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4269 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4270 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4271 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4272 BPF_MOV64_IMM(BPF_REG_2, 16),
4273 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4274 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4275 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4276 BPF_MOV64_IMM(BPF_REG_4, 0),
4277 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4278 BPF_MOV64_IMM(BPF_REG_3, 0),
4279 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4280 BPF_MOV64_IMM(BPF_REG_0, 0),
4281 BPF_EXIT_INSN(),
4282 },
4283 .result = ACCEPT,
4284 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4285 },
4286 {
4287 "helper access to variable memory: stack, bitwise AND, zero included",
4288 .insns = {
4289 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4290 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4291 BPF_MOV64_IMM(BPF_REG_2, 16),
4292 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4293 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4294 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4295 BPF_MOV64_IMM(BPF_REG_3, 0),
4296 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4297 BPF_EXIT_INSN(),
4298 },
4299 .errstr = "invalid stack type R1 off=-64 access_size=0",
4300 .result = REJECT,
4301 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4302 },
4303 {
4304 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
4305 .insns = {
4306 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4308 BPF_MOV64_IMM(BPF_REG_2, 16),
4309 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4310 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4311 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
4312 BPF_MOV64_IMM(BPF_REG_4, 0),
4313 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4314 BPF_MOV64_IMM(BPF_REG_3, 0),
4315 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4316 BPF_MOV64_IMM(BPF_REG_0, 0),
4317 BPF_EXIT_INSN(),
4318 },
4319 .errstr = "invalid stack type R1 off=-64 access_size=65",
4320 .result = REJECT,
4321 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4322 },
4323 {
4324 "helper access to variable memory: stack, JMP, correct bounds",
4325 .insns = {
4326 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4327 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4328 BPF_MOV64_IMM(BPF_REG_0, 0),
4329 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4330 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4331 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4332 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4333 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4334 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4335 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4336 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4337 BPF_MOV64_IMM(BPF_REG_2, 16),
4338 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4339 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4340 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
4341 BPF_MOV64_IMM(BPF_REG_4, 0),
4342 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4343 BPF_MOV64_IMM(BPF_REG_3, 0),
4344 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4345 BPF_MOV64_IMM(BPF_REG_0, 0),
4346 BPF_EXIT_INSN(),
4347 },
4348 .result = ACCEPT,
4349 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4350 },
4351 {
4352 "helper access to variable memory: stack, JMP (signed), correct bounds",
4353 .insns = {
4354 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4355 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4356 BPF_MOV64_IMM(BPF_REG_0, 0),
4357 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4358 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4359 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4360 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4361 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4362 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4363 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4364 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4365 BPF_MOV64_IMM(BPF_REG_2, 16),
4366 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4367 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4368 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
4369 BPF_MOV64_IMM(BPF_REG_4, 0),
4370 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
4371 BPF_MOV64_IMM(BPF_REG_3, 0),
4372 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4373 BPF_MOV64_IMM(BPF_REG_0, 0),
4374 BPF_EXIT_INSN(),
4375 },
4376 .result = ACCEPT,
4377 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4378 },
4379 {
4380 "helper access to variable memory: stack, JMP, bounds + offset",
4381 .insns = {
4382 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4384 BPF_MOV64_IMM(BPF_REG_2, 16),
4385 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4386 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4387 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
4388 BPF_MOV64_IMM(BPF_REG_4, 0),
4389 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
4390 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4391 BPF_MOV64_IMM(BPF_REG_3, 0),
4392 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4393 BPF_MOV64_IMM(BPF_REG_0, 0),
4394 BPF_EXIT_INSN(),
4395 },
4396 .errstr = "invalid stack type R1 off=-64 access_size=65",
4397 .result = REJECT,
4398 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4399 },
4400 {
4401 "helper access to variable memory: stack, JMP, wrong max",
4402 .insns = {
4403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4404 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4405 BPF_MOV64_IMM(BPF_REG_2, 16),
4406 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4407 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4408 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
4409 BPF_MOV64_IMM(BPF_REG_4, 0),
4410 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4411 BPF_MOV64_IMM(BPF_REG_3, 0),
4412 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4413 BPF_MOV64_IMM(BPF_REG_0, 0),
4414 BPF_EXIT_INSN(),
4415 },
4416 .errstr = "invalid stack type R1 off=-64 access_size=65",
4417 .result = REJECT,
4418 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4419 },
4420 {
4421 "helper access to variable memory: stack, JMP, no max check",
4422 .insns = {
4423 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4425 BPF_MOV64_IMM(BPF_REG_2, 16),
4426 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4427 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4428 BPF_MOV64_IMM(BPF_REG_4, 0),
4429 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4430 BPF_MOV64_IMM(BPF_REG_3, 0),
4431 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4432 BPF_MOV64_IMM(BPF_REG_0, 0),
4433 BPF_EXIT_INSN(),
4434 },
4435 .errstr = "R2 unbounded memory access",
4436 .result = REJECT,
4437 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4438 },
4439 {
4440 "helper access to variable memory: stack, JMP, no min check",
4441 .insns = {
4442 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4444 BPF_MOV64_IMM(BPF_REG_2, 16),
4445 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4446 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4447 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
4448 BPF_MOV64_IMM(BPF_REG_3, 0),
4449 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4450 BPF_MOV64_IMM(BPF_REG_0, 0),
4451 BPF_EXIT_INSN(),
4452 },
4453 .errstr = "invalid stack type R1 off=-64 access_size=0",
4454 .result = REJECT,
4455 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4456 },
4457 {
4458 "helper access to variable memory: stack, JMP (signed), no min check",
4459 .insns = {
4460 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4462 BPF_MOV64_IMM(BPF_REG_2, 16),
4463 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4464 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4465 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
4466 BPF_MOV64_IMM(BPF_REG_3, 0),
4467 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4468 BPF_MOV64_IMM(BPF_REG_0, 0),
4469 BPF_EXIT_INSN(),
4470 },
4471 .errstr = "R2 min value is negative",
4472 .result = REJECT,
4473 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4474 },
4475 {
4476 "helper access to variable memory: map, JMP, correct bounds",
4477 .insns = {
4478 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4479 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4480 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4481 BPF_LD_MAP_FD(BPF_REG_1, 0),
4482 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4483 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4484 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4485 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4486 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4487 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4488 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4489 sizeof(struct test_val), 4),
4490 BPF_MOV64_IMM(BPF_REG_4, 0),
4491 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4492 BPF_MOV64_IMM(BPF_REG_3, 0),
4493 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4494 BPF_MOV64_IMM(BPF_REG_0, 0),
4495 BPF_EXIT_INSN(),
4496 },
4497 .fixup_map2 = { 3 },
4498 .result = ACCEPT,
4499 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4500 },
4501 {
4502 "helper access to variable memory: map, JMP, wrong max",
4503 .insns = {
4504 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4506 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4507 BPF_LD_MAP_FD(BPF_REG_1, 0),
4508 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4509 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4510 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4511 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4512 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4513 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4514 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4515 sizeof(struct test_val) + 1, 4),
4516 BPF_MOV64_IMM(BPF_REG_4, 0),
4517 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4518 BPF_MOV64_IMM(BPF_REG_3, 0),
4519 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4520 BPF_MOV64_IMM(BPF_REG_0, 0),
4521 BPF_EXIT_INSN(),
4522 },
4523 .fixup_map2 = { 3 },
4524 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
4525 .result = REJECT,
4526 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4527 },
4528 {
4529 "helper access to variable memory: map adjusted, JMP, correct bounds",
4530 .insns = {
4531 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4533 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4534 BPF_LD_MAP_FD(BPF_REG_1, 0),
4535 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4536 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4537 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4538 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4539 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4540 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4541 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4542 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4543 sizeof(struct test_val) - 20, 4),
4544 BPF_MOV64_IMM(BPF_REG_4, 0),
4545 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4546 BPF_MOV64_IMM(BPF_REG_3, 0),
4547 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4548 BPF_MOV64_IMM(BPF_REG_0, 0),
4549 BPF_EXIT_INSN(),
4550 },
4551 .fixup_map2 = { 3 },
4552 .result = ACCEPT,
4553 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4554 },
4555 {
4556 "helper access to variable memory: map adjusted, JMP, wrong max",
4557 .insns = {
4558 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4560 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4561 BPF_LD_MAP_FD(BPF_REG_1, 0),
4562 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4563 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4564 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4566 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4567 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4568 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4569 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4570 sizeof(struct test_val) - 19, 4),
4571 BPF_MOV64_IMM(BPF_REG_4, 0),
4572 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4573 BPF_MOV64_IMM(BPF_REG_3, 0),
4574 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4575 BPF_MOV64_IMM(BPF_REG_0, 0),
4576 BPF_EXIT_INSN(),
4577 },
4578 .fixup_map2 = { 3 },
4579 .errstr = "R1 min value is outside of the array range",
4580 .result = REJECT,
4581 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4582 },
4583 {
4584 "helper access to variable memory: size > 0 not allowed on NULL",
4585 .insns = {
4586 BPF_MOV64_IMM(BPF_REG_1, 0),
4587 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01004588 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4589 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004590 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4591 BPF_MOV64_IMM(BPF_REG_3, 0),
4592 BPF_MOV64_IMM(BPF_REG_4, 0),
4593 BPF_MOV64_IMM(BPF_REG_5, 0),
4594 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4595 BPF_EXIT_INSN(),
4596 },
4597 .errstr = "R1 type=imm expected=fp",
4598 .result = REJECT,
4599 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4600 },
4601 {
4602 "helper access to variable memory: size = 0 not allowed on != NULL",
4603 .insns = {
4604 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
4606 BPF_MOV64_IMM(BPF_REG_2, 0),
4607 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
4608 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
4609 BPF_MOV64_IMM(BPF_REG_3, 0),
4610 BPF_MOV64_IMM(BPF_REG_4, 0),
4611 BPF_MOV64_IMM(BPF_REG_5, 0),
4612 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4613 BPF_EXIT_INSN(),
4614 },
4615 .errstr = "invalid stack type R1 off=-8 access_size=0",
4616 .result = REJECT,
4617 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4618 },
4619 {
4620 "helper access to variable memory: 8 bytes leak",
4621 .insns = {
4622 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4624 BPF_MOV64_IMM(BPF_REG_0, 0),
4625 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4626 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4627 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4628 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4629 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4630 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4631 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4632 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01004633 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4634 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004635 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
4636 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4637 BPF_MOV64_IMM(BPF_REG_3, 0),
4638 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4639 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4640 BPF_EXIT_INSN(),
4641 },
4642 .errstr = "invalid indirect read from stack off -64+32 size 64",
4643 .result = REJECT,
4644 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4645 },
4646 {
4647 "helper access to variable memory: 8 bytes no leak (init memory)",
4648 .insns = {
4649 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4650 BPF_MOV64_IMM(BPF_REG_0, 0),
4651 BPF_MOV64_IMM(BPF_REG_0, 0),
4652 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4653 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4654 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4655 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4656 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4657 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4658 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4659 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4660 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4661 BPF_MOV64_IMM(BPF_REG_2, 0),
4662 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
4663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
4664 BPF_MOV64_IMM(BPF_REG_3, 0),
4665 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4666 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4667 BPF_EXIT_INSN(),
4668 },
4669 .result = ACCEPT,
4670 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4671 },
Josef Bacik29200c12017-02-03 16:25:23 -05004672 {
4673 "invalid and of negative number",
4674 .insns = {
4675 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4676 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4677 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4678 BPF_LD_MAP_FD(BPF_REG_1, 0),
4679 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4680 BPF_FUNC_map_lookup_elem),
4681 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4682 BPF_MOV64_IMM(BPF_REG_1, 6),
4683 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
4684 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4685 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4686 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4687 offsetof(struct test_val, foo)),
4688 BPF_EXIT_INSN(),
4689 },
4690 .fixup_map2 = { 3 },
4691 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4692 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4693 .result = REJECT,
4694 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004695 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik29200c12017-02-03 16:25:23 -05004696 },
4697 {
4698 "invalid range check",
4699 .insns = {
4700 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4701 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4703 BPF_LD_MAP_FD(BPF_REG_1, 0),
4704 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4705 BPF_FUNC_map_lookup_elem),
4706 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
4707 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4708 BPF_MOV64_IMM(BPF_REG_9, 1),
4709 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
4710 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
4711 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
4712 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
4713 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
4714 BPF_MOV32_IMM(BPF_REG_3, 1),
4715 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
4716 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
4717 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
4718 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
4719 BPF_MOV64_REG(BPF_REG_0, 0),
4720 BPF_EXIT_INSN(),
4721 },
4722 .fixup_map2 = { 3 },
4723 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4724 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4725 .result = REJECT,
4726 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004727 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004728 },
4729 {
4730 "map in map access",
4731 .insns = {
4732 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4733 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4735 BPF_LD_MAP_FD(BPF_REG_1, 0),
4736 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4737 BPF_FUNC_map_lookup_elem),
4738 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4739 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4740 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4741 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4742 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4743 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4744 BPF_FUNC_map_lookup_elem),
4745 BPF_MOV64_REG(BPF_REG_0, 0),
4746 BPF_EXIT_INSN(),
4747 },
4748 .fixup_map_in_map = { 3 },
4749 .result = ACCEPT,
4750 },
4751 {
4752 "invalid inner map pointer",
4753 .insns = {
4754 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4755 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4756 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4757 BPF_LD_MAP_FD(BPF_REG_1, 0),
4758 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4759 BPF_FUNC_map_lookup_elem),
4760 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4761 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4762 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4763 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4764 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4765 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4766 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4767 BPF_FUNC_map_lookup_elem),
4768 BPF_MOV64_REG(BPF_REG_0, 0),
4769 BPF_EXIT_INSN(),
4770 },
4771 .fixup_map_in_map = { 3 },
4772 .errstr = "R1 type=inv expected=map_ptr",
4773 .errstr_unpriv = "R1 pointer arithmetic prohibited",
4774 .result = REJECT,
4775 },
4776 {
4777 "forgot null checking on the inner map pointer",
4778 .insns = {
4779 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4780 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4781 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4782 BPF_LD_MAP_FD(BPF_REG_1, 0),
4783 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4784 BPF_FUNC_map_lookup_elem),
4785 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4786 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4788 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4789 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4790 BPF_FUNC_map_lookup_elem),
4791 BPF_MOV64_REG(BPF_REG_0, 0),
4792 BPF_EXIT_INSN(),
4793 },
4794 .fixup_map_in_map = { 3 },
4795 .errstr = "R1 type=map_value_or_null expected=map_ptr",
4796 .result = REJECT,
Josef Bacik29200c12017-02-03 16:25:23 -05004797 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004798};
4799
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004800static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004801{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004802 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004803
4804 for (len = MAX_INSNS - 1; len > 0; --len)
4805 if (fp[len].code != 0 || fp[len].imm != 0)
4806 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004807 return len + 1;
4808}
4809
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004810static int create_map(uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004811{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004812 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004813
Mickaël Salaünf4874d02017-02-10 00:21:43 +01004814 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004815 size_value, max_elem, BPF_F_NO_PREALLOC);
4816 if (fd < 0)
4817 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004818
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004819 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004820}
4821
4822static int create_prog_array(void)
4823{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004824 int fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004825
Mickaël Salaünf4874d02017-02-10 00:21:43 +01004826 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004827 sizeof(int), 4, 0);
4828 if (fd < 0)
4829 printf("Failed to create prog array '%s'!\n", strerror(errno));
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004830
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004831 return fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004832}
4833
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004834static int create_map_in_map(void)
4835{
4836 int inner_map_fd, outer_map_fd;
4837
4838 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
4839 sizeof(int), 1, 0);
4840 if (inner_map_fd < 0) {
4841 printf("Failed to create array '%s'!\n", strerror(errno));
4842 return inner_map_fd;
4843 }
4844
4845 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS,
4846 sizeof(int), inner_map_fd, 1, 0);
4847 if (outer_map_fd < 0)
4848 printf("Failed to create array of maps '%s'!\n",
4849 strerror(errno));
4850
4851 close(inner_map_fd);
4852
4853 return outer_map_fd;
4854}
4855
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004856static char bpf_vlog[32768];
4857
4858static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004859 int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004860{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004861 int *fixup_map1 = test->fixup_map1;
4862 int *fixup_map2 = test->fixup_map2;
4863 int *fixup_prog = test->fixup_prog;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004864 int *fixup_map_in_map = test->fixup_map_in_map;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004865
4866 /* Allocating HTs with 1 elem is fine here, since we only test
4867 * for verifier and not do a runtime lookup, so the only thing
4868 * that really matters is value size in this case.
4869 */
4870 if (*fixup_map1) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004871 map_fds[0] = create_map(sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004872 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004873 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004874 fixup_map1++;
4875 } while (*fixup_map1);
4876 }
4877
4878 if (*fixup_map2) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004879 map_fds[1] = create_map(sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004880 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004881 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004882 fixup_map2++;
4883 } while (*fixup_map2);
4884 }
4885
4886 if (*fixup_prog) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004887 map_fds[2] = create_prog_array();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004888 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004889 prog[*fixup_prog].imm = map_fds[2];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004890 fixup_prog++;
4891 } while (*fixup_prog);
4892 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004893
4894 if (*fixup_map_in_map) {
4895 map_fds[3] = create_map_in_map();
4896 do {
4897 prog[*fixup_map_in_map].imm = map_fds[3];
4898 fixup_map_in_map++;
4899 } while (*fixup_map_in_map);
4900 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004901}
4902
4903static void do_test_single(struct bpf_test *test, bool unpriv,
4904 int *passes, int *errors)
4905{
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004906 int fd_prog, expected_ret, reject_from_alignment;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004907 struct bpf_insn *prog = test->insns;
4908 int prog_len = probe_filter_length(prog);
4909 int prog_type = test->prog_type;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004910 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004911 const char *expected_err;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004912 int i;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004913
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004914 for (i = 0; i < MAX_NR_MAPS; i++)
4915 map_fds[i] = -1;
4916
4917 do_test_fixup(test, prog, map_fds);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004918
Mickaël Salaün2ee89fb2017-02-10 00:21:38 +01004919 fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
4920 prog, prog_len, "GPL", 0, bpf_vlog,
4921 sizeof(bpf_vlog));
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004922
4923 expected_ret = unpriv && test->result_unpriv != UNDEF ?
4924 test->result_unpriv : test->result;
4925 expected_err = unpriv && test->errstr_unpriv ?
4926 test->errstr_unpriv : test->errstr;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004927
4928 reject_from_alignment = fd_prog < 0 &&
4929 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
4930 strstr(bpf_vlog, "Unknown alignment.");
4931#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
4932 if (reject_from_alignment) {
4933 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
4934 strerror(errno));
4935 goto fail_log;
4936 }
4937#endif
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004938 if (expected_ret == ACCEPT) {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004939 if (fd_prog < 0 && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004940 printf("FAIL\nFailed to load prog '%s'!\n",
4941 strerror(errno));
4942 goto fail_log;
4943 }
4944 } else {
4945 if (fd_prog >= 0) {
4946 printf("FAIL\nUnexpected success to load!\n");
4947 goto fail_log;
4948 }
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004949 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004950 printf("FAIL\nUnexpected error message!\n");
4951 goto fail_log;
4952 }
4953 }
4954
4955 (*passes)++;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004956 printf("OK%s\n", reject_from_alignment ?
4957 " (NOTE: reject due to unknown alignment)" : "");
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004958close_fds:
4959 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004960 for (i = 0; i < MAX_NR_MAPS; i++)
4961 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004962 sched_yield();
4963 return;
4964fail_log:
4965 (*errors)++;
4966 printf("%s", bpf_vlog);
4967 goto close_fds;
4968}
4969
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004970static bool is_admin(void)
4971{
4972 cap_t caps;
4973 cap_flag_value_t sysadmin = CAP_CLEAR;
4974 const cap_value_t cap_val = CAP_SYS_ADMIN;
4975
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08004976#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004977 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
4978 perror("cap_get_flag");
4979 return false;
4980 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08004981#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004982 caps = cap_get_proc();
4983 if (!caps) {
4984 perror("cap_get_proc");
4985 return false;
4986 }
4987 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
4988 perror("cap_get_flag");
4989 if (cap_free(caps))
4990 perror("cap_free");
4991 return (sysadmin == CAP_SET);
4992}
4993
4994static int set_admin(bool admin)
4995{
4996 cap_t caps;
4997 const cap_value_t cap_val = CAP_SYS_ADMIN;
4998 int ret = -1;
4999
5000 caps = cap_get_proc();
5001 if (!caps) {
5002 perror("cap_get_proc");
5003 return -1;
5004 }
5005 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
5006 admin ? CAP_SET : CAP_CLEAR)) {
5007 perror("cap_set_flag");
5008 goto out;
5009 }
5010 if (cap_set_proc(caps)) {
5011 perror("cap_set_proc");
5012 goto out;
5013 }
5014 ret = 0;
5015out:
5016 if (cap_free(caps))
5017 perror("cap_free");
5018 return ret;
5019}
5020
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005021static int do_test(bool unpriv, unsigned int from, unsigned int to)
5022{
5023 int i, passes = 0, errors = 0;
5024
5025 for (i = from; i < to; i++) {
5026 struct bpf_test *test = &tests[i];
5027
5028 /* Program types that are not supported by non-root we
5029 * skip right away.
5030 */
Mickaël Salaünd02d8982017-02-10 00:21:37 +01005031 if (!test->prog_type) {
5032 if (!unpriv)
5033 set_admin(false);
5034 printf("#%d/u %s ", i, test->descr);
5035 do_test_single(test, true, &passes, &errors);
5036 if (!unpriv)
5037 set_admin(true);
5038 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005039
Mickaël Salaünd02d8982017-02-10 00:21:37 +01005040 if (!unpriv) {
5041 printf("#%d/p %s ", i, test->descr);
5042 do_test_single(test, false, &passes, &errors);
5043 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005044 }
5045
5046 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
5047 return errors ? -errors : 0;
5048}
5049
5050int main(int argc, char **argv)
5051{
5052 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
5053 struct rlimit rlim = { 1 << 20, 1 << 20 };
5054 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +01005055 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005056
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005057 if (argc == 3) {
5058 unsigned int l = atoi(argv[argc - 2]);
5059 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005060
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005061 if (l < to && u < to) {
5062 from = l;
5063 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005064 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005065 } else if (argc == 2) {
5066 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -07005067
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005068 if (t < to) {
5069 from = t;
5070 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07005071 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005072 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005073
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02005074 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
5075 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07005076}