blob: f4f43c98cf7f14951ba5a9f448cc427746549b7b [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 Borkmann5aa5bd12016-10-17 14:28:36 +020033#include "../../../include/linux/filter.h"
34
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020035#ifndef ARRAY_SIZE
36# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
37#endif
38
39#define MAX_INSNS 512
40#define MAX_FIXUPS 8
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070041#define MAX_NR_MAPS 4
Alexei Starovoitovbf508872015-10-07 22:23:23 -070042
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070043struct bpf_test {
44 const char *descr;
45 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020046 int fixup_map1[MAX_FIXUPS];
47 int fixup_map2[MAX_FIXUPS];
48 int fixup_prog[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070049 int fixup_map_in_map[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070050 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070051 const char *errstr_unpriv;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070052 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070053 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070054 ACCEPT,
55 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070056 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070057 enum bpf_prog_type prog_type;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070058};
59
Josef Bacik48461132016-09-28 10:54:32 -040060/* Note we want this to be 64 bit aligned so that the end of our array is
61 * actually the end of the structure.
62 */
63#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040064
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020065struct test_val {
66 unsigned int index;
67 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040068};
69
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070070static struct bpf_test tests[] = {
71 {
72 "add+sub+mul",
73 .insns = {
74 BPF_MOV64_IMM(BPF_REG_1, 1),
75 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
76 BPF_MOV64_IMM(BPF_REG_2, 3),
77 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
78 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
79 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
80 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
81 BPF_EXIT_INSN(),
82 },
83 .result = ACCEPT,
84 },
85 {
86 "unreachable",
87 .insns = {
88 BPF_EXIT_INSN(),
89 BPF_EXIT_INSN(),
90 },
91 .errstr = "unreachable",
92 .result = REJECT,
93 },
94 {
95 "unreachable2",
96 .insns = {
97 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
98 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
99 BPF_EXIT_INSN(),
100 },
101 .errstr = "unreachable",
102 .result = REJECT,
103 },
104 {
105 "out of range jump",
106 .insns = {
107 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
108 BPF_EXIT_INSN(),
109 },
110 .errstr = "jump out of range",
111 .result = REJECT,
112 },
113 {
114 "out of range jump2",
115 .insns = {
116 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
117 BPF_EXIT_INSN(),
118 },
119 .errstr = "jump out of range",
120 .result = REJECT,
121 },
122 {
123 "test1 ld_imm64",
124 .insns = {
125 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
126 BPF_LD_IMM64(BPF_REG_0, 0),
127 BPF_LD_IMM64(BPF_REG_0, 0),
128 BPF_LD_IMM64(BPF_REG_0, 1),
129 BPF_LD_IMM64(BPF_REG_0, 1),
130 BPF_MOV64_IMM(BPF_REG_0, 2),
131 BPF_EXIT_INSN(),
132 },
133 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700134 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700135 .result = REJECT,
136 },
137 {
138 "test2 ld_imm64",
139 .insns = {
140 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
141 BPF_LD_IMM64(BPF_REG_0, 0),
142 BPF_LD_IMM64(BPF_REG_0, 0),
143 BPF_LD_IMM64(BPF_REG_0, 1),
144 BPF_LD_IMM64(BPF_REG_0, 1),
145 BPF_EXIT_INSN(),
146 },
147 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700148 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700149 .result = REJECT,
150 },
151 {
152 "test3 ld_imm64",
153 .insns = {
154 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
155 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
156 BPF_LD_IMM64(BPF_REG_0, 0),
157 BPF_LD_IMM64(BPF_REG_0, 0),
158 BPF_LD_IMM64(BPF_REG_0, 1),
159 BPF_LD_IMM64(BPF_REG_0, 1),
160 BPF_EXIT_INSN(),
161 },
162 .errstr = "invalid bpf_ld_imm64 insn",
163 .result = REJECT,
164 },
165 {
166 "test4 ld_imm64",
167 .insns = {
168 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
169 BPF_EXIT_INSN(),
170 },
171 .errstr = "invalid bpf_ld_imm64 insn",
172 .result = REJECT,
173 },
174 {
175 "test5 ld_imm64",
176 .insns = {
177 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
178 },
179 .errstr = "invalid bpf_ld_imm64 insn",
180 .result = REJECT,
181 },
182 {
183 "no bpf_exit",
184 .insns = {
185 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
186 },
187 .errstr = "jump out of range",
188 .result = REJECT,
189 },
190 {
191 "loop (back-edge)",
192 .insns = {
193 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
194 BPF_EXIT_INSN(),
195 },
196 .errstr = "back-edge",
197 .result = REJECT,
198 },
199 {
200 "loop2 (back-edge)",
201 .insns = {
202 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
203 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
204 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
205 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
206 BPF_EXIT_INSN(),
207 },
208 .errstr = "back-edge",
209 .result = REJECT,
210 },
211 {
212 "conditional loop",
213 .insns = {
214 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
215 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
216 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
217 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
218 BPF_EXIT_INSN(),
219 },
220 .errstr = "back-edge",
221 .result = REJECT,
222 },
223 {
224 "read uninitialized register",
225 .insns = {
226 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
227 BPF_EXIT_INSN(),
228 },
229 .errstr = "R2 !read_ok",
230 .result = REJECT,
231 },
232 {
233 "read invalid register",
234 .insns = {
235 BPF_MOV64_REG(BPF_REG_0, -1),
236 BPF_EXIT_INSN(),
237 },
238 .errstr = "R15 is invalid",
239 .result = REJECT,
240 },
241 {
242 "program doesn't init R0 before exit",
243 .insns = {
244 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
245 BPF_EXIT_INSN(),
246 },
247 .errstr = "R0 !read_ok",
248 .result = REJECT,
249 },
250 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700251 "program doesn't init R0 before exit in all branches",
252 .insns = {
253 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
254 BPF_MOV64_IMM(BPF_REG_0, 1),
255 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
256 BPF_EXIT_INSN(),
257 },
258 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700259 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700260 .result = REJECT,
261 },
262 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700263 "stack out of bounds",
264 .insns = {
265 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
266 BPF_EXIT_INSN(),
267 },
268 .errstr = "invalid stack",
269 .result = REJECT,
270 },
271 {
272 "invalid call insn1",
273 .insns = {
274 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
275 BPF_EXIT_INSN(),
276 },
277 .errstr = "BPF_CALL uses reserved",
278 .result = REJECT,
279 },
280 {
281 "invalid call insn2",
282 .insns = {
283 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
284 BPF_EXIT_INSN(),
285 },
286 .errstr = "BPF_CALL uses reserved",
287 .result = REJECT,
288 },
289 {
290 "invalid function call",
291 .insns = {
292 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
293 BPF_EXIT_INSN(),
294 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100295 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700296 .result = REJECT,
297 },
298 {
299 "uninitialized stack1",
300 .insns = {
301 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
303 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200304 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
305 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700306 BPF_EXIT_INSN(),
307 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200308 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700309 .errstr = "invalid indirect read from stack",
310 .result = REJECT,
311 },
312 {
313 "uninitialized stack2",
314 .insns = {
315 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
316 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
317 BPF_EXIT_INSN(),
318 },
319 .errstr = "invalid read from stack",
320 .result = REJECT,
321 },
322 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200323 "invalid argument register",
324 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
326 BPF_FUNC_get_cgroup_classid),
327 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
328 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200329 BPF_EXIT_INSN(),
330 },
331 .errstr = "R1 !read_ok",
332 .result = REJECT,
333 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
334 },
335 {
336 "non-invalid argument register",
337 .insns = {
338 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200339 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
340 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200341 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200342 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
343 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200344 BPF_EXIT_INSN(),
345 },
346 .result = ACCEPT,
347 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
348 },
349 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700350 "check valid spill/fill",
351 .insns = {
352 /* spill R1(ctx) into stack */
353 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700354 /* fill it back into R2 */
355 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700356 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100357 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
358 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700359 BPF_EXIT_INSN(),
360 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700361 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700362 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700363 .result_unpriv = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700364 },
365 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200366 "check valid spill/fill, skb mark",
367 .insns = {
368 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
369 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
370 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
371 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
372 offsetof(struct __sk_buff, mark)),
373 BPF_EXIT_INSN(),
374 },
375 .result = ACCEPT,
376 .result_unpriv = ACCEPT,
377 },
378 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700379 "check corrupted spill/fill",
380 .insns = {
381 /* spill R1(ctx) into stack */
382 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700383 /* mess up with R1 pointer on stack */
384 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700385 /* fill back into R0 should fail */
386 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700387 BPF_EXIT_INSN(),
388 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700389 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700390 .errstr = "corrupted spill",
391 .result = REJECT,
392 },
393 {
394 "invalid src register in STX",
395 .insns = {
396 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
397 BPF_EXIT_INSN(),
398 },
399 .errstr = "R15 is invalid",
400 .result = REJECT,
401 },
402 {
403 "invalid dst register in STX",
404 .insns = {
405 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
406 BPF_EXIT_INSN(),
407 },
408 .errstr = "R14 is invalid",
409 .result = REJECT,
410 },
411 {
412 "invalid dst register in ST",
413 .insns = {
414 BPF_ST_MEM(BPF_B, 14, -1, -1),
415 BPF_EXIT_INSN(),
416 },
417 .errstr = "R14 is invalid",
418 .result = REJECT,
419 },
420 {
421 "invalid src register in LDX",
422 .insns = {
423 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
424 BPF_EXIT_INSN(),
425 },
426 .errstr = "R12 is invalid",
427 .result = REJECT,
428 },
429 {
430 "invalid dst register in LDX",
431 .insns = {
432 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
433 BPF_EXIT_INSN(),
434 },
435 .errstr = "R11 is invalid",
436 .result = REJECT,
437 },
438 {
439 "junk insn",
440 .insns = {
441 BPF_RAW_INSN(0, 0, 0, 0, 0),
442 BPF_EXIT_INSN(),
443 },
444 .errstr = "invalid BPF_LD_IMM",
445 .result = REJECT,
446 },
447 {
448 "junk insn2",
449 .insns = {
450 BPF_RAW_INSN(1, 0, 0, 0, 0),
451 BPF_EXIT_INSN(),
452 },
453 .errstr = "BPF_LDX uses reserved fields",
454 .result = REJECT,
455 },
456 {
457 "junk insn3",
458 .insns = {
459 BPF_RAW_INSN(-1, 0, 0, 0, 0),
460 BPF_EXIT_INSN(),
461 },
462 .errstr = "invalid BPF_ALU opcode f0",
463 .result = REJECT,
464 },
465 {
466 "junk insn4",
467 .insns = {
468 BPF_RAW_INSN(-1, -1, -1, -1, -1),
469 BPF_EXIT_INSN(),
470 },
471 .errstr = "invalid BPF_ALU opcode f0",
472 .result = REJECT,
473 },
474 {
475 "junk insn5",
476 .insns = {
477 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
478 BPF_EXIT_INSN(),
479 },
480 .errstr = "BPF_ALU uses reserved fields",
481 .result = REJECT,
482 },
483 {
484 "misaligned read from stack",
485 .insns = {
486 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
487 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
488 BPF_EXIT_INSN(),
489 },
490 .errstr = "misaligned access",
491 .result = REJECT,
492 },
493 {
494 "invalid map_fd for function call",
495 .insns = {
496 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
497 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
498 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
499 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200500 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
501 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700502 BPF_EXIT_INSN(),
503 },
504 .errstr = "fd 0 is not pointing to valid bpf_map",
505 .result = REJECT,
506 },
507 {
508 "don't check return value before access",
509 .insns = {
510 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
511 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
513 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200514 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
515 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700516 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
517 BPF_EXIT_INSN(),
518 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200519 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700520 .errstr = "R0 invalid mem access 'map_value_or_null'",
521 .result = REJECT,
522 },
523 {
524 "access memory with incorrect alignment",
525 .insns = {
526 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
527 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
528 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
529 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200530 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
531 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700532 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
533 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
534 BPF_EXIT_INSN(),
535 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200536 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700537 .errstr = "misaligned access",
538 .result = REJECT,
539 },
540 {
541 "sometimes access memory with incorrect alignment",
542 .insns = {
543 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
544 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
546 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200547 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
548 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700549 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
550 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
551 BPF_EXIT_INSN(),
552 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
553 BPF_EXIT_INSN(),
554 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200555 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700556 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700557 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700558 .result = REJECT,
559 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700560 {
561 "jump test 1",
562 .insns = {
563 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
564 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
565 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
566 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
567 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
568 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
569 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
570 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
571 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
572 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
573 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
574 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
575 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
576 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
577 BPF_MOV64_IMM(BPF_REG_0, 0),
578 BPF_EXIT_INSN(),
579 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700580 .errstr_unpriv = "R1 pointer comparison",
581 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700582 .result = ACCEPT,
583 },
584 {
585 "jump test 2",
586 .insns = {
587 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
588 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
589 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
590 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
591 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
592 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
593 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
594 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
595 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
596 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
597 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
598 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
599 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
600 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
601 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
602 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
603 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
604 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
605 BPF_MOV64_IMM(BPF_REG_0, 0),
606 BPF_EXIT_INSN(),
607 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700608 .errstr_unpriv = "R1 pointer comparison",
609 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700610 .result = ACCEPT,
611 },
612 {
613 "jump test 3",
614 .insns = {
615 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
616 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
617 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
618 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
619 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
620 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
621 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
622 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
623 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
624 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
625 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
627 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
628 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
629 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
630 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
631 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
632 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
633 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
635 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
636 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
637 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
638 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
639 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200640 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
641 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700642 BPF_EXIT_INSN(),
643 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200644 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700645 .errstr_unpriv = "R1 pointer comparison",
646 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700647 .result = ACCEPT,
648 },
649 {
650 "jump test 4",
651 .insns = {
652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
653 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
654 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
655 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
656 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
657 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
658 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
660 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
661 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
662 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
664 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
666 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
667 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
669 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
670 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
672 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
673 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
674 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
675 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
676 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
677 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
678 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
679 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
680 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
681 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
683 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
685 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
687 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
688 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
689 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
690 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
691 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
692 BPF_MOV64_IMM(BPF_REG_0, 0),
693 BPF_EXIT_INSN(),
694 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700695 .errstr_unpriv = "R1 pointer comparison",
696 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -0700697 .result = ACCEPT,
698 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700699 {
700 "jump test 5",
701 .insns = {
702 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
703 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
704 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
705 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
706 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
707 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
708 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
709 BPF_MOV64_IMM(BPF_REG_0, 0),
710 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
711 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
712 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
713 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
714 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
715 BPF_MOV64_IMM(BPF_REG_0, 0),
716 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
717 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
718 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
719 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
720 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
721 BPF_MOV64_IMM(BPF_REG_0, 0),
722 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
723 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
724 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
725 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
726 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
727 BPF_MOV64_IMM(BPF_REG_0, 0),
728 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
729 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
730 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
731 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
732 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
733 BPF_MOV64_IMM(BPF_REG_0, 0),
734 BPF_EXIT_INSN(),
735 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700736 .errstr_unpriv = "R1 pointer comparison",
737 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -0700738 .result = ACCEPT,
739 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700740 {
741 "access skb fields ok",
742 .insns = {
743 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
744 offsetof(struct __sk_buff, len)),
745 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
746 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
747 offsetof(struct __sk_buff, mark)),
748 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
749 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
750 offsetof(struct __sk_buff, pkt_type)),
751 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
752 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
753 offsetof(struct __sk_buff, queue_mapping)),
754 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -0700755 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
756 offsetof(struct __sk_buff, protocol)),
757 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
758 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
759 offsetof(struct __sk_buff, vlan_present)),
760 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
761 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
762 offsetof(struct __sk_buff, vlan_tci)),
763 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700764 BPF_EXIT_INSN(),
765 },
766 .result = ACCEPT,
767 },
768 {
769 "access skb fields bad1",
770 .insns = {
771 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
772 BPF_EXIT_INSN(),
773 },
774 .errstr = "invalid bpf_context access",
775 .result = REJECT,
776 },
777 {
778 "access skb fields bad2",
779 .insns = {
780 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
781 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
782 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
784 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200785 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
786 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700787 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
788 BPF_EXIT_INSN(),
789 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
790 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
791 offsetof(struct __sk_buff, pkt_type)),
792 BPF_EXIT_INSN(),
793 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200794 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700795 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700796 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700797 .result = REJECT,
798 },
799 {
800 "access skb fields bad3",
801 .insns = {
802 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
803 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
804 offsetof(struct __sk_buff, pkt_type)),
805 BPF_EXIT_INSN(),
806 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
807 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
809 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200810 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
811 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700812 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
813 BPF_EXIT_INSN(),
814 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
815 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
816 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200817 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700818 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700819 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -0700820 .result = REJECT,
821 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700822 {
823 "access skb fields bad4",
824 .insns = {
825 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
826 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
827 offsetof(struct __sk_buff, len)),
828 BPF_MOV64_IMM(BPF_REG_0, 0),
829 BPF_EXIT_INSN(),
830 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
831 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
832 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
833 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200834 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
835 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700836 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
837 BPF_EXIT_INSN(),
838 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
839 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
840 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200841 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700842 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700843 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -0700844 .result = REJECT,
845 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700846 {
847 "check skb->mark is not writeable by sockets",
848 .insns = {
849 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
850 offsetof(struct __sk_buff, mark)),
851 BPF_EXIT_INSN(),
852 },
853 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700854 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700855 .result = REJECT,
856 },
857 {
858 "check skb->tc_index is not writeable by sockets",
859 .insns = {
860 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
861 offsetof(struct __sk_buff, tc_index)),
862 BPF_EXIT_INSN(),
863 },
864 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700865 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700866 .result = REJECT,
867 },
868 {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100869 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -0700870 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +0100871 BPF_MOV64_IMM(BPF_REG_0, 0),
872 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
873 offsetof(struct __sk_buff, cb[0])),
874 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
875 offsetof(struct __sk_buff, cb[0]) + 1),
876 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
877 offsetof(struct __sk_buff, cb[0]) + 2),
878 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
879 offsetof(struct __sk_buff, cb[0]) + 3),
880 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
881 offsetof(struct __sk_buff, cb[1])),
882 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
883 offsetof(struct __sk_buff, cb[1]) + 1),
884 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
885 offsetof(struct __sk_buff, cb[1]) + 2),
886 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
887 offsetof(struct __sk_buff, cb[1]) + 3),
888 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
889 offsetof(struct __sk_buff, cb[2])),
890 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
891 offsetof(struct __sk_buff, cb[2]) + 1),
892 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
893 offsetof(struct __sk_buff, cb[2]) + 2),
894 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
895 offsetof(struct __sk_buff, cb[2]) + 3),
896 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
897 offsetof(struct __sk_buff, cb[3])),
898 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
899 offsetof(struct __sk_buff, cb[3]) + 1),
900 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
901 offsetof(struct __sk_buff, cb[3]) + 2),
902 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
903 offsetof(struct __sk_buff, cb[3]) + 3),
904 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
905 offsetof(struct __sk_buff, cb[4])),
906 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
907 offsetof(struct __sk_buff, cb[4]) + 1),
908 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
909 offsetof(struct __sk_buff, cb[4]) + 2),
910 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
911 offsetof(struct __sk_buff, cb[4]) + 3),
912 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
913 offsetof(struct __sk_buff, cb[0])),
914 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
915 offsetof(struct __sk_buff, cb[0]) + 1),
916 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
917 offsetof(struct __sk_buff, cb[0]) + 2),
918 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
919 offsetof(struct __sk_buff, cb[0]) + 3),
920 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
921 offsetof(struct __sk_buff, cb[1])),
922 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
923 offsetof(struct __sk_buff, cb[1]) + 1),
924 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
925 offsetof(struct __sk_buff, cb[1]) + 2),
926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
927 offsetof(struct __sk_buff, cb[1]) + 3),
928 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
929 offsetof(struct __sk_buff, cb[2])),
930 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
931 offsetof(struct __sk_buff, cb[2]) + 1),
932 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
933 offsetof(struct __sk_buff, cb[2]) + 2),
934 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
935 offsetof(struct __sk_buff, cb[2]) + 3),
936 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
937 offsetof(struct __sk_buff, cb[3])),
938 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
939 offsetof(struct __sk_buff, cb[3]) + 1),
940 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
941 offsetof(struct __sk_buff, cb[3]) + 2),
942 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
943 offsetof(struct __sk_buff, cb[3]) + 3),
944 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
945 offsetof(struct __sk_buff, cb[4])),
946 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
947 offsetof(struct __sk_buff, cb[4]) + 1),
948 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
949 offsetof(struct __sk_buff, cb[4]) + 2),
950 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
951 offsetof(struct __sk_buff, cb[4]) + 3),
952 BPF_EXIT_INSN(),
953 },
954 .result = ACCEPT,
955 },
956 {
957 "check cb access: byte, oob 1",
958 .insns = {
959 BPF_MOV64_IMM(BPF_REG_0, 0),
960 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
961 offsetof(struct __sk_buff, cb[4]) + 4),
962 BPF_EXIT_INSN(),
963 },
964 .errstr = "invalid bpf_context access",
965 .result = REJECT,
966 },
967 {
968 "check cb access: byte, oob 2",
969 .insns = {
970 BPF_MOV64_IMM(BPF_REG_0, 0),
971 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
972 offsetof(struct __sk_buff, cb[0]) - 1),
973 BPF_EXIT_INSN(),
974 },
975 .errstr = "invalid bpf_context access",
976 .result = REJECT,
977 },
978 {
979 "check cb access: byte, oob 3",
980 .insns = {
981 BPF_MOV64_IMM(BPF_REG_0, 0),
982 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
983 offsetof(struct __sk_buff, cb[4]) + 4),
984 BPF_EXIT_INSN(),
985 },
986 .errstr = "invalid bpf_context access",
987 .result = REJECT,
988 },
989 {
990 "check cb access: byte, oob 4",
991 .insns = {
992 BPF_MOV64_IMM(BPF_REG_0, 0),
993 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
994 offsetof(struct __sk_buff, cb[0]) - 1),
995 BPF_EXIT_INSN(),
996 },
997 .errstr = "invalid bpf_context access",
998 .result = REJECT,
999 },
1000 {
1001 "check cb access: byte, wrong type",
1002 .insns = {
1003 BPF_MOV64_IMM(BPF_REG_0, 0),
1004 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001005 offsetof(struct __sk_buff, cb[0])),
1006 BPF_EXIT_INSN(),
1007 },
1008 .errstr = "invalid bpf_context access",
1009 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01001010 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1011 },
1012 {
1013 "check cb access: half",
1014 .insns = {
1015 BPF_MOV64_IMM(BPF_REG_0, 0),
1016 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1017 offsetof(struct __sk_buff, cb[0])),
1018 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1019 offsetof(struct __sk_buff, cb[0]) + 2),
1020 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1021 offsetof(struct __sk_buff, cb[1])),
1022 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1023 offsetof(struct __sk_buff, cb[1]) + 2),
1024 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1025 offsetof(struct __sk_buff, cb[2])),
1026 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1027 offsetof(struct __sk_buff, cb[2]) + 2),
1028 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1029 offsetof(struct __sk_buff, cb[3])),
1030 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1031 offsetof(struct __sk_buff, cb[3]) + 2),
1032 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1033 offsetof(struct __sk_buff, cb[4])),
1034 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1035 offsetof(struct __sk_buff, cb[4]) + 2),
1036 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1037 offsetof(struct __sk_buff, cb[0])),
1038 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1039 offsetof(struct __sk_buff, cb[0]) + 2),
1040 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1041 offsetof(struct __sk_buff, cb[1])),
1042 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1043 offsetof(struct __sk_buff, cb[1]) + 2),
1044 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1045 offsetof(struct __sk_buff, cb[2])),
1046 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1047 offsetof(struct __sk_buff, cb[2]) + 2),
1048 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1049 offsetof(struct __sk_buff, cb[3])),
1050 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1051 offsetof(struct __sk_buff, cb[3]) + 2),
1052 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1053 offsetof(struct __sk_buff, cb[4])),
1054 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1055 offsetof(struct __sk_buff, cb[4]) + 2),
1056 BPF_EXIT_INSN(),
1057 },
1058 .result = ACCEPT,
1059 },
1060 {
1061 "check cb access: half, unaligned",
1062 .insns = {
1063 BPF_MOV64_IMM(BPF_REG_0, 0),
1064 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1065 offsetof(struct __sk_buff, cb[0]) + 1),
1066 BPF_EXIT_INSN(),
1067 },
1068 .errstr = "misaligned access",
1069 .result = REJECT,
1070 },
1071 {
1072 "check cb access: half, oob 1",
1073 .insns = {
1074 BPF_MOV64_IMM(BPF_REG_0, 0),
1075 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1076 offsetof(struct __sk_buff, cb[4]) + 4),
1077 BPF_EXIT_INSN(),
1078 },
1079 .errstr = "invalid bpf_context access",
1080 .result = REJECT,
1081 },
1082 {
1083 "check cb access: half, oob 2",
1084 .insns = {
1085 BPF_MOV64_IMM(BPF_REG_0, 0),
1086 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1087 offsetof(struct __sk_buff, cb[0]) - 2),
1088 BPF_EXIT_INSN(),
1089 },
1090 .errstr = "invalid bpf_context access",
1091 .result = REJECT,
1092 },
1093 {
1094 "check cb access: half, oob 3",
1095 .insns = {
1096 BPF_MOV64_IMM(BPF_REG_0, 0),
1097 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1098 offsetof(struct __sk_buff, cb[4]) + 4),
1099 BPF_EXIT_INSN(),
1100 },
1101 .errstr = "invalid bpf_context access",
1102 .result = REJECT,
1103 },
1104 {
1105 "check cb access: half, oob 4",
1106 .insns = {
1107 BPF_MOV64_IMM(BPF_REG_0, 0),
1108 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1109 offsetof(struct __sk_buff, cb[0]) - 2),
1110 BPF_EXIT_INSN(),
1111 },
1112 .errstr = "invalid bpf_context access",
1113 .result = REJECT,
1114 },
1115 {
1116 "check cb access: half, wrong type",
1117 .insns = {
1118 BPF_MOV64_IMM(BPF_REG_0, 0),
1119 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1120 offsetof(struct __sk_buff, cb[0])),
1121 BPF_EXIT_INSN(),
1122 },
1123 .errstr = "invalid bpf_context access",
1124 .result = REJECT,
1125 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1126 },
1127 {
1128 "check cb access: word",
1129 .insns = {
1130 BPF_MOV64_IMM(BPF_REG_0, 0),
1131 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1132 offsetof(struct __sk_buff, cb[0])),
1133 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1134 offsetof(struct __sk_buff, cb[1])),
1135 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1136 offsetof(struct __sk_buff, cb[2])),
1137 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1138 offsetof(struct __sk_buff, cb[3])),
1139 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1140 offsetof(struct __sk_buff, cb[4])),
1141 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1142 offsetof(struct __sk_buff, cb[0])),
1143 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1144 offsetof(struct __sk_buff, cb[1])),
1145 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1146 offsetof(struct __sk_buff, cb[2])),
1147 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1148 offsetof(struct __sk_buff, cb[3])),
1149 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1150 offsetof(struct __sk_buff, cb[4])),
1151 BPF_EXIT_INSN(),
1152 },
1153 .result = ACCEPT,
1154 },
1155 {
1156 "check cb access: word, unaligned 1",
1157 .insns = {
1158 BPF_MOV64_IMM(BPF_REG_0, 0),
1159 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1160 offsetof(struct __sk_buff, cb[0]) + 2),
1161 BPF_EXIT_INSN(),
1162 },
1163 .errstr = "misaligned access",
1164 .result = REJECT,
1165 },
1166 {
1167 "check cb access: word, unaligned 2",
1168 .insns = {
1169 BPF_MOV64_IMM(BPF_REG_0, 0),
1170 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1171 offsetof(struct __sk_buff, cb[4]) + 1),
1172 BPF_EXIT_INSN(),
1173 },
1174 .errstr = "misaligned access",
1175 .result = REJECT,
1176 },
1177 {
1178 "check cb access: word, unaligned 3",
1179 .insns = {
1180 BPF_MOV64_IMM(BPF_REG_0, 0),
1181 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1182 offsetof(struct __sk_buff, cb[4]) + 2),
1183 BPF_EXIT_INSN(),
1184 },
1185 .errstr = "misaligned access",
1186 .result = REJECT,
1187 },
1188 {
1189 "check cb access: word, unaligned 4",
1190 .insns = {
1191 BPF_MOV64_IMM(BPF_REG_0, 0),
1192 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1193 offsetof(struct __sk_buff, cb[4]) + 3),
1194 BPF_EXIT_INSN(),
1195 },
1196 .errstr = "misaligned access",
1197 .result = REJECT,
1198 },
1199 {
1200 "check cb access: double",
1201 .insns = {
1202 BPF_MOV64_IMM(BPF_REG_0, 0),
1203 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1204 offsetof(struct __sk_buff, cb[0])),
1205 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1206 offsetof(struct __sk_buff, cb[2])),
1207 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1208 offsetof(struct __sk_buff, cb[0])),
1209 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1210 offsetof(struct __sk_buff, cb[2])),
1211 BPF_EXIT_INSN(),
1212 },
1213 .result = ACCEPT,
1214 },
1215 {
1216 "check cb access: double, unaligned 1",
1217 .insns = {
1218 BPF_MOV64_IMM(BPF_REG_0, 0),
1219 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1220 offsetof(struct __sk_buff, cb[1])),
1221 BPF_EXIT_INSN(),
1222 },
1223 .errstr = "misaligned access",
1224 .result = REJECT,
1225 },
1226 {
1227 "check cb access: double, unaligned 2",
1228 .insns = {
1229 BPF_MOV64_IMM(BPF_REG_0, 0),
1230 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1231 offsetof(struct __sk_buff, cb[3])),
1232 BPF_EXIT_INSN(),
1233 },
1234 .errstr = "misaligned access",
1235 .result = REJECT,
1236 },
1237 {
1238 "check cb access: double, oob 1",
1239 .insns = {
1240 BPF_MOV64_IMM(BPF_REG_0, 0),
1241 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1242 offsetof(struct __sk_buff, cb[4])),
1243 BPF_EXIT_INSN(),
1244 },
1245 .errstr = "invalid bpf_context access",
1246 .result = REJECT,
1247 },
1248 {
1249 "check cb access: double, oob 2",
1250 .insns = {
1251 BPF_MOV64_IMM(BPF_REG_0, 0),
1252 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1253 offsetof(struct __sk_buff, cb[4]) + 8),
1254 BPF_EXIT_INSN(),
1255 },
1256 .errstr = "invalid bpf_context access",
1257 .result = REJECT,
1258 },
1259 {
1260 "check cb access: double, oob 3",
1261 .insns = {
1262 BPF_MOV64_IMM(BPF_REG_0, 0),
1263 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1264 offsetof(struct __sk_buff, cb[0]) - 8),
1265 BPF_EXIT_INSN(),
1266 },
1267 .errstr = "invalid bpf_context access",
1268 .result = REJECT,
1269 },
1270 {
1271 "check cb access: double, oob 4",
1272 .insns = {
1273 BPF_MOV64_IMM(BPF_REG_0, 0),
1274 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1275 offsetof(struct __sk_buff, cb[4])),
1276 BPF_EXIT_INSN(),
1277 },
1278 .errstr = "invalid bpf_context access",
1279 .result = REJECT,
1280 },
1281 {
1282 "check cb access: double, oob 5",
1283 .insns = {
1284 BPF_MOV64_IMM(BPF_REG_0, 0),
1285 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1286 offsetof(struct __sk_buff, cb[4]) + 8),
1287 BPF_EXIT_INSN(),
1288 },
1289 .errstr = "invalid bpf_context access",
1290 .result = REJECT,
1291 },
1292 {
1293 "check cb access: double, oob 6",
1294 .insns = {
1295 BPF_MOV64_IMM(BPF_REG_0, 0),
1296 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1297 offsetof(struct __sk_buff, cb[0]) - 8),
1298 BPF_EXIT_INSN(),
1299 },
1300 .errstr = "invalid bpf_context access",
1301 .result = REJECT,
1302 },
1303 {
1304 "check cb access: double, wrong type",
1305 .insns = {
1306 BPF_MOV64_IMM(BPF_REG_0, 0),
1307 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1308 offsetof(struct __sk_buff, cb[0])),
1309 BPF_EXIT_INSN(),
1310 },
1311 .errstr = "invalid bpf_context access",
1312 .result = REJECT,
1313 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001314 },
1315 {
1316 "check out of range skb->cb access",
1317 .insns = {
1318 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001319 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001320 BPF_EXIT_INSN(),
1321 },
1322 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001323 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001324 .result = REJECT,
1325 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
1326 },
1327 {
1328 "write skb fields from socket prog",
1329 .insns = {
1330 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1331 offsetof(struct __sk_buff, cb[4])),
1332 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1333 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1334 offsetof(struct __sk_buff, mark)),
1335 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1336 offsetof(struct __sk_buff, tc_index)),
1337 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1338 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1339 offsetof(struct __sk_buff, cb[0])),
1340 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1341 offsetof(struct __sk_buff, cb[2])),
1342 BPF_EXIT_INSN(),
1343 },
1344 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001345 .errstr_unpriv = "R1 leaks addr",
1346 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001347 },
1348 {
1349 "write skb fields from tc_cls_act prog",
1350 .insns = {
1351 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1352 offsetof(struct __sk_buff, cb[0])),
1353 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1354 offsetof(struct __sk_buff, mark)),
1355 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1356 offsetof(struct __sk_buff, tc_index)),
1357 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1358 offsetof(struct __sk_buff, tc_index)),
1359 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1360 offsetof(struct __sk_buff, cb[3])),
1361 BPF_EXIT_INSN(),
1362 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001363 .errstr_unpriv = "",
1364 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001365 .result = ACCEPT,
1366 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1367 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07001368 {
1369 "PTR_TO_STACK store/load",
1370 .insns = {
1371 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1372 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1373 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1374 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1375 BPF_EXIT_INSN(),
1376 },
1377 .result = ACCEPT,
1378 },
1379 {
1380 "PTR_TO_STACK store/load - bad alignment on off",
1381 .insns = {
1382 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1384 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
1385 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
1386 BPF_EXIT_INSN(),
1387 },
1388 .result = REJECT,
1389 .errstr = "misaligned access off -6 size 8",
1390 },
1391 {
1392 "PTR_TO_STACK store/load - bad alignment on reg",
1393 .insns = {
1394 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1395 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
1396 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1397 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1398 BPF_EXIT_INSN(),
1399 },
1400 .result = REJECT,
1401 .errstr = "misaligned access off -2 size 8",
1402 },
1403 {
1404 "PTR_TO_STACK store/load - out of bounds low",
1405 .insns = {
1406 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1407 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
1408 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1409 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1410 BPF_EXIT_INSN(),
1411 },
1412 .result = REJECT,
1413 .errstr = "invalid stack off=-79992 size=8",
1414 },
1415 {
1416 "PTR_TO_STACK store/load - out of bounds high",
1417 .insns = {
1418 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1420 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
1421 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
1422 BPF_EXIT_INSN(),
1423 },
1424 .result = REJECT,
1425 .errstr = "invalid stack off=0 size=8",
1426 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001427 {
1428 "unpriv: return pointer",
1429 .insns = {
1430 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1431 BPF_EXIT_INSN(),
1432 },
1433 .result = ACCEPT,
1434 .result_unpriv = REJECT,
1435 .errstr_unpriv = "R0 leaks addr",
1436 },
1437 {
1438 "unpriv: add const to pointer",
1439 .insns = {
1440 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1441 BPF_MOV64_IMM(BPF_REG_0, 0),
1442 BPF_EXIT_INSN(),
1443 },
1444 .result = ACCEPT,
1445 .result_unpriv = REJECT,
1446 .errstr_unpriv = "R1 pointer arithmetic",
1447 },
1448 {
1449 "unpriv: add pointer to pointer",
1450 .insns = {
1451 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
1452 BPF_MOV64_IMM(BPF_REG_0, 0),
1453 BPF_EXIT_INSN(),
1454 },
1455 .result = ACCEPT,
1456 .result_unpriv = REJECT,
1457 .errstr_unpriv = "R1 pointer arithmetic",
1458 },
1459 {
1460 "unpriv: neg pointer",
1461 .insns = {
1462 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
1463 BPF_MOV64_IMM(BPF_REG_0, 0),
1464 BPF_EXIT_INSN(),
1465 },
1466 .result = ACCEPT,
1467 .result_unpriv = REJECT,
1468 .errstr_unpriv = "R1 pointer arithmetic",
1469 },
1470 {
1471 "unpriv: cmp pointer with const",
1472 .insns = {
1473 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1474 BPF_MOV64_IMM(BPF_REG_0, 0),
1475 BPF_EXIT_INSN(),
1476 },
1477 .result = ACCEPT,
1478 .result_unpriv = REJECT,
1479 .errstr_unpriv = "R1 pointer comparison",
1480 },
1481 {
1482 "unpriv: cmp pointer with pointer",
1483 .insns = {
1484 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1485 BPF_MOV64_IMM(BPF_REG_0, 0),
1486 BPF_EXIT_INSN(),
1487 },
1488 .result = ACCEPT,
1489 .result_unpriv = REJECT,
1490 .errstr_unpriv = "R10 pointer comparison",
1491 },
1492 {
1493 "unpriv: check that printk is disallowed",
1494 .insns = {
1495 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1496 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1497 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1498 BPF_MOV64_IMM(BPF_REG_2, 8),
1499 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001500 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1501 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001502 BPF_MOV64_IMM(BPF_REG_0, 0),
1503 BPF_EXIT_INSN(),
1504 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01001505 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001506 .result_unpriv = REJECT,
1507 .result = ACCEPT,
1508 },
1509 {
1510 "unpriv: pass pointer to helper function",
1511 .insns = {
1512 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1513 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1514 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1515 BPF_LD_MAP_FD(BPF_REG_1, 0),
1516 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1517 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001518 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1519 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001520 BPF_MOV64_IMM(BPF_REG_0, 0),
1521 BPF_EXIT_INSN(),
1522 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001523 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001524 .errstr_unpriv = "R4 leaks addr",
1525 .result_unpriv = REJECT,
1526 .result = ACCEPT,
1527 },
1528 {
1529 "unpriv: indirectly pass pointer on stack to helper function",
1530 .insns = {
1531 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1532 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1534 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001535 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1536 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001537 BPF_MOV64_IMM(BPF_REG_0, 0),
1538 BPF_EXIT_INSN(),
1539 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001540 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001541 .errstr = "invalid indirect read from stack off -8+0 size 8",
1542 .result = REJECT,
1543 },
1544 {
1545 "unpriv: mangle pointer on stack 1",
1546 .insns = {
1547 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1548 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
1549 BPF_MOV64_IMM(BPF_REG_0, 0),
1550 BPF_EXIT_INSN(),
1551 },
1552 .errstr_unpriv = "attempt to corrupt spilled",
1553 .result_unpriv = REJECT,
1554 .result = ACCEPT,
1555 },
1556 {
1557 "unpriv: mangle pointer on stack 2",
1558 .insns = {
1559 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1560 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
1561 BPF_MOV64_IMM(BPF_REG_0, 0),
1562 BPF_EXIT_INSN(),
1563 },
1564 .errstr_unpriv = "attempt to corrupt spilled",
1565 .result_unpriv = REJECT,
1566 .result = ACCEPT,
1567 },
1568 {
1569 "unpriv: read pointer from stack in small chunks",
1570 .insns = {
1571 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
1572 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
1573 BPF_MOV64_IMM(BPF_REG_0, 0),
1574 BPF_EXIT_INSN(),
1575 },
1576 .errstr = "invalid size",
1577 .result = REJECT,
1578 },
1579 {
1580 "unpriv: write pointer into ctx",
1581 .insns = {
1582 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1583 BPF_MOV64_IMM(BPF_REG_0, 0),
1584 BPF_EXIT_INSN(),
1585 },
1586 .errstr_unpriv = "R1 leaks addr",
1587 .result_unpriv = REJECT,
1588 .errstr = "invalid bpf_context access",
1589 .result = REJECT,
1590 },
1591 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001592 "unpriv: spill/fill of ctx",
1593 .insns = {
1594 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1595 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1596 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1597 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1598 BPF_MOV64_IMM(BPF_REG_0, 0),
1599 BPF_EXIT_INSN(),
1600 },
1601 .result = ACCEPT,
1602 },
1603 {
1604 "unpriv: spill/fill of ctx 2",
1605 .insns = {
1606 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1608 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1609 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001610 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1611 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001612 BPF_EXIT_INSN(),
1613 },
1614 .result = ACCEPT,
1615 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1616 },
1617 {
1618 "unpriv: spill/fill of ctx 3",
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_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1624 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001625 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1626 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001627 BPF_EXIT_INSN(),
1628 },
1629 .result = REJECT,
1630 .errstr = "R1 type=fp expected=ctx",
1631 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1632 },
1633 {
1634 "unpriv: spill/fill of ctx 4",
1635 .insns = {
1636 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1638 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1639 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001640 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
1641 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001642 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001643 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1644 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001645 BPF_EXIT_INSN(),
1646 },
1647 .result = REJECT,
1648 .errstr = "R1 type=inv expected=ctx",
1649 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1650 },
1651 {
1652 "unpriv: spill/fill of different pointers stx",
1653 .insns = {
1654 BPF_MOV64_IMM(BPF_REG_3, 42),
1655 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1656 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1657 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1658 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1659 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1660 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1661 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1662 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1663 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1664 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
1665 offsetof(struct __sk_buff, mark)),
1666 BPF_MOV64_IMM(BPF_REG_0, 0),
1667 BPF_EXIT_INSN(),
1668 },
1669 .result = REJECT,
1670 .errstr = "same insn cannot be used with different pointers",
1671 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1672 },
1673 {
1674 "unpriv: spill/fill of different pointers ldx",
1675 .insns = {
1676 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1677 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1678 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1679 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
1681 -(__s32)offsetof(struct bpf_perf_event_data,
1682 sample_period) - 8),
1683 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
1684 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
1685 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1686 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
1687 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
1688 offsetof(struct bpf_perf_event_data,
1689 sample_period)),
1690 BPF_MOV64_IMM(BPF_REG_0, 0),
1691 BPF_EXIT_INSN(),
1692 },
1693 .result = REJECT,
1694 .errstr = "same insn cannot be used with different pointers",
1695 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
1696 },
1697 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001698 "unpriv: write pointer into map elem value",
1699 .insns = {
1700 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1701 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1703 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001704 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1705 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001706 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1707 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
1708 BPF_EXIT_INSN(),
1709 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001710 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001711 .errstr_unpriv = "R0 leaks addr",
1712 .result_unpriv = REJECT,
1713 .result = ACCEPT,
1714 },
1715 {
1716 "unpriv: partial copy of pointer",
1717 .insns = {
1718 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
1719 BPF_MOV64_IMM(BPF_REG_0, 0),
1720 BPF_EXIT_INSN(),
1721 },
1722 .errstr_unpriv = "R10 partial copy",
1723 .result_unpriv = REJECT,
1724 .result = ACCEPT,
1725 },
1726 {
1727 "unpriv: pass pointer to tail_call",
1728 .insns = {
1729 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
1730 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001731 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1732 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001733 BPF_MOV64_IMM(BPF_REG_0, 0),
1734 BPF_EXIT_INSN(),
1735 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001736 .fixup_prog = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001737 .errstr_unpriv = "R3 leaks addr into helper",
1738 .result_unpriv = REJECT,
1739 .result = ACCEPT,
1740 },
1741 {
1742 "unpriv: cmp map pointer with zero",
1743 .insns = {
1744 BPF_MOV64_IMM(BPF_REG_1, 0),
1745 BPF_LD_MAP_FD(BPF_REG_1, 0),
1746 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
1747 BPF_MOV64_IMM(BPF_REG_0, 0),
1748 BPF_EXIT_INSN(),
1749 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001750 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001751 .errstr_unpriv = "R1 pointer comparison",
1752 .result_unpriv = REJECT,
1753 .result = ACCEPT,
1754 },
1755 {
1756 "unpriv: write into frame pointer",
1757 .insns = {
1758 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
1759 BPF_MOV64_IMM(BPF_REG_0, 0),
1760 BPF_EXIT_INSN(),
1761 },
1762 .errstr = "frame pointer is read only",
1763 .result = REJECT,
1764 },
1765 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02001766 "unpriv: spill/fill frame pointer",
1767 .insns = {
1768 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1769 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1770 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
1771 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
1772 BPF_MOV64_IMM(BPF_REG_0, 0),
1773 BPF_EXIT_INSN(),
1774 },
1775 .errstr = "frame pointer is read only",
1776 .result = REJECT,
1777 },
1778 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001779 "unpriv: cmp of frame pointer",
1780 .insns = {
1781 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
1782 BPF_MOV64_IMM(BPF_REG_0, 0),
1783 BPF_EXIT_INSN(),
1784 },
1785 .errstr_unpriv = "R10 pointer comparison",
1786 .result_unpriv = REJECT,
1787 .result = ACCEPT,
1788 },
1789 {
1790 "unpriv: cmp of stack pointer",
1791 .insns = {
1792 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1794 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
1795 BPF_MOV64_IMM(BPF_REG_0, 0),
1796 BPF_EXIT_INSN(),
1797 },
1798 .errstr_unpriv = "R2 pointer comparison",
1799 .result_unpriv = REJECT,
1800 .result = ACCEPT,
1801 },
1802 {
1803 "unpriv: obfuscate stack pointer",
1804 .insns = {
1805 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1808 BPF_MOV64_IMM(BPF_REG_0, 0),
1809 BPF_EXIT_INSN(),
1810 },
1811 .errstr_unpriv = "R2 pointer arithmetic",
1812 .result_unpriv = REJECT,
1813 .result = ACCEPT,
1814 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001815 {
1816 "raw_stack: no skb_load_bytes",
1817 .insns = {
1818 BPF_MOV64_IMM(BPF_REG_2, 4),
1819 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1821 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1822 BPF_MOV64_IMM(BPF_REG_4, 8),
1823 /* Call to skb_load_bytes() omitted. */
1824 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1825 BPF_EXIT_INSN(),
1826 },
1827 .result = REJECT,
1828 .errstr = "invalid read from stack off -8+0 size 8",
1829 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1830 },
1831 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001832 "raw_stack: skb_load_bytes, negative len",
1833 .insns = {
1834 BPF_MOV64_IMM(BPF_REG_2, 4),
1835 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1836 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1837 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1838 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001839 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1840 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001841 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1842 BPF_EXIT_INSN(),
1843 },
1844 .result = REJECT,
1845 .errstr = "invalid stack type R3",
1846 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1847 },
1848 {
1849 "raw_stack: skb_load_bytes, negative len 2",
1850 .insns = {
1851 BPF_MOV64_IMM(BPF_REG_2, 4),
1852 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1853 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1854 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1855 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001856 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1857 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001858 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1859 BPF_EXIT_INSN(),
1860 },
1861 .result = REJECT,
1862 .errstr = "invalid stack type R3",
1863 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1864 },
1865 {
1866 "raw_stack: skb_load_bytes, zero len",
1867 .insns = {
1868 BPF_MOV64_IMM(BPF_REG_2, 4),
1869 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1871 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1872 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001873 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1874 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02001875 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1876 BPF_EXIT_INSN(),
1877 },
1878 .result = REJECT,
1879 .errstr = "invalid stack type R3",
1880 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1881 },
1882 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001883 "raw_stack: skb_load_bytes, no init",
1884 .insns = {
1885 BPF_MOV64_IMM(BPF_REG_2, 4),
1886 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1888 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1889 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001890 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1891 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001892 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1893 BPF_EXIT_INSN(),
1894 },
1895 .result = ACCEPT,
1896 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1897 },
1898 {
1899 "raw_stack: skb_load_bytes, init",
1900 .insns = {
1901 BPF_MOV64_IMM(BPF_REG_2, 4),
1902 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1903 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
1904 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
1905 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1906 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001907 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1908 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001909 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1910 BPF_EXIT_INSN(),
1911 },
1912 .result = ACCEPT,
1913 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1914 },
1915 {
1916 "raw_stack: skb_load_bytes, spilled regs around bounds",
1917 .insns = {
1918 BPF_MOV64_IMM(BPF_REG_2, 4),
1919 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1920 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001921 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1922 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001923 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1924 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001925 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1926 BPF_FUNC_skb_load_bytes),
1927 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1928 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001929 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1930 offsetof(struct __sk_buff, mark)),
1931 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1932 offsetof(struct __sk_buff, priority)),
1933 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1934 BPF_EXIT_INSN(),
1935 },
1936 .result = ACCEPT,
1937 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1938 },
1939 {
1940 "raw_stack: skb_load_bytes, spilled regs corruption",
1941 .insns = {
1942 BPF_MOV64_IMM(BPF_REG_2, 4),
1943 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1944 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001945 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001946 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1947 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001948 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1949 BPF_FUNC_skb_load_bytes),
1950 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001951 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1952 offsetof(struct __sk_buff, mark)),
1953 BPF_EXIT_INSN(),
1954 },
1955 .result = REJECT,
1956 .errstr = "R0 invalid mem access 'inv'",
1957 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1958 },
1959 {
1960 "raw_stack: skb_load_bytes, spilled regs corruption 2",
1961 .insns = {
1962 BPF_MOV64_IMM(BPF_REG_2, 4),
1963 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1964 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001965 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1966 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1967 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001968 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1969 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001970 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1971 BPF_FUNC_skb_load_bytes),
1972 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
1973 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
1974 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001975 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
1976 offsetof(struct __sk_buff, mark)),
1977 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
1978 offsetof(struct __sk_buff, priority)),
1979 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
1980 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
1981 offsetof(struct __sk_buff, pkt_type)),
1982 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
1983 BPF_EXIT_INSN(),
1984 },
1985 .result = REJECT,
1986 .errstr = "R3 invalid mem access 'inv'",
1987 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1988 },
1989 {
1990 "raw_stack: skb_load_bytes, spilled regs + data",
1991 .insns = {
1992 BPF_MOV64_IMM(BPF_REG_2, 4),
1993 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
1994 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001995 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
1996 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
1997 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02001998 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
1999 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002000 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2001 BPF_FUNC_skb_load_bytes),
2002 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
2003 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
2004 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002005 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
2006 offsetof(struct __sk_buff, mark)),
2007 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
2008 offsetof(struct __sk_buff, priority)),
2009 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
2010 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
2011 BPF_EXIT_INSN(),
2012 },
2013 .result = ACCEPT,
2014 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2015 },
2016 {
2017 "raw_stack: skb_load_bytes, invalid access 1",
2018 .insns = {
2019 BPF_MOV64_IMM(BPF_REG_2, 4),
2020 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2021 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
2022 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2023 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002024 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2025 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002026 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2027 BPF_EXIT_INSN(),
2028 },
2029 .result = REJECT,
2030 .errstr = "invalid stack type R3 off=-513 access_size=8",
2031 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2032 },
2033 {
2034 "raw_stack: skb_load_bytes, invalid access 2",
2035 .insns = {
2036 BPF_MOV64_IMM(BPF_REG_2, 4),
2037 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2039 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2040 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002041 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2042 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002043 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2044 BPF_EXIT_INSN(),
2045 },
2046 .result = REJECT,
2047 .errstr = "invalid stack type R3 off=-1 access_size=8",
2048 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2049 },
2050 {
2051 "raw_stack: skb_load_bytes, invalid access 3",
2052 .insns = {
2053 BPF_MOV64_IMM(BPF_REG_2, 4),
2054 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
2056 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2057 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002058 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2059 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002060 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2061 BPF_EXIT_INSN(),
2062 },
2063 .result = REJECT,
2064 .errstr = "invalid stack type R3 off=-1 access_size=-1",
2065 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2066 },
2067 {
2068 "raw_stack: skb_load_bytes, invalid access 4",
2069 .insns = {
2070 BPF_MOV64_IMM(BPF_REG_2, 4),
2071 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
2073 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2074 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2076 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002077 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2078 BPF_EXIT_INSN(),
2079 },
2080 .result = REJECT,
2081 .errstr = "invalid stack type R3 off=-1 access_size=2147483647",
2082 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2083 },
2084 {
2085 "raw_stack: skb_load_bytes, invalid access 5",
2086 .insns = {
2087 BPF_MOV64_IMM(BPF_REG_2, 4),
2088 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2089 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2090 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2091 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002092 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2093 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002094 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2095 BPF_EXIT_INSN(),
2096 },
2097 .result = REJECT,
2098 .errstr = "invalid stack type R3 off=-512 access_size=2147483647",
2099 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2100 },
2101 {
2102 "raw_stack: skb_load_bytes, invalid access 6",
2103 .insns = {
2104 BPF_MOV64_IMM(BPF_REG_2, 4),
2105 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2106 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2107 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2108 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2110 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2112 BPF_EXIT_INSN(),
2113 },
2114 .result = REJECT,
2115 .errstr = "invalid stack type R3 off=-512 access_size=0",
2116 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2117 },
2118 {
2119 "raw_stack: skb_load_bytes, large access",
2120 .insns = {
2121 BPF_MOV64_IMM(BPF_REG_2, 4),
2122 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2123 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
2124 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2125 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002126 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2127 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002128 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2129 BPF_EXIT_INSN(),
2130 },
2131 .result = ACCEPT,
2132 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2133 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002134 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002135 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002136 .insns = {
2137 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2138 offsetof(struct __sk_buff, data)),
2139 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2140 offsetof(struct __sk_buff, data_end)),
2141 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2142 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2143 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2144 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2145 BPF_MOV64_IMM(BPF_REG_0, 0),
2146 BPF_EXIT_INSN(),
2147 },
2148 .result = ACCEPT,
2149 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2150 },
2151 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002152 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002153 .insns = {
2154 BPF_MOV64_IMM(BPF_REG_0, 1),
2155 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
2156 offsetof(struct __sk_buff, data_end)),
2157 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2158 offsetof(struct __sk_buff, data)),
2159 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
2161 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
2162 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
2163 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
2164 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
2165 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2166 offsetof(struct __sk_buff, data)),
2167 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
2168 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
2169 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48),
2170 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48),
2171 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
2172 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
2173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2174 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2175 offsetof(struct __sk_buff, data_end)),
2176 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
2177 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
2178 BPF_MOV64_IMM(BPF_REG_0, 0),
2179 BPF_EXIT_INSN(),
2180 },
2181 .result = ACCEPT,
2182 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2183 },
2184 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002185 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002186 .insns = {
2187 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2188 offsetof(struct __sk_buff, data)),
2189 BPF_MOV64_IMM(BPF_REG_0, 0),
2190 BPF_EXIT_INSN(),
2191 },
2192 .errstr = "invalid bpf_context access off=76",
2193 .result = REJECT,
2194 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2195 },
2196 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002197 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002198 .insns = {
2199 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2200 offsetof(struct __sk_buff, data)),
2201 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2202 offsetof(struct __sk_buff, data_end)),
2203 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2205 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2206 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2207 BPF_MOV64_IMM(BPF_REG_0, 0),
2208 BPF_EXIT_INSN(),
2209 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002210 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07002211 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2212 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002213 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02002214 "direct packet access: test5 (pkt_end >= reg, good access)",
2215 .insns = {
2216 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2217 offsetof(struct __sk_buff, data)),
2218 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2219 offsetof(struct __sk_buff, data_end)),
2220 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2221 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2222 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2223 BPF_MOV64_IMM(BPF_REG_0, 1),
2224 BPF_EXIT_INSN(),
2225 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2226 BPF_MOV64_IMM(BPF_REG_0, 0),
2227 BPF_EXIT_INSN(),
2228 },
2229 .result = ACCEPT,
2230 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2231 },
2232 {
2233 "direct packet access: test6 (pkt_end >= reg, bad access)",
2234 .insns = {
2235 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2236 offsetof(struct __sk_buff, data)),
2237 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2238 offsetof(struct __sk_buff, data_end)),
2239 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2240 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2241 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2242 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2243 BPF_MOV64_IMM(BPF_REG_0, 1),
2244 BPF_EXIT_INSN(),
2245 BPF_MOV64_IMM(BPF_REG_0, 0),
2246 BPF_EXIT_INSN(),
2247 },
2248 .errstr = "invalid access to packet",
2249 .result = REJECT,
2250 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2251 },
2252 {
2253 "direct packet access: test7 (pkt_end >= reg, both accesses)",
2254 .insns = {
2255 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2256 offsetof(struct __sk_buff, data)),
2257 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2258 offsetof(struct __sk_buff, data_end)),
2259 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2261 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
2262 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2263 BPF_MOV64_IMM(BPF_REG_0, 1),
2264 BPF_EXIT_INSN(),
2265 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2266 BPF_MOV64_IMM(BPF_REG_0, 0),
2267 BPF_EXIT_INSN(),
2268 },
2269 .errstr = "invalid access to packet",
2270 .result = REJECT,
2271 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2272 },
2273 {
2274 "direct packet access: test8 (double test, variant 1)",
2275 .insns = {
2276 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2277 offsetof(struct __sk_buff, data)),
2278 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2279 offsetof(struct __sk_buff, data_end)),
2280 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2282 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
2283 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2284 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2285 BPF_MOV64_IMM(BPF_REG_0, 1),
2286 BPF_EXIT_INSN(),
2287 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2288 BPF_MOV64_IMM(BPF_REG_0, 0),
2289 BPF_EXIT_INSN(),
2290 },
2291 .result = ACCEPT,
2292 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2293 },
2294 {
2295 "direct packet access: test9 (double test, variant 2)",
2296 .insns = {
2297 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2298 offsetof(struct __sk_buff, data)),
2299 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2300 offsetof(struct __sk_buff, data_end)),
2301 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2303 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
2304 BPF_MOV64_IMM(BPF_REG_0, 1),
2305 BPF_EXIT_INSN(),
2306 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
2307 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2308 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
2309 BPF_MOV64_IMM(BPF_REG_0, 0),
2310 BPF_EXIT_INSN(),
2311 },
2312 .result = ACCEPT,
2313 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2314 },
2315 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002316 "direct packet access: test10 (write invalid)",
2317 .insns = {
2318 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2319 offsetof(struct __sk_buff, data)),
2320 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2321 offsetof(struct __sk_buff, data_end)),
2322 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2324 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2325 BPF_MOV64_IMM(BPF_REG_0, 0),
2326 BPF_EXIT_INSN(),
2327 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
2328 BPF_MOV64_IMM(BPF_REG_0, 0),
2329 BPF_EXIT_INSN(),
2330 },
2331 .errstr = "invalid access to packet",
2332 .result = REJECT,
2333 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2334 },
2335 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01002336 "direct packet access: test11 (shift, good access)",
2337 .insns = {
2338 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2339 offsetof(struct __sk_buff, data)),
2340 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2341 offsetof(struct __sk_buff, data_end)),
2342 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2344 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2345 BPF_MOV64_IMM(BPF_REG_3, 144),
2346 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2347 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2348 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2349 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2350 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2351 BPF_MOV64_IMM(BPF_REG_0, 1),
2352 BPF_EXIT_INSN(),
2353 BPF_MOV64_IMM(BPF_REG_0, 0),
2354 BPF_EXIT_INSN(),
2355 },
2356 .result = ACCEPT,
2357 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2358 },
2359 {
2360 "direct packet access: test12 (and, good access)",
2361 .insns = {
2362 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2363 offsetof(struct __sk_buff, data)),
2364 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2365 offsetof(struct __sk_buff, data_end)),
2366 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2368 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2369 BPF_MOV64_IMM(BPF_REG_3, 144),
2370 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2371 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2372 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2373 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2374 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2375 BPF_MOV64_IMM(BPF_REG_0, 1),
2376 BPF_EXIT_INSN(),
2377 BPF_MOV64_IMM(BPF_REG_0, 0),
2378 BPF_EXIT_INSN(),
2379 },
2380 .result = ACCEPT,
2381 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2382 },
2383 {
2384 "direct packet access: test13 (branches, good access)",
2385 .insns = {
2386 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2387 offsetof(struct __sk_buff, data)),
2388 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2389 offsetof(struct __sk_buff, data_end)),
2390 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2392 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2393 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2394 offsetof(struct __sk_buff, mark)),
2395 BPF_MOV64_IMM(BPF_REG_4, 1),
2396 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2397 BPF_MOV64_IMM(BPF_REG_3, 14),
2398 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2399 BPF_MOV64_IMM(BPF_REG_3, 24),
2400 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2401 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2402 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2403 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2404 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2405 BPF_MOV64_IMM(BPF_REG_0, 1),
2406 BPF_EXIT_INSN(),
2407 BPF_MOV64_IMM(BPF_REG_0, 0),
2408 BPF_EXIT_INSN(),
2409 },
2410 .result = ACCEPT,
2411 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2412 },
2413 {
William Tu63dfef72017-02-04 08:37:29 -08002414 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2415 .insns = {
2416 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2417 offsetof(struct __sk_buff, data)),
2418 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2419 offsetof(struct __sk_buff, data_end)),
2420 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2422 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2423 BPF_MOV64_IMM(BPF_REG_5, 12),
2424 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2425 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2426 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2427 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2428 BPF_MOV64_IMM(BPF_REG_0, 1),
2429 BPF_EXIT_INSN(),
2430 BPF_MOV64_IMM(BPF_REG_0, 0),
2431 BPF_EXIT_INSN(),
2432 },
2433 .result = ACCEPT,
2434 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2435 },
2436 {
Aaron Yue1633ac02016-08-11 18:17:17 -07002437 "helper access to packet: test1, valid packet_ptr range",
2438 .insns = {
2439 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2440 offsetof(struct xdp_md, data)),
2441 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2442 offsetof(struct xdp_md, data_end)),
2443 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2445 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2446 BPF_LD_MAP_FD(BPF_REG_1, 0),
2447 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2448 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002449 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2450 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002451 BPF_MOV64_IMM(BPF_REG_0, 0),
2452 BPF_EXIT_INSN(),
2453 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002454 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002455 .result_unpriv = ACCEPT,
2456 .result = ACCEPT,
2457 .prog_type = BPF_PROG_TYPE_XDP,
2458 },
2459 {
2460 "helper access to packet: test2, unchecked packet_ptr",
2461 .insns = {
2462 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2463 offsetof(struct xdp_md, data)),
2464 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002465 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2466 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002467 BPF_MOV64_IMM(BPF_REG_0, 0),
2468 BPF_EXIT_INSN(),
2469 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002470 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002471 .result = REJECT,
2472 .errstr = "invalid access to packet",
2473 .prog_type = BPF_PROG_TYPE_XDP,
2474 },
2475 {
2476 "helper access to packet: test3, variable add",
2477 .insns = {
2478 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2479 offsetof(struct xdp_md, data)),
2480 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2481 offsetof(struct xdp_md, data_end)),
2482 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2483 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2484 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2485 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2486 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2487 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2488 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2489 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2490 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2491 BPF_LD_MAP_FD(BPF_REG_1, 0),
2492 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002493 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2494 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002495 BPF_MOV64_IMM(BPF_REG_0, 0),
2496 BPF_EXIT_INSN(),
2497 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002498 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002499 .result = ACCEPT,
2500 .prog_type = BPF_PROG_TYPE_XDP,
2501 },
2502 {
2503 "helper access to packet: test4, packet_ptr with bad range",
2504 .insns = {
2505 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2506 offsetof(struct xdp_md, data)),
2507 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2508 offsetof(struct xdp_md, data_end)),
2509 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2511 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2512 BPF_MOV64_IMM(BPF_REG_0, 0),
2513 BPF_EXIT_INSN(),
2514 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002515 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2516 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002517 BPF_MOV64_IMM(BPF_REG_0, 0),
2518 BPF_EXIT_INSN(),
2519 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002520 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002521 .result = REJECT,
2522 .errstr = "invalid access to packet",
2523 .prog_type = BPF_PROG_TYPE_XDP,
2524 },
2525 {
2526 "helper access to packet: test5, packet_ptr with too short range",
2527 .insns = {
2528 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2529 offsetof(struct xdp_md, data)),
2530 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2531 offsetof(struct xdp_md, data_end)),
2532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2533 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2535 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2536 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002537 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2538 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07002539 BPF_MOV64_IMM(BPF_REG_0, 0),
2540 BPF_EXIT_INSN(),
2541 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002542 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07002543 .result = REJECT,
2544 .errstr = "invalid access to packet",
2545 .prog_type = BPF_PROG_TYPE_XDP,
2546 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002547 {
2548 "helper access to packet: test6, cls valid packet_ptr range",
2549 .insns = {
2550 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2551 offsetof(struct __sk_buff, data)),
2552 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2553 offsetof(struct __sk_buff, data_end)),
2554 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
2555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2556 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
2557 BPF_LD_MAP_FD(BPF_REG_1, 0),
2558 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2559 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002560 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2561 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002562 BPF_MOV64_IMM(BPF_REG_0, 0),
2563 BPF_EXIT_INSN(),
2564 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002565 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002566 .result = ACCEPT,
2567 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2568 },
2569 {
2570 "helper access to packet: test7, cls unchecked packet_ptr",
2571 .insns = {
2572 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2573 offsetof(struct __sk_buff, data)),
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),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002577 BPF_MOV64_IMM(BPF_REG_0, 0),
2578 BPF_EXIT_INSN(),
2579 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002580 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002581 .result = REJECT,
2582 .errstr = "invalid access to packet",
2583 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2584 },
2585 {
2586 "helper access to packet: test8, cls variable add",
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_4, BPF_REG_2),
2593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
2594 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
2595 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
2596 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2597 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
2598 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
2599 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
2600 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
2601 BPF_LD_MAP_FD(BPF_REG_1, 0),
2602 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002603 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2604 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002605 BPF_MOV64_IMM(BPF_REG_0, 0),
2606 BPF_EXIT_INSN(),
2607 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002608 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002609 .result = ACCEPT,
2610 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2611 },
2612 {
2613 "helper access to packet: test9, cls packet_ptr with bad range",
2614 .insns = {
2615 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2616 offsetof(struct __sk_buff, data)),
2617 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2618 offsetof(struct __sk_buff, data_end)),
2619 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2620 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
2621 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
2622 BPF_MOV64_IMM(BPF_REG_0, 0),
2623 BPF_EXIT_INSN(),
2624 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002625 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2626 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002627 BPF_MOV64_IMM(BPF_REG_0, 0),
2628 BPF_EXIT_INSN(),
2629 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002630 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002631 .result = REJECT,
2632 .errstr = "invalid access to packet",
2633 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2634 },
2635 {
2636 "helper access to packet: test10, cls packet_ptr with too short range",
2637 .insns = {
2638 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2639 offsetof(struct __sk_buff, data)),
2640 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2641 offsetof(struct __sk_buff, data_end)),
2642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
2643 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
2644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
2645 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
2646 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002647 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2648 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002649 BPF_MOV64_IMM(BPF_REG_0, 0),
2650 BPF_EXIT_INSN(),
2651 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002652 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002653 .result = REJECT,
2654 .errstr = "invalid access to packet",
2655 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2656 },
2657 {
2658 "helper access to packet: test11, cls unsuitable helper 1",
2659 .insns = {
2660 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2661 offsetof(struct __sk_buff, data)),
2662 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2663 offsetof(struct __sk_buff, data_end)),
2664 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2665 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2666 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
2667 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
2668 BPF_MOV64_IMM(BPF_REG_2, 0),
2669 BPF_MOV64_IMM(BPF_REG_4, 42),
2670 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002671 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2672 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002673 BPF_MOV64_IMM(BPF_REG_0, 0),
2674 BPF_EXIT_INSN(),
2675 },
2676 .result = REJECT,
2677 .errstr = "helper access to the packet",
2678 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2679 },
2680 {
2681 "helper access to packet: test12, cls unsuitable helper 2",
2682 .insns = {
2683 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2684 offsetof(struct __sk_buff, data)),
2685 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2686 offsetof(struct __sk_buff, data_end)),
2687 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2688 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
2689 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
2690 BPF_MOV64_IMM(BPF_REG_2, 0),
2691 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002692 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2693 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002694 BPF_MOV64_IMM(BPF_REG_0, 0),
2695 BPF_EXIT_INSN(),
2696 },
2697 .result = REJECT,
2698 .errstr = "helper access to the packet",
2699 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2700 },
2701 {
2702 "helper access to packet: test13, cls helper ok",
2703 .insns = {
2704 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2705 offsetof(struct __sk_buff, data)),
2706 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2707 offsetof(struct __sk_buff, data_end)),
2708 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2709 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2710 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2711 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2712 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2713 BPF_MOV64_IMM(BPF_REG_2, 4),
2714 BPF_MOV64_IMM(BPF_REG_3, 0),
2715 BPF_MOV64_IMM(BPF_REG_4, 0),
2716 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002717 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2718 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002719 BPF_MOV64_IMM(BPF_REG_0, 0),
2720 BPF_EXIT_INSN(),
2721 },
2722 .result = ACCEPT,
2723 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2724 },
2725 {
2726 "helper access to packet: test14, cls helper fail sub",
2727 .insns = {
2728 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2729 offsetof(struct __sk_buff, data)),
2730 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2731 offsetof(struct __sk_buff, data_end)),
2732 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2733 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2735 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2736 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
2737 BPF_MOV64_IMM(BPF_REG_2, 4),
2738 BPF_MOV64_IMM(BPF_REG_3, 0),
2739 BPF_MOV64_IMM(BPF_REG_4, 0),
2740 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002741 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2742 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002743 BPF_MOV64_IMM(BPF_REG_0, 0),
2744 BPF_EXIT_INSN(),
2745 },
2746 .result = REJECT,
2747 .errstr = "type=inv expected=fp",
2748 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2749 },
2750 {
2751 "helper access to packet: test15, cls helper fail range 1",
2752 .insns = {
2753 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2754 offsetof(struct __sk_buff, data)),
2755 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2756 offsetof(struct __sk_buff, data_end)),
2757 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2758 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2759 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2760 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2761 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2762 BPF_MOV64_IMM(BPF_REG_2, 8),
2763 BPF_MOV64_IMM(BPF_REG_3, 0),
2764 BPF_MOV64_IMM(BPF_REG_4, 0),
2765 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002766 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2767 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002768 BPF_MOV64_IMM(BPF_REG_0, 0),
2769 BPF_EXIT_INSN(),
2770 },
2771 .result = REJECT,
2772 .errstr = "invalid access to packet",
2773 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2774 },
2775 {
2776 "helper access to packet: test16, cls helper fail range 2",
2777 .insns = {
2778 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2779 offsetof(struct __sk_buff, data)),
2780 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2781 offsetof(struct __sk_buff, data_end)),
2782 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2783 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2784 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2785 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2786 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2787 BPF_MOV64_IMM(BPF_REG_2, -9),
2788 BPF_MOV64_IMM(BPF_REG_3, 0),
2789 BPF_MOV64_IMM(BPF_REG_4, 0),
2790 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002791 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2792 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002793 BPF_MOV64_IMM(BPF_REG_0, 0),
2794 BPF_EXIT_INSN(),
2795 },
2796 .result = REJECT,
2797 .errstr = "invalid access to packet",
2798 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2799 },
2800 {
2801 "helper access to packet: test17, cls helper fail range 3",
2802 .insns = {
2803 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2804 offsetof(struct __sk_buff, data)),
2805 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2806 offsetof(struct __sk_buff, data_end)),
2807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2808 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2809 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2810 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2811 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2812 BPF_MOV64_IMM(BPF_REG_2, ~0),
2813 BPF_MOV64_IMM(BPF_REG_3, 0),
2814 BPF_MOV64_IMM(BPF_REG_4, 0),
2815 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002816 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2817 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002818 BPF_MOV64_IMM(BPF_REG_0, 0),
2819 BPF_EXIT_INSN(),
2820 },
2821 .result = REJECT,
2822 .errstr = "invalid access to packet",
2823 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2824 },
2825 {
2826 "helper access to packet: test18, cls helper fail range zero",
2827 .insns = {
2828 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2829 offsetof(struct __sk_buff, data)),
2830 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2831 offsetof(struct __sk_buff, data_end)),
2832 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2833 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2834 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2835 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2836 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2837 BPF_MOV64_IMM(BPF_REG_2, 0),
2838 BPF_MOV64_IMM(BPF_REG_3, 0),
2839 BPF_MOV64_IMM(BPF_REG_4, 0),
2840 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002841 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2842 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002843 BPF_MOV64_IMM(BPF_REG_0, 0),
2844 BPF_EXIT_INSN(),
2845 },
2846 .result = REJECT,
2847 .errstr = "invalid access to packet",
2848 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2849 },
2850 {
2851 "helper access to packet: test19, pkt end as input",
2852 .insns = {
2853 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2854 offsetof(struct __sk_buff, data)),
2855 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2856 offsetof(struct __sk_buff, data_end)),
2857 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2858 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2860 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2861 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
2862 BPF_MOV64_IMM(BPF_REG_2, 4),
2863 BPF_MOV64_IMM(BPF_REG_3, 0),
2864 BPF_MOV64_IMM(BPF_REG_4, 0),
2865 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002866 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2867 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002868 BPF_MOV64_IMM(BPF_REG_0, 0),
2869 BPF_EXIT_INSN(),
2870 },
2871 .result = REJECT,
2872 .errstr = "R1 type=pkt_end expected=fp",
2873 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2874 },
2875 {
2876 "helper access to packet: test20, wrong reg",
2877 .insns = {
2878 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
2879 offsetof(struct __sk_buff, data)),
2880 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
2881 offsetof(struct __sk_buff, data_end)),
2882 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
2883 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
2885 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
2886 BPF_MOV64_IMM(BPF_REG_2, 4),
2887 BPF_MOV64_IMM(BPF_REG_3, 0),
2888 BPF_MOV64_IMM(BPF_REG_4, 0),
2889 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002890 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2891 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002892 BPF_MOV64_IMM(BPF_REG_0, 0),
2893 BPF_EXIT_INSN(),
2894 },
2895 .result = REJECT,
2896 .errstr = "invalid access to packet",
2897 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2898 },
Josef Bacik48461132016-09-28 10:54:32 -04002899 {
2900 "valid map access into an array with a constant",
2901 .insns = {
2902 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2903 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2904 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2905 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002906 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2907 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002908 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002909 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2910 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002911 BPF_EXIT_INSN(),
2912 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002913 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04002914 .errstr_unpriv = "R0 leaks addr",
2915 .result_unpriv = REJECT,
2916 .result = ACCEPT,
2917 },
2918 {
2919 "valid map access into an array with a register",
2920 .insns = {
2921 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2922 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2923 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2924 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002925 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2926 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002927 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
2928 BPF_MOV64_IMM(BPF_REG_1, 4),
2929 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2930 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002931 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2932 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002933 BPF_EXIT_INSN(),
2934 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002935 .fixup_map2 = { 3 },
2936 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04002937 .result_unpriv = REJECT,
2938 .result = ACCEPT,
2939 },
2940 {
2941 "valid map access into an array with a variable",
2942 .insns = {
2943 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2944 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2946 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002947 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2948 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002949 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
2950 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2951 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
2952 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
2953 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002954 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2955 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002956 BPF_EXIT_INSN(),
2957 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002958 .fixup_map2 = { 3 },
2959 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04002960 .result_unpriv = REJECT,
2961 .result = ACCEPT,
2962 },
2963 {
2964 "valid map access into an array with a signed variable",
2965 .insns = {
2966 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2967 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2969 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002970 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2971 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002972 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
2973 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
2974 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
2975 BPF_MOV32_IMM(BPF_REG_1, 0),
2976 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
2977 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
2978 BPF_MOV32_IMM(BPF_REG_1, 0),
2979 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
2980 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002981 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
2982 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04002983 BPF_EXIT_INSN(),
2984 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002985 .fixup_map2 = { 3 },
2986 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04002987 .result_unpriv = REJECT,
2988 .result = ACCEPT,
2989 },
2990 {
2991 "invalid map access into an array with a constant",
2992 .insns = {
2993 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2994 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2995 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2996 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002997 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2998 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04002999 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3000 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
3001 offsetof(struct test_val, foo)),
3002 BPF_EXIT_INSN(),
3003 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003004 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04003005 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
3006 .result = REJECT,
3007 },
3008 {
3009 "invalid map access into an array with a register",
3010 .insns = {
3011 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3012 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3014 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003015 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3016 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003017 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3018 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
3019 BPF_ALU64_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 .errstr = "R0 min value is outside of the array range",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003028 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003029 .result = REJECT,
3030 },
3031 {
3032 "invalid map access into an array with a variable",
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, 4),
3041 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3042 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3043 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003044 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3045 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003046 BPF_EXIT_INSN(),
3047 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003048 .fixup_map2 = { 3 },
3049 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003050 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003051 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003052 .result = REJECT,
3053 },
3054 {
3055 "invalid map access into an array with no floor check",
3056 .insns = {
3057 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3058 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3059 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3060 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003061 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3062 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003063 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3064 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3065 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
3066 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
3067 BPF_MOV32_IMM(BPF_REG_1, 0),
3068 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3069 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003070 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3071 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003072 BPF_EXIT_INSN(),
3073 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003074 .fixup_map2 = { 3 },
3075 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003076 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003077 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003078 .result = REJECT,
3079 },
3080 {
3081 "invalid map access into an array with a invalid max check",
3082 .insns = {
3083 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3084 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3085 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3086 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003087 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3088 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003089 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3090 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3091 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
3092 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3093 BPF_MOV32_IMM(BPF_REG_1, 0),
3094 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
3095 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003096 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
3097 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003098 BPF_EXIT_INSN(),
3099 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003100 .fixup_map2 = { 3 },
3101 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003102 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003103 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003104 .result = REJECT,
3105 },
3106 {
3107 "invalid map access into an array with a invalid max check",
3108 .insns = {
3109 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3110 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3112 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003113 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3114 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003115 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
3116 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
3117 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3118 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3120 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003121 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3122 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04003123 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
3124 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003125 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3126 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04003127 BPF_EXIT_INSN(),
3128 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003129 .fixup_map2 = { 3, 11 },
3130 .errstr_unpriv = "R0 pointer arithmetic prohibited",
Josef Bacik48461132016-09-28 10:54:32 -04003131 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003132 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04003133 .result = REJECT,
3134 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02003135 {
3136 "multiple registers share map_lookup_elem result",
3137 .insns = {
3138 BPF_MOV64_IMM(BPF_REG_1, 10),
3139 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3140 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3141 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3142 BPF_LD_MAP_FD(BPF_REG_1, 0),
3143 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3144 BPF_FUNC_map_lookup_elem),
3145 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3146 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3147 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3148 BPF_EXIT_INSN(),
3149 },
3150 .fixup_map1 = { 4 },
3151 .result = ACCEPT,
3152 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3153 },
3154 {
3155 "invalid memory access with multiple map_lookup_elem calls",
3156 .insns = {
3157 BPF_MOV64_IMM(BPF_REG_1, 10),
3158 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3159 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3161 BPF_LD_MAP_FD(BPF_REG_1, 0),
3162 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3163 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3164 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3165 BPF_FUNC_map_lookup_elem),
3166 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3167 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3168 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3169 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3170 BPF_FUNC_map_lookup_elem),
3171 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3172 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3173 BPF_EXIT_INSN(),
3174 },
3175 .fixup_map1 = { 4 },
3176 .result = REJECT,
3177 .errstr = "R4 !read_ok",
3178 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3179 },
3180 {
3181 "valid indirect map_lookup_elem access with 2nd lookup in branch",
3182 .insns = {
3183 BPF_MOV64_IMM(BPF_REG_1, 10),
3184 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3185 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3186 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3187 BPF_LD_MAP_FD(BPF_REG_1, 0),
3188 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
3189 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
3190 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3191 BPF_FUNC_map_lookup_elem),
3192 BPF_MOV64_IMM(BPF_REG_2, 10),
3193 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
3194 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
3195 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3197 BPF_FUNC_map_lookup_elem),
3198 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3199 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3200 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
3201 BPF_EXIT_INSN(),
3202 },
3203 .fixup_map1 = { 4 },
3204 .result = ACCEPT,
3205 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3206 },
Josef Bacike9548902016-11-29 12:35:19 -05003207 {
Daniel Borkmanna08dd0d2016-12-15 01:30:06 +01003208 "multiple registers share map_lookup_elem bad reg type",
3209 .insns = {
3210 BPF_MOV64_IMM(BPF_REG_1, 10),
3211 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
3212 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3213 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3214 BPF_LD_MAP_FD(BPF_REG_1, 0),
3215 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3216 BPF_FUNC_map_lookup_elem),
3217 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
3218 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
3219 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3220 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3221 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3222 BPF_MOV64_IMM(BPF_REG_1, 1),
3223 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
3224 BPF_MOV64_IMM(BPF_REG_1, 2),
3225 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1),
3226 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 0),
3227 BPF_MOV64_IMM(BPF_REG_1, 3),
3228 BPF_EXIT_INSN(),
3229 },
3230 .fixup_map1 = { 4 },
3231 .result = REJECT,
3232 .errstr = "R3 invalid mem access 'inv'",
3233 .prog_type = BPF_PROG_TYPE_SCHED_CLS
3234 },
3235 {
Josef Bacike9548902016-11-29 12:35:19 -05003236 "invalid map access from else condition",
3237 .insns = {
3238 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
3239 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3240 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3241 BPF_LD_MAP_FD(BPF_REG_1, 0),
3242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
3243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3244 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
3245 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
3246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
3247 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
3248 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3249 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
3250 BPF_EXIT_INSN(),
3251 },
3252 .fixup_map2 = { 3 },
3253 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
3254 .result = REJECT,
3255 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3256 .result_unpriv = REJECT,
3257 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08003258 {
3259 "constant register |= constant should keep constant type",
3260 .insns = {
3261 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3262 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3263 BPF_MOV64_IMM(BPF_REG_2, 34),
3264 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
3265 BPF_MOV64_IMM(BPF_REG_3, 0),
3266 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3267 BPF_EXIT_INSN(),
3268 },
3269 .result = ACCEPT,
3270 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3271 },
3272 {
3273 "constant register |= constant should not bypass stack boundary checks",
3274 .insns = {
3275 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3276 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3277 BPF_MOV64_IMM(BPF_REG_2, 34),
3278 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
3279 BPF_MOV64_IMM(BPF_REG_3, 0),
3280 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3281 BPF_EXIT_INSN(),
3282 },
3283 .errstr = "invalid stack type R1 off=-48 access_size=58",
3284 .result = REJECT,
3285 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3286 },
3287 {
3288 "constant register |= constant register should keep constant type",
3289 .insns = {
3290 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3291 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3292 BPF_MOV64_IMM(BPF_REG_2, 34),
3293 BPF_MOV64_IMM(BPF_REG_4, 13),
3294 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3295 BPF_MOV64_IMM(BPF_REG_3, 0),
3296 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3297 BPF_EXIT_INSN(),
3298 },
3299 .result = ACCEPT,
3300 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3301 },
3302 {
3303 "constant register |= constant register should not bypass stack boundary checks",
3304 .insns = {
3305 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
3307 BPF_MOV64_IMM(BPF_REG_2, 34),
3308 BPF_MOV64_IMM(BPF_REG_4, 24),
3309 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
3310 BPF_MOV64_IMM(BPF_REG_3, 0),
3311 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3312 BPF_EXIT_INSN(),
3313 },
3314 .errstr = "invalid stack type R1 off=-48 access_size=58",
3315 .result = REJECT,
3316 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3317 },
Thomas Graf3f731d82016-12-05 10:30:52 +01003318 {
3319 "invalid direct packet write for LWT_IN",
3320 .insns = {
3321 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3322 offsetof(struct __sk_buff, data)),
3323 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3324 offsetof(struct __sk_buff, data_end)),
3325 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3327 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3328 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3329 BPF_MOV64_IMM(BPF_REG_0, 0),
3330 BPF_EXIT_INSN(),
3331 },
3332 .errstr = "cannot write into packet",
3333 .result = REJECT,
3334 .prog_type = BPF_PROG_TYPE_LWT_IN,
3335 },
3336 {
3337 "invalid direct packet write for LWT_OUT",
3338 .insns = {
3339 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3340 offsetof(struct __sk_buff, data)),
3341 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3342 offsetof(struct __sk_buff, data_end)),
3343 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3344 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3345 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3346 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3347 BPF_MOV64_IMM(BPF_REG_0, 0),
3348 BPF_EXIT_INSN(),
3349 },
3350 .errstr = "cannot write into packet",
3351 .result = REJECT,
3352 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3353 },
3354 {
3355 "direct packet write for LWT_XMIT",
3356 .insns = {
3357 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3358 offsetof(struct __sk_buff, data)),
3359 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3360 offsetof(struct __sk_buff, data_end)),
3361 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3362 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3363 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3364 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3365 BPF_MOV64_IMM(BPF_REG_0, 0),
3366 BPF_EXIT_INSN(),
3367 },
3368 .result = ACCEPT,
3369 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3370 },
3371 {
3372 "direct packet read for LWT_IN",
3373 .insns = {
3374 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3375 offsetof(struct __sk_buff, data)),
3376 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3377 offsetof(struct __sk_buff, data_end)),
3378 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3379 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3380 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3381 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3382 BPF_MOV64_IMM(BPF_REG_0, 0),
3383 BPF_EXIT_INSN(),
3384 },
3385 .result = ACCEPT,
3386 .prog_type = BPF_PROG_TYPE_LWT_IN,
3387 },
3388 {
3389 "direct packet read for LWT_OUT",
3390 .insns = {
3391 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3392 offsetof(struct __sk_buff, data)),
3393 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3394 offsetof(struct __sk_buff, data_end)),
3395 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3396 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3397 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3398 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3399 BPF_MOV64_IMM(BPF_REG_0, 0),
3400 BPF_EXIT_INSN(),
3401 },
3402 .result = ACCEPT,
3403 .prog_type = BPF_PROG_TYPE_LWT_OUT,
3404 },
3405 {
3406 "direct packet read for LWT_XMIT",
3407 .insns = {
3408 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3409 offsetof(struct __sk_buff, data)),
3410 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3411 offsetof(struct __sk_buff, data_end)),
3412 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3413 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3414 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3415 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3416 BPF_MOV64_IMM(BPF_REG_0, 0),
3417 BPF_EXIT_INSN(),
3418 },
3419 .result = ACCEPT,
3420 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3421 },
3422 {
3423 "invalid access of tc_classid for LWT_IN",
3424 .insns = {
3425 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3426 offsetof(struct __sk_buff, tc_classid)),
3427 BPF_EXIT_INSN(),
3428 },
3429 .result = REJECT,
3430 .errstr = "invalid bpf_context access",
3431 },
3432 {
3433 "invalid access of tc_classid for LWT_OUT",
3434 .insns = {
3435 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3436 offsetof(struct __sk_buff, tc_classid)),
3437 BPF_EXIT_INSN(),
3438 },
3439 .result = REJECT,
3440 .errstr = "invalid bpf_context access",
3441 },
3442 {
3443 "invalid access of tc_classid for LWT_XMIT",
3444 .insns = {
3445 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
3446 offsetof(struct __sk_buff, tc_classid)),
3447 BPF_EXIT_INSN(),
3448 },
3449 .result = REJECT,
3450 .errstr = "invalid bpf_context access",
3451 },
Gianluca Borello57225692017-01-09 10:19:47 -08003452 {
3453 "helper access to map: full range",
3454 .insns = {
3455 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3457 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3458 BPF_LD_MAP_FD(BPF_REG_1, 0),
3459 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3460 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3461 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3462 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
3463 BPF_MOV64_IMM(BPF_REG_3, 0),
3464 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3465 BPF_EXIT_INSN(),
3466 },
3467 .fixup_map2 = { 3 },
3468 .result = ACCEPT,
3469 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3470 },
3471 {
3472 "helper access to map: partial range",
3473 .insns = {
3474 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3476 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3477 BPF_LD_MAP_FD(BPF_REG_1, 0),
3478 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3479 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3480 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3481 BPF_MOV64_IMM(BPF_REG_2, 8),
3482 BPF_MOV64_IMM(BPF_REG_3, 0),
3483 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3484 BPF_EXIT_INSN(),
3485 },
3486 .fixup_map2 = { 3 },
3487 .result = ACCEPT,
3488 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3489 },
3490 {
3491 "helper access to map: empty range",
3492 .insns = {
3493 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3495 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3496 BPF_LD_MAP_FD(BPF_REG_1, 0),
3497 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3498 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3499 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3500 BPF_MOV64_IMM(BPF_REG_2, 0),
3501 BPF_MOV64_IMM(BPF_REG_3, 0),
3502 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3503 BPF_EXIT_INSN(),
3504 },
3505 .fixup_map2 = { 3 },
3506 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
3507 .result = REJECT,
3508 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3509 },
3510 {
3511 "helper access to map: out-of-bound range",
3512 .insns = {
3513 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3514 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3515 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3516 BPF_LD_MAP_FD(BPF_REG_1, 0),
3517 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3518 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3519 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3520 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
3521 BPF_MOV64_IMM(BPF_REG_3, 0),
3522 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3523 BPF_EXIT_INSN(),
3524 },
3525 .fixup_map2 = { 3 },
3526 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
3527 .result = REJECT,
3528 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3529 },
3530 {
3531 "helper access to map: negative range",
3532 .insns = {
3533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3535 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3536 BPF_LD_MAP_FD(BPF_REG_1, 0),
3537 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3538 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3539 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3540 BPF_MOV64_IMM(BPF_REG_2, -8),
3541 BPF_MOV64_IMM(BPF_REG_3, 0),
3542 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3543 BPF_EXIT_INSN(),
3544 },
3545 .fixup_map2 = { 3 },
3546 .errstr = "invalid access to map value, value_size=48 off=0 size=-8",
3547 .result = REJECT,
3548 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3549 },
3550 {
3551 "helper access to adjusted map (via const imm): full range",
3552 .insns = {
3553 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3554 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3555 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3556 BPF_LD_MAP_FD(BPF_REG_1, 0),
3557 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3558 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3559 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3560 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3561 offsetof(struct test_val, foo)),
3562 BPF_MOV64_IMM(BPF_REG_2,
3563 sizeof(struct test_val) -
3564 offsetof(struct test_val, foo)),
3565 BPF_MOV64_IMM(BPF_REG_3, 0),
3566 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3567 BPF_EXIT_INSN(),
3568 },
3569 .fixup_map2 = { 3 },
3570 .result = ACCEPT,
3571 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3572 },
3573 {
3574 "helper access to adjusted map (via const imm): partial range",
3575 .insns = {
3576 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3577 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3578 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3579 BPF_LD_MAP_FD(BPF_REG_1, 0),
3580 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3581 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3582 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3583 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3584 offsetof(struct test_val, foo)),
3585 BPF_MOV64_IMM(BPF_REG_2, 8),
3586 BPF_MOV64_IMM(BPF_REG_3, 0),
3587 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3588 BPF_EXIT_INSN(),
3589 },
3590 .fixup_map2 = { 3 },
3591 .result = ACCEPT,
3592 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3593 },
3594 {
3595 "helper access to adjusted map (via const imm): empty range",
3596 .insns = {
3597 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3598 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3599 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3600 BPF_LD_MAP_FD(BPF_REG_1, 0),
3601 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3602 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3603 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3604 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3605 offsetof(struct test_val, foo)),
3606 BPF_MOV64_IMM(BPF_REG_2, 0),
3607 BPF_MOV64_IMM(BPF_REG_3, 0),
3608 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3609 BPF_EXIT_INSN(),
3610 },
3611 .fixup_map2 = { 3 },
3612 .errstr = "R1 min value is outside of the array range",
3613 .result = REJECT,
3614 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3615 },
3616 {
3617 "helper access to adjusted map (via const imm): out-of-bound range",
3618 .insns = {
3619 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3620 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3621 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3622 BPF_LD_MAP_FD(BPF_REG_1, 0),
3623 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3624 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3625 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3627 offsetof(struct test_val, foo)),
3628 BPF_MOV64_IMM(BPF_REG_2,
3629 sizeof(struct test_val) -
3630 offsetof(struct test_val, foo) + 8),
3631 BPF_MOV64_IMM(BPF_REG_3, 0),
3632 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3633 BPF_EXIT_INSN(),
3634 },
3635 .fixup_map2 = { 3 },
3636 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3637 .result = REJECT,
3638 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3639 },
3640 {
3641 "helper access to adjusted map (via const imm): negative range (> adjustment)",
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 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3659 .result = REJECT,
3660 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3661 },
3662 {
3663 "helper access to adjusted map (via const imm): negative range (< adjustment)",
3664 .insns = {
3665 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3666 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3667 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3668 BPF_LD_MAP_FD(BPF_REG_1, 0),
3669 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3670 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3671 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3672 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3673 offsetof(struct test_val, foo)),
3674 BPF_MOV64_IMM(BPF_REG_2, -1),
3675 BPF_MOV64_IMM(BPF_REG_3, 0),
3676 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3677 BPF_EXIT_INSN(),
3678 },
3679 .fixup_map2 = { 3 },
3680 .errstr = "R1 min value is outside of the array range",
3681 .result = REJECT,
3682 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3683 },
3684 {
3685 "helper access to adjusted map (via const reg): full range",
3686 .insns = {
3687 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3688 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3689 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3690 BPF_LD_MAP_FD(BPF_REG_1, 0),
3691 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3692 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3693 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3694 BPF_MOV64_IMM(BPF_REG_3,
3695 offsetof(struct test_val, foo)),
3696 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3697 BPF_MOV64_IMM(BPF_REG_2,
3698 sizeof(struct test_val) -
3699 offsetof(struct test_val, foo)),
3700 BPF_MOV64_IMM(BPF_REG_3, 0),
3701 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3702 BPF_EXIT_INSN(),
3703 },
3704 .fixup_map2 = { 3 },
3705 .result = ACCEPT,
3706 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3707 },
3708 {
3709 "helper access to adjusted map (via const reg): partial range",
3710 .insns = {
3711 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3712 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3713 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3714 BPF_LD_MAP_FD(BPF_REG_1, 0),
3715 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3716 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3717 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3718 BPF_MOV64_IMM(BPF_REG_3,
3719 offsetof(struct test_val, foo)),
3720 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3721 BPF_MOV64_IMM(BPF_REG_2, 8),
3722 BPF_MOV64_IMM(BPF_REG_3, 0),
3723 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3724 BPF_EXIT_INSN(),
3725 },
3726 .fixup_map2 = { 3 },
3727 .result = ACCEPT,
3728 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3729 },
3730 {
3731 "helper access to adjusted map (via const reg): empty range",
3732 .insns = {
3733 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3735 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3736 BPF_LD_MAP_FD(BPF_REG_1, 0),
3737 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3738 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3739 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3740 BPF_MOV64_IMM(BPF_REG_3, 0),
3741 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3742 BPF_MOV64_IMM(BPF_REG_2, 0),
3743 BPF_MOV64_IMM(BPF_REG_3, 0),
3744 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3745 BPF_EXIT_INSN(),
3746 },
3747 .fixup_map2 = { 3 },
3748 .errstr = "R1 min value is outside of the array range",
3749 .result = REJECT,
3750 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3751 },
3752 {
3753 "helper access to adjusted map (via const reg): out-of-bound range",
3754 .insns = {
3755 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3756 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3757 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3758 BPF_LD_MAP_FD(BPF_REG_1, 0),
3759 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3760 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3761 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3762 BPF_MOV64_IMM(BPF_REG_3,
3763 offsetof(struct test_val, foo)),
3764 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3765 BPF_MOV64_IMM(BPF_REG_2,
3766 sizeof(struct test_val) -
3767 offsetof(struct test_val, foo) + 8),
3768 BPF_MOV64_IMM(BPF_REG_3, 0),
3769 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3770 BPF_EXIT_INSN(),
3771 },
3772 .fixup_map2 = { 3 },
3773 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3774 .result = REJECT,
3775 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3776 },
3777 {
3778 "helper access to adjusted map (via const reg): negative range (> adjustment)",
3779 .insns = {
3780 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3781 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3782 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3783 BPF_LD_MAP_FD(BPF_REG_1, 0),
3784 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3785 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3786 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3787 BPF_MOV64_IMM(BPF_REG_3,
3788 offsetof(struct test_val, foo)),
3789 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3790 BPF_MOV64_IMM(BPF_REG_2, -8),
3791 BPF_MOV64_IMM(BPF_REG_3, 0),
3792 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3793 BPF_EXIT_INSN(),
3794 },
3795 .fixup_map2 = { 3 },
3796 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3797 .result = REJECT,
3798 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3799 },
3800 {
3801 "helper access to adjusted map (via const reg): negative range (< adjustment)",
3802 .insns = {
3803 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3804 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3805 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3806 BPF_LD_MAP_FD(BPF_REG_1, 0),
3807 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3808 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3809 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3810 BPF_MOV64_IMM(BPF_REG_3,
3811 offsetof(struct test_val, foo)),
3812 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3813 BPF_MOV64_IMM(BPF_REG_2, -1),
3814 BPF_MOV64_IMM(BPF_REG_3, 0),
3815 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3816 BPF_EXIT_INSN(),
3817 },
3818 .fixup_map2 = { 3 },
3819 .errstr = "R1 min value is outside of the array range",
3820 .result = REJECT,
3821 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3822 },
3823 {
3824 "helper access to adjusted map (via variable): full range",
3825 .insns = {
3826 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3827 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3828 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3829 BPF_LD_MAP_FD(BPF_REG_1, 0),
3830 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3831 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3832 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3833 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3834 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3835 offsetof(struct test_val, foo), 4),
3836 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3837 BPF_MOV64_IMM(BPF_REG_2,
3838 sizeof(struct test_val) -
3839 offsetof(struct test_val, foo)),
3840 BPF_MOV64_IMM(BPF_REG_3, 0),
3841 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3842 BPF_EXIT_INSN(),
3843 },
3844 .fixup_map2 = { 3 },
3845 .result = ACCEPT,
3846 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3847 },
3848 {
3849 "helper access to adjusted map (via variable): partial range",
3850 .insns = {
3851 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3853 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3854 BPF_LD_MAP_FD(BPF_REG_1, 0),
3855 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3856 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3857 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3858 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3859 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3860 offsetof(struct test_val, foo), 4),
3861 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3862 BPF_MOV64_IMM(BPF_REG_2, 8),
3863 BPF_MOV64_IMM(BPF_REG_3, 0),
3864 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3865 BPF_EXIT_INSN(),
3866 },
3867 .fixup_map2 = { 3 },
3868 .result = ACCEPT,
3869 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3870 },
3871 {
3872 "helper access to adjusted map (via variable): empty range",
3873 .insns = {
3874 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3875 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3876 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3877 BPF_LD_MAP_FD(BPF_REG_1, 0),
3878 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3879 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3880 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3881 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3882 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3883 offsetof(struct test_val, foo), 4),
3884 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3885 BPF_MOV64_IMM(BPF_REG_2, 0),
3886 BPF_MOV64_IMM(BPF_REG_3, 0),
3887 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3888 BPF_EXIT_INSN(),
3889 },
3890 .fixup_map2 = { 3 },
3891 .errstr = "R1 min value is outside of the array range",
3892 .result = REJECT,
3893 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3894 },
3895 {
3896 "helper access to adjusted map (via variable): no max check",
3897 .insns = {
3898 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3899 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3900 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3901 BPF_LD_MAP_FD(BPF_REG_1, 0),
3902 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3903 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3904 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3905 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3906 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3907 BPF_MOV64_IMM(BPF_REG_2, 0),
3908 BPF_MOV64_IMM(BPF_REG_3, 0),
3909 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3910 BPF_EXIT_INSN(),
3911 },
3912 .fixup_map2 = { 3 },
3913 .errstr = "R1 min value is negative, either use unsigned index or do a if (index >=0) check",
3914 .result = REJECT,
3915 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3916 },
3917 {
3918 "helper access to adjusted map (via variable): wrong max check",
3919 .insns = {
3920 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3921 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3922 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3923 BPF_LD_MAP_FD(BPF_REG_1, 0),
3924 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3925 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3926 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3927 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3928 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3929 offsetof(struct test_val, foo), 4),
3930 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3931 BPF_MOV64_IMM(BPF_REG_2,
3932 sizeof(struct test_val) -
3933 offsetof(struct test_val, foo) + 1),
3934 BPF_MOV64_IMM(BPF_REG_3, 0),
3935 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3936 BPF_EXIT_INSN(),
3937 },
3938 .fixup_map2 = { 3 },
3939 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
3940 .result = REJECT,
3941 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3942 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08003943 {
3944 "map element value is preserved across register spilling",
3945 .insns = {
3946 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3947 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3948 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3949 BPF_LD_MAP_FD(BPF_REG_1, 0),
3950 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3951 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3952 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3953 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3955 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3956 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3957 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3958 BPF_EXIT_INSN(),
3959 },
3960 .fixup_map2 = { 3 },
3961 .errstr_unpriv = "R0 leaks addr",
3962 .result = ACCEPT,
3963 .result_unpriv = REJECT,
3964 },
3965 {
3966 "map element value (adjusted) is preserved across register spilling",
3967 .insns = {
3968 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3970 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3971 BPF_LD_MAP_FD(BPF_REG_1, 0),
3972 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3973 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3974 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
3975 offsetof(struct test_val, foo)),
3976 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3977 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3978 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3979 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3980 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3981 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3982 BPF_EXIT_INSN(),
3983 },
3984 .fixup_map2 = { 3 },
3985 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3986 .result = ACCEPT,
3987 .result_unpriv = REJECT,
3988 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08003989 {
3990 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
3991 .insns = {
3992 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3993 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
3994 BPF_MOV64_IMM(BPF_REG_0, 0),
3995 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
3996 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
3997 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
3998 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
3999 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4000 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4001 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4002 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4003 BPF_MOV64_IMM(BPF_REG_2, 16),
4004 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4005 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4006 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4007 BPF_MOV64_IMM(BPF_REG_4, 0),
4008 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4009 BPF_MOV64_IMM(BPF_REG_3, 0),
4010 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4011 BPF_MOV64_IMM(BPF_REG_0, 0),
4012 BPF_EXIT_INSN(),
4013 },
4014 .result = ACCEPT,
4015 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4016 },
4017 {
4018 "helper access to variable memory: stack, bitwise AND, zero included",
4019 .insns = {
4020 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4021 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4022 BPF_MOV64_IMM(BPF_REG_2, 16),
4023 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4024 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4025 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4026 BPF_MOV64_IMM(BPF_REG_3, 0),
4027 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4028 BPF_EXIT_INSN(),
4029 },
4030 .errstr = "invalid stack type R1 off=-64 access_size=0",
4031 .result = REJECT,
4032 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4033 },
4034 {
4035 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
4036 .insns = {
4037 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4039 BPF_MOV64_IMM(BPF_REG_2, 16),
4040 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4041 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4042 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
4043 BPF_MOV64_IMM(BPF_REG_4, 0),
4044 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4045 BPF_MOV64_IMM(BPF_REG_3, 0),
4046 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4047 BPF_MOV64_IMM(BPF_REG_0, 0),
4048 BPF_EXIT_INSN(),
4049 },
4050 .errstr = "invalid stack type R1 off=-64 access_size=65",
4051 .result = REJECT,
4052 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4053 },
4054 {
4055 "helper access to variable memory: stack, JMP, correct bounds",
4056 .insns = {
4057 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4059 BPF_MOV64_IMM(BPF_REG_0, 0),
4060 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4061 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4062 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4063 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4064 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4065 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4066 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4067 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4068 BPF_MOV64_IMM(BPF_REG_2, 16),
4069 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4070 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4071 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
4072 BPF_MOV64_IMM(BPF_REG_4, 0),
4073 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4074 BPF_MOV64_IMM(BPF_REG_3, 0),
4075 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4076 BPF_MOV64_IMM(BPF_REG_0, 0),
4077 BPF_EXIT_INSN(),
4078 },
4079 .result = ACCEPT,
4080 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4081 },
4082 {
4083 "helper access to variable memory: stack, JMP (signed), correct bounds",
4084 .insns = {
4085 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4086 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4087 BPF_MOV64_IMM(BPF_REG_0, 0),
4088 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4089 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4090 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4091 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4092 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4093 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4094 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4095 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4096 BPF_MOV64_IMM(BPF_REG_2, 16),
4097 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4098 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4099 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
4100 BPF_MOV64_IMM(BPF_REG_4, 0),
4101 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
4102 BPF_MOV64_IMM(BPF_REG_3, 0),
4103 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4104 BPF_MOV64_IMM(BPF_REG_0, 0),
4105 BPF_EXIT_INSN(),
4106 },
4107 .result = ACCEPT,
4108 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4109 },
4110 {
4111 "helper access to variable memory: stack, JMP, bounds + offset",
4112 .insns = {
4113 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4115 BPF_MOV64_IMM(BPF_REG_2, 16),
4116 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4117 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4118 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
4119 BPF_MOV64_IMM(BPF_REG_4, 0),
4120 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
4121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4122 BPF_MOV64_IMM(BPF_REG_3, 0),
4123 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4124 BPF_MOV64_IMM(BPF_REG_0, 0),
4125 BPF_EXIT_INSN(),
4126 },
4127 .errstr = "invalid stack type R1 off=-64 access_size=65",
4128 .result = REJECT,
4129 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4130 },
4131 {
4132 "helper access to variable memory: stack, JMP, wrong max",
4133 .insns = {
4134 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4136 BPF_MOV64_IMM(BPF_REG_2, 16),
4137 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4138 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4139 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
4140 BPF_MOV64_IMM(BPF_REG_4, 0),
4141 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4142 BPF_MOV64_IMM(BPF_REG_3, 0),
4143 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4144 BPF_MOV64_IMM(BPF_REG_0, 0),
4145 BPF_EXIT_INSN(),
4146 },
4147 .errstr = "invalid stack type R1 off=-64 access_size=65",
4148 .result = REJECT,
4149 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4150 },
4151 {
4152 "helper access to variable memory: stack, JMP, no max check",
4153 .insns = {
4154 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4155 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4156 BPF_MOV64_IMM(BPF_REG_2, 16),
4157 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4158 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4159 BPF_MOV64_IMM(BPF_REG_4, 0),
4160 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4161 BPF_MOV64_IMM(BPF_REG_3, 0),
4162 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4163 BPF_MOV64_IMM(BPF_REG_0, 0),
4164 BPF_EXIT_INSN(),
4165 },
4166 .errstr = "R2 unbounded memory access",
4167 .result = REJECT,
4168 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4169 },
4170 {
4171 "helper access to variable memory: stack, JMP, no min check",
4172 .insns = {
4173 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4175 BPF_MOV64_IMM(BPF_REG_2, 16),
4176 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4177 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4178 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
4179 BPF_MOV64_IMM(BPF_REG_3, 0),
4180 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4181 BPF_MOV64_IMM(BPF_REG_0, 0),
4182 BPF_EXIT_INSN(),
4183 },
4184 .errstr = "invalid stack type R1 off=-64 access_size=0",
4185 .result = REJECT,
4186 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4187 },
4188 {
4189 "helper access to variable memory: stack, JMP (signed), no min check",
4190 .insns = {
4191 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4193 BPF_MOV64_IMM(BPF_REG_2, 16),
4194 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4195 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4196 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
4197 BPF_MOV64_IMM(BPF_REG_3, 0),
4198 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4199 BPF_MOV64_IMM(BPF_REG_0, 0),
4200 BPF_EXIT_INSN(),
4201 },
4202 .errstr = "R2 min value is negative",
4203 .result = REJECT,
4204 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4205 },
4206 {
4207 "helper access to variable memory: map, JMP, correct bounds",
4208 .insns = {
4209 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4211 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4212 BPF_LD_MAP_FD(BPF_REG_1, 0),
4213 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4214 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4215 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4216 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4217 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4218 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4219 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4220 sizeof(struct test_val), 4),
4221 BPF_MOV64_IMM(BPF_REG_4, 0),
4222 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4223 BPF_MOV64_IMM(BPF_REG_3, 0),
4224 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4225 BPF_MOV64_IMM(BPF_REG_0, 0),
4226 BPF_EXIT_INSN(),
4227 },
4228 .fixup_map2 = { 3 },
4229 .result = ACCEPT,
4230 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4231 },
4232 {
4233 "helper access to variable memory: map, JMP, wrong max",
4234 .insns = {
4235 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4236 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4237 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4238 BPF_LD_MAP_FD(BPF_REG_1, 0),
4239 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4240 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4241 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4242 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4243 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4244 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4245 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4246 sizeof(struct test_val) + 1, 4),
4247 BPF_MOV64_IMM(BPF_REG_4, 0),
4248 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4249 BPF_MOV64_IMM(BPF_REG_3, 0),
4250 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4251 BPF_MOV64_IMM(BPF_REG_0, 0),
4252 BPF_EXIT_INSN(),
4253 },
4254 .fixup_map2 = { 3 },
4255 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
4256 .result = REJECT,
4257 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4258 },
4259 {
4260 "helper access to variable memory: map adjusted, JMP, correct bounds",
4261 .insns = {
4262 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4264 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4265 BPF_LD_MAP_FD(BPF_REG_1, 0),
4266 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4268 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4269 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4270 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4271 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4272 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4273 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4274 sizeof(struct test_val) - 20, 4),
4275 BPF_MOV64_IMM(BPF_REG_4, 0),
4276 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4277 BPF_MOV64_IMM(BPF_REG_3, 0),
4278 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4279 BPF_MOV64_IMM(BPF_REG_0, 0),
4280 BPF_EXIT_INSN(),
4281 },
4282 .fixup_map2 = { 3 },
4283 .result = ACCEPT,
4284 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4285 },
4286 {
4287 "helper access to variable memory: map adjusted, JMP, wrong max",
4288 .insns = {
4289 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4290 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4291 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4292 BPF_LD_MAP_FD(BPF_REG_1, 0),
4293 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4294 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4295 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4296 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4297 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4298 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4299 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4300 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4301 sizeof(struct test_val) - 19, 4),
4302 BPF_MOV64_IMM(BPF_REG_4, 0),
4303 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4304 BPF_MOV64_IMM(BPF_REG_3, 0),
4305 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4306 BPF_MOV64_IMM(BPF_REG_0, 0),
4307 BPF_EXIT_INSN(),
4308 },
4309 .fixup_map2 = { 3 },
4310 .errstr = "R1 min value is outside of the array range",
4311 .result = REJECT,
4312 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4313 },
4314 {
4315 "helper access to variable memory: size > 0 not allowed on NULL",
4316 .insns = {
4317 BPF_MOV64_IMM(BPF_REG_1, 0),
4318 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01004319 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4320 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004321 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4322 BPF_MOV64_IMM(BPF_REG_3, 0),
4323 BPF_MOV64_IMM(BPF_REG_4, 0),
4324 BPF_MOV64_IMM(BPF_REG_5, 0),
4325 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4326 BPF_EXIT_INSN(),
4327 },
4328 .errstr = "R1 type=imm expected=fp",
4329 .result = REJECT,
4330 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4331 },
4332 {
4333 "helper access to variable memory: size = 0 not allowed on != NULL",
4334 .insns = {
4335 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4336 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
4337 BPF_MOV64_IMM(BPF_REG_2, 0),
4338 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
4339 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
4340 BPF_MOV64_IMM(BPF_REG_3, 0),
4341 BPF_MOV64_IMM(BPF_REG_4, 0),
4342 BPF_MOV64_IMM(BPF_REG_5, 0),
4343 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4344 BPF_EXIT_INSN(),
4345 },
4346 .errstr = "invalid stack type R1 off=-8 access_size=0",
4347 .result = REJECT,
4348 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4349 },
4350 {
4351 "helper access to variable memory: 8 bytes leak",
4352 .insns = {
4353 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4354 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4355 BPF_MOV64_IMM(BPF_REG_0, 0),
4356 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4357 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4358 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4359 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4360 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4361 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4362 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4363 BPF_MOV64_IMM(BPF_REG_2, 0),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01004364 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4365 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08004366 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
4367 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4368 BPF_MOV64_IMM(BPF_REG_3, 0),
4369 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4370 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4371 BPF_EXIT_INSN(),
4372 },
4373 .errstr = "invalid indirect read from stack off -64+32 size 64",
4374 .result = REJECT,
4375 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4376 },
4377 {
4378 "helper access to variable memory: 8 bytes no leak (init memory)",
4379 .insns = {
4380 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4381 BPF_MOV64_IMM(BPF_REG_0, 0),
4382 BPF_MOV64_IMM(BPF_REG_0, 0),
4383 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4384 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4385 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4386 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4387 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4388 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4389 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4390 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4391 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4392 BPF_MOV64_IMM(BPF_REG_2, 0),
4393 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
4394 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
4395 BPF_MOV64_IMM(BPF_REG_3, 0),
4396 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4397 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4398 BPF_EXIT_INSN(),
4399 },
4400 .result = ACCEPT,
4401 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4402 },
Josef Bacik29200c12017-02-03 16:25:23 -05004403 {
4404 "invalid and of negative number",
4405 .insns = {
4406 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4407 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4408 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4409 BPF_LD_MAP_FD(BPF_REG_1, 0),
4410 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4411 BPF_FUNC_map_lookup_elem),
4412 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4413 BPF_MOV64_IMM(BPF_REG_1, 6),
4414 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
4415 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4416 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4417 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4418 offsetof(struct test_val, foo)),
4419 BPF_EXIT_INSN(),
4420 },
4421 .fixup_map2 = { 3 },
4422 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4423 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4424 .result = REJECT,
4425 .result_unpriv = REJECT,
4426 },
4427 {
4428 "invalid range check",
4429 .insns = {
4430 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4431 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4433 BPF_LD_MAP_FD(BPF_REG_1, 0),
4434 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4435 BPF_FUNC_map_lookup_elem),
4436 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
4437 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4438 BPF_MOV64_IMM(BPF_REG_9, 1),
4439 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
4440 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
4441 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
4442 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
4443 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
4444 BPF_MOV32_IMM(BPF_REG_3, 1),
4445 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
4446 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
4447 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
4448 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
4449 BPF_MOV64_REG(BPF_REG_0, 0),
4450 BPF_EXIT_INSN(),
4451 },
4452 .fixup_map2 = { 3 },
4453 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4454 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4455 .result = REJECT,
4456 .result_unpriv = REJECT,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004457 },
4458 {
4459 "map in map access",
4460 .insns = {
4461 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4462 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4463 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4464 BPF_LD_MAP_FD(BPF_REG_1, 0),
4465 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4466 BPF_FUNC_map_lookup_elem),
4467 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4468 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4469 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4471 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4472 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4473 BPF_FUNC_map_lookup_elem),
4474 BPF_MOV64_REG(BPF_REG_0, 0),
4475 BPF_EXIT_INSN(),
4476 },
4477 .fixup_map_in_map = { 3 },
4478 .result = ACCEPT,
4479 },
4480 {
4481 "invalid inner map pointer",
4482 .insns = {
4483 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4484 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4485 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4486 BPF_LD_MAP_FD(BPF_REG_1, 0),
4487 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4488 BPF_FUNC_map_lookup_elem),
4489 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4490 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4491 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4493 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4495 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4496 BPF_FUNC_map_lookup_elem),
4497 BPF_MOV64_REG(BPF_REG_0, 0),
4498 BPF_EXIT_INSN(),
4499 },
4500 .fixup_map_in_map = { 3 },
4501 .errstr = "R1 type=inv expected=map_ptr",
4502 .errstr_unpriv = "R1 pointer arithmetic prohibited",
4503 .result = REJECT,
4504 },
4505 {
4506 "forgot null checking on the inner map pointer",
4507 .insns = {
4508 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4509 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4511 BPF_LD_MAP_FD(BPF_REG_1, 0),
4512 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4513 BPF_FUNC_map_lookup_elem),
4514 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
4515 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4516 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
4517 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4518 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4519 BPF_FUNC_map_lookup_elem),
4520 BPF_MOV64_REG(BPF_REG_0, 0),
4521 BPF_EXIT_INSN(),
4522 },
4523 .fixup_map_in_map = { 3 },
4524 .errstr = "R1 type=map_value_or_null expected=map_ptr",
4525 .result = REJECT,
4526 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004527};
4528
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004529static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004530{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004531 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004532
4533 for (len = MAX_INSNS - 1; len > 0; --len)
4534 if (fp[len].code != 0 || fp[len].imm != 0)
4535 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004536 return len + 1;
4537}
4538
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004539static int create_map(uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004540{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004541 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004542
Mickaël Salaünf4874d02017-02-10 00:21:43 +01004543 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004544 size_value, max_elem, BPF_F_NO_PREALLOC);
4545 if (fd < 0)
4546 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004547
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004548 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004549}
4550
4551static int create_prog_array(void)
4552{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004553 int fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004554
Mickaël Salaünf4874d02017-02-10 00:21:43 +01004555 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004556 sizeof(int), 4, 0);
4557 if (fd < 0)
4558 printf("Failed to create prog array '%s'!\n", strerror(errno));
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004559
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004560 return fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004561}
4562
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004563static int create_map_in_map(void)
4564{
4565 int inner_map_fd, outer_map_fd;
4566
4567 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
4568 sizeof(int), 1, 0);
4569 if (inner_map_fd < 0) {
4570 printf("Failed to create array '%s'!\n", strerror(errno));
4571 return inner_map_fd;
4572 }
4573
4574 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS,
4575 sizeof(int), inner_map_fd, 1, 0);
4576 if (outer_map_fd < 0)
4577 printf("Failed to create array of maps '%s'!\n",
4578 strerror(errno));
4579
4580 close(inner_map_fd);
4581
4582 return outer_map_fd;
4583}
4584
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004585static char bpf_vlog[32768];
4586
4587static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004588 int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004589{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004590 int *fixup_map1 = test->fixup_map1;
4591 int *fixup_map2 = test->fixup_map2;
4592 int *fixup_prog = test->fixup_prog;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004593 int *fixup_map_in_map = test->fixup_map_in_map;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004594
4595 /* Allocating HTs with 1 elem is fine here, since we only test
4596 * for verifier and not do a runtime lookup, so the only thing
4597 * that really matters is value size in this case.
4598 */
4599 if (*fixup_map1) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004600 map_fds[0] = create_map(sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004601 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004602 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004603 fixup_map1++;
4604 } while (*fixup_map1);
4605 }
4606
4607 if (*fixup_map2) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004608 map_fds[1] = create_map(sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004609 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004610 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004611 fixup_map2++;
4612 } while (*fixup_map2);
4613 }
4614
4615 if (*fixup_prog) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004616 map_fds[2] = create_prog_array();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004617 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004618 prog[*fixup_prog].imm = map_fds[2];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004619 fixup_prog++;
4620 } while (*fixup_prog);
4621 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004622
4623 if (*fixup_map_in_map) {
4624 map_fds[3] = create_map_in_map();
4625 do {
4626 prog[*fixup_map_in_map].imm = map_fds[3];
4627 fixup_map_in_map++;
4628 } while (*fixup_map_in_map);
4629 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004630}
4631
4632static void do_test_single(struct bpf_test *test, bool unpriv,
4633 int *passes, int *errors)
4634{
4635 struct bpf_insn *prog = test->insns;
4636 int prog_len = probe_filter_length(prog);
4637 int prog_type = test->prog_type;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004638 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004639 int fd_prog, expected_ret;
4640 const char *expected_err;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004641 int i;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004642
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004643 for (i = 0; i < MAX_NR_MAPS; i++)
4644 map_fds[i] = -1;
4645
4646 do_test_fixup(test, prog, map_fds);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004647
Mickaël Salaün2ee89fb2017-02-10 00:21:38 +01004648 fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
4649 prog, prog_len, "GPL", 0, bpf_vlog,
4650 sizeof(bpf_vlog));
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004651
4652 expected_ret = unpriv && test->result_unpriv != UNDEF ?
4653 test->result_unpriv : test->result;
4654 expected_err = unpriv && test->errstr_unpriv ?
4655 test->errstr_unpriv : test->errstr;
4656 if (expected_ret == ACCEPT) {
4657 if (fd_prog < 0) {
4658 printf("FAIL\nFailed to load prog '%s'!\n",
4659 strerror(errno));
4660 goto fail_log;
4661 }
4662 } else {
4663 if (fd_prog >= 0) {
4664 printf("FAIL\nUnexpected success to load!\n");
4665 goto fail_log;
4666 }
4667 if (!strstr(bpf_vlog, expected_err)) {
4668 printf("FAIL\nUnexpected error message!\n");
4669 goto fail_log;
4670 }
4671 }
4672
4673 (*passes)++;
4674 printf("OK\n");
4675close_fds:
4676 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07004677 for (i = 0; i < MAX_NR_MAPS; i++)
4678 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004679 sched_yield();
4680 return;
4681fail_log:
4682 (*errors)++;
4683 printf("%s", bpf_vlog);
4684 goto close_fds;
4685}
4686
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004687static bool is_admin(void)
4688{
4689 cap_t caps;
4690 cap_flag_value_t sysadmin = CAP_CLEAR;
4691 const cap_value_t cap_val = CAP_SYS_ADMIN;
4692
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08004693#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004694 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
4695 perror("cap_get_flag");
4696 return false;
4697 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -08004698#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004699 caps = cap_get_proc();
4700 if (!caps) {
4701 perror("cap_get_proc");
4702 return false;
4703 }
4704 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
4705 perror("cap_get_flag");
4706 if (cap_free(caps))
4707 perror("cap_free");
4708 return (sysadmin == CAP_SET);
4709}
4710
4711static int set_admin(bool admin)
4712{
4713 cap_t caps;
4714 const cap_value_t cap_val = CAP_SYS_ADMIN;
4715 int ret = -1;
4716
4717 caps = cap_get_proc();
4718 if (!caps) {
4719 perror("cap_get_proc");
4720 return -1;
4721 }
4722 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
4723 admin ? CAP_SET : CAP_CLEAR)) {
4724 perror("cap_set_flag");
4725 goto out;
4726 }
4727 if (cap_set_proc(caps)) {
4728 perror("cap_set_proc");
4729 goto out;
4730 }
4731 ret = 0;
4732out:
4733 if (cap_free(caps))
4734 perror("cap_free");
4735 return ret;
4736}
4737
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004738static int do_test(bool unpriv, unsigned int from, unsigned int to)
4739{
4740 int i, passes = 0, errors = 0;
4741
4742 for (i = from; i < to; i++) {
4743 struct bpf_test *test = &tests[i];
4744
4745 /* Program types that are not supported by non-root we
4746 * skip right away.
4747 */
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004748 if (!test->prog_type) {
4749 if (!unpriv)
4750 set_admin(false);
4751 printf("#%d/u %s ", i, test->descr);
4752 do_test_single(test, true, &passes, &errors);
4753 if (!unpriv)
4754 set_admin(true);
4755 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004756
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004757 if (!unpriv) {
4758 printf("#%d/p %s ", i, test->descr);
4759 do_test_single(test, false, &passes, &errors);
4760 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004761 }
4762
4763 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
4764 return errors ? -errors : 0;
4765}
4766
4767int main(int argc, char **argv)
4768{
4769 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
4770 struct rlimit rlim = { 1 << 20, 1 << 20 };
4771 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +01004772 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004773
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004774 if (argc == 3) {
4775 unsigned int l = atoi(argv[argc - 2]);
4776 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004777
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004778 if (l < to && u < to) {
4779 from = l;
4780 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004781 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004782 } else if (argc == 2) {
4783 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004784
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004785 if (t < to) {
4786 from = t;
4787 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -07004788 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004789 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004790
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004791 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf);
4792 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07004793}