blob: 6ec4d9def877f684b10adba037bc68f5db1642f8 [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
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -08005 * Copyright (c) 2017 Facebook
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07006 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General Public
9 * License as published by the Free Software Foundation.
10 */
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020011
Daniel Borkmann2c460622017-08-04 22:24:41 +020012#include <endian.h>
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080013#include <asm/types.h>
14#include <linux/types.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010015#include <stdint.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070016#include <stdio.h>
Mickaël Salaün702498a2017-02-10 00:21:44 +010017#include <stdlib.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070018#include <unistd.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070019#include <errno.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070020#include <string.h>
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -070021#include <stddef.h>
Alexei Starovoitovbf508872015-10-07 22:23:23 -070022#include <stdbool.h>
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020023#include <sched.h>
Daniel Borkmann21ccaf22018-01-26 23:33:48 +010024#include <limits.h>
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020025
Mickaël Salaünd02d8982017-02-10 00:21:37 +010026#include <sys/capability.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070027
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020028#include <linux/unistd.h>
29#include <linux/filter.h>
30#include <linux/bpf_perf_event.h>
31#include <linux/bpf.h>
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080032#include <linux/if_ether.h>
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070033
Mickaël Salaün2ee89fb2017-02-10 00:21:38 +010034#include <bpf/bpf.h>
35
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020036#ifdef HAVE_GENHDR
37# include "autoconf.h"
38#else
39# if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
40# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
41# endif
42#endif
Daniel Borkmannfe8d6622018-02-26 22:34:32 +010043#include "bpf_rlimit.h"
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +020044#include "bpf_rand.h"
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020045#include "../../../include/linux/filter.h"
46
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020047#ifndef ARRAY_SIZE
48# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
49#endif
50
Daniel Borkmann93731ef2018-05-04 01:08:13 +020051#define MAX_INSNS BPF_MAXINSNS
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020052#define MAX_FIXUPS 8
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070053#define MAX_NR_MAPS 4
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080054#define POINTER_VALUE 0xcafe4all
55#define TEST_DATA_LEN 64
Alexei Starovoitovbf508872015-10-07 22:23:23 -070056
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020057#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
Daniel Borkmann614d0d72017-05-25 01:05:09 +020058#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020059
Joe Stringer0a6748742018-02-14 13:50:36 -080060#define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
61static bool unpriv_disabled = false;
62
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070063struct bpf_test {
64 const char *descr;
65 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020066 int fixup_map1[MAX_FIXUPS];
67 int fixup_map2[MAX_FIXUPS];
Paul Chaignon5f90dd62018-04-24 15:08:19 +020068 int fixup_map3[MAX_FIXUPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020069 int fixup_prog[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070070 int fixup_map_in_map[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070071 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070072 const char *errstr_unpriv;
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080073 uint32_t retval;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070074 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070075 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070076 ACCEPT,
77 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070078 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070079 enum bpf_prog_type prog_type;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020080 uint8_t flags;
Daniel Borkmann93731ef2018-05-04 01:08:13 +020081 __u8 data[TEST_DATA_LEN];
82 void (*fill_helper)(struct bpf_test *self);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070083};
84
Josef Bacik48461132016-09-28 10:54:32 -040085/* Note we want this to be 64 bit aligned so that the end of our array is
86 * actually the end of the structure.
87 */
88#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040089
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020090struct test_val {
91 unsigned int index;
92 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040093};
94
Paul Chaignon5f90dd62018-04-24 15:08:19 +020095struct other_val {
96 long long foo;
97 long long bar;
98};
99
Daniel Borkmann93731ef2018-05-04 01:08:13 +0200100static void bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
101{
102 /* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
103#define PUSH_CNT 51
104 unsigned int len = BPF_MAXINSNS;
105 struct bpf_insn *insn = self->insns;
106 int i = 0, j, k = 0;
107
108 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
109loop:
110 for (j = 0; j < PUSH_CNT; j++) {
111 insn[i++] = BPF_LD_ABS(BPF_B, 0);
112 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
113 i++;
114 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
115 insn[i++] = BPF_MOV64_IMM(BPF_REG_2, 1);
116 insn[i++] = BPF_MOV64_IMM(BPF_REG_3, 2);
117 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
118 BPF_FUNC_skb_vlan_push),
119 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
120 i++;
121 }
122
123 for (j = 0; j < PUSH_CNT; j++) {
124 insn[i++] = BPF_LD_ABS(BPF_B, 0);
125 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
126 i++;
127 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
128 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
129 BPF_FUNC_skb_vlan_pop),
130 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
131 i++;
132 }
133 if (++k < 5)
134 goto loop;
135
136 for (; i < len - 1; i++)
137 insn[i] = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, 0xbef);
138 insn[len - 1] = BPF_EXIT_INSN();
139}
140
141static void bpf_fill_jump_around_ld_abs(struct bpf_test *self)
142{
143 struct bpf_insn *insn = self->insns;
144 unsigned int len = BPF_MAXINSNS;
145 int i = 0;
146
147 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
148 insn[i++] = BPF_LD_ABS(BPF_B, 0);
149 insn[i] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 10, len - i - 2);
150 i++;
151 while (i < len - 1)
152 insn[i++] = BPF_LD_ABS(BPF_B, 1);
153 insn[i] = BPF_EXIT_INSN();
154}
155
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +0200156static void bpf_fill_rand_ld_dw(struct bpf_test *self)
157{
158 struct bpf_insn *insn = self->insns;
159 uint64_t res = 0;
160 int i = 0;
161
162 insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0);
163 while (i < self->retval) {
164 uint64_t val = bpf_semi_rand_get();
165 struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) };
166
167 res ^= val;
168 insn[i++] = tmp[0];
169 insn[i++] = tmp[1];
170 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
171 }
172 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
173 insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32);
174 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
175 insn[i] = BPF_EXIT_INSN();
176 res ^= (res >> 32);
177 self->retval = (uint32_t)res;
178}
179
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700180static struct bpf_test tests[] = {
181 {
182 "add+sub+mul",
183 .insns = {
184 BPF_MOV64_IMM(BPF_REG_1, 1),
185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
186 BPF_MOV64_IMM(BPF_REG_2, 3),
187 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
189 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
190 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
191 BPF_EXIT_INSN(),
192 },
193 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800194 .retval = -3,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700195 },
196 {
Daniel Borkmann87c17932018-01-20 01:24:32 +0100197 "DIV32 by 0, zero check 1",
198 .insns = {
199 BPF_MOV32_IMM(BPF_REG_0, 42),
200 BPF_MOV32_IMM(BPF_REG_1, 0),
201 BPF_MOV32_IMM(BPF_REG_2, 1),
202 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
203 BPF_EXIT_INSN(),
204 },
205 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100206 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100207 },
208 {
209 "DIV32 by 0, zero check 2",
210 .insns = {
211 BPF_MOV32_IMM(BPF_REG_0, 42),
212 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
213 BPF_MOV32_IMM(BPF_REG_2, 1),
214 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
215 BPF_EXIT_INSN(),
216 },
217 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100218 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100219 },
220 {
221 "DIV64 by 0, zero check",
222 .insns = {
223 BPF_MOV32_IMM(BPF_REG_0, 42),
224 BPF_MOV32_IMM(BPF_REG_1, 0),
225 BPF_MOV32_IMM(BPF_REG_2, 1),
226 BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
227 BPF_EXIT_INSN(),
228 },
229 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100230 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100231 },
232 {
233 "MOD32 by 0, zero check 1",
234 .insns = {
235 BPF_MOV32_IMM(BPF_REG_0, 42),
236 BPF_MOV32_IMM(BPF_REG_1, 0),
237 BPF_MOV32_IMM(BPF_REG_2, 1),
238 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
239 BPF_EXIT_INSN(),
240 },
241 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100242 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100243 },
244 {
245 "MOD32 by 0, zero check 2",
246 .insns = {
247 BPF_MOV32_IMM(BPF_REG_0, 42),
248 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
249 BPF_MOV32_IMM(BPF_REG_2, 1),
250 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
251 BPF_EXIT_INSN(),
252 },
253 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100254 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100255 },
256 {
257 "MOD64 by 0, zero check",
258 .insns = {
259 BPF_MOV32_IMM(BPF_REG_0, 42),
260 BPF_MOV32_IMM(BPF_REG_1, 0),
261 BPF_MOV32_IMM(BPF_REG_2, 1),
262 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
263 BPF_EXIT_INSN(),
264 },
265 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100266 .retval = 42,
267 },
268 {
269 "DIV32 by 0, zero check ok, cls",
270 .insns = {
271 BPF_MOV32_IMM(BPF_REG_0, 42),
272 BPF_MOV32_IMM(BPF_REG_1, 2),
273 BPF_MOV32_IMM(BPF_REG_2, 16),
274 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
275 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
276 BPF_EXIT_INSN(),
277 },
278 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
279 .result = ACCEPT,
280 .retval = 8,
281 },
282 {
283 "DIV32 by 0, zero check 1, cls",
284 .insns = {
285 BPF_MOV32_IMM(BPF_REG_1, 0),
286 BPF_MOV32_IMM(BPF_REG_0, 1),
287 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
288 BPF_EXIT_INSN(),
289 },
290 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
291 .result = ACCEPT,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100292 .retval = 0,
293 },
294 {
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100295 "DIV32 by 0, zero check 2, cls",
296 .insns = {
297 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
298 BPF_MOV32_IMM(BPF_REG_0, 1),
299 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
300 BPF_EXIT_INSN(),
301 },
302 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
303 .result = ACCEPT,
304 .retval = 0,
305 },
306 {
307 "DIV64 by 0, zero check, cls",
308 .insns = {
309 BPF_MOV32_IMM(BPF_REG_1, 0),
310 BPF_MOV32_IMM(BPF_REG_0, 1),
311 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
312 BPF_EXIT_INSN(),
313 },
314 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
315 .result = ACCEPT,
316 .retval = 0,
317 },
318 {
319 "MOD32 by 0, zero check ok, cls",
320 .insns = {
321 BPF_MOV32_IMM(BPF_REG_0, 42),
322 BPF_MOV32_IMM(BPF_REG_1, 3),
323 BPF_MOV32_IMM(BPF_REG_2, 5),
324 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
325 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
326 BPF_EXIT_INSN(),
327 },
328 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
329 .result = ACCEPT,
330 .retval = 2,
331 },
332 {
333 "MOD32 by 0, zero check 1, cls",
334 .insns = {
335 BPF_MOV32_IMM(BPF_REG_1, 0),
336 BPF_MOV32_IMM(BPF_REG_0, 1),
337 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
338 BPF_EXIT_INSN(),
339 },
340 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
341 .result = ACCEPT,
342 .retval = 1,
343 },
344 {
345 "MOD32 by 0, zero check 2, cls",
346 .insns = {
347 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
348 BPF_MOV32_IMM(BPF_REG_0, 1),
349 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
350 BPF_EXIT_INSN(),
351 },
352 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
353 .result = ACCEPT,
354 .retval = 1,
355 },
356 {
357 "MOD64 by 0, zero check 1, cls",
358 .insns = {
359 BPF_MOV32_IMM(BPF_REG_1, 0),
360 BPF_MOV32_IMM(BPF_REG_0, 2),
361 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
362 BPF_EXIT_INSN(),
363 },
364 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
365 .result = ACCEPT,
366 .retval = 2,
367 },
368 {
369 "MOD64 by 0, zero check 2, cls",
370 .insns = {
371 BPF_MOV32_IMM(BPF_REG_1, 0),
372 BPF_MOV32_IMM(BPF_REG_0, -1),
373 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
374 BPF_EXIT_INSN(),
375 },
376 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
377 .result = ACCEPT,
378 .retval = -1,
379 },
380 /* Just make sure that JITs used udiv/umod as otherwise we get
381 * an exception from INT_MIN/-1 overflow similarly as with div
382 * by zero.
383 */
384 {
385 "DIV32 overflow, check 1",
386 .insns = {
387 BPF_MOV32_IMM(BPF_REG_1, -1),
388 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
389 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
390 BPF_EXIT_INSN(),
391 },
392 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
393 .result = ACCEPT,
394 .retval = 0,
395 },
396 {
397 "DIV32 overflow, check 2",
398 .insns = {
399 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
400 BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
401 BPF_EXIT_INSN(),
402 },
403 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
404 .result = ACCEPT,
405 .retval = 0,
406 },
407 {
408 "DIV64 overflow, check 1",
409 .insns = {
410 BPF_MOV64_IMM(BPF_REG_1, -1),
411 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
412 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
413 BPF_EXIT_INSN(),
414 },
415 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
416 .result = ACCEPT,
417 .retval = 0,
418 },
419 {
420 "DIV64 overflow, check 2",
421 .insns = {
422 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
423 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
424 BPF_EXIT_INSN(),
425 },
426 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
427 .result = ACCEPT,
428 .retval = 0,
429 },
430 {
431 "MOD32 overflow, check 1",
432 .insns = {
433 BPF_MOV32_IMM(BPF_REG_1, -1),
434 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
435 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
436 BPF_EXIT_INSN(),
437 },
438 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
439 .result = ACCEPT,
440 .retval = INT_MIN,
441 },
442 {
443 "MOD32 overflow, check 2",
444 .insns = {
445 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
446 BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
447 BPF_EXIT_INSN(),
448 },
449 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
450 .result = ACCEPT,
451 .retval = INT_MIN,
452 },
453 {
454 "MOD64 overflow, check 1",
455 .insns = {
456 BPF_MOV64_IMM(BPF_REG_1, -1),
457 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
458 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
459 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
460 BPF_MOV32_IMM(BPF_REG_0, 0),
461 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
462 BPF_MOV32_IMM(BPF_REG_0, 1),
463 BPF_EXIT_INSN(),
464 },
465 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
466 .result = ACCEPT,
467 .retval = 1,
468 },
469 {
470 "MOD64 overflow, check 2",
471 .insns = {
472 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
473 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
474 BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
475 BPF_MOV32_IMM(BPF_REG_0, 0),
476 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
477 BPF_MOV32_IMM(BPF_REG_0, 1),
478 BPF_EXIT_INSN(),
479 },
480 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
481 .result = ACCEPT,
482 .retval = 1,
483 },
484 {
485 "xor32 zero extend check",
486 .insns = {
487 BPF_MOV32_IMM(BPF_REG_2, -1),
488 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
489 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
490 BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
491 BPF_MOV32_IMM(BPF_REG_0, 2),
492 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
493 BPF_MOV32_IMM(BPF_REG_0, 1),
494 BPF_EXIT_INSN(),
495 },
496 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
497 .result = ACCEPT,
498 .retval = 1,
499 },
500 {
Daniel Borkmann87c17932018-01-20 01:24:32 +0100501 "empty prog",
502 .insns = {
503 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100504 .errstr = "unknown opcode 00",
Daniel Borkmann87c17932018-01-20 01:24:32 +0100505 .result = REJECT,
506 },
507 {
508 "only exit insn",
509 .insns = {
510 BPF_EXIT_INSN(),
511 },
512 .errstr = "R0 !read_ok",
513 .result = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700514 },
515 {
516 "unreachable",
517 .insns = {
518 BPF_EXIT_INSN(),
519 BPF_EXIT_INSN(),
520 },
521 .errstr = "unreachable",
522 .result = REJECT,
523 },
524 {
525 "unreachable2",
526 .insns = {
527 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
528 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
529 BPF_EXIT_INSN(),
530 },
531 .errstr = "unreachable",
532 .result = REJECT,
533 },
534 {
535 "out of range jump",
536 .insns = {
537 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
538 BPF_EXIT_INSN(),
539 },
540 .errstr = "jump out of range",
541 .result = REJECT,
542 },
543 {
544 "out of range jump2",
545 .insns = {
546 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
547 BPF_EXIT_INSN(),
548 },
549 .errstr = "jump out of range",
550 .result = REJECT,
551 },
552 {
553 "test1 ld_imm64",
554 .insns = {
555 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
556 BPF_LD_IMM64(BPF_REG_0, 0),
557 BPF_LD_IMM64(BPF_REG_0, 0),
558 BPF_LD_IMM64(BPF_REG_0, 1),
559 BPF_LD_IMM64(BPF_REG_0, 1),
560 BPF_MOV64_IMM(BPF_REG_0, 2),
561 BPF_EXIT_INSN(),
562 },
563 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700564 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700565 .result = REJECT,
566 },
567 {
568 "test2 ld_imm64",
569 .insns = {
570 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
571 BPF_LD_IMM64(BPF_REG_0, 0),
572 BPF_LD_IMM64(BPF_REG_0, 0),
573 BPF_LD_IMM64(BPF_REG_0, 1),
574 BPF_LD_IMM64(BPF_REG_0, 1),
575 BPF_EXIT_INSN(),
576 },
577 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700578 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700579 .result = REJECT,
580 },
581 {
582 "test3 ld_imm64",
583 .insns = {
584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
585 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
586 BPF_LD_IMM64(BPF_REG_0, 0),
587 BPF_LD_IMM64(BPF_REG_0, 0),
588 BPF_LD_IMM64(BPF_REG_0, 1),
589 BPF_LD_IMM64(BPF_REG_0, 1),
590 BPF_EXIT_INSN(),
591 },
592 .errstr = "invalid bpf_ld_imm64 insn",
593 .result = REJECT,
594 },
595 {
596 "test4 ld_imm64",
597 .insns = {
598 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
599 BPF_EXIT_INSN(),
600 },
601 .errstr = "invalid bpf_ld_imm64 insn",
602 .result = REJECT,
603 },
604 {
605 "test5 ld_imm64",
606 .insns = {
607 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
608 },
609 .errstr = "invalid bpf_ld_imm64 insn",
610 .result = REJECT,
611 },
612 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200613 "test6 ld_imm64",
614 .insns = {
615 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
616 BPF_RAW_INSN(0, 0, 0, 0, 0),
617 BPF_EXIT_INSN(),
618 },
619 .result = ACCEPT,
620 },
621 {
622 "test7 ld_imm64",
623 .insns = {
624 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
625 BPF_RAW_INSN(0, 0, 0, 0, 1),
626 BPF_EXIT_INSN(),
627 },
628 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800629 .retval = 1,
Daniel Borkmann728a8532017-04-27 01:39:32 +0200630 },
631 {
632 "test8 ld_imm64",
633 .insns = {
634 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
635 BPF_RAW_INSN(0, 0, 0, 0, 1),
636 BPF_EXIT_INSN(),
637 },
638 .errstr = "uses reserved fields",
639 .result = REJECT,
640 },
641 {
642 "test9 ld_imm64",
643 .insns = {
644 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
645 BPF_RAW_INSN(0, 0, 0, 1, 1),
646 BPF_EXIT_INSN(),
647 },
648 .errstr = "invalid bpf_ld_imm64 insn",
649 .result = REJECT,
650 },
651 {
652 "test10 ld_imm64",
653 .insns = {
654 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
655 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
656 BPF_EXIT_INSN(),
657 },
658 .errstr = "invalid bpf_ld_imm64 insn",
659 .result = REJECT,
660 },
661 {
662 "test11 ld_imm64",
663 .insns = {
664 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
665 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
666 BPF_EXIT_INSN(),
667 },
668 .errstr = "invalid bpf_ld_imm64 insn",
669 .result = REJECT,
670 },
671 {
672 "test12 ld_imm64",
673 .insns = {
674 BPF_MOV64_IMM(BPF_REG_1, 0),
675 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
676 BPF_RAW_INSN(0, 0, 0, 0, 1),
677 BPF_EXIT_INSN(),
678 },
679 .errstr = "not pointing to valid bpf_map",
680 .result = REJECT,
681 },
682 {
683 "test13 ld_imm64",
684 .insns = {
685 BPF_MOV64_IMM(BPF_REG_1, 0),
686 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
687 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
688 BPF_EXIT_INSN(),
689 },
690 .errstr = "invalid bpf_ld_imm64 insn",
691 .result = REJECT,
692 },
693 {
Daniel Borkmann7891a872018-01-10 20:04:37 +0100694 "arsh32 on imm",
695 .insns = {
696 BPF_MOV64_IMM(BPF_REG_0, 1),
697 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
698 BPF_EXIT_INSN(),
699 },
700 .result = REJECT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100701 .errstr = "unknown opcode c4",
Daniel Borkmann7891a872018-01-10 20:04:37 +0100702 },
703 {
704 "arsh32 on reg",
705 .insns = {
706 BPF_MOV64_IMM(BPF_REG_0, 1),
707 BPF_MOV64_IMM(BPF_REG_1, 5),
708 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
709 BPF_EXIT_INSN(),
710 },
711 .result = REJECT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100712 .errstr = "unknown opcode cc",
Daniel Borkmann7891a872018-01-10 20:04:37 +0100713 },
714 {
715 "arsh64 on imm",
716 .insns = {
717 BPF_MOV64_IMM(BPF_REG_0, 1),
718 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
719 BPF_EXIT_INSN(),
720 },
721 .result = ACCEPT,
722 },
723 {
724 "arsh64 on reg",
725 .insns = {
726 BPF_MOV64_IMM(BPF_REG_0, 1),
727 BPF_MOV64_IMM(BPF_REG_1, 5),
728 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
729 BPF_EXIT_INSN(),
730 },
731 .result = ACCEPT,
732 },
733 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700734 "no bpf_exit",
735 .insns = {
736 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
737 },
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -0800738 .errstr = "not an exit",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700739 .result = REJECT,
740 },
741 {
742 "loop (back-edge)",
743 .insns = {
744 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
745 BPF_EXIT_INSN(),
746 },
747 .errstr = "back-edge",
748 .result = REJECT,
749 },
750 {
751 "loop2 (back-edge)",
752 .insns = {
753 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
754 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
755 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
756 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
757 BPF_EXIT_INSN(),
758 },
759 .errstr = "back-edge",
760 .result = REJECT,
761 },
762 {
763 "conditional loop",
764 .insns = {
765 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
766 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
767 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
768 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
769 BPF_EXIT_INSN(),
770 },
771 .errstr = "back-edge",
772 .result = REJECT,
773 },
774 {
775 "read uninitialized register",
776 .insns = {
777 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
778 BPF_EXIT_INSN(),
779 },
780 .errstr = "R2 !read_ok",
781 .result = REJECT,
782 },
783 {
784 "read invalid register",
785 .insns = {
786 BPF_MOV64_REG(BPF_REG_0, -1),
787 BPF_EXIT_INSN(),
788 },
789 .errstr = "R15 is invalid",
790 .result = REJECT,
791 },
792 {
793 "program doesn't init R0 before exit",
794 .insns = {
795 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
796 BPF_EXIT_INSN(),
797 },
798 .errstr = "R0 !read_ok",
799 .result = REJECT,
800 },
801 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700802 "program doesn't init R0 before exit in all branches",
803 .insns = {
804 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
805 BPF_MOV64_IMM(BPF_REG_0, 1),
806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
807 BPF_EXIT_INSN(),
808 },
809 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700810 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700811 .result = REJECT,
812 },
813 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700814 "stack out of bounds",
815 .insns = {
816 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
817 BPF_EXIT_INSN(),
818 },
819 .errstr = "invalid stack",
820 .result = REJECT,
821 },
822 {
823 "invalid call insn1",
824 .insns = {
825 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
826 BPF_EXIT_INSN(),
827 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100828 .errstr = "unknown opcode 8d",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700829 .result = REJECT,
830 },
831 {
832 "invalid call insn2",
833 .insns = {
834 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
835 BPF_EXIT_INSN(),
836 },
837 .errstr = "BPF_CALL uses reserved",
838 .result = REJECT,
839 },
840 {
841 "invalid function call",
842 .insns = {
843 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
844 BPF_EXIT_INSN(),
845 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100846 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700847 .result = REJECT,
848 },
849 {
850 "uninitialized stack1",
851 .insns = {
852 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
853 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
854 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200855 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
856 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700857 BPF_EXIT_INSN(),
858 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200859 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700860 .errstr = "invalid indirect read from stack",
861 .result = REJECT,
862 },
863 {
864 "uninitialized stack2",
865 .insns = {
866 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
867 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
868 BPF_EXIT_INSN(),
869 },
870 .errstr = "invalid read from stack",
871 .result = REJECT,
872 },
873 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200874 "invalid fp arithmetic",
875 /* If this gets ever changed, make sure JITs can deal with it. */
876 .insns = {
877 BPF_MOV64_IMM(BPF_REG_0, 0),
878 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
879 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
880 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
881 BPF_EXIT_INSN(),
882 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -0800883 .errstr = "R1 subtraction from stack pointer",
Daniel Borkmann728a8532017-04-27 01:39:32 +0200884 .result = REJECT,
885 },
886 {
887 "non-invalid fp arithmetic",
888 .insns = {
889 BPF_MOV64_IMM(BPF_REG_0, 0),
890 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
891 BPF_EXIT_INSN(),
892 },
893 .result = ACCEPT,
894 },
895 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200896 "invalid argument register",
897 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200898 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
899 BPF_FUNC_get_cgroup_classid),
900 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
901 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200902 BPF_EXIT_INSN(),
903 },
904 .errstr = "R1 !read_ok",
905 .result = REJECT,
906 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
907 },
908 {
909 "non-invalid argument register",
910 .insns = {
911 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200912 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
913 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200914 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200915 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
916 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200917 BPF_EXIT_INSN(),
918 },
919 .result = ACCEPT,
920 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
921 },
922 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700923 "check valid spill/fill",
924 .insns = {
925 /* spill R1(ctx) into stack */
926 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700927 /* fill it back into R2 */
928 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700929 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100930 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
931 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700932 BPF_EXIT_INSN(),
933 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700934 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700935 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700936 .result_unpriv = REJECT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800937 .retval = POINTER_VALUE,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700938 },
939 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200940 "check valid spill/fill, skb mark",
941 .insns = {
942 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
943 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
944 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
945 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
946 offsetof(struct __sk_buff, mark)),
947 BPF_EXIT_INSN(),
948 },
949 .result = ACCEPT,
950 .result_unpriv = ACCEPT,
951 },
952 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700953 "check corrupted spill/fill",
954 .insns = {
955 /* spill R1(ctx) into stack */
956 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700957 /* mess up with R1 pointer on stack */
958 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700959 /* fill back into R0 should fail */
960 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700961 BPF_EXIT_INSN(),
962 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700963 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700964 .errstr = "corrupted spill",
965 .result = REJECT,
966 },
967 {
968 "invalid src register in STX",
969 .insns = {
970 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
971 BPF_EXIT_INSN(),
972 },
973 .errstr = "R15 is invalid",
974 .result = REJECT,
975 },
976 {
977 "invalid dst register in STX",
978 .insns = {
979 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
980 BPF_EXIT_INSN(),
981 },
982 .errstr = "R14 is invalid",
983 .result = REJECT,
984 },
985 {
986 "invalid dst register in ST",
987 .insns = {
988 BPF_ST_MEM(BPF_B, 14, -1, -1),
989 BPF_EXIT_INSN(),
990 },
991 .errstr = "R14 is invalid",
992 .result = REJECT,
993 },
994 {
995 "invalid src register in LDX",
996 .insns = {
997 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
998 BPF_EXIT_INSN(),
999 },
1000 .errstr = "R12 is invalid",
1001 .result = REJECT,
1002 },
1003 {
1004 "invalid dst register in LDX",
1005 .insns = {
1006 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
1007 BPF_EXIT_INSN(),
1008 },
1009 .errstr = "R11 is invalid",
1010 .result = REJECT,
1011 },
1012 {
1013 "junk insn",
1014 .insns = {
1015 BPF_RAW_INSN(0, 0, 0, 0, 0),
1016 BPF_EXIT_INSN(),
1017 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001018 .errstr = "unknown opcode 00",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001019 .result = REJECT,
1020 },
1021 {
1022 "junk insn2",
1023 .insns = {
1024 BPF_RAW_INSN(1, 0, 0, 0, 0),
1025 BPF_EXIT_INSN(),
1026 },
1027 .errstr = "BPF_LDX uses reserved fields",
1028 .result = REJECT,
1029 },
1030 {
1031 "junk insn3",
1032 .insns = {
1033 BPF_RAW_INSN(-1, 0, 0, 0, 0),
1034 BPF_EXIT_INSN(),
1035 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001036 .errstr = "unknown opcode ff",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001037 .result = REJECT,
1038 },
1039 {
1040 "junk insn4",
1041 .insns = {
1042 BPF_RAW_INSN(-1, -1, -1, -1, -1),
1043 BPF_EXIT_INSN(),
1044 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001045 .errstr = "unknown opcode ff",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001046 .result = REJECT,
1047 },
1048 {
1049 "junk insn5",
1050 .insns = {
1051 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
1052 BPF_EXIT_INSN(),
1053 },
1054 .errstr = "BPF_ALU uses reserved fields",
1055 .result = REJECT,
1056 },
1057 {
1058 "misaligned read from stack",
1059 .insns = {
1060 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1061 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
1062 BPF_EXIT_INSN(),
1063 },
Edward Creef65b1842017-08-07 15:27:12 +01001064 .errstr = "misaligned stack access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001065 .result = REJECT,
1066 },
1067 {
1068 "invalid map_fd for function call",
1069 .insns = {
1070 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1071 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
1072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1073 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001074 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1075 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001076 BPF_EXIT_INSN(),
1077 },
1078 .errstr = "fd 0 is not pointing to valid bpf_map",
1079 .result = REJECT,
1080 },
1081 {
1082 "don't check return value before access",
1083 .insns = {
1084 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1085 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1086 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1087 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001088 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1089 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001090 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1091 BPF_EXIT_INSN(),
1092 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001093 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001094 .errstr = "R0 invalid mem access 'map_value_or_null'",
1095 .result = REJECT,
1096 },
1097 {
1098 "access memory with incorrect alignment",
1099 .insns = {
1100 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1101 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1103 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001104 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1105 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001106 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1107 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
1108 BPF_EXIT_INSN(),
1109 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001110 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01001111 .errstr = "misaligned value access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001112 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001113 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001114 },
1115 {
1116 "sometimes access memory with incorrect alignment",
1117 .insns = {
1118 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1119 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1120 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1121 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001122 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1123 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001124 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1125 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1126 BPF_EXIT_INSN(),
1127 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
1128 BPF_EXIT_INSN(),
1129 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001130 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001131 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001132 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001133 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001134 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001135 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001136 {
1137 "jump test 1",
1138 .insns = {
1139 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1140 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
1141 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1142 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1143 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
1144 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
1145 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
1146 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
1147 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
1148 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
1149 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
1150 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
1151 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1152 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
1153 BPF_MOV64_IMM(BPF_REG_0, 0),
1154 BPF_EXIT_INSN(),
1155 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001156 .errstr_unpriv = "R1 pointer comparison",
1157 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001158 .result = ACCEPT,
1159 },
1160 {
1161 "jump test 2",
1162 .insns = {
1163 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1164 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
1165 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1166 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
1167 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
1168 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1169 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1170 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
1171 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1172 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
1173 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
1174 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1175 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
1176 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
1177 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1178 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1179 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1180 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1181 BPF_MOV64_IMM(BPF_REG_0, 0),
1182 BPF_EXIT_INSN(),
1183 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001184 .errstr_unpriv = "R1 pointer comparison",
1185 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001186 .result = ACCEPT,
1187 },
1188 {
1189 "jump test 3",
1190 .insns = {
1191 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1192 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1193 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1195 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
1196 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
1197 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1198 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1199 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
1200 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
1201 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
1203 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1204 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
1205 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
1207 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
1208 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
1209 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
1211 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
1213 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1214 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
1215 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001216 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1217 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001218 BPF_EXIT_INSN(),
1219 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001220 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001221 .errstr_unpriv = "R1 pointer comparison",
1222 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001223 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08001224 .retval = -ENOENT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001225 },
1226 {
1227 "jump test 4",
1228 .insns = {
1229 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1230 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1231 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1232 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1233 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1234 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1235 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1236 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1237 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1238 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1239 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1240 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1244 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1245 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1246 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1247 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1248 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1251 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1252 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1253 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1254 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1255 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1257 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1260 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1261 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1262 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1264 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1265 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1266 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1268 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1269 BPF_MOV64_IMM(BPF_REG_0, 0),
1270 BPF_EXIT_INSN(),
1271 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001272 .errstr_unpriv = "R1 pointer comparison",
1273 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001274 .result = ACCEPT,
1275 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -07001276 {
1277 "jump test 5",
1278 .insns = {
1279 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1280 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1281 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1282 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1283 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1284 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1285 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1286 BPF_MOV64_IMM(BPF_REG_0, 0),
1287 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1288 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1289 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1290 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1291 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1292 BPF_MOV64_IMM(BPF_REG_0, 0),
1293 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1294 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1295 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1296 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1297 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1298 BPF_MOV64_IMM(BPF_REG_0, 0),
1299 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1300 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1301 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1302 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1303 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1304 BPF_MOV64_IMM(BPF_REG_0, 0),
1305 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1306 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1307 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1308 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1309 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1310 BPF_MOV64_IMM(BPF_REG_0, 0),
1311 BPF_EXIT_INSN(),
1312 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001313 .errstr_unpriv = "R1 pointer comparison",
1314 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -07001315 .result = ACCEPT,
1316 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001317 {
1318 "access skb fields ok",
1319 .insns = {
1320 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1321 offsetof(struct __sk_buff, len)),
1322 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1323 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1324 offsetof(struct __sk_buff, mark)),
1325 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1326 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1327 offsetof(struct __sk_buff, pkt_type)),
1328 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1329 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1330 offsetof(struct __sk_buff, queue_mapping)),
1331 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -07001332 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1333 offsetof(struct __sk_buff, protocol)),
1334 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1335 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1336 offsetof(struct __sk_buff, vlan_present)),
1337 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1338 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1339 offsetof(struct __sk_buff, vlan_tci)),
1340 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Daniel Borkmannb1d9fc42017-04-19 23:01:17 +02001341 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1342 offsetof(struct __sk_buff, napi_id)),
1343 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001344 BPF_EXIT_INSN(),
1345 },
1346 .result = ACCEPT,
1347 },
1348 {
1349 "access skb fields bad1",
1350 .insns = {
1351 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
1352 BPF_EXIT_INSN(),
1353 },
1354 .errstr = "invalid bpf_context access",
1355 .result = REJECT,
1356 },
1357 {
1358 "access skb fields bad2",
1359 .insns = {
1360 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
1361 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1362 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1364 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001365 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1366 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001367 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1368 BPF_EXIT_INSN(),
1369 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1370 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1371 offsetof(struct __sk_buff, pkt_type)),
1372 BPF_EXIT_INSN(),
1373 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001374 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001375 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001376 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001377 .result = REJECT,
1378 },
1379 {
1380 "access skb fields bad3",
1381 .insns = {
1382 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1383 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1384 offsetof(struct __sk_buff, pkt_type)),
1385 BPF_EXIT_INSN(),
1386 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1387 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1388 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1389 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001390 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1391 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001392 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1393 BPF_EXIT_INSN(),
1394 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1395 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
1396 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001397 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001398 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001399 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001400 .result = REJECT,
1401 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001402 {
1403 "access skb fields bad4",
1404 .insns = {
1405 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
1406 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1407 offsetof(struct __sk_buff, len)),
1408 BPF_MOV64_IMM(BPF_REG_0, 0),
1409 BPF_EXIT_INSN(),
1410 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1411 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1413 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001414 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1415 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001416 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1417 BPF_EXIT_INSN(),
1418 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1419 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1420 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001421 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001422 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001423 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001424 .result = REJECT,
1425 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001426 {
John Fastabend41bc94f2017-08-15 22:33:56 -07001427 "invalid access __sk_buff family",
1428 .insns = {
1429 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1430 offsetof(struct __sk_buff, family)),
1431 BPF_EXIT_INSN(),
1432 },
1433 .errstr = "invalid bpf_context access",
1434 .result = REJECT,
1435 },
1436 {
1437 "invalid access __sk_buff remote_ip4",
1438 .insns = {
1439 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1440 offsetof(struct __sk_buff, remote_ip4)),
1441 BPF_EXIT_INSN(),
1442 },
1443 .errstr = "invalid bpf_context access",
1444 .result = REJECT,
1445 },
1446 {
1447 "invalid access __sk_buff local_ip4",
1448 .insns = {
1449 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1450 offsetof(struct __sk_buff, local_ip4)),
1451 BPF_EXIT_INSN(),
1452 },
1453 .errstr = "invalid bpf_context access",
1454 .result = REJECT,
1455 },
1456 {
1457 "invalid access __sk_buff remote_ip6",
1458 .insns = {
1459 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1460 offsetof(struct __sk_buff, remote_ip6)),
1461 BPF_EXIT_INSN(),
1462 },
1463 .errstr = "invalid bpf_context access",
1464 .result = REJECT,
1465 },
1466 {
1467 "invalid access __sk_buff local_ip6",
1468 .insns = {
1469 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1470 offsetof(struct __sk_buff, local_ip6)),
1471 BPF_EXIT_INSN(),
1472 },
1473 .errstr = "invalid bpf_context access",
1474 .result = REJECT,
1475 },
1476 {
1477 "invalid access __sk_buff remote_port",
1478 .insns = {
1479 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1480 offsetof(struct __sk_buff, remote_port)),
1481 BPF_EXIT_INSN(),
1482 },
1483 .errstr = "invalid bpf_context access",
1484 .result = REJECT,
1485 },
1486 {
1487 "invalid access __sk_buff remote_port",
1488 .insns = {
1489 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1490 offsetof(struct __sk_buff, local_port)),
1491 BPF_EXIT_INSN(),
1492 },
1493 .errstr = "invalid bpf_context access",
1494 .result = REJECT,
1495 },
1496 {
1497 "valid access __sk_buff family",
1498 .insns = {
1499 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1500 offsetof(struct __sk_buff, family)),
1501 BPF_EXIT_INSN(),
1502 },
1503 .result = ACCEPT,
1504 .prog_type = BPF_PROG_TYPE_SK_SKB,
1505 },
1506 {
1507 "valid access __sk_buff remote_ip4",
1508 .insns = {
1509 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1510 offsetof(struct __sk_buff, remote_ip4)),
1511 BPF_EXIT_INSN(),
1512 },
1513 .result = ACCEPT,
1514 .prog_type = BPF_PROG_TYPE_SK_SKB,
1515 },
1516 {
1517 "valid access __sk_buff local_ip4",
1518 .insns = {
1519 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1520 offsetof(struct __sk_buff, local_ip4)),
1521 BPF_EXIT_INSN(),
1522 },
1523 .result = ACCEPT,
1524 .prog_type = BPF_PROG_TYPE_SK_SKB,
1525 },
1526 {
1527 "valid access __sk_buff remote_ip6",
1528 .insns = {
1529 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1530 offsetof(struct __sk_buff, remote_ip6[0])),
1531 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1532 offsetof(struct __sk_buff, remote_ip6[1])),
1533 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1534 offsetof(struct __sk_buff, remote_ip6[2])),
1535 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1536 offsetof(struct __sk_buff, remote_ip6[3])),
1537 BPF_EXIT_INSN(),
1538 },
1539 .result = ACCEPT,
1540 .prog_type = BPF_PROG_TYPE_SK_SKB,
1541 },
1542 {
1543 "valid access __sk_buff local_ip6",
1544 .insns = {
1545 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1546 offsetof(struct __sk_buff, local_ip6[0])),
1547 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1548 offsetof(struct __sk_buff, local_ip6[1])),
1549 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1550 offsetof(struct __sk_buff, local_ip6[2])),
1551 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1552 offsetof(struct __sk_buff, local_ip6[3])),
1553 BPF_EXIT_INSN(),
1554 },
1555 .result = ACCEPT,
1556 .prog_type = BPF_PROG_TYPE_SK_SKB,
1557 },
1558 {
1559 "valid access __sk_buff remote_port",
1560 .insns = {
1561 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1562 offsetof(struct __sk_buff, remote_port)),
1563 BPF_EXIT_INSN(),
1564 },
1565 .result = ACCEPT,
1566 .prog_type = BPF_PROG_TYPE_SK_SKB,
1567 },
1568 {
1569 "valid access __sk_buff remote_port",
1570 .insns = {
1571 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1572 offsetof(struct __sk_buff, local_port)),
1573 BPF_EXIT_INSN(),
1574 },
1575 .result = ACCEPT,
1576 .prog_type = BPF_PROG_TYPE_SK_SKB,
1577 },
1578 {
John Fastabended850542017-08-28 07:11:24 -07001579 "invalid access of tc_classid for SK_SKB",
1580 .insns = {
1581 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1582 offsetof(struct __sk_buff, tc_classid)),
1583 BPF_EXIT_INSN(),
1584 },
1585 .result = REJECT,
1586 .prog_type = BPF_PROG_TYPE_SK_SKB,
1587 .errstr = "invalid bpf_context access",
1588 },
1589 {
John Fastabendf7e9cb12017-10-18 07:10:58 -07001590 "invalid access of skb->mark for SK_SKB",
1591 .insns = {
1592 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1593 offsetof(struct __sk_buff, mark)),
1594 BPF_EXIT_INSN(),
1595 },
1596 .result = REJECT,
1597 .prog_type = BPF_PROG_TYPE_SK_SKB,
1598 .errstr = "invalid bpf_context access",
1599 },
1600 {
1601 "check skb->mark is not writeable by SK_SKB",
John Fastabended850542017-08-28 07:11:24 -07001602 .insns = {
1603 BPF_MOV64_IMM(BPF_REG_0, 0),
1604 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1605 offsetof(struct __sk_buff, mark)),
1606 BPF_EXIT_INSN(),
1607 },
John Fastabendf7e9cb12017-10-18 07:10:58 -07001608 .result = REJECT,
John Fastabended850542017-08-28 07:11:24 -07001609 .prog_type = BPF_PROG_TYPE_SK_SKB,
John Fastabendf7e9cb12017-10-18 07:10:58 -07001610 .errstr = "invalid bpf_context access",
John Fastabended850542017-08-28 07:11:24 -07001611 },
1612 {
1613 "check skb->tc_index is writeable by SK_SKB",
1614 .insns = {
1615 BPF_MOV64_IMM(BPF_REG_0, 0),
1616 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1617 offsetof(struct __sk_buff, tc_index)),
1618 BPF_EXIT_INSN(),
1619 },
1620 .result = ACCEPT,
1621 .prog_type = BPF_PROG_TYPE_SK_SKB,
1622 },
1623 {
1624 "check skb->priority is writeable by SK_SKB",
1625 .insns = {
1626 BPF_MOV64_IMM(BPF_REG_0, 0),
1627 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1628 offsetof(struct __sk_buff, priority)),
1629 BPF_EXIT_INSN(),
1630 },
1631 .result = ACCEPT,
1632 .prog_type = BPF_PROG_TYPE_SK_SKB,
1633 },
1634 {
1635 "direct packet read for SK_SKB",
1636 .insns = {
1637 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1638 offsetof(struct __sk_buff, data)),
1639 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1640 offsetof(struct __sk_buff, data_end)),
1641 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1643 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1644 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1645 BPF_MOV64_IMM(BPF_REG_0, 0),
1646 BPF_EXIT_INSN(),
1647 },
1648 .result = ACCEPT,
1649 .prog_type = BPF_PROG_TYPE_SK_SKB,
1650 },
1651 {
1652 "direct packet write for SK_SKB",
1653 .insns = {
1654 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1655 offsetof(struct __sk_buff, data)),
1656 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1657 offsetof(struct __sk_buff, data_end)),
1658 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1659 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1660 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1661 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1662 BPF_MOV64_IMM(BPF_REG_0, 0),
1663 BPF_EXIT_INSN(),
1664 },
1665 .result = ACCEPT,
1666 .prog_type = BPF_PROG_TYPE_SK_SKB,
1667 },
1668 {
1669 "overlapping checks for direct packet access SK_SKB",
1670 .insns = {
1671 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1672 offsetof(struct __sk_buff, data)),
1673 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1674 offsetof(struct __sk_buff, data_end)),
1675 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1676 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1677 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1678 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1679 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1680 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1681 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1682 BPF_MOV64_IMM(BPF_REG_0, 0),
1683 BPF_EXIT_INSN(),
1684 },
1685 .result = ACCEPT,
1686 .prog_type = BPF_PROG_TYPE_SK_SKB,
1687 },
1688 {
John Fastabend4da0dca2018-05-17 14:17:03 -07001689 "valid access family in SK_MSG",
1690 .insns = {
1691 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1692 offsetof(struct sk_msg_md, family)),
1693 BPF_EXIT_INSN(),
1694 },
1695 .result = ACCEPT,
1696 .prog_type = BPF_PROG_TYPE_SK_MSG,
1697 },
1698 {
1699 "valid access remote_ip4 in SK_MSG",
1700 .insns = {
1701 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1702 offsetof(struct sk_msg_md, remote_ip4)),
1703 BPF_EXIT_INSN(),
1704 },
1705 .result = ACCEPT,
1706 .prog_type = BPF_PROG_TYPE_SK_MSG,
1707 },
1708 {
1709 "valid access local_ip4 in SK_MSG",
1710 .insns = {
1711 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1712 offsetof(struct sk_msg_md, local_ip4)),
1713 BPF_EXIT_INSN(),
1714 },
1715 .result = ACCEPT,
1716 .prog_type = BPF_PROG_TYPE_SK_MSG,
1717 },
1718 {
1719 "valid access remote_port in SK_MSG",
1720 .insns = {
1721 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1722 offsetof(struct sk_msg_md, remote_port)),
1723 BPF_EXIT_INSN(),
1724 },
1725 .result = ACCEPT,
1726 .prog_type = BPF_PROG_TYPE_SK_MSG,
1727 },
1728 {
1729 "valid access local_port in SK_MSG",
1730 .insns = {
1731 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1732 offsetof(struct sk_msg_md, local_port)),
1733 BPF_EXIT_INSN(),
1734 },
1735 .result = ACCEPT,
1736 .prog_type = BPF_PROG_TYPE_SK_MSG,
1737 },
1738 {
1739 "valid access remote_ip6 in SK_MSG",
1740 .insns = {
1741 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1742 offsetof(struct sk_msg_md, remote_ip6[0])),
1743 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1744 offsetof(struct sk_msg_md, remote_ip6[1])),
1745 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1746 offsetof(struct sk_msg_md, remote_ip6[2])),
1747 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1748 offsetof(struct sk_msg_md, remote_ip6[3])),
1749 BPF_EXIT_INSN(),
1750 },
1751 .result = ACCEPT,
1752 .prog_type = BPF_PROG_TYPE_SK_SKB,
1753 },
1754 {
1755 "valid access local_ip6 in SK_MSG",
1756 .insns = {
1757 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1758 offsetof(struct sk_msg_md, local_ip6[0])),
1759 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1760 offsetof(struct sk_msg_md, local_ip6[1])),
1761 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1762 offsetof(struct sk_msg_md, local_ip6[2])),
1763 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1764 offsetof(struct sk_msg_md, local_ip6[3])),
1765 BPF_EXIT_INSN(),
1766 },
1767 .result = ACCEPT,
1768 .prog_type = BPF_PROG_TYPE_SK_SKB,
1769 },
1770 {
1771 "invalid 64B read of family in SK_MSG",
1772 .insns = {
1773 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1774 offsetof(struct sk_msg_md, family)),
1775 BPF_EXIT_INSN(),
1776 },
1777 .errstr = "invalid bpf_context access",
1778 .result = REJECT,
1779 .prog_type = BPF_PROG_TYPE_SK_MSG,
1780 },
1781 {
1782 "invalid read past end of SK_MSG",
1783 .insns = {
1784 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1785 offsetof(struct sk_msg_md, local_port) + 4),
1786 BPF_EXIT_INSN(),
1787 },
1788 .errstr = "R0 !read_ok",
1789 .result = REJECT,
1790 .prog_type = BPF_PROG_TYPE_SK_MSG,
1791 },
1792 {
1793 "invalid read offset in SK_MSG",
1794 .insns = {
1795 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1796 offsetof(struct sk_msg_md, family) + 1),
1797 BPF_EXIT_INSN(),
1798 },
1799 .errstr = "invalid bpf_context access",
1800 .result = REJECT,
1801 .prog_type = BPF_PROG_TYPE_SK_MSG,
1802 },
1803 {
John Fastabend1acc60b2018-03-18 12:57:36 -07001804 "direct packet read for SK_MSG",
1805 .insns = {
1806 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1807 offsetof(struct sk_msg_md, data)),
1808 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1809 offsetof(struct sk_msg_md, data_end)),
1810 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1811 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1812 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1813 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1814 BPF_MOV64_IMM(BPF_REG_0, 0),
1815 BPF_EXIT_INSN(),
1816 },
1817 .result = ACCEPT,
1818 .prog_type = BPF_PROG_TYPE_SK_MSG,
1819 },
1820 {
1821 "direct packet write for SK_MSG",
1822 .insns = {
1823 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1824 offsetof(struct sk_msg_md, data)),
1825 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1826 offsetof(struct sk_msg_md, data_end)),
1827 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1829 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1830 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1831 BPF_MOV64_IMM(BPF_REG_0, 0),
1832 BPF_EXIT_INSN(),
1833 },
1834 .result = ACCEPT,
1835 .prog_type = BPF_PROG_TYPE_SK_MSG,
1836 },
1837 {
1838 "overlapping checks for direct packet access SK_MSG",
1839 .insns = {
1840 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1841 offsetof(struct sk_msg_md, data)),
1842 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1843 offsetof(struct sk_msg_md, data_end)),
1844 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1845 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1846 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1847 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1849 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1850 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1851 BPF_MOV64_IMM(BPF_REG_0, 0),
1852 BPF_EXIT_INSN(),
1853 },
1854 .result = ACCEPT,
1855 .prog_type = BPF_PROG_TYPE_SK_MSG,
1856 },
1857 {
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001858 "check skb->mark is not writeable by sockets",
1859 .insns = {
1860 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1861 offsetof(struct __sk_buff, mark)),
1862 BPF_EXIT_INSN(),
1863 },
1864 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001865 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001866 .result = REJECT,
1867 },
1868 {
1869 "check skb->tc_index is not writeable by sockets",
1870 .insns = {
1871 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1872 offsetof(struct __sk_buff, tc_index)),
1873 BPF_EXIT_INSN(),
1874 },
1875 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001876 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001877 .result = REJECT,
1878 },
1879 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001880 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001881 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001882 BPF_MOV64_IMM(BPF_REG_0, 0),
1883 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1884 offsetof(struct __sk_buff, cb[0])),
1885 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1886 offsetof(struct __sk_buff, cb[0]) + 1),
1887 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1888 offsetof(struct __sk_buff, cb[0]) + 2),
1889 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1890 offsetof(struct __sk_buff, cb[0]) + 3),
1891 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1892 offsetof(struct __sk_buff, cb[1])),
1893 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1894 offsetof(struct __sk_buff, cb[1]) + 1),
1895 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1896 offsetof(struct __sk_buff, cb[1]) + 2),
1897 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1898 offsetof(struct __sk_buff, cb[1]) + 3),
1899 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1900 offsetof(struct __sk_buff, cb[2])),
1901 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1902 offsetof(struct __sk_buff, cb[2]) + 1),
1903 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1904 offsetof(struct __sk_buff, cb[2]) + 2),
1905 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1906 offsetof(struct __sk_buff, cb[2]) + 3),
1907 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1908 offsetof(struct __sk_buff, cb[3])),
1909 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1910 offsetof(struct __sk_buff, cb[3]) + 1),
1911 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1912 offsetof(struct __sk_buff, cb[3]) + 2),
1913 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1914 offsetof(struct __sk_buff, cb[3]) + 3),
1915 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1916 offsetof(struct __sk_buff, cb[4])),
1917 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1918 offsetof(struct __sk_buff, cb[4]) + 1),
1919 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1920 offsetof(struct __sk_buff, cb[4]) + 2),
1921 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1922 offsetof(struct __sk_buff, cb[4]) + 3),
1923 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1924 offsetof(struct __sk_buff, cb[0])),
1925 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1926 offsetof(struct __sk_buff, cb[0]) + 1),
1927 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1928 offsetof(struct __sk_buff, cb[0]) + 2),
1929 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1930 offsetof(struct __sk_buff, cb[0]) + 3),
1931 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1932 offsetof(struct __sk_buff, cb[1])),
1933 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1934 offsetof(struct __sk_buff, cb[1]) + 1),
1935 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1936 offsetof(struct __sk_buff, cb[1]) + 2),
1937 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1938 offsetof(struct __sk_buff, cb[1]) + 3),
1939 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1940 offsetof(struct __sk_buff, cb[2])),
1941 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1942 offsetof(struct __sk_buff, cb[2]) + 1),
1943 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1944 offsetof(struct __sk_buff, cb[2]) + 2),
1945 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1946 offsetof(struct __sk_buff, cb[2]) + 3),
1947 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1948 offsetof(struct __sk_buff, cb[3])),
1949 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1950 offsetof(struct __sk_buff, cb[3]) + 1),
1951 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1952 offsetof(struct __sk_buff, cb[3]) + 2),
1953 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1954 offsetof(struct __sk_buff, cb[3]) + 3),
1955 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1956 offsetof(struct __sk_buff, cb[4])),
1957 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1958 offsetof(struct __sk_buff, cb[4]) + 1),
1959 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1960 offsetof(struct __sk_buff, cb[4]) + 2),
1961 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1962 offsetof(struct __sk_buff, cb[4]) + 3),
1963 BPF_EXIT_INSN(),
1964 },
1965 .result = ACCEPT,
1966 },
1967 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001968 "__sk_buff->hash, offset 0, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001969 .insns = {
1970 BPF_MOV64_IMM(BPF_REG_0, 0),
1971 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001972 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001973 BPF_EXIT_INSN(),
1974 },
1975 .errstr = "invalid bpf_context access",
1976 .result = REJECT,
1977 },
1978 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001979 "__sk_buff->tc_index, offset 3, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001980 .insns = {
1981 BPF_MOV64_IMM(BPF_REG_0, 0),
1982 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001983 offsetof(struct __sk_buff, tc_index) + 3),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001984 BPF_EXIT_INSN(),
1985 },
1986 .errstr = "invalid bpf_context access",
1987 .result = REJECT,
1988 },
1989 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001990 "check skb->hash byte load permitted",
1991 .insns = {
1992 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001993#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001994 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1995 offsetof(struct __sk_buff, hash)),
1996#else
1997 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1998 offsetof(struct __sk_buff, hash) + 3),
1999#endif
2000 BPF_EXIT_INSN(),
2001 },
2002 .result = ACCEPT,
2003 },
2004 {
2005 "check skb->hash byte load not permitted 1",
2006 .insns = {
2007 BPF_MOV64_IMM(BPF_REG_0, 0),
2008 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2009 offsetof(struct __sk_buff, hash) + 1),
2010 BPF_EXIT_INSN(),
2011 },
2012 .errstr = "invalid bpf_context access",
2013 .result = REJECT,
2014 },
2015 {
2016 "check skb->hash byte load not permitted 2",
2017 .insns = {
2018 BPF_MOV64_IMM(BPF_REG_0, 0),
2019 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2020 offsetof(struct __sk_buff, hash) + 2),
2021 BPF_EXIT_INSN(),
2022 },
2023 .errstr = "invalid bpf_context access",
2024 .result = REJECT,
2025 },
2026 {
2027 "check skb->hash byte load not permitted 3",
2028 .insns = {
2029 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002030#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002031 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2032 offsetof(struct __sk_buff, hash) + 3),
2033#else
2034 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2035 offsetof(struct __sk_buff, hash)),
2036#endif
2037 BPF_EXIT_INSN(),
2038 },
2039 .errstr = "invalid bpf_context access",
2040 .result = REJECT,
2041 },
2042 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01002043 "check cb access: byte, wrong type",
2044 .insns = {
2045 BPF_MOV64_IMM(BPF_REG_0, 0),
2046 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002047 offsetof(struct __sk_buff, cb[0])),
2048 BPF_EXIT_INSN(),
2049 },
2050 .errstr = "invalid bpf_context access",
2051 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002052 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2053 },
2054 {
2055 "check cb access: half",
2056 .insns = {
2057 BPF_MOV64_IMM(BPF_REG_0, 0),
2058 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2059 offsetof(struct __sk_buff, cb[0])),
2060 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2061 offsetof(struct __sk_buff, cb[0]) + 2),
2062 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2063 offsetof(struct __sk_buff, cb[1])),
2064 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2065 offsetof(struct __sk_buff, cb[1]) + 2),
2066 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2067 offsetof(struct __sk_buff, cb[2])),
2068 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2069 offsetof(struct __sk_buff, cb[2]) + 2),
2070 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2071 offsetof(struct __sk_buff, cb[3])),
2072 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2073 offsetof(struct __sk_buff, cb[3]) + 2),
2074 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2075 offsetof(struct __sk_buff, cb[4])),
2076 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2077 offsetof(struct __sk_buff, cb[4]) + 2),
2078 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2079 offsetof(struct __sk_buff, cb[0])),
2080 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2081 offsetof(struct __sk_buff, cb[0]) + 2),
2082 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2083 offsetof(struct __sk_buff, cb[1])),
2084 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2085 offsetof(struct __sk_buff, cb[1]) + 2),
2086 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2087 offsetof(struct __sk_buff, cb[2])),
2088 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2089 offsetof(struct __sk_buff, cb[2]) + 2),
2090 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2091 offsetof(struct __sk_buff, cb[3])),
2092 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2093 offsetof(struct __sk_buff, cb[3]) + 2),
2094 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2095 offsetof(struct __sk_buff, cb[4])),
2096 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2097 offsetof(struct __sk_buff, cb[4]) + 2),
2098 BPF_EXIT_INSN(),
2099 },
2100 .result = ACCEPT,
2101 },
2102 {
2103 "check cb access: half, unaligned",
2104 .insns = {
2105 BPF_MOV64_IMM(BPF_REG_0, 0),
2106 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2107 offsetof(struct __sk_buff, cb[0]) + 1),
2108 BPF_EXIT_INSN(),
2109 },
Edward Creef65b1842017-08-07 15:27:12 +01002110 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002111 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002112 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002113 },
2114 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002115 "check __sk_buff->hash, offset 0, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002116 .insns = {
2117 BPF_MOV64_IMM(BPF_REG_0, 0),
2118 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07002119 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002120 BPF_EXIT_INSN(),
2121 },
2122 .errstr = "invalid bpf_context access",
2123 .result = REJECT,
2124 },
2125 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002126 "check __sk_buff->tc_index, offset 2, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002127 .insns = {
2128 BPF_MOV64_IMM(BPF_REG_0, 0),
2129 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07002130 offsetof(struct __sk_buff, tc_index) + 2),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002131 BPF_EXIT_INSN(),
2132 },
2133 .errstr = "invalid bpf_context access",
2134 .result = REJECT,
2135 },
2136 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002137 "check skb->hash half load permitted",
2138 .insns = {
2139 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002140#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002141 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2142 offsetof(struct __sk_buff, hash)),
2143#else
2144 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2145 offsetof(struct __sk_buff, hash) + 2),
2146#endif
2147 BPF_EXIT_INSN(),
2148 },
2149 .result = ACCEPT,
2150 },
2151 {
2152 "check skb->hash half load not permitted",
2153 .insns = {
2154 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002155#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002156 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2157 offsetof(struct __sk_buff, hash) + 2),
2158#else
2159 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2160 offsetof(struct __sk_buff, hash)),
2161#endif
2162 BPF_EXIT_INSN(),
2163 },
2164 .errstr = "invalid bpf_context access",
2165 .result = REJECT,
2166 },
2167 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01002168 "check cb access: half, wrong type",
2169 .insns = {
2170 BPF_MOV64_IMM(BPF_REG_0, 0),
2171 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2172 offsetof(struct __sk_buff, cb[0])),
2173 BPF_EXIT_INSN(),
2174 },
2175 .errstr = "invalid bpf_context access",
2176 .result = REJECT,
2177 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2178 },
2179 {
2180 "check cb access: word",
2181 .insns = {
2182 BPF_MOV64_IMM(BPF_REG_0, 0),
2183 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2184 offsetof(struct __sk_buff, cb[0])),
2185 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2186 offsetof(struct __sk_buff, cb[1])),
2187 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2188 offsetof(struct __sk_buff, cb[2])),
2189 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2190 offsetof(struct __sk_buff, cb[3])),
2191 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2192 offsetof(struct __sk_buff, cb[4])),
2193 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2194 offsetof(struct __sk_buff, cb[0])),
2195 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2196 offsetof(struct __sk_buff, cb[1])),
2197 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2198 offsetof(struct __sk_buff, cb[2])),
2199 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2200 offsetof(struct __sk_buff, cb[3])),
2201 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2202 offsetof(struct __sk_buff, cb[4])),
2203 BPF_EXIT_INSN(),
2204 },
2205 .result = ACCEPT,
2206 },
2207 {
2208 "check cb access: word, unaligned 1",
2209 .insns = {
2210 BPF_MOV64_IMM(BPF_REG_0, 0),
2211 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2212 offsetof(struct __sk_buff, cb[0]) + 2),
2213 BPF_EXIT_INSN(),
2214 },
Edward Creef65b1842017-08-07 15:27:12 +01002215 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002216 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002217 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002218 },
2219 {
2220 "check cb access: word, unaligned 2",
2221 .insns = {
2222 BPF_MOV64_IMM(BPF_REG_0, 0),
2223 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2224 offsetof(struct __sk_buff, cb[4]) + 1),
2225 BPF_EXIT_INSN(),
2226 },
Edward Creef65b1842017-08-07 15:27:12 +01002227 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002228 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002229 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002230 },
2231 {
2232 "check cb access: word, unaligned 3",
2233 .insns = {
2234 BPF_MOV64_IMM(BPF_REG_0, 0),
2235 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2236 offsetof(struct __sk_buff, cb[4]) + 2),
2237 BPF_EXIT_INSN(),
2238 },
Edward Creef65b1842017-08-07 15:27:12 +01002239 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002240 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002241 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002242 },
2243 {
2244 "check cb access: word, unaligned 4",
2245 .insns = {
2246 BPF_MOV64_IMM(BPF_REG_0, 0),
2247 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2248 offsetof(struct __sk_buff, cb[4]) + 3),
2249 BPF_EXIT_INSN(),
2250 },
Edward Creef65b1842017-08-07 15:27:12 +01002251 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002252 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002253 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002254 },
2255 {
2256 "check cb access: double",
2257 .insns = {
2258 BPF_MOV64_IMM(BPF_REG_0, 0),
2259 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2260 offsetof(struct __sk_buff, cb[0])),
2261 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2262 offsetof(struct __sk_buff, cb[2])),
2263 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2264 offsetof(struct __sk_buff, cb[0])),
2265 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2266 offsetof(struct __sk_buff, cb[2])),
2267 BPF_EXIT_INSN(),
2268 },
2269 .result = ACCEPT,
2270 },
2271 {
2272 "check cb access: double, unaligned 1",
2273 .insns = {
2274 BPF_MOV64_IMM(BPF_REG_0, 0),
2275 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2276 offsetof(struct __sk_buff, cb[1])),
2277 BPF_EXIT_INSN(),
2278 },
Edward Creef65b1842017-08-07 15:27:12 +01002279 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002280 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002281 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002282 },
2283 {
2284 "check cb access: double, unaligned 2",
2285 .insns = {
2286 BPF_MOV64_IMM(BPF_REG_0, 0),
2287 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2288 offsetof(struct __sk_buff, cb[3])),
2289 BPF_EXIT_INSN(),
2290 },
Edward Creef65b1842017-08-07 15:27:12 +01002291 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002292 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002293 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002294 },
2295 {
2296 "check cb access: double, oob 1",
2297 .insns = {
2298 BPF_MOV64_IMM(BPF_REG_0, 0),
2299 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2300 offsetof(struct __sk_buff, cb[4])),
2301 BPF_EXIT_INSN(),
2302 },
2303 .errstr = "invalid bpf_context access",
2304 .result = REJECT,
2305 },
2306 {
2307 "check cb access: double, oob 2",
2308 .insns = {
2309 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002310 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2311 offsetof(struct __sk_buff, cb[4])),
2312 BPF_EXIT_INSN(),
2313 },
2314 .errstr = "invalid bpf_context access",
2315 .result = REJECT,
2316 },
2317 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002318 "check __sk_buff->ifindex dw store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002319 .insns = {
2320 BPF_MOV64_IMM(BPF_REG_0, 0),
Yonghong Song31fd8582017-06-13 15:52:13 -07002321 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2322 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002323 BPF_EXIT_INSN(),
2324 },
2325 .errstr = "invalid bpf_context access",
2326 .result = REJECT,
2327 },
2328 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002329 "check __sk_buff->ifindex dw load not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002330 .insns = {
2331 BPF_MOV64_IMM(BPF_REG_0, 0),
2332 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
Yonghong Song31fd8582017-06-13 15:52:13 -07002333 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002334 BPF_EXIT_INSN(),
2335 },
2336 .errstr = "invalid bpf_context access",
2337 .result = REJECT,
2338 },
2339 {
2340 "check cb access: double, wrong type",
2341 .insns = {
2342 BPF_MOV64_IMM(BPF_REG_0, 0),
2343 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2344 offsetof(struct __sk_buff, cb[0])),
2345 BPF_EXIT_INSN(),
2346 },
2347 .errstr = "invalid bpf_context access",
2348 .result = REJECT,
2349 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002350 },
2351 {
2352 "check out of range skb->cb access",
2353 .insns = {
2354 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002355 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002356 BPF_EXIT_INSN(),
2357 },
2358 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002359 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002360 .result = REJECT,
2361 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
2362 },
2363 {
2364 "write skb fields from socket prog",
2365 .insns = {
2366 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2367 offsetof(struct __sk_buff, cb[4])),
2368 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2369 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2370 offsetof(struct __sk_buff, mark)),
2371 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2372 offsetof(struct __sk_buff, tc_index)),
2373 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2374 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2375 offsetof(struct __sk_buff, cb[0])),
2376 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2377 offsetof(struct __sk_buff, cb[2])),
2378 BPF_EXIT_INSN(),
2379 },
2380 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002381 .errstr_unpriv = "R1 leaks addr",
2382 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002383 },
2384 {
2385 "write skb fields from tc_cls_act prog",
2386 .insns = {
2387 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2388 offsetof(struct __sk_buff, cb[0])),
2389 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2390 offsetof(struct __sk_buff, mark)),
2391 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2392 offsetof(struct __sk_buff, tc_index)),
2393 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2394 offsetof(struct __sk_buff, tc_index)),
2395 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2396 offsetof(struct __sk_buff, cb[3])),
2397 BPF_EXIT_INSN(),
2398 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002399 .errstr_unpriv = "",
2400 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002401 .result = ACCEPT,
2402 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2403 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002404 {
2405 "PTR_TO_STACK store/load",
2406 .insns = {
2407 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2408 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2409 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2410 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2411 BPF_EXIT_INSN(),
2412 },
2413 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002414 .retval = 0xfaceb00c,
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002415 },
2416 {
2417 "PTR_TO_STACK store/load - bad alignment on off",
2418 .insns = {
2419 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2420 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2421 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2423 BPF_EXIT_INSN(),
2424 },
2425 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002426 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002427 },
2428 {
2429 "PTR_TO_STACK store/load - bad alignment on reg",
2430 .insns = {
2431 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2432 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2433 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2434 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2435 BPF_EXIT_INSN(),
2436 },
2437 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002438 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002439 },
2440 {
2441 "PTR_TO_STACK store/load - out of bounds low",
2442 .insns = {
2443 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
2445 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2446 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2447 BPF_EXIT_INSN(),
2448 },
2449 .result = REJECT,
2450 .errstr = "invalid stack off=-79992 size=8",
2451 },
2452 {
2453 "PTR_TO_STACK store/load - out of bounds high",
2454 .insns = {
2455 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2457 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2458 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2459 BPF_EXIT_INSN(),
2460 },
2461 .result = REJECT,
2462 .errstr = "invalid stack off=0 size=8",
2463 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002464 {
2465 "unpriv: return pointer",
2466 .insns = {
2467 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
2468 BPF_EXIT_INSN(),
2469 },
2470 .result = ACCEPT,
2471 .result_unpriv = REJECT,
2472 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002473 .retval = POINTER_VALUE,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002474 },
2475 {
2476 "unpriv: add const to pointer",
2477 .insns = {
2478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2479 BPF_MOV64_IMM(BPF_REG_0, 0),
2480 BPF_EXIT_INSN(),
2481 },
2482 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002483 },
2484 {
2485 "unpriv: add pointer to pointer",
2486 .insns = {
2487 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2488 BPF_MOV64_IMM(BPF_REG_0, 0),
2489 BPF_EXIT_INSN(),
2490 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08002491 .result = REJECT,
2492 .errstr = "R1 pointer += pointer",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002493 },
2494 {
2495 "unpriv: neg pointer",
2496 .insns = {
2497 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
2498 BPF_MOV64_IMM(BPF_REG_0, 0),
2499 BPF_EXIT_INSN(),
2500 },
2501 .result = ACCEPT,
2502 .result_unpriv = REJECT,
2503 .errstr_unpriv = "R1 pointer arithmetic",
2504 },
2505 {
2506 "unpriv: cmp pointer with const",
2507 .insns = {
2508 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2509 BPF_MOV64_IMM(BPF_REG_0, 0),
2510 BPF_EXIT_INSN(),
2511 },
2512 .result = ACCEPT,
2513 .result_unpriv = REJECT,
2514 .errstr_unpriv = "R1 pointer comparison",
2515 },
2516 {
2517 "unpriv: cmp pointer with pointer",
2518 .insns = {
2519 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
2520 BPF_MOV64_IMM(BPF_REG_0, 0),
2521 BPF_EXIT_INSN(),
2522 },
2523 .result = ACCEPT,
2524 .result_unpriv = REJECT,
2525 .errstr_unpriv = "R10 pointer comparison",
2526 },
2527 {
2528 "unpriv: check that printk is disallowed",
2529 .insns = {
2530 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2531 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2533 BPF_MOV64_IMM(BPF_REG_2, 8),
2534 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002535 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2536 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002537 BPF_MOV64_IMM(BPF_REG_0, 0),
2538 BPF_EXIT_INSN(),
2539 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01002540 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002541 .result_unpriv = REJECT,
2542 .result = ACCEPT,
2543 },
2544 {
2545 "unpriv: pass pointer to helper function",
2546 .insns = {
2547 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2548 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2549 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2550 BPF_LD_MAP_FD(BPF_REG_1, 0),
2551 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2552 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002553 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2554 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002555 BPF_MOV64_IMM(BPF_REG_0, 0),
2556 BPF_EXIT_INSN(),
2557 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002558 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002559 .errstr_unpriv = "R4 leaks addr",
2560 .result_unpriv = REJECT,
2561 .result = ACCEPT,
2562 },
2563 {
2564 "unpriv: indirectly pass pointer on stack to helper function",
2565 .insns = {
2566 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2567 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2568 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2569 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002570 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2571 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002572 BPF_MOV64_IMM(BPF_REG_0, 0),
2573 BPF_EXIT_INSN(),
2574 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002575 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002576 .errstr = "invalid indirect read from stack off -8+0 size 8",
2577 .result = REJECT,
2578 },
2579 {
2580 "unpriv: mangle pointer on stack 1",
2581 .insns = {
2582 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2583 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
2584 BPF_MOV64_IMM(BPF_REG_0, 0),
2585 BPF_EXIT_INSN(),
2586 },
2587 .errstr_unpriv = "attempt to corrupt spilled",
2588 .result_unpriv = REJECT,
2589 .result = ACCEPT,
2590 },
2591 {
2592 "unpriv: mangle pointer on stack 2",
2593 .insns = {
2594 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2595 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2596 BPF_MOV64_IMM(BPF_REG_0, 0),
2597 BPF_EXIT_INSN(),
2598 },
2599 .errstr_unpriv = "attempt to corrupt spilled",
2600 .result_unpriv = REJECT,
2601 .result = ACCEPT,
2602 },
2603 {
2604 "unpriv: read pointer from stack in small chunks",
2605 .insns = {
2606 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2607 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2608 BPF_MOV64_IMM(BPF_REG_0, 0),
2609 BPF_EXIT_INSN(),
2610 },
2611 .errstr = "invalid size",
2612 .result = REJECT,
2613 },
2614 {
2615 "unpriv: write pointer into ctx",
2616 .insns = {
2617 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2618 BPF_MOV64_IMM(BPF_REG_0, 0),
2619 BPF_EXIT_INSN(),
2620 },
2621 .errstr_unpriv = "R1 leaks addr",
2622 .result_unpriv = REJECT,
2623 .errstr = "invalid bpf_context access",
2624 .result = REJECT,
2625 },
2626 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002627 "unpriv: spill/fill of ctx",
2628 .insns = {
2629 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2630 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2631 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2632 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2633 BPF_MOV64_IMM(BPF_REG_0, 0),
2634 BPF_EXIT_INSN(),
2635 },
2636 .result = ACCEPT,
2637 },
2638 {
2639 "unpriv: spill/fill of ctx 2",
2640 .insns = {
2641 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2643 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2644 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002645 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2646 BPF_FUNC_get_hash_recalc),
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002647 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002648 BPF_EXIT_INSN(),
2649 },
2650 .result = ACCEPT,
2651 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2652 },
2653 {
2654 "unpriv: spill/fill of ctx 3",
2655 .insns = {
2656 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2657 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2658 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2659 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2660 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002661 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2662 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002663 BPF_EXIT_INSN(),
2664 },
2665 .result = REJECT,
2666 .errstr = "R1 type=fp expected=ctx",
2667 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2668 },
2669 {
2670 "unpriv: spill/fill of ctx 4",
2671 .insns = {
2672 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2674 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2675 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002676 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2677 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002678 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002679 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2680 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002681 BPF_EXIT_INSN(),
2682 },
2683 .result = REJECT,
2684 .errstr = "R1 type=inv expected=ctx",
2685 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2686 },
2687 {
2688 "unpriv: spill/fill of different pointers stx",
2689 .insns = {
2690 BPF_MOV64_IMM(BPF_REG_3, 42),
2691 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2692 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2693 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2694 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2695 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2696 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2697 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2698 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2699 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2700 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2701 offsetof(struct __sk_buff, mark)),
2702 BPF_MOV64_IMM(BPF_REG_0, 0),
2703 BPF_EXIT_INSN(),
2704 },
2705 .result = REJECT,
2706 .errstr = "same insn cannot be used with different pointers",
2707 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2708 },
2709 {
2710 "unpriv: spill/fill of different pointers ldx",
2711 .insns = {
2712 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2713 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2714 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2715 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2716 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2717 -(__s32)offsetof(struct bpf_perf_event_data,
2718 sample_period) - 8),
2719 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2720 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2721 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2722 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2723 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2724 offsetof(struct bpf_perf_event_data,
2725 sample_period)),
2726 BPF_MOV64_IMM(BPF_REG_0, 0),
2727 BPF_EXIT_INSN(),
2728 },
2729 .result = REJECT,
2730 .errstr = "same insn cannot be used with different pointers",
2731 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2732 },
2733 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002734 "unpriv: write pointer into map elem value",
2735 .insns = {
2736 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2737 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2739 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002740 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2741 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002742 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2743 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2744 BPF_EXIT_INSN(),
2745 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002746 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002747 .errstr_unpriv = "R0 leaks addr",
2748 .result_unpriv = REJECT,
2749 .result = ACCEPT,
2750 },
2751 {
2752 "unpriv: partial copy of pointer",
2753 .insns = {
2754 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2755 BPF_MOV64_IMM(BPF_REG_0, 0),
2756 BPF_EXIT_INSN(),
2757 },
2758 .errstr_unpriv = "R10 partial copy",
2759 .result_unpriv = REJECT,
2760 .result = ACCEPT,
2761 },
2762 {
2763 "unpriv: pass pointer to tail_call",
2764 .insns = {
2765 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2766 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002767 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2768 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002769 BPF_MOV64_IMM(BPF_REG_0, 0),
2770 BPF_EXIT_INSN(),
2771 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002772 .fixup_prog = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002773 .errstr_unpriv = "R3 leaks addr into helper",
2774 .result_unpriv = REJECT,
2775 .result = ACCEPT,
2776 },
2777 {
2778 "unpriv: cmp map pointer with zero",
2779 .insns = {
2780 BPF_MOV64_IMM(BPF_REG_1, 0),
2781 BPF_LD_MAP_FD(BPF_REG_1, 0),
2782 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2783 BPF_MOV64_IMM(BPF_REG_0, 0),
2784 BPF_EXIT_INSN(),
2785 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002786 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002787 .errstr_unpriv = "R1 pointer comparison",
2788 .result_unpriv = REJECT,
2789 .result = ACCEPT,
2790 },
2791 {
2792 "unpriv: write into frame pointer",
2793 .insns = {
2794 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2795 BPF_MOV64_IMM(BPF_REG_0, 0),
2796 BPF_EXIT_INSN(),
2797 },
2798 .errstr = "frame pointer is read only",
2799 .result = REJECT,
2800 },
2801 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002802 "unpriv: spill/fill frame pointer",
2803 .insns = {
2804 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2805 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2806 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2807 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2808 BPF_MOV64_IMM(BPF_REG_0, 0),
2809 BPF_EXIT_INSN(),
2810 },
2811 .errstr = "frame pointer is read only",
2812 .result = REJECT,
2813 },
2814 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002815 "unpriv: cmp of frame pointer",
2816 .insns = {
2817 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2818 BPF_MOV64_IMM(BPF_REG_0, 0),
2819 BPF_EXIT_INSN(),
2820 },
2821 .errstr_unpriv = "R10 pointer comparison",
2822 .result_unpriv = REJECT,
2823 .result = ACCEPT,
2824 },
2825 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02002826 "unpriv: adding of fp",
2827 .insns = {
2828 BPF_MOV64_IMM(BPF_REG_0, 0),
2829 BPF_MOV64_IMM(BPF_REG_1, 0),
2830 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2831 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2832 BPF_EXIT_INSN(),
2833 },
Edward Creef65b1842017-08-07 15:27:12 +01002834 .result = ACCEPT,
Daniel Borkmann728a8532017-04-27 01:39:32 +02002835 },
2836 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002837 "unpriv: cmp of stack pointer",
2838 .insns = {
2839 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2840 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2841 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2842 BPF_MOV64_IMM(BPF_REG_0, 0),
2843 BPF_EXIT_INSN(),
2844 },
2845 .errstr_unpriv = "R2 pointer comparison",
2846 .result_unpriv = REJECT,
2847 .result = ACCEPT,
2848 },
2849 {
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002850 "runtime/jit: tail_call within bounds, prog once",
2851 .insns = {
2852 BPF_MOV64_IMM(BPF_REG_3, 0),
2853 BPF_LD_MAP_FD(BPF_REG_2, 0),
2854 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2855 BPF_FUNC_tail_call),
2856 BPF_MOV64_IMM(BPF_REG_0, 1),
2857 BPF_EXIT_INSN(),
2858 },
2859 .fixup_prog = { 1 },
2860 .result = ACCEPT,
2861 .retval = 42,
2862 },
2863 {
2864 "runtime/jit: tail_call within bounds, prog loop",
2865 .insns = {
2866 BPF_MOV64_IMM(BPF_REG_3, 1),
2867 BPF_LD_MAP_FD(BPF_REG_2, 0),
2868 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2869 BPF_FUNC_tail_call),
2870 BPF_MOV64_IMM(BPF_REG_0, 1),
2871 BPF_EXIT_INSN(),
2872 },
2873 .fixup_prog = { 1 },
2874 .result = ACCEPT,
2875 .retval = 41,
2876 },
2877 {
2878 "runtime/jit: tail_call within bounds, no prog",
2879 .insns = {
2880 BPF_MOV64_IMM(BPF_REG_3, 2),
2881 BPF_LD_MAP_FD(BPF_REG_2, 0),
2882 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2883 BPF_FUNC_tail_call),
2884 BPF_MOV64_IMM(BPF_REG_0, 1),
2885 BPF_EXIT_INSN(),
2886 },
2887 .fixup_prog = { 1 },
2888 .result = ACCEPT,
2889 .retval = 1,
2890 },
2891 {
2892 "runtime/jit: tail_call out of bounds",
2893 .insns = {
2894 BPF_MOV64_IMM(BPF_REG_3, 256),
2895 BPF_LD_MAP_FD(BPF_REG_2, 0),
2896 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2897 BPF_FUNC_tail_call),
2898 BPF_MOV64_IMM(BPF_REG_0, 2),
2899 BPF_EXIT_INSN(),
2900 },
2901 .fixup_prog = { 1 },
2902 .result = ACCEPT,
2903 .retval = 2,
2904 },
2905 {
Daniel Borkmann16338a92018-02-23 01:03:43 +01002906 "runtime/jit: pass negative index to tail_call",
2907 .insns = {
2908 BPF_MOV64_IMM(BPF_REG_3, -1),
2909 BPF_LD_MAP_FD(BPF_REG_2, 0),
2910 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2911 BPF_FUNC_tail_call),
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002912 BPF_MOV64_IMM(BPF_REG_0, 2),
Daniel Borkmann16338a92018-02-23 01:03:43 +01002913 BPF_EXIT_INSN(),
2914 },
2915 .fixup_prog = { 1 },
2916 .result = ACCEPT,
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002917 .retval = 2,
Daniel Borkmann16338a92018-02-23 01:03:43 +01002918 },
2919 {
2920 "runtime/jit: pass > 32bit index to tail_call",
2921 .insns = {
2922 BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
2923 BPF_LD_MAP_FD(BPF_REG_2, 0),
2924 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2925 BPF_FUNC_tail_call),
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002926 BPF_MOV64_IMM(BPF_REG_0, 2),
Daniel Borkmann16338a92018-02-23 01:03:43 +01002927 BPF_EXIT_INSN(),
2928 },
2929 .fixup_prog = { 2 },
2930 .result = ACCEPT,
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002931 .retval = 42,
Daniel Borkmann16338a92018-02-23 01:03:43 +01002932 },
2933 {
Yonghong Song332270f2017-04-29 22:52:42 -07002934 "stack pointer arithmetic",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002935 .insns = {
Yonghong Song332270f2017-04-29 22:52:42 -07002936 BPF_MOV64_IMM(BPF_REG_1, 4),
2937 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2938 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2942 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2943 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2944 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2946 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002947 BPF_MOV64_IMM(BPF_REG_0, 0),
2948 BPF_EXIT_INSN(),
2949 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002950 .result = ACCEPT,
2951 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002952 {
2953 "raw_stack: no skb_load_bytes",
2954 .insns = {
2955 BPF_MOV64_IMM(BPF_REG_2, 4),
2956 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2957 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2958 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2959 BPF_MOV64_IMM(BPF_REG_4, 8),
2960 /* Call to skb_load_bytes() omitted. */
2961 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2962 BPF_EXIT_INSN(),
2963 },
2964 .result = REJECT,
2965 .errstr = "invalid read from stack off -8+0 size 8",
2966 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2967 },
2968 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002969 "raw_stack: skb_load_bytes, negative len",
2970 .insns = {
2971 BPF_MOV64_IMM(BPF_REG_2, 4),
2972 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2973 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2974 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2975 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002976 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2977 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002978 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2979 BPF_EXIT_INSN(),
2980 },
2981 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002982 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002983 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2984 },
2985 {
2986 "raw_stack: skb_load_bytes, negative len 2",
2987 .insns = {
2988 BPF_MOV64_IMM(BPF_REG_2, 4),
2989 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2990 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2991 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2992 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002993 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2994 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002995 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2996 BPF_EXIT_INSN(),
2997 },
2998 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002999 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003000 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3001 },
3002 {
3003 "raw_stack: skb_load_bytes, zero len",
3004 .insns = {
3005 BPF_MOV64_IMM(BPF_REG_2, 4),
3006 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3008 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3009 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003010 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3011 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003012 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3013 BPF_EXIT_INSN(),
3014 },
3015 .result = REJECT,
3016 .errstr = "invalid stack type R3",
3017 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3018 },
3019 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003020 "raw_stack: skb_load_bytes, no init",
3021 .insns = {
3022 BPF_MOV64_IMM(BPF_REG_2, 4),
3023 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3024 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3025 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3026 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003027 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3028 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003029 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3030 BPF_EXIT_INSN(),
3031 },
3032 .result = ACCEPT,
3033 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3034 },
3035 {
3036 "raw_stack: skb_load_bytes, init",
3037 .insns = {
3038 BPF_MOV64_IMM(BPF_REG_2, 4),
3039 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3040 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3041 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
3042 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3043 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003044 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3045 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003046 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3047 BPF_EXIT_INSN(),
3048 },
3049 .result = ACCEPT,
3050 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3051 },
3052 {
3053 "raw_stack: skb_load_bytes, spilled regs around bounds",
3054 .insns = {
3055 BPF_MOV64_IMM(BPF_REG_2, 4),
3056 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003058 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3059 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003060 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3061 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003062 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3063 BPF_FUNC_skb_load_bytes),
3064 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3065 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003066 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3067 offsetof(struct __sk_buff, mark)),
3068 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3069 offsetof(struct __sk_buff, priority)),
3070 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3071 BPF_EXIT_INSN(),
3072 },
3073 .result = ACCEPT,
3074 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3075 },
3076 {
3077 "raw_stack: skb_load_bytes, spilled regs corruption",
3078 .insns = {
3079 BPF_MOV64_IMM(BPF_REG_2, 4),
3080 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003082 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003083 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3084 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003085 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3086 BPF_FUNC_skb_load_bytes),
3087 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003088 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3089 offsetof(struct __sk_buff, mark)),
3090 BPF_EXIT_INSN(),
3091 },
3092 .result = REJECT,
3093 .errstr = "R0 invalid mem access 'inv'",
3094 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3095 },
3096 {
3097 "raw_stack: skb_load_bytes, spilled regs corruption 2",
3098 .insns = {
3099 BPF_MOV64_IMM(BPF_REG_2, 4),
3100 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3101 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003102 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3103 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3104 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003105 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3106 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003107 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3108 BPF_FUNC_skb_load_bytes),
3109 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3110 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3111 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003112 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3113 offsetof(struct __sk_buff, mark)),
3114 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3115 offsetof(struct __sk_buff, priority)),
3116 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3117 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
3118 offsetof(struct __sk_buff, pkt_type)),
3119 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3120 BPF_EXIT_INSN(),
3121 },
3122 .result = REJECT,
3123 .errstr = "R3 invalid mem access 'inv'",
3124 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3125 },
3126 {
3127 "raw_stack: skb_load_bytes, spilled regs + data",
3128 .insns = {
3129 BPF_MOV64_IMM(BPF_REG_2, 4),
3130 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3131 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003132 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3133 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3134 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003135 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3136 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003137 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3138 BPF_FUNC_skb_load_bytes),
3139 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3140 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3141 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003142 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3143 offsetof(struct __sk_buff, mark)),
3144 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3145 offsetof(struct __sk_buff, priority)),
3146 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3147 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3148 BPF_EXIT_INSN(),
3149 },
3150 .result = ACCEPT,
3151 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3152 },
3153 {
3154 "raw_stack: skb_load_bytes, invalid access 1",
3155 .insns = {
3156 BPF_MOV64_IMM(BPF_REG_2, 4),
3157 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3158 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
3159 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3160 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003161 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3162 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003163 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3164 BPF_EXIT_INSN(),
3165 },
3166 .result = REJECT,
3167 .errstr = "invalid stack type R3 off=-513 access_size=8",
3168 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3169 },
3170 {
3171 "raw_stack: skb_load_bytes, invalid access 2",
3172 .insns = {
3173 BPF_MOV64_IMM(BPF_REG_2, 4),
3174 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3175 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3176 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3177 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003178 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3179 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003180 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3181 BPF_EXIT_INSN(),
3182 },
3183 .result = REJECT,
3184 .errstr = "invalid stack type R3 off=-1 access_size=8",
3185 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3186 },
3187 {
3188 "raw_stack: skb_load_bytes, invalid access 3",
3189 .insns = {
3190 BPF_MOV64_IMM(BPF_REG_2, 4),
3191 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3192 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
3193 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3194 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003195 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3196 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003197 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3198 BPF_EXIT_INSN(),
3199 },
3200 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003201 .errstr = "R4 min value is negative",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003202 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3203 },
3204 {
3205 "raw_stack: skb_load_bytes, invalid access 4",
3206 .insns = {
3207 BPF_MOV64_IMM(BPF_REG_2, 4),
3208 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3209 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3210 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3211 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003212 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3213 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003214 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3215 BPF_EXIT_INSN(),
3216 },
3217 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003218 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003219 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3220 },
3221 {
3222 "raw_stack: skb_load_bytes, invalid access 5",
3223 .insns = {
3224 BPF_MOV64_IMM(BPF_REG_2, 4),
3225 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3226 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3227 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3228 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003229 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3230 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003231 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3232 BPF_EXIT_INSN(),
3233 },
3234 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003235 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003236 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3237 },
3238 {
3239 "raw_stack: skb_load_bytes, invalid access 6",
3240 .insns = {
3241 BPF_MOV64_IMM(BPF_REG_2, 4),
3242 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3243 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3244 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3245 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003246 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3247 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003248 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3249 BPF_EXIT_INSN(),
3250 },
3251 .result = REJECT,
3252 .errstr = "invalid stack type R3 off=-512 access_size=0",
3253 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3254 },
3255 {
3256 "raw_stack: skb_load_bytes, large access",
3257 .insns = {
3258 BPF_MOV64_IMM(BPF_REG_2, 4),
3259 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3261 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3262 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003263 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3264 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003265 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3266 BPF_EXIT_INSN(),
3267 },
3268 .result = ACCEPT,
3269 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3270 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003271 {
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01003272 "context stores via ST",
3273 .insns = {
3274 BPF_MOV64_IMM(BPF_REG_0, 0),
3275 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
3276 BPF_EXIT_INSN(),
3277 },
3278 .errstr = "BPF_ST stores into R1 context is not allowed",
3279 .result = REJECT,
3280 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3281 },
3282 {
3283 "context stores via XADD",
3284 .insns = {
3285 BPF_MOV64_IMM(BPF_REG_0, 0),
3286 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
3287 BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
3288 BPF_EXIT_INSN(),
3289 },
3290 .errstr = "BPF_XADD stores into R1 context is not allowed",
3291 .result = REJECT,
3292 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3293 },
3294 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003295 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003296 .insns = {
3297 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3298 offsetof(struct __sk_buff, data)),
3299 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3300 offsetof(struct __sk_buff, data_end)),
3301 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3303 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3304 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3305 BPF_MOV64_IMM(BPF_REG_0, 0),
3306 BPF_EXIT_INSN(),
3307 },
3308 .result = ACCEPT,
3309 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3310 },
3311 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003312 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003313 .insns = {
3314 BPF_MOV64_IMM(BPF_REG_0, 1),
3315 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
3316 offsetof(struct __sk_buff, data_end)),
3317 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3318 offsetof(struct __sk_buff, data)),
3319 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3320 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
3321 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
3322 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
3323 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
3324 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
3325 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3326 offsetof(struct __sk_buff, data)),
3327 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08003328 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3329 offsetof(struct __sk_buff, len)),
Edward Cree1f9ab382017-08-07 15:29:11 +01003330 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
3331 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003332 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
3333 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
3334 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
3335 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
3336 offsetof(struct __sk_buff, data_end)),
3337 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3338 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
3339 BPF_MOV64_IMM(BPF_REG_0, 0),
3340 BPF_EXIT_INSN(),
3341 },
3342 .result = ACCEPT,
3343 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3344 },
3345 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003346 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003347 .insns = {
3348 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3349 offsetof(struct __sk_buff, data)),
3350 BPF_MOV64_IMM(BPF_REG_0, 0),
3351 BPF_EXIT_INSN(),
3352 },
3353 .errstr = "invalid bpf_context access off=76",
3354 .result = REJECT,
3355 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
3356 },
3357 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003358 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003359 .insns = {
3360 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3361 offsetof(struct __sk_buff, data)),
3362 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3363 offsetof(struct __sk_buff, data_end)),
3364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3366 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3367 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3368 BPF_MOV64_IMM(BPF_REG_0, 0),
3369 BPF_EXIT_INSN(),
3370 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003371 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003372 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3373 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003374 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02003375 "direct packet access: test5 (pkt_end >= reg, good access)",
3376 .insns = {
3377 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3378 offsetof(struct __sk_buff, data)),
3379 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3380 offsetof(struct __sk_buff, data_end)),
3381 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3382 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3383 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3384 BPF_MOV64_IMM(BPF_REG_0, 1),
3385 BPF_EXIT_INSN(),
3386 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3387 BPF_MOV64_IMM(BPF_REG_0, 0),
3388 BPF_EXIT_INSN(),
3389 },
3390 .result = ACCEPT,
3391 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3392 },
3393 {
3394 "direct packet access: test6 (pkt_end >= reg, bad access)",
3395 .insns = {
3396 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3397 offsetof(struct __sk_buff, data)),
3398 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3399 offsetof(struct __sk_buff, data_end)),
3400 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3401 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3402 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3403 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3404 BPF_MOV64_IMM(BPF_REG_0, 1),
3405 BPF_EXIT_INSN(),
3406 BPF_MOV64_IMM(BPF_REG_0, 0),
3407 BPF_EXIT_INSN(),
3408 },
3409 .errstr = "invalid access to packet",
3410 .result = REJECT,
3411 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3412 },
3413 {
3414 "direct packet access: test7 (pkt_end >= reg, both accesses)",
3415 .insns = {
3416 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3417 offsetof(struct __sk_buff, data)),
3418 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3419 offsetof(struct __sk_buff, data_end)),
3420 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3422 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3423 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3424 BPF_MOV64_IMM(BPF_REG_0, 1),
3425 BPF_EXIT_INSN(),
3426 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3427 BPF_MOV64_IMM(BPF_REG_0, 0),
3428 BPF_EXIT_INSN(),
3429 },
3430 .errstr = "invalid access to packet",
3431 .result = REJECT,
3432 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3433 },
3434 {
3435 "direct packet access: test8 (double test, variant 1)",
3436 .insns = {
3437 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3438 offsetof(struct __sk_buff, data)),
3439 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3440 offsetof(struct __sk_buff, data_end)),
3441 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3442 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3443 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
3444 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3445 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3446 BPF_MOV64_IMM(BPF_REG_0, 1),
3447 BPF_EXIT_INSN(),
3448 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3449 BPF_MOV64_IMM(BPF_REG_0, 0),
3450 BPF_EXIT_INSN(),
3451 },
3452 .result = ACCEPT,
3453 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3454 },
3455 {
3456 "direct packet access: test9 (double test, variant 2)",
3457 .insns = {
3458 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3459 offsetof(struct __sk_buff, data)),
3460 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3461 offsetof(struct __sk_buff, data_end)),
3462 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3463 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3464 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3465 BPF_MOV64_IMM(BPF_REG_0, 1),
3466 BPF_EXIT_INSN(),
3467 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3468 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3469 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3470 BPF_MOV64_IMM(BPF_REG_0, 0),
3471 BPF_EXIT_INSN(),
3472 },
3473 .result = ACCEPT,
3474 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3475 },
3476 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003477 "direct packet access: test10 (write invalid)",
3478 .insns = {
3479 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3480 offsetof(struct __sk_buff, data)),
3481 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3482 offsetof(struct __sk_buff, data_end)),
3483 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3484 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3485 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3486 BPF_MOV64_IMM(BPF_REG_0, 0),
3487 BPF_EXIT_INSN(),
3488 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3489 BPF_MOV64_IMM(BPF_REG_0, 0),
3490 BPF_EXIT_INSN(),
3491 },
3492 .errstr = "invalid access to packet",
3493 .result = REJECT,
3494 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3495 },
3496 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003497 "direct packet access: test11 (shift, good access)",
3498 .insns = {
3499 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3500 offsetof(struct __sk_buff, data)),
3501 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3502 offsetof(struct __sk_buff, data_end)),
3503 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3504 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3505 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3506 BPF_MOV64_IMM(BPF_REG_3, 144),
3507 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3508 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3509 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
3510 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3511 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3512 BPF_MOV64_IMM(BPF_REG_0, 1),
3513 BPF_EXIT_INSN(),
3514 BPF_MOV64_IMM(BPF_REG_0, 0),
3515 BPF_EXIT_INSN(),
3516 },
3517 .result = ACCEPT,
3518 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003519 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003520 },
3521 {
3522 "direct packet access: test12 (and, good access)",
3523 .insns = {
3524 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3525 offsetof(struct __sk_buff, data)),
3526 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3527 offsetof(struct __sk_buff, data_end)),
3528 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3529 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3530 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3531 BPF_MOV64_IMM(BPF_REG_3, 144),
3532 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3534 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3535 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3536 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3537 BPF_MOV64_IMM(BPF_REG_0, 1),
3538 BPF_EXIT_INSN(),
3539 BPF_MOV64_IMM(BPF_REG_0, 0),
3540 BPF_EXIT_INSN(),
3541 },
3542 .result = ACCEPT,
3543 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003544 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003545 },
3546 {
3547 "direct packet access: test13 (branches, good access)",
3548 .insns = {
3549 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3550 offsetof(struct __sk_buff, data)),
3551 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3552 offsetof(struct __sk_buff, data_end)),
3553 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3554 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3555 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
3556 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3557 offsetof(struct __sk_buff, mark)),
3558 BPF_MOV64_IMM(BPF_REG_4, 1),
3559 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
3560 BPF_MOV64_IMM(BPF_REG_3, 14),
3561 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
3562 BPF_MOV64_IMM(BPF_REG_3, 24),
3563 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3565 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3566 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3567 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3568 BPF_MOV64_IMM(BPF_REG_0, 1),
3569 BPF_EXIT_INSN(),
3570 BPF_MOV64_IMM(BPF_REG_0, 0),
3571 BPF_EXIT_INSN(),
3572 },
3573 .result = ACCEPT,
3574 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003575 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003576 },
3577 {
William Tu63dfef72017-02-04 08:37:29 -08003578 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
3579 .insns = {
3580 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3581 offsetof(struct __sk_buff, data)),
3582 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3583 offsetof(struct __sk_buff, data_end)),
3584 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3585 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3586 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
3587 BPF_MOV64_IMM(BPF_REG_5, 12),
3588 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
3589 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3590 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3591 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
3592 BPF_MOV64_IMM(BPF_REG_0, 1),
3593 BPF_EXIT_INSN(),
3594 BPF_MOV64_IMM(BPF_REG_0, 0),
3595 BPF_EXIT_INSN(),
3596 },
3597 .result = ACCEPT,
3598 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003599 .retval = 1,
William Tu63dfef72017-02-04 08:37:29 -08003600 },
3601 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003602 "direct packet access: test15 (spill with xadd)",
3603 .insns = {
3604 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3605 offsetof(struct __sk_buff, data)),
3606 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3607 offsetof(struct __sk_buff, data_end)),
3608 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3610 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3611 BPF_MOV64_IMM(BPF_REG_5, 4096),
3612 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
3613 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
3614 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
3615 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
3616 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
3617 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
3618 BPF_MOV64_IMM(BPF_REG_0, 0),
3619 BPF_EXIT_INSN(),
3620 },
3621 .errstr = "R2 invalid mem access 'inv'",
3622 .result = REJECT,
3623 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3624 },
3625 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02003626 "direct packet access: test16 (arith on data_end)",
3627 .insns = {
3628 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3629 offsetof(struct __sk_buff, data)),
3630 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3631 offsetof(struct __sk_buff, data_end)),
3632 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3633 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
3635 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3636 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3637 BPF_MOV64_IMM(BPF_REG_0, 0),
3638 BPF_EXIT_INSN(),
3639 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08003640 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmann728a8532017-04-27 01:39:32 +02003641 .result = REJECT,
3642 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3643 },
3644 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003645 "direct packet access: test17 (pruning, alignment)",
3646 .insns = {
3647 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3648 offsetof(struct __sk_buff, data)),
3649 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3650 offsetof(struct __sk_buff, data_end)),
3651 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3652 offsetof(struct __sk_buff, mark)),
3653 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
3655 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
3656 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3657 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
3658 BPF_MOV64_IMM(BPF_REG_0, 0),
3659 BPF_EXIT_INSN(),
3660 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3661 BPF_JMP_A(-6),
3662 },
Edward Creef65b1842017-08-07 15:27:12 +01003663 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003664 .result = REJECT,
3665 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3666 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
3667 },
3668 {
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003669 "direct packet access: test18 (imm += pkt_ptr, 1)",
3670 .insns = {
3671 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3672 offsetof(struct __sk_buff, data)),
3673 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3674 offsetof(struct __sk_buff, data_end)),
3675 BPF_MOV64_IMM(BPF_REG_0, 8),
3676 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3677 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3678 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3679 BPF_MOV64_IMM(BPF_REG_0, 0),
3680 BPF_EXIT_INSN(),
3681 },
3682 .result = ACCEPT,
3683 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3684 },
3685 {
3686 "direct packet access: test19 (imm += pkt_ptr, 2)",
3687 .insns = {
3688 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3689 offsetof(struct __sk_buff, data)),
3690 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3691 offsetof(struct __sk_buff, data_end)),
3692 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3694 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
3695 BPF_MOV64_IMM(BPF_REG_4, 4),
3696 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3697 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
3698 BPF_MOV64_IMM(BPF_REG_0, 0),
3699 BPF_EXIT_INSN(),
3700 },
3701 .result = ACCEPT,
3702 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3703 },
3704 {
3705 "direct packet access: test20 (x += pkt_ptr, 1)",
3706 .insns = {
3707 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3708 offsetof(struct __sk_buff, data)),
3709 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3710 offsetof(struct __sk_buff, data_end)),
3711 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3712 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3713 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003714 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003715 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3716 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3717 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003719 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3720 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3721 BPF_MOV64_IMM(BPF_REG_0, 0),
3722 BPF_EXIT_INSN(),
3723 },
3724 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3725 .result = ACCEPT,
3726 },
3727 {
3728 "direct packet access: test21 (x += pkt_ptr, 2)",
3729 .insns = {
3730 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3731 offsetof(struct __sk_buff, data)),
3732 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3733 offsetof(struct __sk_buff, data_end)),
3734 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3735 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3736 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3737 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3738 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3739 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003740 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003741 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3742 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003743 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003744 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3745 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3746 BPF_MOV64_IMM(BPF_REG_0, 0),
3747 BPF_EXIT_INSN(),
3748 },
3749 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3750 .result = ACCEPT,
3751 },
3752 {
3753 "direct packet access: test22 (x += pkt_ptr, 3)",
3754 .insns = {
3755 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3756 offsetof(struct __sk_buff, data)),
3757 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3758 offsetof(struct __sk_buff, data_end)),
3759 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3760 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3761 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3762 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3763 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3764 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3765 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3766 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3767 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3768 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003769 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003770 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3771 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3773 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3774 BPF_MOV64_IMM(BPF_REG_2, 1),
3775 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3776 BPF_MOV64_IMM(BPF_REG_0, 0),
3777 BPF_EXIT_INSN(),
3778 },
3779 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3780 .result = ACCEPT,
3781 },
3782 {
3783 "direct packet access: test23 (x += pkt_ptr, 4)",
3784 .insns = {
3785 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3786 offsetof(struct __sk_buff, data)),
3787 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3788 offsetof(struct __sk_buff, data_end)),
3789 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3790 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3791 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3792 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3793 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3794 BPF_MOV64_IMM(BPF_REG_0, 31),
3795 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3796 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3797 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3798 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3799 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3800 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3801 BPF_MOV64_IMM(BPF_REG_0, 0),
3802 BPF_EXIT_INSN(),
3803 },
3804 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3805 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003806 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003807 },
3808 {
3809 "direct packet access: test24 (x += pkt_ptr, 5)",
3810 .insns = {
3811 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3812 offsetof(struct __sk_buff, data)),
3813 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3814 offsetof(struct __sk_buff, data_end)),
3815 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3816 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3817 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3818 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3819 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3820 BPF_MOV64_IMM(BPF_REG_0, 64),
3821 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3822 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3823 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
Edward Cree1f9ab382017-08-07 15:29:11 +01003824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003825 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3826 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3827 BPF_MOV64_IMM(BPF_REG_0, 0),
3828 BPF_EXIT_INSN(),
3829 },
3830 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3831 .result = ACCEPT,
3832 },
3833 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02003834 "direct packet access: test25 (marking on <, good access)",
3835 .insns = {
3836 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3837 offsetof(struct __sk_buff, data)),
3838 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3839 offsetof(struct __sk_buff, data_end)),
3840 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3842 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
3843 BPF_MOV64_IMM(BPF_REG_0, 0),
3844 BPF_EXIT_INSN(),
3845 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3846 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3847 },
3848 .result = ACCEPT,
3849 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3850 },
3851 {
3852 "direct packet access: test26 (marking on <, bad access)",
3853 .insns = {
3854 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3855 offsetof(struct __sk_buff, data)),
3856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3857 offsetof(struct __sk_buff, data_end)),
3858 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3860 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
3861 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3862 BPF_MOV64_IMM(BPF_REG_0, 0),
3863 BPF_EXIT_INSN(),
3864 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
3865 },
3866 .result = REJECT,
3867 .errstr = "invalid access to packet",
3868 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3869 },
3870 {
3871 "direct packet access: test27 (marking on <=, good access)",
3872 .insns = {
3873 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3874 offsetof(struct __sk_buff, data)),
3875 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3876 offsetof(struct __sk_buff, data_end)),
3877 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3879 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
3880 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3881 BPF_MOV64_IMM(BPF_REG_0, 1),
3882 BPF_EXIT_INSN(),
3883 },
3884 .result = ACCEPT,
3885 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003886 .retval = 1,
Daniel Borkmann31e482b2017-08-10 01:40:03 +02003887 },
3888 {
3889 "direct packet access: test28 (marking on <=, bad access)",
3890 .insns = {
3891 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3892 offsetof(struct __sk_buff, data)),
3893 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3894 offsetof(struct __sk_buff, data_end)),
3895 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3896 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3897 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
3898 BPF_MOV64_IMM(BPF_REG_0, 1),
3899 BPF_EXIT_INSN(),
3900 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3901 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3902 },
3903 .result = REJECT,
3904 .errstr = "invalid access to packet",
3905 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3906 },
3907 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003908 "helper access to packet: test1, valid packet_ptr range",
3909 .insns = {
3910 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3911 offsetof(struct xdp_md, data)),
3912 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3913 offsetof(struct xdp_md, data_end)),
3914 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3915 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3916 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3917 BPF_LD_MAP_FD(BPF_REG_1, 0),
3918 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3919 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003920 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3921 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003922 BPF_MOV64_IMM(BPF_REG_0, 0),
3923 BPF_EXIT_INSN(),
3924 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003925 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003926 .result_unpriv = ACCEPT,
3927 .result = ACCEPT,
3928 .prog_type = BPF_PROG_TYPE_XDP,
3929 },
3930 {
3931 "helper access to packet: test2, unchecked packet_ptr",
3932 .insns = {
3933 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3934 offsetof(struct xdp_md, data)),
3935 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003936 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3937 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003938 BPF_MOV64_IMM(BPF_REG_0, 0),
3939 BPF_EXIT_INSN(),
3940 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003941 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003942 .result = REJECT,
3943 .errstr = "invalid access to packet",
3944 .prog_type = BPF_PROG_TYPE_XDP,
3945 },
3946 {
3947 "helper access to packet: test3, variable add",
3948 .insns = {
3949 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3950 offsetof(struct xdp_md, data)),
3951 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3952 offsetof(struct xdp_md, data_end)),
3953 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3954 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3955 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3956 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3957 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3958 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3959 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3960 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3961 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3962 BPF_LD_MAP_FD(BPF_REG_1, 0),
3963 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003964 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3965 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003966 BPF_MOV64_IMM(BPF_REG_0, 0),
3967 BPF_EXIT_INSN(),
3968 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003969 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003970 .result = ACCEPT,
3971 .prog_type = BPF_PROG_TYPE_XDP,
3972 },
3973 {
3974 "helper access to packet: test4, packet_ptr with bad range",
3975 .insns = {
3976 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3977 offsetof(struct xdp_md, data)),
3978 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3979 offsetof(struct xdp_md, data_end)),
3980 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3981 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3982 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3983 BPF_MOV64_IMM(BPF_REG_0, 0),
3984 BPF_EXIT_INSN(),
3985 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003986 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3987 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003988 BPF_MOV64_IMM(BPF_REG_0, 0),
3989 BPF_EXIT_INSN(),
3990 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003991 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003992 .result = REJECT,
3993 .errstr = "invalid access to packet",
3994 .prog_type = BPF_PROG_TYPE_XDP,
3995 },
3996 {
3997 "helper access to packet: test5, packet_ptr with too short range",
3998 .insns = {
3999 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4000 offsetof(struct xdp_md, data)),
4001 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4002 offsetof(struct xdp_md, data_end)),
4003 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4004 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4005 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4006 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4007 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004008 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4009 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07004010 BPF_MOV64_IMM(BPF_REG_0, 0),
4011 BPF_EXIT_INSN(),
4012 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004013 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07004014 .result = REJECT,
4015 .errstr = "invalid access to packet",
4016 .prog_type = BPF_PROG_TYPE_XDP,
4017 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004018 {
4019 "helper access to packet: test6, cls valid packet_ptr range",
4020 .insns = {
4021 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4022 offsetof(struct __sk_buff, data)),
4023 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4024 offsetof(struct __sk_buff, data_end)),
4025 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4027 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
4028 BPF_LD_MAP_FD(BPF_REG_1, 0),
4029 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
4030 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004031 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4032 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004033 BPF_MOV64_IMM(BPF_REG_0, 0),
4034 BPF_EXIT_INSN(),
4035 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004036 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004037 .result = ACCEPT,
4038 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4039 },
4040 {
4041 "helper access to packet: test7, cls unchecked packet_ptr",
4042 .insns = {
4043 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4044 offsetof(struct __sk_buff, data)),
4045 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4047 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004048 BPF_MOV64_IMM(BPF_REG_0, 0),
4049 BPF_EXIT_INSN(),
4050 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004051 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004052 .result = REJECT,
4053 .errstr = "invalid access to packet",
4054 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4055 },
4056 {
4057 "helper access to packet: test8, cls variable add",
4058 .insns = {
4059 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4060 offsetof(struct __sk_buff, data)),
4061 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4062 offsetof(struct __sk_buff, data_end)),
4063 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4064 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
4065 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
4066 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
4067 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4068 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
4069 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
4070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
4071 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
4072 BPF_LD_MAP_FD(BPF_REG_1, 0),
4073 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004074 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4075 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004076 BPF_MOV64_IMM(BPF_REG_0, 0),
4077 BPF_EXIT_INSN(),
4078 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004079 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004080 .result = ACCEPT,
4081 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4082 },
4083 {
4084 "helper access to packet: test9, cls packet_ptr with bad range",
4085 .insns = {
4086 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4087 offsetof(struct __sk_buff, data)),
4088 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4089 offsetof(struct __sk_buff, data_end)),
4090 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4091 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
4092 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
4093 BPF_MOV64_IMM(BPF_REG_0, 0),
4094 BPF_EXIT_INSN(),
4095 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004096 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4097 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004098 BPF_MOV64_IMM(BPF_REG_0, 0),
4099 BPF_EXIT_INSN(),
4100 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004101 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004102 .result = REJECT,
4103 .errstr = "invalid access to packet",
4104 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4105 },
4106 {
4107 "helper access to packet: test10, cls packet_ptr with too short range",
4108 .insns = {
4109 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4110 offsetof(struct __sk_buff, data)),
4111 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4112 offsetof(struct __sk_buff, data_end)),
4113 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4114 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4116 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4117 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004118 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4119 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004120 BPF_MOV64_IMM(BPF_REG_0, 0),
4121 BPF_EXIT_INSN(),
4122 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004123 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004124 .result = REJECT,
4125 .errstr = "invalid access to packet",
4126 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4127 },
4128 {
4129 "helper access to packet: test11, cls unsuitable helper 1",
4130 .insns = {
4131 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4132 offsetof(struct __sk_buff, data)),
4133 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4134 offsetof(struct __sk_buff, data_end)),
4135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4136 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4137 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
4138 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
4139 BPF_MOV64_IMM(BPF_REG_2, 0),
4140 BPF_MOV64_IMM(BPF_REG_4, 42),
4141 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004142 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4143 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004144 BPF_MOV64_IMM(BPF_REG_0, 0),
4145 BPF_EXIT_INSN(),
4146 },
4147 .result = REJECT,
4148 .errstr = "helper access to the packet",
4149 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4150 },
4151 {
4152 "helper access to packet: test12, cls unsuitable helper 2",
4153 .insns = {
4154 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4155 offsetof(struct __sk_buff, data)),
4156 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4157 offsetof(struct __sk_buff, data_end)),
4158 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4159 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
4160 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
4161 BPF_MOV64_IMM(BPF_REG_2, 0),
4162 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4164 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004165 BPF_MOV64_IMM(BPF_REG_0, 0),
4166 BPF_EXIT_INSN(),
4167 },
4168 .result = REJECT,
4169 .errstr = "helper access to the packet",
4170 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4171 },
4172 {
4173 "helper access to packet: test13, cls helper ok",
4174 .insns = {
4175 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4176 offsetof(struct __sk_buff, data)),
4177 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4178 offsetof(struct __sk_buff, data_end)),
4179 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4180 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4182 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4183 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4184 BPF_MOV64_IMM(BPF_REG_2, 4),
4185 BPF_MOV64_IMM(BPF_REG_3, 0),
4186 BPF_MOV64_IMM(BPF_REG_4, 0),
4187 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4189 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004190 BPF_MOV64_IMM(BPF_REG_0, 0),
4191 BPF_EXIT_INSN(),
4192 },
4193 .result = ACCEPT,
4194 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4195 },
4196 {
Edward Creef65b1842017-08-07 15:27:12 +01004197 "helper access to packet: test14, cls helper ok sub",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004198 .insns = {
4199 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4200 offsetof(struct __sk_buff, data)),
4201 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4202 offsetof(struct __sk_buff, data_end)),
4203 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4204 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4205 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4206 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4207 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
4208 BPF_MOV64_IMM(BPF_REG_2, 4),
4209 BPF_MOV64_IMM(BPF_REG_3, 0),
4210 BPF_MOV64_IMM(BPF_REG_4, 0),
4211 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004212 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4213 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004214 BPF_MOV64_IMM(BPF_REG_0, 0),
4215 BPF_EXIT_INSN(),
4216 },
Edward Creef65b1842017-08-07 15:27:12 +01004217 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004218 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4219 },
4220 {
Edward Creef65b1842017-08-07 15:27:12 +01004221 "helper access to packet: test15, cls helper fail sub",
4222 .insns = {
4223 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4224 offsetof(struct __sk_buff, data)),
4225 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4226 offsetof(struct __sk_buff, data_end)),
4227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4228 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4230 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4231 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
4232 BPF_MOV64_IMM(BPF_REG_2, 4),
4233 BPF_MOV64_IMM(BPF_REG_3, 0),
4234 BPF_MOV64_IMM(BPF_REG_4, 0),
4235 BPF_MOV64_IMM(BPF_REG_5, 0),
4236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4237 BPF_FUNC_csum_diff),
4238 BPF_MOV64_IMM(BPF_REG_0, 0),
4239 BPF_EXIT_INSN(),
4240 },
4241 .result = REJECT,
4242 .errstr = "invalid access to packet",
4243 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4244 },
4245 {
4246 "helper access to packet: test16, cls helper fail range 1",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004247 .insns = {
4248 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4249 offsetof(struct __sk_buff, data)),
4250 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4251 offsetof(struct __sk_buff, data_end)),
4252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4253 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4255 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4256 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4257 BPF_MOV64_IMM(BPF_REG_2, 8),
4258 BPF_MOV64_IMM(BPF_REG_3, 0),
4259 BPF_MOV64_IMM(BPF_REG_4, 0),
4260 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4262 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004263 BPF_MOV64_IMM(BPF_REG_0, 0),
4264 BPF_EXIT_INSN(),
4265 },
4266 .result = REJECT,
4267 .errstr = "invalid access to packet",
4268 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4269 },
4270 {
Edward Creef65b1842017-08-07 15:27:12 +01004271 "helper access to packet: test17, cls helper fail range 2",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004272 .insns = {
4273 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4274 offsetof(struct __sk_buff, data)),
4275 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4276 offsetof(struct __sk_buff, data_end)),
4277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4278 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4280 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4281 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4282 BPF_MOV64_IMM(BPF_REG_2, -9),
4283 BPF_MOV64_IMM(BPF_REG_3, 0),
4284 BPF_MOV64_IMM(BPF_REG_4, 0),
4285 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004286 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4287 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004288 BPF_MOV64_IMM(BPF_REG_0, 0),
4289 BPF_EXIT_INSN(),
4290 },
4291 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004292 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004293 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4294 },
4295 {
Edward Creef65b1842017-08-07 15:27:12 +01004296 "helper access to packet: test18, cls helper fail range 3",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004297 .insns = {
4298 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4299 offsetof(struct __sk_buff, data)),
4300 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4301 offsetof(struct __sk_buff, data_end)),
4302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4303 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4305 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4306 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4307 BPF_MOV64_IMM(BPF_REG_2, ~0),
4308 BPF_MOV64_IMM(BPF_REG_3, 0),
4309 BPF_MOV64_IMM(BPF_REG_4, 0),
4310 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004311 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4312 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004313 BPF_MOV64_IMM(BPF_REG_0, 0),
4314 BPF_EXIT_INSN(),
4315 },
4316 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004317 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004318 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4319 },
4320 {
Yonghong Songb6ff6392017-11-12 14:49:11 -08004321 "helper access to packet: test19, cls helper range zero",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004322 .insns = {
4323 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4324 offsetof(struct __sk_buff, data)),
4325 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4326 offsetof(struct __sk_buff, data_end)),
4327 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4328 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4329 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4330 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4331 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4332 BPF_MOV64_IMM(BPF_REG_2, 0),
4333 BPF_MOV64_IMM(BPF_REG_3, 0),
4334 BPF_MOV64_IMM(BPF_REG_4, 0),
4335 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004336 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4337 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004338 BPF_MOV64_IMM(BPF_REG_0, 0),
4339 BPF_EXIT_INSN(),
4340 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08004341 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004342 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4343 },
4344 {
Edward Creef65b1842017-08-07 15:27:12 +01004345 "helper access to packet: test20, pkt end as input",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004346 .insns = {
4347 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4348 offsetof(struct __sk_buff, data)),
4349 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4350 offsetof(struct __sk_buff, data_end)),
4351 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4352 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4354 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4355 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
4356 BPF_MOV64_IMM(BPF_REG_2, 4),
4357 BPF_MOV64_IMM(BPF_REG_3, 0),
4358 BPF_MOV64_IMM(BPF_REG_4, 0),
4359 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004360 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4361 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004362 BPF_MOV64_IMM(BPF_REG_0, 0),
4363 BPF_EXIT_INSN(),
4364 },
4365 .result = REJECT,
4366 .errstr = "R1 type=pkt_end expected=fp",
4367 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4368 },
4369 {
Edward Creef65b1842017-08-07 15:27:12 +01004370 "helper access to packet: test21, wrong reg",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004371 .insns = {
4372 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4373 offsetof(struct __sk_buff, data)),
4374 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4375 offsetof(struct __sk_buff, data_end)),
4376 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4377 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4378 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4379 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4380 BPF_MOV64_IMM(BPF_REG_2, 4),
4381 BPF_MOV64_IMM(BPF_REG_3, 0),
4382 BPF_MOV64_IMM(BPF_REG_4, 0),
4383 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004384 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4385 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004386 BPF_MOV64_IMM(BPF_REG_0, 0),
4387 BPF_EXIT_INSN(),
4388 },
4389 .result = REJECT,
4390 .errstr = "invalid access to packet",
4391 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4392 },
Josef Bacik48461132016-09-28 10:54:32 -04004393 {
4394 "valid map access into an array with a constant",
4395 .insns = {
4396 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4397 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4398 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4399 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004400 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4401 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004402 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004403 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4404 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004405 BPF_EXIT_INSN(),
4406 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004407 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004408 .errstr_unpriv = "R0 leaks addr",
4409 .result_unpriv = REJECT,
4410 .result = ACCEPT,
4411 },
4412 {
4413 "valid map access into an array with a register",
4414 .insns = {
4415 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4416 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4417 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4418 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004419 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4420 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004421 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4422 BPF_MOV64_IMM(BPF_REG_1, 4),
4423 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4424 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004425 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4426 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004427 BPF_EXIT_INSN(),
4428 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004429 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004430 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004431 .result_unpriv = REJECT,
4432 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004433 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004434 },
4435 {
4436 "valid map access into an array with a variable",
4437 .insns = {
4438 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4439 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4440 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4441 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004442 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4443 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004444 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4445 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4446 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
4447 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4448 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004449 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4450 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004451 BPF_EXIT_INSN(),
4452 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004453 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004454 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004455 .result_unpriv = REJECT,
4456 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004457 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004458 },
4459 {
4460 "valid map access into an array with a signed variable",
4461 .insns = {
4462 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4463 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4464 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4465 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004466 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4467 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004468 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
4469 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4470 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
4471 BPF_MOV32_IMM(BPF_REG_1, 0),
4472 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4473 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4474 BPF_MOV32_IMM(BPF_REG_1, 0),
4475 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4476 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004477 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4478 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004479 BPF_EXIT_INSN(),
4480 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004481 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004482 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004483 .result_unpriv = REJECT,
4484 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004485 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004486 },
4487 {
4488 "invalid map access into an array with a constant",
4489 .insns = {
4490 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4491 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4493 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004494 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4495 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004496 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4497 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
4498 offsetof(struct test_val, foo)),
4499 BPF_EXIT_INSN(),
4500 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004501 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004502 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
4503 .result = REJECT,
4504 },
4505 {
4506 "invalid map access into an array with a register",
4507 .insns = {
4508 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4509 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4511 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004512 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4513 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004514 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4515 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
4516 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4517 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004518 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4519 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004520 BPF_EXIT_INSN(),
4521 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004522 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004523 .errstr = "R0 min value is outside of the array range",
4524 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004525 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004526 },
4527 {
4528 "invalid map access into an array with a variable",
4529 .insns = {
4530 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4531 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4533 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004534 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4535 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004536 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4537 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4538 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4539 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004540 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4541 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004542 BPF_EXIT_INSN(),
4543 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004544 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004545 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
Josef Bacik48461132016-09-28 10:54:32 -04004546 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004547 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004548 },
4549 {
4550 "invalid map access into an array with no floor check",
4551 .insns = {
4552 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4553 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4554 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4555 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004556 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4557 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004558 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
Edward Creef65b1842017-08-07 15:27:12 +01004559 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik48461132016-09-28 10:54:32 -04004560 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4561 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4562 BPF_MOV32_IMM(BPF_REG_1, 0),
4563 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4564 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004565 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4566 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004567 BPF_EXIT_INSN(),
4568 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004569 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004570 .errstr_unpriv = "R0 leaks addr",
4571 .errstr = "R0 unbounded memory access",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004572 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04004573 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004574 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004575 },
4576 {
4577 "invalid map access into an array with a invalid max check",
4578 .insns = {
4579 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4582 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004583 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4584 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4586 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4587 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
4588 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
4589 BPF_MOV32_IMM(BPF_REG_1, 0),
4590 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4591 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004592 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4593 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004594 BPF_EXIT_INSN(),
4595 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004596 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004597 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004598 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004599 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04004600 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004601 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004602 },
4603 {
4604 "invalid map access into an array with a invalid max check",
4605 .insns = {
4606 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4607 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4608 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4609 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004610 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4611 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004612 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4613 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4614 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4615 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4616 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4617 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004618 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4619 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004620 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4621 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004622 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
4623 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004624 BPF_EXIT_INSN(),
4625 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004626 .fixup_map2 = { 3, 11 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004627 .errstr = "R0 pointer += pointer",
Josef Bacik48461132016-09-28 10:54:32 -04004628 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004629 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004630 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02004631 {
4632 "multiple registers share map_lookup_elem result",
4633 .insns = {
4634 BPF_MOV64_IMM(BPF_REG_1, 10),
4635 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4636 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4638 BPF_LD_MAP_FD(BPF_REG_1, 0),
4639 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4640 BPF_FUNC_map_lookup_elem),
4641 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4642 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4643 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4644 BPF_EXIT_INSN(),
4645 },
4646 .fixup_map1 = { 4 },
4647 .result = ACCEPT,
4648 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4649 },
4650 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004651 "alu ops on ptr_to_map_value_or_null, 1",
4652 .insns = {
4653 BPF_MOV64_IMM(BPF_REG_1, 10),
4654 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4655 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4656 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4657 BPF_LD_MAP_FD(BPF_REG_1, 0),
4658 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4659 BPF_FUNC_map_lookup_elem),
4660 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
4662 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
4663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4664 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4665 BPF_EXIT_INSN(),
4666 },
4667 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004668 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004669 .result = REJECT,
4670 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4671 },
4672 {
4673 "alu ops on ptr_to_map_value_or_null, 2",
4674 .insns = {
4675 BPF_MOV64_IMM(BPF_REG_1, 10),
4676 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4677 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4679 BPF_LD_MAP_FD(BPF_REG_1, 0),
4680 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4681 BPF_FUNC_map_lookup_elem),
4682 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4683 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
4684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4685 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4686 BPF_EXIT_INSN(),
4687 },
4688 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004689 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004690 .result = REJECT,
4691 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4692 },
4693 {
4694 "alu ops on ptr_to_map_value_or_null, 3",
4695 .insns = {
4696 BPF_MOV64_IMM(BPF_REG_1, 10),
4697 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4698 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4700 BPF_LD_MAP_FD(BPF_REG_1, 0),
4701 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4702 BPF_FUNC_map_lookup_elem),
4703 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4704 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4705 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4706 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4707 BPF_EXIT_INSN(),
4708 },
4709 .fixup_map1 = { 4 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004710 .errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004711 .result = REJECT,
4712 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4713 },
4714 {
Thomas Graf57a09bf2016-10-18 19:51:19 +02004715 "invalid memory access with multiple map_lookup_elem calls",
4716 .insns = {
4717 BPF_MOV64_IMM(BPF_REG_1, 10),
4718 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4719 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4721 BPF_LD_MAP_FD(BPF_REG_1, 0),
4722 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4723 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4724 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4725 BPF_FUNC_map_lookup_elem),
4726 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4727 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4728 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4729 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4730 BPF_FUNC_map_lookup_elem),
4731 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4732 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4733 BPF_EXIT_INSN(),
4734 },
4735 .fixup_map1 = { 4 },
4736 .result = REJECT,
4737 .errstr = "R4 !read_ok",
4738 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4739 },
4740 {
4741 "valid indirect map_lookup_elem access with 2nd lookup in branch",
4742 .insns = {
4743 BPF_MOV64_IMM(BPF_REG_1, 10),
4744 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4745 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4747 BPF_LD_MAP_FD(BPF_REG_1, 0),
4748 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4749 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4750 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4751 BPF_FUNC_map_lookup_elem),
4752 BPF_MOV64_IMM(BPF_REG_2, 10),
4753 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
4754 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4755 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4756 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4757 BPF_FUNC_map_lookup_elem),
4758 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4759 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4760 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4761 BPF_EXIT_INSN(),
4762 },
4763 .fixup_map1 = { 4 },
4764 .result = ACCEPT,
4765 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4766 },
Josef Bacike9548902016-11-29 12:35:19 -05004767 {
4768 "invalid map access from else condition",
4769 .insns = {
4770 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4771 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4773 BPF_LD_MAP_FD(BPF_REG_1, 0),
4774 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
4775 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4776 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4777 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
4778 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4779 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4780 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4781 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
4782 BPF_EXIT_INSN(),
4783 },
4784 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004785 .errstr = "R0 unbounded memory access",
Josef Bacike9548902016-11-29 12:35:19 -05004786 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004787 .errstr_unpriv = "R0 leaks addr",
Josef Bacike9548902016-11-29 12:35:19 -05004788 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004789 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacike9548902016-11-29 12:35:19 -05004790 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08004791 {
4792 "constant register |= constant should keep constant type",
4793 .insns = {
4794 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4796 BPF_MOV64_IMM(BPF_REG_2, 34),
4797 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
4798 BPF_MOV64_IMM(BPF_REG_3, 0),
4799 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4800 BPF_EXIT_INSN(),
4801 },
4802 .result = ACCEPT,
4803 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4804 },
4805 {
4806 "constant register |= constant should not bypass stack boundary checks",
4807 .insns = {
4808 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4809 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4810 BPF_MOV64_IMM(BPF_REG_2, 34),
4811 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
4812 BPF_MOV64_IMM(BPF_REG_3, 0),
4813 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4814 BPF_EXIT_INSN(),
4815 },
4816 .errstr = "invalid stack type R1 off=-48 access_size=58",
4817 .result = REJECT,
4818 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4819 },
4820 {
4821 "constant register |= constant register should keep constant type",
4822 .insns = {
4823 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4824 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4825 BPF_MOV64_IMM(BPF_REG_2, 34),
4826 BPF_MOV64_IMM(BPF_REG_4, 13),
4827 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4828 BPF_MOV64_IMM(BPF_REG_3, 0),
4829 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4830 BPF_EXIT_INSN(),
4831 },
4832 .result = ACCEPT,
4833 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4834 },
4835 {
4836 "constant register |= constant register should not bypass stack boundary checks",
4837 .insns = {
4838 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4839 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
4840 BPF_MOV64_IMM(BPF_REG_2, 34),
4841 BPF_MOV64_IMM(BPF_REG_4, 24),
4842 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
4843 BPF_MOV64_IMM(BPF_REG_3, 0),
4844 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4845 BPF_EXIT_INSN(),
4846 },
4847 .errstr = "invalid stack type R1 off=-48 access_size=58",
4848 .result = REJECT,
4849 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4850 },
Thomas Graf3f731d82016-12-05 10:30:52 +01004851 {
4852 "invalid direct packet write for LWT_IN",
4853 .insns = {
4854 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4855 offsetof(struct __sk_buff, data)),
4856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4857 offsetof(struct __sk_buff, data_end)),
4858 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4860 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4861 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4862 BPF_MOV64_IMM(BPF_REG_0, 0),
4863 BPF_EXIT_INSN(),
4864 },
4865 .errstr = "cannot write into packet",
4866 .result = REJECT,
4867 .prog_type = BPF_PROG_TYPE_LWT_IN,
4868 },
4869 {
4870 "invalid direct packet write for LWT_OUT",
4871 .insns = {
4872 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4873 offsetof(struct __sk_buff, data)),
4874 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4875 offsetof(struct __sk_buff, data_end)),
4876 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4878 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4879 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4880 BPF_MOV64_IMM(BPF_REG_0, 0),
4881 BPF_EXIT_INSN(),
4882 },
4883 .errstr = "cannot write into packet",
4884 .result = REJECT,
4885 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4886 },
4887 {
4888 "direct packet write for LWT_XMIT",
4889 .insns = {
4890 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4891 offsetof(struct __sk_buff, data)),
4892 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4893 offsetof(struct __sk_buff, data_end)),
4894 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4895 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4896 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4897 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
4898 BPF_MOV64_IMM(BPF_REG_0, 0),
4899 BPF_EXIT_INSN(),
4900 },
4901 .result = ACCEPT,
4902 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4903 },
4904 {
4905 "direct packet read for LWT_IN",
4906 .insns = {
4907 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4908 offsetof(struct __sk_buff, data)),
4909 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4910 offsetof(struct __sk_buff, data_end)),
4911 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4912 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4913 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4914 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4915 BPF_MOV64_IMM(BPF_REG_0, 0),
4916 BPF_EXIT_INSN(),
4917 },
4918 .result = ACCEPT,
4919 .prog_type = BPF_PROG_TYPE_LWT_IN,
4920 },
4921 {
4922 "direct packet read for LWT_OUT",
4923 .insns = {
4924 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4925 offsetof(struct __sk_buff, data)),
4926 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4927 offsetof(struct __sk_buff, data_end)),
4928 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4930 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4931 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4932 BPF_MOV64_IMM(BPF_REG_0, 0),
4933 BPF_EXIT_INSN(),
4934 },
4935 .result = ACCEPT,
4936 .prog_type = BPF_PROG_TYPE_LWT_OUT,
4937 },
4938 {
4939 "direct packet read for LWT_XMIT",
4940 .insns = {
4941 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4942 offsetof(struct __sk_buff, data)),
4943 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4944 offsetof(struct __sk_buff, data_end)),
4945 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4946 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4947 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
4948 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
4949 BPF_MOV64_IMM(BPF_REG_0, 0),
4950 BPF_EXIT_INSN(),
4951 },
4952 .result = ACCEPT,
4953 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4954 },
4955 {
Alexei Starovoitovb1977682017-03-24 15:57:33 -07004956 "overlapping checks for direct packet access",
4957 .insns = {
4958 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4959 offsetof(struct __sk_buff, data)),
4960 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4961 offsetof(struct __sk_buff, data_end)),
4962 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4963 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4964 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
4965 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
4967 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
4968 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
4969 BPF_MOV64_IMM(BPF_REG_0, 0),
4970 BPF_EXIT_INSN(),
4971 },
4972 .result = ACCEPT,
4973 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4974 },
4975 {
Thomas Graf3f731d82016-12-05 10:30:52 +01004976 "invalid access of tc_classid for LWT_IN",
4977 .insns = {
4978 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4979 offsetof(struct __sk_buff, tc_classid)),
4980 BPF_EXIT_INSN(),
4981 },
4982 .result = REJECT,
4983 .errstr = "invalid bpf_context access",
4984 },
4985 {
4986 "invalid access of tc_classid for LWT_OUT",
4987 .insns = {
4988 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4989 offsetof(struct __sk_buff, tc_classid)),
4990 BPF_EXIT_INSN(),
4991 },
4992 .result = REJECT,
4993 .errstr = "invalid bpf_context access",
4994 },
4995 {
4996 "invalid access of tc_classid for LWT_XMIT",
4997 .insns = {
4998 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
4999 offsetof(struct __sk_buff, tc_classid)),
5000 BPF_EXIT_INSN(),
5001 },
5002 .result = REJECT,
5003 .errstr = "invalid bpf_context access",
5004 },
Gianluca Borello57225692017-01-09 10:19:47 -08005005 {
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005006 "leak pointer into ctx 1",
5007 .insns = {
5008 BPF_MOV64_IMM(BPF_REG_0, 0),
5009 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5010 offsetof(struct __sk_buff, cb[0])),
5011 BPF_LD_MAP_FD(BPF_REG_2, 0),
5012 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
5013 offsetof(struct __sk_buff, cb[0])),
5014 BPF_EXIT_INSN(),
5015 },
5016 .fixup_map1 = { 2 },
5017 .errstr_unpriv = "R2 leaks addr into mem",
5018 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01005019 .result = REJECT,
5020 .errstr = "BPF_XADD stores into R1 context is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005021 },
5022 {
5023 "leak pointer into ctx 2",
5024 .insns = {
5025 BPF_MOV64_IMM(BPF_REG_0, 0),
5026 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5027 offsetof(struct __sk_buff, cb[0])),
5028 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
5029 offsetof(struct __sk_buff, cb[0])),
5030 BPF_EXIT_INSN(),
5031 },
5032 .errstr_unpriv = "R10 leaks addr into mem",
5033 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01005034 .result = REJECT,
5035 .errstr = "BPF_XADD stores into R1 context is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005036 },
5037 {
5038 "leak pointer into ctx 3",
5039 .insns = {
5040 BPF_MOV64_IMM(BPF_REG_0, 0),
5041 BPF_LD_MAP_FD(BPF_REG_2, 0),
5042 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
5043 offsetof(struct __sk_buff, cb[0])),
5044 BPF_EXIT_INSN(),
5045 },
5046 .fixup_map1 = { 1 },
5047 .errstr_unpriv = "R2 leaks addr into ctx",
5048 .result_unpriv = REJECT,
5049 .result = ACCEPT,
5050 },
5051 {
5052 "leak pointer into map val",
5053 .insns = {
5054 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5055 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5056 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5058 BPF_LD_MAP_FD(BPF_REG_1, 0),
5059 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5060 BPF_FUNC_map_lookup_elem),
5061 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5062 BPF_MOV64_IMM(BPF_REG_3, 0),
5063 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
5064 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
5065 BPF_MOV64_IMM(BPF_REG_0, 0),
5066 BPF_EXIT_INSN(),
5067 },
5068 .fixup_map1 = { 4 },
5069 .errstr_unpriv = "R6 leaks addr into mem",
5070 .result_unpriv = REJECT,
5071 .result = ACCEPT,
5072 },
5073 {
Gianluca Borello57225692017-01-09 10:19:47 -08005074 "helper access to map: full range",
5075 .insns = {
5076 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5077 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5078 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5079 BPF_LD_MAP_FD(BPF_REG_1, 0),
5080 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5081 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5082 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5083 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5084 BPF_MOV64_IMM(BPF_REG_3, 0),
5085 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5086 BPF_EXIT_INSN(),
5087 },
5088 .fixup_map2 = { 3 },
5089 .result = ACCEPT,
5090 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5091 },
5092 {
5093 "helper access to map: partial range",
5094 .insns = {
5095 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5096 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5097 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5098 BPF_LD_MAP_FD(BPF_REG_1, 0),
5099 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5100 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5101 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5102 BPF_MOV64_IMM(BPF_REG_2, 8),
5103 BPF_MOV64_IMM(BPF_REG_3, 0),
5104 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5105 BPF_EXIT_INSN(),
5106 },
5107 .fixup_map2 = { 3 },
5108 .result = ACCEPT,
5109 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5110 },
5111 {
5112 "helper access to map: empty range",
5113 .insns = {
5114 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5116 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5117 BPF_LD_MAP_FD(BPF_REG_1, 0),
5118 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005119 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5120 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5121 BPF_MOV64_IMM(BPF_REG_2, 0),
5122 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005123 BPF_EXIT_INSN(),
5124 },
5125 .fixup_map2 = { 3 },
5126 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
5127 .result = REJECT,
5128 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5129 },
5130 {
5131 "helper access to map: out-of-bound range",
5132 .insns = {
5133 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5134 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5135 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5136 BPF_LD_MAP_FD(BPF_REG_1, 0),
5137 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5138 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5139 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5140 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
5141 BPF_MOV64_IMM(BPF_REG_3, 0),
5142 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5143 BPF_EXIT_INSN(),
5144 },
5145 .fixup_map2 = { 3 },
5146 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
5147 .result = REJECT,
5148 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5149 },
5150 {
5151 "helper access to map: negative range",
5152 .insns = {
5153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5155 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5156 BPF_LD_MAP_FD(BPF_REG_1, 0),
5157 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5158 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5159 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5160 BPF_MOV64_IMM(BPF_REG_2, -8),
5161 BPF_MOV64_IMM(BPF_REG_3, 0),
5162 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5163 BPF_EXIT_INSN(),
5164 },
5165 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005166 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005167 .result = REJECT,
5168 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5169 },
5170 {
5171 "helper access to adjusted map (via const imm): full range",
5172 .insns = {
5173 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5175 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5176 BPF_LD_MAP_FD(BPF_REG_1, 0),
5177 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5178 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5179 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5180 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5181 offsetof(struct test_val, foo)),
5182 BPF_MOV64_IMM(BPF_REG_2,
5183 sizeof(struct test_val) -
5184 offsetof(struct test_val, foo)),
5185 BPF_MOV64_IMM(BPF_REG_3, 0),
5186 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5187 BPF_EXIT_INSN(),
5188 },
5189 .fixup_map2 = { 3 },
5190 .result = ACCEPT,
5191 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5192 },
5193 {
5194 "helper access to adjusted map (via const imm): partial range",
5195 .insns = {
5196 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5198 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5199 BPF_LD_MAP_FD(BPF_REG_1, 0),
5200 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5201 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5202 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5203 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5204 offsetof(struct test_val, foo)),
5205 BPF_MOV64_IMM(BPF_REG_2, 8),
5206 BPF_MOV64_IMM(BPF_REG_3, 0),
5207 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5208 BPF_EXIT_INSN(),
5209 },
5210 .fixup_map2 = { 3 },
5211 .result = ACCEPT,
5212 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5213 },
5214 {
5215 "helper access to adjusted map (via const imm): empty range",
5216 .insns = {
5217 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5219 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5220 BPF_LD_MAP_FD(BPF_REG_1, 0),
5221 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005222 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Gianluca Borello57225692017-01-09 10:19:47 -08005223 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5224 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5225 offsetof(struct test_val, foo)),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005226 BPF_MOV64_IMM(BPF_REG_2, 0),
5227 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005228 BPF_EXIT_INSN(),
5229 },
5230 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005231 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
Gianluca Borello57225692017-01-09 10:19:47 -08005232 .result = REJECT,
5233 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5234 },
5235 {
5236 "helper access to adjusted map (via const imm): out-of-bound range",
5237 .insns = {
5238 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5239 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5240 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5241 BPF_LD_MAP_FD(BPF_REG_1, 0),
5242 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5244 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5245 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5246 offsetof(struct test_val, foo)),
5247 BPF_MOV64_IMM(BPF_REG_2,
5248 sizeof(struct test_val) -
5249 offsetof(struct test_val, foo) + 8),
5250 BPF_MOV64_IMM(BPF_REG_3, 0),
5251 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5252 BPF_EXIT_INSN(),
5253 },
5254 .fixup_map2 = { 3 },
5255 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5256 .result = REJECT,
5257 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5258 },
5259 {
5260 "helper access to adjusted map (via const imm): negative range (> adjustment)",
5261 .insns = {
5262 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5264 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5265 BPF_LD_MAP_FD(BPF_REG_1, 0),
5266 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5267 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5268 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5269 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5270 offsetof(struct test_val, foo)),
5271 BPF_MOV64_IMM(BPF_REG_2, -8),
5272 BPF_MOV64_IMM(BPF_REG_3, 0),
5273 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5274 BPF_EXIT_INSN(),
5275 },
5276 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005277 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005278 .result = REJECT,
5279 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5280 },
5281 {
5282 "helper access to adjusted map (via const imm): negative range (< adjustment)",
5283 .insns = {
5284 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5285 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5286 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5287 BPF_LD_MAP_FD(BPF_REG_1, 0),
5288 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5289 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5290 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5291 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5292 offsetof(struct test_val, foo)),
5293 BPF_MOV64_IMM(BPF_REG_2, -1),
5294 BPF_MOV64_IMM(BPF_REG_3, 0),
5295 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5296 BPF_EXIT_INSN(),
5297 },
5298 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005299 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005300 .result = REJECT,
5301 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5302 },
5303 {
5304 "helper access to adjusted map (via const reg): full range",
5305 .insns = {
5306 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5308 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5309 BPF_LD_MAP_FD(BPF_REG_1, 0),
5310 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5311 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5312 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5313 BPF_MOV64_IMM(BPF_REG_3,
5314 offsetof(struct test_val, foo)),
5315 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5316 BPF_MOV64_IMM(BPF_REG_2,
5317 sizeof(struct test_val) -
5318 offsetof(struct test_val, foo)),
5319 BPF_MOV64_IMM(BPF_REG_3, 0),
5320 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5321 BPF_EXIT_INSN(),
5322 },
5323 .fixup_map2 = { 3 },
5324 .result = ACCEPT,
5325 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5326 },
5327 {
5328 "helper access to adjusted map (via const reg): partial range",
5329 .insns = {
5330 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5332 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5333 BPF_LD_MAP_FD(BPF_REG_1, 0),
5334 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5335 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5336 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5337 BPF_MOV64_IMM(BPF_REG_3,
5338 offsetof(struct test_val, foo)),
5339 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5340 BPF_MOV64_IMM(BPF_REG_2, 8),
5341 BPF_MOV64_IMM(BPF_REG_3, 0),
5342 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5343 BPF_EXIT_INSN(),
5344 },
5345 .fixup_map2 = { 3 },
5346 .result = ACCEPT,
5347 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5348 },
5349 {
5350 "helper access to adjusted map (via const reg): empty range",
5351 .insns = {
5352 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5354 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5355 BPF_LD_MAP_FD(BPF_REG_1, 0),
5356 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005357 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
Gianluca Borello57225692017-01-09 10:19:47 -08005358 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5359 BPF_MOV64_IMM(BPF_REG_3, 0),
5360 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005361 BPF_MOV64_IMM(BPF_REG_2, 0),
5362 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005363 BPF_EXIT_INSN(),
5364 },
5365 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005366 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08005367 .result = REJECT,
5368 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5369 },
5370 {
5371 "helper access to adjusted map (via const reg): out-of-bound range",
5372 .insns = {
5373 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5374 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5375 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5376 BPF_LD_MAP_FD(BPF_REG_1, 0),
5377 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5378 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5380 BPF_MOV64_IMM(BPF_REG_3,
5381 offsetof(struct test_val, foo)),
5382 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5383 BPF_MOV64_IMM(BPF_REG_2,
5384 sizeof(struct test_val) -
5385 offsetof(struct test_val, foo) + 8),
5386 BPF_MOV64_IMM(BPF_REG_3, 0),
5387 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5388 BPF_EXIT_INSN(),
5389 },
5390 .fixup_map2 = { 3 },
5391 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5392 .result = REJECT,
5393 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5394 },
5395 {
5396 "helper access to adjusted map (via const reg): negative range (> adjustment)",
5397 .insns = {
5398 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5400 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5401 BPF_LD_MAP_FD(BPF_REG_1, 0),
5402 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5403 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5404 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5405 BPF_MOV64_IMM(BPF_REG_3,
5406 offsetof(struct test_val, foo)),
5407 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5408 BPF_MOV64_IMM(BPF_REG_2, -8),
5409 BPF_MOV64_IMM(BPF_REG_3, 0),
5410 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5411 BPF_EXIT_INSN(),
5412 },
5413 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005414 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005415 .result = REJECT,
5416 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5417 },
5418 {
5419 "helper access to adjusted map (via const reg): negative range (< adjustment)",
5420 .insns = {
5421 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5423 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5424 BPF_LD_MAP_FD(BPF_REG_1, 0),
5425 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5426 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5427 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5428 BPF_MOV64_IMM(BPF_REG_3,
5429 offsetof(struct test_val, foo)),
5430 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5431 BPF_MOV64_IMM(BPF_REG_2, -1),
5432 BPF_MOV64_IMM(BPF_REG_3, 0),
5433 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5434 BPF_EXIT_INSN(),
5435 },
5436 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005437 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005438 .result = REJECT,
5439 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5440 },
5441 {
5442 "helper access to adjusted map (via variable): full range",
5443 .insns = {
5444 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5445 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5446 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5447 BPF_LD_MAP_FD(BPF_REG_1, 0),
5448 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5449 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5450 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5451 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5452 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5453 offsetof(struct test_val, foo), 4),
5454 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5455 BPF_MOV64_IMM(BPF_REG_2,
5456 sizeof(struct test_val) -
5457 offsetof(struct test_val, foo)),
5458 BPF_MOV64_IMM(BPF_REG_3, 0),
5459 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5460 BPF_EXIT_INSN(),
5461 },
5462 .fixup_map2 = { 3 },
5463 .result = ACCEPT,
5464 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5465 },
5466 {
5467 "helper access to adjusted map (via variable): partial range",
5468 .insns = {
5469 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5471 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5472 BPF_LD_MAP_FD(BPF_REG_1, 0),
5473 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5474 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5475 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5476 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5477 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5478 offsetof(struct test_val, foo), 4),
5479 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5480 BPF_MOV64_IMM(BPF_REG_2, 8),
5481 BPF_MOV64_IMM(BPF_REG_3, 0),
5482 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5483 BPF_EXIT_INSN(),
5484 },
5485 .fixup_map2 = { 3 },
5486 .result = ACCEPT,
5487 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5488 },
5489 {
5490 "helper access to adjusted map (via variable): empty range",
5491 .insns = {
5492 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5493 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5494 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5495 BPF_LD_MAP_FD(BPF_REG_1, 0),
5496 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005497 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
Gianluca Borello57225692017-01-09 10:19:47 -08005498 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5499 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5500 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005501 offsetof(struct test_val, foo), 3),
Gianluca Borello57225692017-01-09 10:19:47 -08005502 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005503 BPF_MOV64_IMM(BPF_REG_2, 0),
5504 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005505 BPF_EXIT_INSN(),
5506 },
5507 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005508 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08005509 .result = REJECT,
5510 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5511 },
5512 {
5513 "helper access to adjusted map (via variable): no max check",
5514 .insns = {
5515 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5516 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5517 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5518 BPF_LD_MAP_FD(BPF_REG_1, 0),
5519 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5520 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5521 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5522 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5523 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Edward Creef65b1842017-08-07 15:27:12 +01005524 BPF_MOV64_IMM(BPF_REG_2, 1),
Gianluca Borello57225692017-01-09 10:19:47 -08005525 BPF_MOV64_IMM(BPF_REG_3, 0),
5526 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5527 BPF_EXIT_INSN(),
5528 },
5529 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005530 .errstr = "R1 unbounded memory access",
Gianluca Borello57225692017-01-09 10:19:47 -08005531 .result = REJECT,
5532 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5533 },
5534 {
5535 "helper access to adjusted map (via variable): wrong max check",
5536 .insns = {
5537 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5538 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5539 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5540 BPF_LD_MAP_FD(BPF_REG_1, 0),
5541 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5542 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5543 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5544 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5545 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5546 offsetof(struct test_val, foo), 4),
5547 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5548 BPF_MOV64_IMM(BPF_REG_2,
5549 sizeof(struct test_val) -
5550 offsetof(struct test_val, foo) + 1),
5551 BPF_MOV64_IMM(BPF_REG_3, 0),
5552 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5553 BPF_EXIT_INSN(),
5554 },
5555 .fixup_map2 = { 3 },
5556 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
5557 .result = REJECT,
5558 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5559 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08005560 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02005561 "helper access to map: bounds check using <, good access",
5562 .insns = {
5563 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5565 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5566 BPF_LD_MAP_FD(BPF_REG_1, 0),
5567 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5568 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5569 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5570 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5571 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
5572 BPF_MOV64_IMM(BPF_REG_0, 0),
5573 BPF_EXIT_INSN(),
5574 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5575 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5576 BPF_MOV64_IMM(BPF_REG_0, 0),
5577 BPF_EXIT_INSN(),
5578 },
5579 .fixup_map2 = { 3 },
5580 .result = ACCEPT,
5581 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5582 },
5583 {
5584 "helper access to map: bounds check using <, bad access",
5585 .insns = {
5586 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5588 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5589 BPF_LD_MAP_FD(BPF_REG_1, 0),
5590 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5591 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5592 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5593 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5594 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
5595 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5596 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5597 BPF_MOV64_IMM(BPF_REG_0, 0),
5598 BPF_EXIT_INSN(),
5599 BPF_MOV64_IMM(BPF_REG_0, 0),
5600 BPF_EXIT_INSN(),
5601 },
5602 .fixup_map2 = { 3 },
5603 .result = REJECT,
5604 .errstr = "R1 unbounded memory access",
5605 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5606 },
5607 {
5608 "helper access to map: bounds check using <=, good access",
5609 .insns = {
5610 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5611 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5612 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5613 BPF_LD_MAP_FD(BPF_REG_1, 0),
5614 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5615 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5616 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5617 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5618 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
5619 BPF_MOV64_IMM(BPF_REG_0, 0),
5620 BPF_EXIT_INSN(),
5621 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5622 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5623 BPF_MOV64_IMM(BPF_REG_0, 0),
5624 BPF_EXIT_INSN(),
5625 },
5626 .fixup_map2 = { 3 },
5627 .result = ACCEPT,
5628 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5629 },
5630 {
5631 "helper access to map: bounds check using <=, bad access",
5632 .insns = {
5633 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5635 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5636 BPF_LD_MAP_FD(BPF_REG_1, 0),
5637 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5638 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5639 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5640 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5641 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
5642 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5643 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5644 BPF_MOV64_IMM(BPF_REG_0, 0),
5645 BPF_EXIT_INSN(),
5646 BPF_MOV64_IMM(BPF_REG_0, 0),
5647 BPF_EXIT_INSN(),
5648 },
5649 .fixup_map2 = { 3 },
5650 .result = REJECT,
5651 .errstr = "R1 unbounded memory access",
5652 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5653 },
5654 {
5655 "helper access to map: bounds check using s<, good access",
5656 .insns = {
5657 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5659 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5660 BPF_LD_MAP_FD(BPF_REG_1, 0),
5661 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5662 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5663 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5664 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5665 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5666 BPF_MOV64_IMM(BPF_REG_0, 0),
5667 BPF_EXIT_INSN(),
5668 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
5669 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5670 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5671 BPF_MOV64_IMM(BPF_REG_0, 0),
5672 BPF_EXIT_INSN(),
5673 },
5674 .fixup_map2 = { 3 },
5675 .result = ACCEPT,
5676 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5677 },
5678 {
5679 "helper access to map: bounds check using s<, good access 2",
5680 .insns = {
5681 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5682 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5683 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5684 BPF_LD_MAP_FD(BPF_REG_1, 0),
5685 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5687 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5688 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5689 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5690 BPF_MOV64_IMM(BPF_REG_0, 0),
5691 BPF_EXIT_INSN(),
5692 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5693 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5694 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5695 BPF_MOV64_IMM(BPF_REG_0, 0),
5696 BPF_EXIT_INSN(),
5697 },
5698 .fixup_map2 = { 3 },
5699 .result = ACCEPT,
5700 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5701 },
5702 {
5703 "helper access to map: bounds check using s<, bad access",
5704 .insns = {
5705 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5707 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5708 BPF_LD_MAP_FD(BPF_REG_1, 0),
5709 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5710 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5711 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5712 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5713 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5714 BPF_MOV64_IMM(BPF_REG_0, 0),
5715 BPF_EXIT_INSN(),
5716 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5717 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5718 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5719 BPF_MOV64_IMM(BPF_REG_0, 0),
5720 BPF_EXIT_INSN(),
5721 },
5722 .fixup_map2 = { 3 },
5723 .result = REJECT,
5724 .errstr = "R1 min value is negative",
5725 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5726 },
5727 {
5728 "helper access to map: bounds check using s<=, good access",
5729 .insns = {
5730 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5731 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5732 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5733 BPF_LD_MAP_FD(BPF_REG_1, 0),
5734 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5735 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5736 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5737 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5738 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5739 BPF_MOV64_IMM(BPF_REG_0, 0),
5740 BPF_EXIT_INSN(),
5741 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
5742 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5743 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5744 BPF_MOV64_IMM(BPF_REG_0, 0),
5745 BPF_EXIT_INSN(),
5746 },
5747 .fixup_map2 = { 3 },
5748 .result = ACCEPT,
5749 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5750 },
5751 {
5752 "helper access to map: bounds check using s<=, good access 2",
5753 .insns = {
5754 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5755 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5756 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5757 BPF_LD_MAP_FD(BPF_REG_1, 0),
5758 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5759 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5760 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5761 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5762 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5763 BPF_MOV64_IMM(BPF_REG_0, 0),
5764 BPF_EXIT_INSN(),
5765 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5766 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5767 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5768 BPF_MOV64_IMM(BPF_REG_0, 0),
5769 BPF_EXIT_INSN(),
5770 },
5771 .fixup_map2 = { 3 },
5772 .result = ACCEPT,
5773 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5774 },
5775 {
5776 "helper access to map: bounds check using s<=, bad access",
5777 .insns = {
5778 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5780 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5781 BPF_LD_MAP_FD(BPF_REG_1, 0),
5782 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5783 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5784 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5785 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5786 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5787 BPF_MOV64_IMM(BPF_REG_0, 0),
5788 BPF_EXIT_INSN(),
5789 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
5790 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5791 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5792 BPF_MOV64_IMM(BPF_REG_0, 0),
5793 BPF_EXIT_INSN(),
5794 },
5795 .fixup_map2 = { 3 },
5796 .result = REJECT,
5797 .errstr = "R1 min value is negative",
5798 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5799 },
5800 {
Paul Chaignon5f90dd62018-04-24 15:08:19 +02005801 "map lookup helper access to map",
5802 .insns = {
5803 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5804 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5805 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5806 BPF_LD_MAP_FD(BPF_REG_1, 0),
5807 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5808 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5809 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5810 BPF_LD_MAP_FD(BPF_REG_1, 0),
5811 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5812 BPF_EXIT_INSN(),
5813 },
5814 .fixup_map3 = { 3, 8 },
5815 .result = ACCEPT,
5816 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5817 },
5818 {
5819 "map update helper access to map",
5820 .insns = {
5821 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5823 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5824 BPF_LD_MAP_FD(BPF_REG_1, 0),
5825 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5826 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5827 BPF_MOV64_IMM(BPF_REG_4, 0),
5828 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
5829 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5830 BPF_LD_MAP_FD(BPF_REG_1, 0),
5831 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
5832 BPF_EXIT_INSN(),
5833 },
5834 .fixup_map3 = { 3, 10 },
5835 .result = ACCEPT,
5836 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5837 },
5838 {
5839 "map update helper access to map: wrong size",
5840 .insns = {
5841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5843 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5844 BPF_LD_MAP_FD(BPF_REG_1, 0),
5845 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5847 BPF_MOV64_IMM(BPF_REG_4, 0),
5848 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
5849 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5850 BPF_LD_MAP_FD(BPF_REG_1, 0),
5851 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
5852 BPF_EXIT_INSN(),
5853 },
5854 .fixup_map1 = { 3 },
5855 .fixup_map3 = { 10 },
5856 .result = REJECT,
5857 .errstr = "invalid access to map value, value_size=8 off=0 size=16",
5858 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5859 },
5860 {
5861 "map helper access to adjusted map (via const imm)",
5862 .insns = {
5863 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5864 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5865 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5866 BPF_LD_MAP_FD(BPF_REG_1, 0),
5867 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5868 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5869 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
5871 offsetof(struct other_val, bar)),
5872 BPF_LD_MAP_FD(BPF_REG_1, 0),
5873 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5874 BPF_EXIT_INSN(),
5875 },
5876 .fixup_map3 = { 3, 9 },
5877 .result = ACCEPT,
5878 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5879 },
5880 {
5881 "map helper access to adjusted map (via const imm): out-of-bound 1",
5882 .insns = {
5883 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5885 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5886 BPF_LD_MAP_FD(BPF_REG_1, 0),
5887 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5888 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5889 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5890 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
5891 sizeof(struct other_val) - 4),
5892 BPF_LD_MAP_FD(BPF_REG_1, 0),
5893 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5894 BPF_EXIT_INSN(),
5895 },
5896 .fixup_map3 = { 3, 9 },
5897 .result = REJECT,
5898 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
5899 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5900 },
5901 {
5902 "map helper access to adjusted map (via const imm): out-of-bound 2",
5903 .insns = {
5904 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5906 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5907 BPF_LD_MAP_FD(BPF_REG_1, 0),
5908 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5909 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5910 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5911 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
5912 BPF_LD_MAP_FD(BPF_REG_1, 0),
5913 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5914 BPF_EXIT_INSN(),
5915 },
5916 .fixup_map3 = { 3, 9 },
5917 .result = REJECT,
5918 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
5919 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5920 },
5921 {
5922 "map helper access to adjusted map (via const reg)",
5923 .insns = {
5924 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5925 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5926 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5927 BPF_LD_MAP_FD(BPF_REG_1, 0),
5928 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5929 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5930 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5931 BPF_MOV64_IMM(BPF_REG_3,
5932 offsetof(struct other_val, bar)),
5933 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5934 BPF_LD_MAP_FD(BPF_REG_1, 0),
5935 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5936 BPF_EXIT_INSN(),
5937 },
5938 .fixup_map3 = { 3, 10 },
5939 .result = ACCEPT,
5940 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5941 },
5942 {
5943 "map helper access to adjusted map (via const reg): out-of-bound 1",
5944 .insns = {
5945 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5946 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5947 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5948 BPF_LD_MAP_FD(BPF_REG_1, 0),
5949 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5950 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5951 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5952 BPF_MOV64_IMM(BPF_REG_3,
5953 sizeof(struct other_val) - 4),
5954 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5955 BPF_LD_MAP_FD(BPF_REG_1, 0),
5956 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5957 BPF_EXIT_INSN(),
5958 },
5959 .fixup_map3 = { 3, 10 },
5960 .result = REJECT,
5961 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
5962 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5963 },
5964 {
5965 "map helper access to adjusted map (via const reg): out-of-bound 2",
5966 .insns = {
5967 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5969 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5970 BPF_LD_MAP_FD(BPF_REG_1, 0),
5971 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5972 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5973 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5974 BPF_MOV64_IMM(BPF_REG_3, -4),
5975 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5976 BPF_LD_MAP_FD(BPF_REG_1, 0),
5977 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5978 BPF_EXIT_INSN(),
5979 },
5980 .fixup_map3 = { 3, 10 },
5981 .result = REJECT,
5982 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
5983 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5984 },
5985 {
5986 "map helper access to adjusted map (via variable)",
5987 .insns = {
5988 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5989 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5990 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5991 BPF_LD_MAP_FD(BPF_REG_1, 0),
5992 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5993 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5994 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
5995 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5996 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5997 offsetof(struct other_val, bar), 4),
5998 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
5999 BPF_LD_MAP_FD(BPF_REG_1, 0),
6000 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6001 BPF_EXIT_INSN(),
6002 },
6003 .fixup_map3 = { 3, 11 },
6004 .result = ACCEPT,
6005 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6006 },
6007 {
6008 "map helper access to adjusted map (via variable): no max check",
6009 .insns = {
6010 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6012 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6013 BPF_LD_MAP_FD(BPF_REG_1, 0),
6014 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6015 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6016 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6017 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6018 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6019 BPF_LD_MAP_FD(BPF_REG_1, 0),
6020 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6021 BPF_EXIT_INSN(),
6022 },
6023 .fixup_map3 = { 3, 10 },
6024 .result = REJECT,
6025 .errstr = "R2 unbounded memory access, make sure to bounds check any array access into a map",
6026 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6027 },
6028 {
6029 "map helper access to adjusted map (via variable): wrong max check",
6030 .insns = {
6031 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6032 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6033 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6034 BPF_LD_MAP_FD(BPF_REG_1, 0),
6035 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6036 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6037 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6038 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6039 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6040 offsetof(struct other_val, bar) + 1, 4),
6041 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6042 BPF_LD_MAP_FD(BPF_REG_1, 0),
6043 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6044 BPF_EXIT_INSN(),
6045 },
6046 .fixup_map3 = { 3, 11 },
6047 .result = REJECT,
6048 .errstr = "invalid access to map value, value_size=16 off=9 size=8",
6049 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6050 },
6051 {
Gianluca Borellof0318d02017-01-09 10:19:48 -08006052 "map element value is preserved across register spilling",
6053 .insns = {
6054 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6056 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6057 BPF_LD_MAP_FD(BPF_REG_1, 0),
6058 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6059 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6060 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6061 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6062 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6063 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6064 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6065 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6066 BPF_EXIT_INSN(),
6067 },
6068 .fixup_map2 = { 3 },
6069 .errstr_unpriv = "R0 leaks addr",
6070 .result = ACCEPT,
6071 .result_unpriv = REJECT,
6072 },
6073 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006074 "map element value or null is marked on register spilling",
6075 .insns = {
6076 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6077 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6078 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6079 BPF_LD_MAP_FD(BPF_REG_1, 0),
6080 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6081 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
6083 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6084 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6085 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6086 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6087 BPF_EXIT_INSN(),
6088 },
6089 .fixup_map2 = { 3 },
6090 .errstr_unpriv = "R0 leaks addr",
6091 .result = ACCEPT,
6092 .result_unpriv = REJECT,
6093 },
6094 {
6095 "map element value store of cleared call register",
6096 .insns = {
6097 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6099 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6100 BPF_LD_MAP_FD(BPF_REG_1, 0),
6101 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6102 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
6103 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
6104 BPF_EXIT_INSN(),
6105 },
6106 .fixup_map2 = { 3 },
6107 .errstr_unpriv = "R1 !read_ok",
6108 .errstr = "R1 !read_ok",
6109 .result = REJECT,
6110 .result_unpriv = REJECT,
6111 },
6112 {
6113 "map element value with unaligned store",
6114 .insns = {
6115 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6117 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6118 BPF_LD_MAP_FD(BPF_REG_1, 0),
6119 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6120 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
6121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6122 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6123 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
6124 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
6125 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6126 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
6127 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
6128 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
6129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
6130 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
6131 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
6132 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
6133 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
6134 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
6135 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
6136 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
6137 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
6138 BPF_EXIT_INSN(),
6139 },
6140 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006141 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006142 .result = ACCEPT,
6143 .result_unpriv = REJECT,
6144 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6145 },
6146 {
6147 "map element value with unaligned load",
6148 .insns = {
6149 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6150 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6151 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6152 BPF_LD_MAP_FD(BPF_REG_1, 0),
6153 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6154 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6155 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6156 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
6157 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6158 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6159 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
6160 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6161 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
6162 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
6163 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
6164 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6165 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
6166 BPF_EXIT_INSN(),
6167 },
6168 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006169 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006170 .result = ACCEPT,
6171 .result_unpriv = REJECT,
6172 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6173 },
6174 {
6175 "map element value illegal alu op, 1",
6176 .insns = {
6177 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6178 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6179 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6180 BPF_LD_MAP_FD(BPF_REG_1, 0),
6181 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6182 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6183 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
6184 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6185 BPF_EXIT_INSN(),
6186 },
6187 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006188 .errstr = "R0 bitwise operator &= on pointer",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006189 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006190 },
6191 {
6192 "map element value illegal alu op, 2",
6193 .insns = {
6194 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6196 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6197 BPF_LD_MAP_FD(BPF_REG_1, 0),
6198 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6199 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6200 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
6201 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6202 BPF_EXIT_INSN(),
6203 },
6204 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006205 .errstr = "R0 32-bit pointer arithmetic prohibited",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006206 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006207 },
6208 {
6209 "map element value illegal alu op, 3",
6210 .insns = {
6211 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6213 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6214 BPF_LD_MAP_FD(BPF_REG_1, 0),
6215 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6216 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6217 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
6218 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6219 BPF_EXIT_INSN(),
6220 },
6221 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006222 .errstr = "R0 pointer arithmetic with /= operator",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006223 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006224 },
6225 {
6226 "map element value illegal alu op, 4",
6227 .insns = {
6228 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6230 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6231 BPF_LD_MAP_FD(BPF_REG_1, 0),
6232 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6233 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6234 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
6235 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6236 BPF_EXIT_INSN(),
6237 },
6238 .fixup_map2 = { 3 },
6239 .errstr_unpriv = "R0 pointer arithmetic prohibited",
6240 .errstr = "invalid mem access 'inv'",
6241 .result = REJECT,
6242 .result_unpriv = REJECT,
6243 },
6244 {
6245 "map element value illegal alu op, 5",
6246 .insns = {
6247 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6248 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6249 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6250 BPF_LD_MAP_FD(BPF_REG_1, 0),
6251 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6252 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6253 BPF_MOV64_IMM(BPF_REG_3, 4096),
6254 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6255 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6256 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6257 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
6258 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
6259 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6260 BPF_EXIT_INSN(),
6261 },
6262 .fixup_map2 = { 3 },
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006263 .errstr = "R0 invalid mem access 'inv'",
6264 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006265 },
6266 {
6267 "map element value is preserved across register spilling",
Gianluca Borellof0318d02017-01-09 10:19:48 -08006268 .insns = {
6269 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6271 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6272 BPF_LD_MAP_FD(BPF_REG_1, 0),
6273 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6274 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6275 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
6276 offsetof(struct test_val, foo)),
6277 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6278 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6280 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6281 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6282 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6283 BPF_EXIT_INSN(),
6284 },
6285 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006286 .errstr_unpriv = "R0 leaks addr",
Gianluca Borellof0318d02017-01-09 10:19:48 -08006287 .result = ACCEPT,
6288 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006289 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Gianluca Borellof0318d02017-01-09 10:19:48 -08006290 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08006291 {
6292 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
6293 .insns = {
6294 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6295 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6296 BPF_MOV64_IMM(BPF_REG_0, 0),
6297 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6298 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6299 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6300 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6301 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6302 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6303 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6304 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6305 BPF_MOV64_IMM(BPF_REG_2, 16),
6306 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6307 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6308 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6309 BPF_MOV64_IMM(BPF_REG_4, 0),
6310 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6311 BPF_MOV64_IMM(BPF_REG_3, 0),
6312 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6313 BPF_MOV64_IMM(BPF_REG_0, 0),
6314 BPF_EXIT_INSN(),
6315 },
6316 .result = ACCEPT,
6317 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6318 },
6319 {
6320 "helper access to variable memory: stack, bitwise AND, zero included",
6321 .insns = {
6322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6324 BPF_MOV64_IMM(BPF_REG_2, 16),
6325 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6326 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6327 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6328 BPF_MOV64_IMM(BPF_REG_3, 0),
6329 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6330 BPF_EXIT_INSN(),
6331 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006332 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006333 .result = REJECT,
6334 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6335 },
6336 {
6337 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
6338 .insns = {
6339 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6340 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6341 BPF_MOV64_IMM(BPF_REG_2, 16),
6342 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6343 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6344 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
6345 BPF_MOV64_IMM(BPF_REG_4, 0),
6346 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6347 BPF_MOV64_IMM(BPF_REG_3, 0),
6348 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6349 BPF_MOV64_IMM(BPF_REG_0, 0),
6350 BPF_EXIT_INSN(),
6351 },
6352 .errstr = "invalid stack type R1 off=-64 access_size=65",
6353 .result = REJECT,
6354 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6355 },
6356 {
6357 "helper access to variable memory: stack, JMP, correct bounds",
6358 .insns = {
6359 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6361 BPF_MOV64_IMM(BPF_REG_0, 0),
6362 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6363 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6364 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6365 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6366 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6367 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6368 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6369 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6370 BPF_MOV64_IMM(BPF_REG_2, 16),
6371 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6372 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6373 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
6374 BPF_MOV64_IMM(BPF_REG_4, 0),
6375 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6376 BPF_MOV64_IMM(BPF_REG_3, 0),
6377 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6378 BPF_MOV64_IMM(BPF_REG_0, 0),
6379 BPF_EXIT_INSN(),
6380 },
6381 .result = ACCEPT,
6382 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6383 },
6384 {
6385 "helper access to variable memory: stack, JMP (signed), correct bounds",
6386 .insns = {
6387 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6388 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6389 BPF_MOV64_IMM(BPF_REG_0, 0),
6390 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6391 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6392 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6393 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6394 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6395 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6396 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6397 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6398 BPF_MOV64_IMM(BPF_REG_2, 16),
6399 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6400 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6401 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
6402 BPF_MOV64_IMM(BPF_REG_4, 0),
6403 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6404 BPF_MOV64_IMM(BPF_REG_3, 0),
6405 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6406 BPF_MOV64_IMM(BPF_REG_0, 0),
6407 BPF_EXIT_INSN(),
6408 },
6409 .result = ACCEPT,
6410 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6411 },
6412 {
6413 "helper access to variable memory: stack, JMP, bounds + offset",
6414 .insns = {
6415 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6416 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6417 BPF_MOV64_IMM(BPF_REG_2, 16),
6418 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6419 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6420 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
6421 BPF_MOV64_IMM(BPF_REG_4, 0),
6422 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
6423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6424 BPF_MOV64_IMM(BPF_REG_3, 0),
6425 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6426 BPF_MOV64_IMM(BPF_REG_0, 0),
6427 BPF_EXIT_INSN(),
6428 },
6429 .errstr = "invalid stack type R1 off=-64 access_size=65",
6430 .result = REJECT,
6431 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6432 },
6433 {
6434 "helper access to variable memory: stack, JMP, wrong max",
6435 .insns = {
6436 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6437 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6438 BPF_MOV64_IMM(BPF_REG_2, 16),
6439 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6440 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6441 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
6442 BPF_MOV64_IMM(BPF_REG_4, 0),
6443 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6444 BPF_MOV64_IMM(BPF_REG_3, 0),
6445 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6446 BPF_MOV64_IMM(BPF_REG_0, 0),
6447 BPF_EXIT_INSN(),
6448 },
6449 .errstr = "invalid stack type R1 off=-64 access_size=65",
6450 .result = REJECT,
6451 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6452 },
6453 {
6454 "helper access to variable memory: stack, JMP, no max check",
6455 .insns = {
6456 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6458 BPF_MOV64_IMM(BPF_REG_2, 16),
6459 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6460 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6461 BPF_MOV64_IMM(BPF_REG_4, 0),
6462 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6463 BPF_MOV64_IMM(BPF_REG_3, 0),
6464 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6465 BPF_MOV64_IMM(BPF_REG_0, 0),
6466 BPF_EXIT_INSN(),
6467 },
Edward Creef65b1842017-08-07 15:27:12 +01006468 /* because max wasn't checked, signed min is negative */
6469 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006470 .result = REJECT,
6471 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6472 },
6473 {
6474 "helper access to variable memory: stack, JMP, no min check",
6475 .insns = {
6476 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6478 BPF_MOV64_IMM(BPF_REG_2, 16),
6479 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6480 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6481 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
6482 BPF_MOV64_IMM(BPF_REG_3, 0),
6483 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6484 BPF_MOV64_IMM(BPF_REG_0, 0),
6485 BPF_EXIT_INSN(),
6486 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006487 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006488 .result = REJECT,
6489 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6490 },
6491 {
6492 "helper access to variable memory: stack, JMP (signed), no min check",
6493 .insns = {
6494 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6495 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6496 BPF_MOV64_IMM(BPF_REG_2, 16),
6497 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6498 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6499 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
6500 BPF_MOV64_IMM(BPF_REG_3, 0),
6501 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6502 BPF_MOV64_IMM(BPF_REG_0, 0),
6503 BPF_EXIT_INSN(),
6504 },
6505 .errstr = "R2 min value is negative",
6506 .result = REJECT,
6507 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6508 },
6509 {
6510 "helper access to variable memory: map, JMP, correct bounds",
6511 .insns = {
6512 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6513 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6514 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6515 BPF_LD_MAP_FD(BPF_REG_1, 0),
6516 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6517 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6518 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6519 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6520 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6521 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6522 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6523 sizeof(struct test_val), 4),
6524 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006525 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006526 BPF_MOV64_IMM(BPF_REG_3, 0),
6527 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6528 BPF_MOV64_IMM(BPF_REG_0, 0),
6529 BPF_EXIT_INSN(),
6530 },
6531 .fixup_map2 = { 3 },
6532 .result = ACCEPT,
6533 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6534 },
6535 {
6536 "helper access to variable memory: map, JMP, wrong max",
6537 .insns = {
6538 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6539 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6540 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6541 BPF_LD_MAP_FD(BPF_REG_1, 0),
6542 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6543 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6544 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6545 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6546 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6547 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6548 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6549 sizeof(struct test_val) + 1, 4),
6550 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006551 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006552 BPF_MOV64_IMM(BPF_REG_3, 0),
6553 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6554 BPF_MOV64_IMM(BPF_REG_0, 0),
6555 BPF_EXIT_INSN(),
6556 },
6557 .fixup_map2 = { 3 },
6558 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
6559 .result = REJECT,
6560 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6561 },
6562 {
6563 "helper access to variable memory: map adjusted, JMP, correct bounds",
6564 .insns = {
6565 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6566 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6567 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6568 BPF_LD_MAP_FD(BPF_REG_1, 0),
6569 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6570 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6571 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6573 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6574 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6575 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6576 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6577 sizeof(struct test_val) - 20, 4),
6578 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006579 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006580 BPF_MOV64_IMM(BPF_REG_3, 0),
6581 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6582 BPF_MOV64_IMM(BPF_REG_0, 0),
6583 BPF_EXIT_INSN(),
6584 },
6585 .fixup_map2 = { 3 },
6586 .result = ACCEPT,
6587 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6588 },
6589 {
6590 "helper access to variable memory: map adjusted, JMP, wrong max",
6591 .insns = {
6592 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6594 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6595 BPF_LD_MAP_FD(BPF_REG_1, 0),
6596 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6597 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6598 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6599 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6600 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6601 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6602 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6603 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6604 sizeof(struct test_val) - 19, 4),
6605 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006606 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006607 BPF_MOV64_IMM(BPF_REG_3, 0),
6608 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6609 BPF_MOV64_IMM(BPF_REG_0, 0),
6610 BPF_EXIT_INSN(),
6611 },
6612 .fixup_map2 = { 3 },
6613 .errstr = "R1 min value is outside of the array range",
6614 .result = REJECT,
6615 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6616 },
6617 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006618 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Edward Creef65b1842017-08-07 15:27:12 +01006619 .insns = {
6620 BPF_MOV64_IMM(BPF_REG_1, 0),
6621 BPF_MOV64_IMM(BPF_REG_2, 0),
6622 BPF_MOV64_IMM(BPF_REG_3, 0),
6623 BPF_MOV64_IMM(BPF_REG_4, 0),
6624 BPF_MOV64_IMM(BPF_REG_5, 0),
6625 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6626 BPF_EXIT_INSN(),
6627 },
6628 .result = ACCEPT,
6629 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6630 },
6631 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006632 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006633 .insns = {
6634 BPF_MOV64_IMM(BPF_REG_1, 0),
Alexei Starovoitovd98588c2017-12-14 17:55:09 -08006635 BPF_MOV64_IMM(BPF_REG_2, 1),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01006636 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6637 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006638 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6639 BPF_MOV64_IMM(BPF_REG_3, 0),
6640 BPF_MOV64_IMM(BPF_REG_4, 0),
6641 BPF_MOV64_IMM(BPF_REG_5, 0),
6642 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6643 BPF_EXIT_INSN(),
6644 },
Edward Creef65b1842017-08-07 15:27:12 +01006645 .errstr = "R1 type=inv expected=fp",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006646 .result = REJECT,
6647 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6648 },
6649 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006650 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006651 .insns = {
6652 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6653 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6654 BPF_MOV64_IMM(BPF_REG_2, 0),
6655 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6656 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
6657 BPF_MOV64_IMM(BPF_REG_3, 0),
6658 BPF_MOV64_IMM(BPF_REG_4, 0),
6659 BPF_MOV64_IMM(BPF_REG_5, 0),
6660 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6661 BPF_EXIT_INSN(),
6662 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006663 .result = ACCEPT,
6664 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6665 },
6666 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006667 "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08006668 .insns = {
6669 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6670 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6671 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6672 BPF_LD_MAP_FD(BPF_REG_1, 0),
6673 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6674 BPF_FUNC_map_lookup_elem),
6675 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6676 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6677 BPF_MOV64_IMM(BPF_REG_2, 0),
6678 BPF_MOV64_IMM(BPF_REG_3, 0),
6679 BPF_MOV64_IMM(BPF_REG_4, 0),
6680 BPF_MOV64_IMM(BPF_REG_5, 0),
6681 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6682 BPF_EXIT_INSN(),
6683 },
6684 .fixup_map1 = { 3 },
6685 .result = ACCEPT,
6686 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6687 },
6688 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006689 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08006690 .insns = {
6691 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6692 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6694 BPF_LD_MAP_FD(BPF_REG_1, 0),
6695 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6696 BPF_FUNC_map_lookup_elem),
6697 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6698 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6699 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
6700 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6701 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6702 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6703 BPF_MOV64_IMM(BPF_REG_3, 0),
6704 BPF_MOV64_IMM(BPF_REG_4, 0),
6705 BPF_MOV64_IMM(BPF_REG_5, 0),
6706 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6707 BPF_EXIT_INSN(),
6708 },
6709 .fixup_map1 = { 3 },
6710 .result = ACCEPT,
6711 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6712 },
6713 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006714 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08006715 .insns = {
6716 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6717 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6718 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6719 BPF_LD_MAP_FD(BPF_REG_1, 0),
6720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6721 BPF_FUNC_map_lookup_elem),
6722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6723 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6724 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6725 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6726 BPF_MOV64_IMM(BPF_REG_3, 0),
6727 BPF_MOV64_IMM(BPF_REG_4, 0),
6728 BPF_MOV64_IMM(BPF_REG_5, 0),
6729 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6730 BPF_EXIT_INSN(),
6731 },
6732 .fixup_map1 = { 3 },
6733 .result = ACCEPT,
6734 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6735 },
6736 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006737 "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
Yonghong Songb6ff6392017-11-12 14:49:11 -08006738 .insns = {
6739 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6740 offsetof(struct __sk_buff, data)),
6741 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6742 offsetof(struct __sk_buff, data_end)),
6743 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
6744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
6745 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
6746 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
6747 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
6748 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6749 BPF_MOV64_IMM(BPF_REG_3, 0),
6750 BPF_MOV64_IMM(BPF_REG_4, 0),
6751 BPF_MOV64_IMM(BPF_REG_5, 0),
6752 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6753 BPF_EXIT_INSN(),
6754 },
6755 .result = ACCEPT,
Gianluca Borello06c1c042017-01-09 10:19:49 -08006756 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08006757 .retval = 0 /* csum_diff of 64-byte packet */,
Gianluca Borello06c1c042017-01-09 10:19:49 -08006758 },
6759 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006760 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6761 .insns = {
6762 BPF_MOV64_IMM(BPF_REG_1, 0),
6763 BPF_MOV64_IMM(BPF_REG_2, 0),
6764 BPF_MOV64_IMM(BPF_REG_3, 0),
6765 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6766 BPF_EXIT_INSN(),
6767 },
6768 .errstr = "R1 type=inv expected=fp",
6769 .result = REJECT,
6770 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6771 },
6772 {
6773 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6774 .insns = {
6775 BPF_MOV64_IMM(BPF_REG_1, 0),
6776 BPF_MOV64_IMM(BPF_REG_2, 1),
6777 BPF_MOV64_IMM(BPF_REG_3, 0),
6778 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6779 BPF_EXIT_INSN(),
6780 },
6781 .errstr = "R1 type=inv expected=fp",
6782 .result = REJECT,
6783 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6784 },
6785 {
6786 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6787 .insns = {
6788 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6789 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6790 BPF_MOV64_IMM(BPF_REG_2, 0),
6791 BPF_MOV64_IMM(BPF_REG_3, 0),
6792 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6793 BPF_EXIT_INSN(),
6794 },
6795 .result = ACCEPT,
6796 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6797 },
6798 {
6799 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6800 .insns = {
6801 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6802 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6803 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6804 BPF_LD_MAP_FD(BPF_REG_1, 0),
6805 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6806 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6807 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6808 BPF_MOV64_IMM(BPF_REG_2, 0),
6809 BPF_MOV64_IMM(BPF_REG_3, 0),
6810 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6811 BPF_EXIT_INSN(),
6812 },
6813 .fixup_map1 = { 3 },
6814 .result = ACCEPT,
6815 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6816 },
6817 {
6818 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6819 .insns = {
6820 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6821 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6823 BPF_LD_MAP_FD(BPF_REG_1, 0),
6824 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6825 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6826 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6827 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6828 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6830 BPF_MOV64_IMM(BPF_REG_3, 0),
6831 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6832 BPF_EXIT_INSN(),
6833 },
6834 .fixup_map1 = { 3 },
6835 .result = ACCEPT,
6836 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6837 },
6838 {
6839 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6840 .insns = {
6841 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6842 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6843 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6844 BPF_LD_MAP_FD(BPF_REG_1, 0),
6845 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6847 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6848 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6849 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
6850 BPF_MOV64_IMM(BPF_REG_3, 0),
6851 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6852 BPF_EXIT_INSN(),
6853 },
6854 .fixup_map1 = { 3 },
6855 .result = ACCEPT,
6856 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6857 },
6858 {
Gianluca Borello06c1c042017-01-09 10:19:49 -08006859 "helper access to variable memory: 8 bytes leak",
6860 .insns = {
6861 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6863 BPF_MOV64_IMM(BPF_REG_0, 0),
6864 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6865 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6866 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6867 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6868 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6869 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6870 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
Alexei Starovoitovd98588c2017-12-14 17:55:09 -08006871 BPF_MOV64_IMM(BPF_REG_2, 1),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01006872 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6873 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006874 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
6875 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6876 BPF_MOV64_IMM(BPF_REG_3, 0),
6877 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6878 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6879 BPF_EXIT_INSN(),
6880 },
6881 .errstr = "invalid indirect read from stack off -64+32 size 64",
6882 .result = REJECT,
6883 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6884 },
6885 {
6886 "helper access to variable memory: 8 bytes no leak (init memory)",
6887 .insns = {
6888 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6889 BPF_MOV64_IMM(BPF_REG_0, 0),
6890 BPF_MOV64_IMM(BPF_REG_0, 0),
6891 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6892 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6893 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6894 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6895 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6896 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6897 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6898 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6899 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6900 BPF_MOV64_IMM(BPF_REG_2, 0),
6901 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
6902 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
6903 BPF_MOV64_IMM(BPF_REG_3, 0),
6904 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6905 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
6906 BPF_EXIT_INSN(),
6907 },
6908 .result = ACCEPT,
6909 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6910 },
Josef Bacik29200c12017-02-03 16:25:23 -05006911 {
6912 "invalid and of negative number",
6913 .insns = {
6914 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6915 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6916 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6917 BPF_LD_MAP_FD(BPF_REG_1, 0),
6918 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6919 BPF_FUNC_map_lookup_elem),
6920 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Edward Creef65b1842017-08-07 15:27:12 +01006921 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik29200c12017-02-03 16:25:23 -05006922 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
6923 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
6924 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6925 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
6926 offsetof(struct test_val, foo)),
6927 BPF_EXIT_INSN(),
6928 },
6929 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006930 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05006931 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006932 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik29200c12017-02-03 16:25:23 -05006933 },
6934 {
6935 "invalid range check",
6936 .insns = {
6937 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6938 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6940 BPF_LD_MAP_FD(BPF_REG_1, 0),
6941 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6942 BPF_FUNC_map_lookup_elem),
6943 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
6944 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6945 BPF_MOV64_IMM(BPF_REG_9, 1),
6946 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
6947 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
6948 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
6949 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
6950 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
6951 BPF_MOV32_IMM(BPF_REG_3, 1),
6952 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
6953 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
6954 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
6955 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
6956 BPF_MOV64_REG(BPF_REG_0, 0),
6957 BPF_EXIT_INSN(),
6958 },
6959 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006960 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05006961 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006962 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07006963 },
6964 {
6965 "map in map access",
6966 .insns = {
6967 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6968 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6970 BPF_LD_MAP_FD(BPF_REG_1, 0),
6971 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6972 BPF_FUNC_map_lookup_elem),
6973 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6974 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6975 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6976 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6977 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6978 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6979 BPF_FUNC_map_lookup_elem),
6980 BPF_MOV64_REG(BPF_REG_0, 0),
6981 BPF_EXIT_INSN(),
6982 },
6983 .fixup_map_in_map = { 3 },
6984 .result = ACCEPT,
6985 },
6986 {
6987 "invalid inner map pointer",
6988 .insns = {
6989 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6990 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6992 BPF_LD_MAP_FD(BPF_REG_1, 0),
6993 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6994 BPF_FUNC_map_lookup_elem),
6995 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6996 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6997 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6999 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7000 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7001 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7002 BPF_FUNC_map_lookup_elem),
7003 BPF_MOV64_REG(BPF_REG_0, 0),
7004 BPF_EXIT_INSN(),
7005 },
7006 .fixup_map_in_map = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08007007 .errstr = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007008 .result = REJECT,
7009 },
7010 {
7011 "forgot null checking on the inner map pointer",
7012 .insns = {
7013 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7014 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7015 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7016 BPF_LD_MAP_FD(BPF_REG_1, 0),
7017 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7018 BPF_FUNC_map_lookup_elem),
7019 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7020 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7021 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7022 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7023 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7024 BPF_FUNC_map_lookup_elem),
7025 BPF_MOV64_REG(BPF_REG_0, 0),
7026 BPF_EXIT_INSN(),
7027 },
7028 .fixup_map_in_map = { 3 },
7029 .errstr = "R1 type=map_value_or_null expected=map_ptr",
7030 .result = REJECT,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007031 },
7032 {
7033 "ld_abs: check calling conv, r1",
7034 .insns = {
7035 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7036 BPF_MOV64_IMM(BPF_REG_1, 0),
7037 BPF_LD_ABS(BPF_W, -0x200000),
7038 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7039 BPF_EXIT_INSN(),
7040 },
7041 .errstr = "R1 !read_ok",
7042 .result = REJECT,
7043 },
7044 {
7045 "ld_abs: check calling conv, r2",
7046 .insns = {
7047 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7048 BPF_MOV64_IMM(BPF_REG_2, 0),
7049 BPF_LD_ABS(BPF_W, -0x200000),
7050 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7051 BPF_EXIT_INSN(),
7052 },
7053 .errstr = "R2 !read_ok",
7054 .result = REJECT,
7055 },
7056 {
7057 "ld_abs: check calling conv, r3",
7058 .insns = {
7059 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7060 BPF_MOV64_IMM(BPF_REG_3, 0),
7061 BPF_LD_ABS(BPF_W, -0x200000),
7062 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7063 BPF_EXIT_INSN(),
7064 },
7065 .errstr = "R3 !read_ok",
7066 .result = REJECT,
7067 },
7068 {
7069 "ld_abs: check calling conv, r4",
7070 .insns = {
7071 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7072 BPF_MOV64_IMM(BPF_REG_4, 0),
7073 BPF_LD_ABS(BPF_W, -0x200000),
7074 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7075 BPF_EXIT_INSN(),
7076 },
7077 .errstr = "R4 !read_ok",
7078 .result = REJECT,
7079 },
7080 {
7081 "ld_abs: check calling conv, r5",
7082 .insns = {
7083 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7084 BPF_MOV64_IMM(BPF_REG_5, 0),
7085 BPF_LD_ABS(BPF_W, -0x200000),
7086 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7087 BPF_EXIT_INSN(),
7088 },
7089 .errstr = "R5 !read_ok",
7090 .result = REJECT,
7091 },
7092 {
7093 "ld_abs: check calling conv, r7",
7094 .insns = {
7095 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7096 BPF_MOV64_IMM(BPF_REG_7, 0),
7097 BPF_LD_ABS(BPF_W, -0x200000),
7098 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7099 BPF_EXIT_INSN(),
7100 },
7101 .result = ACCEPT,
7102 },
7103 {
Daniel Borkmann87ab8192017-12-14 21:07:27 +01007104 "ld_abs: tests on r6 and skb data reload helper",
7105 .insns = {
7106 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7107 BPF_LD_ABS(BPF_B, 0),
7108 BPF_LD_ABS(BPF_H, 0),
7109 BPF_LD_ABS(BPF_W, 0),
7110 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
7111 BPF_MOV64_IMM(BPF_REG_6, 0),
7112 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
7113 BPF_MOV64_IMM(BPF_REG_2, 1),
7114 BPF_MOV64_IMM(BPF_REG_3, 2),
7115 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7116 BPF_FUNC_skb_vlan_push),
7117 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
7118 BPF_LD_ABS(BPF_B, 0),
7119 BPF_LD_ABS(BPF_H, 0),
7120 BPF_LD_ABS(BPF_W, 0),
7121 BPF_MOV64_IMM(BPF_REG_0, 42),
7122 BPF_EXIT_INSN(),
7123 },
7124 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7125 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08007126 .retval = 42 /* ultimate return value */,
Daniel Borkmann87ab8192017-12-14 21:07:27 +01007127 },
7128 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007129 "ld_ind: check calling conv, r1",
7130 .insns = {
7131 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7132 BPF_MOV64_IMM(BPF_REG_1, 1),
7133 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
7134 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7135 BPF_EXIT_INSN(),
7136 },
7137 .errstr = "R1 !read_ok",
7138 .result = REJECT,
7139 },
7140 {
7141 "ld_ind: check calling conv, r2",
7142 .insns = {
7143 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7144 BPF_MOV64_IMM(BPF_REG_2, 1),
7145 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
7146 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7147 BPF_EXIT_INSN(),
7148 },
7149 .errstr = "R2 !read_ok",
7150 .result = REJECT,
7151 },
7152 {
7153 "ld_ind: check calling conv, r3",
7154 .insns = {
7155 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7156 BPF_MOV64_IMM(BPF_REG_3, 1),
7157 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
7158 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7159 BPF_EXIT_INSN(),
7160 },
7161 .errstr = "R3 !read_ok",
7162 .result = REJECT,
7163 },
7164 {
7165 "ld_ind: check calling conv, r4",
7166 .insns = {
7167 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7168 BPF_MOV64_IMM(BPF_REG_4, 1),
7169 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
7170 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7171 BPF_EXIT_INSN(),
7172 },
7173 .errstr = "R4 !read_ok",
7174 .result = REJECT,
7175 },
7176 {
7177 "ld_ind: check calling conv, r5",
7178 .insns = {
7179 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7180 BPF_MOV64_IMM(BPF_REG_5, 1),
7181 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
7182 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7183 BPF_EXIT_INSN(),
7184 },
7185 .errstr = "R5 !read_ok",
7186 .result = REJECT,
7187 },
7188 {
7189 "ld_ind: check calling conv, r7",
7190 .insns = {
7191 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7192 BPF_MOV64_IMM(BPF_REG_7, 1),
7193 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
7194 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7195 BPF_EXIT_INSN(),
7196 },
7197 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08007198 .retval = 1,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007199 },
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007200 {
7201 "check bpf_perf_event_data->sample_period byte load permitted",
7202 .insns = {
7203 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007204#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007205 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7206 offsetof(struct bpf_perf_event_data, sample_period)),
7207#else
7208 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7209 offsetof(struct bpf_perf_event_data, sample_period) + 7),
7210#endif
7211 BPF_EXIT_INSN(),
7212 },
7213 .result = ACCEPT,
7214 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7215 },
7216 {
7217 "check bpf_perf_event_data->sample_period half load permitted",
7218 .insns = {
7219 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007220#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007221 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7222 offsetof(struct bpf_perf_event_data, sample_period)),
7223#else
7224 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7225 offsetof(struct bpf_perf_event_data, sample_period) + 6),
7226#endif
7227 BPF_EXIT_INSN(),
7228 },
7229 .result = ACCEPT,
7230 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7231 },
7232 {
7233 "check bpf_perf_event_data->sample_period word load permitted",
7234 .insns = {
7235 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007236#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007237 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7238 offsetof(struct bpf_perf_event_data, sample_period)),
7239#else
7240 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7241 offsetof(struct bpf_perf_event_data, sample_period) + 4),
7242#endif
7243 BPF_EXIT_INSN(),
7244 },
7245 .result = ACCEPT,
7246 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7247 },
7248 {
7249 "check bpf_perf_event_data->sample_period dword load permitted",
7250 .insns = {
7251 BPF_MOV64_IMM(BPF_REG_0, 0),
7252 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
7253 offsetof(struct bpf_perf_event_data, sample_period)),
7254 BPF_EXIT_INSN(),
7255 },
7256 .result = ACCEPT,
7257 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7258 },
7259 {
7260 "check skb->data half load not permitted",
7261 .insns = {
7262 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007263#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007264 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7265 offsetof(struct __sk_buff, data)),
7266#else
7267 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7268 offsetof(struct __sk_buff, data) + 2),
7269#endif
7270 BPF_EXIT_INSN(),
7271 },
7272 .result = REJECT,
7273 .errstr = "invalid bpf_context access",
7274 },
7275 {
7276 "check skb->tc_classid half load not permitted for lwt prog",
7277 .insns = {
7278 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007279#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007280 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7281 offsetof(struct __sk_buff, tc_classid)),
7282#else
7283 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7284 offsetof(struct __sk_buff, tc_classid) + 2),
7285#endif
7286 BPF_EXIT_INSN(),
7287 },
7288 .result = REJECT,
7289 .errstr = "invalid bpf_context access",
7290 .prog_type = BPF_PROG_TYPE_LWT_IN,
7291 },
Edward Creeb7122962017-07-21 00:00:24 +02007292 {
7293 "bounds checks mixing signed and unsigned, positive bounds",
7294 .insns = {
7295 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7296 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7298 BPF_LD_MAP_FD(BPF_REG_1, 0),
7299 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7300 BPF_FUNC_map_lookup_elem),
7301 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7302 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7303 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7304 BPF_MOV64_IMM(BPF_REG_2, 2),
7305 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
7306 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
7307 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7308 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7309 BPF_MOV64_IMM(BPF_REG_0, 0),
7310 BPF_EXIT_INSN(),
7311 },
7312 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007313 .errstr = "unbounded min value",
Edward Creeb7122962017-07-21 00:00:24 +02007314 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02007315 },
7316 {
7317 "bounds checks mixing signed and unsigned",
7318 .insns = {
7319 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7320 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7321 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7322 BPF_LD_MAP_FD(BPF_REG_1, 0),
7323 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7324 BPF_FUNC_map_lookup_elem),
7325 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7326 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7327 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7328 BPF_MOV64_IMM(BPF_REG_2, -1),
7329 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7330 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7331 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7332 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7333 BPF_MOV64_IMM(BPF_REG_0, 0),
7334 BPF_EXIT_INSN(),
7335 },
7336 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007337 .errstr = "unbounded min value",
Edward Creeb7122962017-07-21 00:00:24 +02007338 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02007339 },
Daniel Borkmann86412502017-07-21 00:00:25 +02007340 {
7341 "bounds checks mixing signed and unsigned, variant 2",
7342 .insns = {
7343 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7344 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7346 BPF_LD_MAP_FD(BPF_REG_1, 0),
7347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7348 BPF_FUNC_map_lookup_elem),
7349 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7350 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7351 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7352 BPF_MOV64_IMM(BPF_REG_2, -1),
7353 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7354 BPF_MOV64_IMM(BPF_REG_8, 0),
7355 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
7356 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7357 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7358 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7359 BPF_MOV64_IMM(BPF_REG_0, 0),
7360 BPF_EXIT_INSN(),
7361 },
7362 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007363 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007364 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007365 },
7366 {
7367 "bounds checks mixing signed and unsigned, variant 3",
7368 .insns = {
7369 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7370 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7371 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7372 BPF_LD_MAP_FD(BPF_REG_1, 0),
7373 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7374 BPF_FUNC_map_lookup_elem),
7375 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7376 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7377 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7378 BPF_MOV64_IMM(BPF_REG_2, -1),
7379 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
7380 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
7381 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7382 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7383 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7384 BPF_MOV64_IMM(BPF_REG_0, 0),
7385 BPF_EXIT_INSN(),
7386 },
7387 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007388 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007389 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007390 },
7391 {
7392 "bounds checks mixing signed and unsigned, variant 4",
7393 .insns = {
7394 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7395 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7396 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7397 BPF_LD_MAP_FD(BPF_REG_1, 0),
7398 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7399 BPF_FUNC_map_lookup_elem),
7400 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7401 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7402 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7403 BPF_MOV64_IMM(BPF_REG_2, 1),
7404 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
7405 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7406 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7407 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7408 BPF_MOV64_IMM(BPF_REG_0, 0),
7409 BPF_EXIT_INSN(),
7410 },
7411 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007412 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007413 },
7414 {
7415 "bounds checks mixing signed and unsigned, variant 5",
7416 .insns = {
7417 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7418 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7420 BPF_LD_MAP_FD(BPF_REG_1, 0),
7421 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7422 BPF_FUNC_map_lookup_elem),
7423 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7424 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7425 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7426 BPF_MOV64_IMM(BPF_REG_2, -1),
7427 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7428 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
7429 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
7430 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
7431 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7432 BPF_MOV64_IMM(BPF_REG_0, 0),
7433 BPF_EXIT_INSN(),
7434 },
7435 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007436 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007437 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007438 },
7439 {
7440 "bounds checks mixing signed and unsigned, variant 6",
7441 .insns = {
7442 BPF_MOV64_IMM(BPF_REG_2, 0),
7443 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
7444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
7445 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7446 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
7447 BPF_MOV64_IMM(BPF_REG_6, -1),
7448 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
7449 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
7450 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
7451 BPF_MOV64_IMM(BPF_REG_5, 0),
7452 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
7453 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7454 BPF_FUNC_skb_load_bytes),
7455 BPF_MOV64_IMM(BPF_REG_0, 0),
7456 BPF_EXIT_INSN(),
7457 },
Daniel Borkmann86412502017-07-21 00:00:25 +02007458 .errstr = "R4 min value is negative, either use unsigned",
7459 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007460 },
7461 {
7462 "bounds checks mixing signed and unsigned, variant 7",
7463 .insns = {
7464 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7465 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7466 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7467 BPF_LD_MAP_FD(BPF_REG_1, 0),
7468 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7469 BPF_FUNC_map_lookup_elem),
7470 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7471 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7472 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7473 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
7474 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7475 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7476 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7477 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7478 BPF_MOV64_IMM(BPF_REG_0, 0),
7479 BPF_EXIT_INSN(),
7480 },
7481 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007482 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007483 },
7484 {
7485 "bounds checks mixing signed and unsigned, variant 8",
7486 .insns = {
7487 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7488 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7489 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7490 BPF_LD_MAP_FD(BPF_REG_1, 0),
7491 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7492 BPF_FUNC_map_lookup_elem),
Daniel Borkmann86412502017-07-21 00:00:25 +02007493 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7494 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7495 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7496 BPF_MOV64_IMM(BPF_REG_2, -1),
7497 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7498 BPF_MOV64_IMM(BPF_REG_0, 0),
7499 BPF_EXIT_INSN(),
7500 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7501 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7502 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7503 BPF_MOV64_IMM(BPF_REG_0, 0),
7504 BPF_EXIT_INSN(),
7505 },
7506 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007507 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007508 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007509 },
7510 {
Edward Creef65b1842017-08-07 15:27:12 +01007511 "bounds checks mixing signed and unsigned, variant 9",
Daniel Borkmann86412502017-07-21 00:00:25 +02007512 .insns = {
7513 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7514 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7516 BPF_LD_MAP_FD(BPF_REG_1, 0),
7517 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7518 BPF_FUNC_map_lookup_elem),
7519 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
7520 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7521 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7522 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
7523 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7524 BPF_MOV64_IMM(BPF_REG_0, 0),
7525 BPF_EXIT_INSN(),
7526 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7527 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7528 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7529 BPF_MOV64_IMM(BPF_REG_0, 0),
7530 BPF_EXIT_INSN(),
7531 },
7532 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007533 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007534 },
7535 {
Edward Creef65b1842017-08-07 15:27:12 +01007536 "bounds checks mixing signed and unsigned, variant 10",
Daniel Borkmann86412502017-07-21 00:00:25 +02007537 .insns = {
7538 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7539 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7540 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7541 BPF_LD_MAP_FD(BPF_REG_1, 0),
7542 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7543 BPF_FUNC_map_lookup_elem),
7544 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7545 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7546 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7547 BPF_MOV64_IMM(BPF_REG_2, 0),
7548 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7549 BPF_MOV64_IMM(BPF_REG_0, 0),
7550 BPF_EXIT_INSN(),
7551 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7552 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7553 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7554 BPF_MOV64_IMM(BPF_REG_0, 0),
7555 BPF_EXIT_INSN(),
7556 },
7557 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007558 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007559 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007560 },
7561 {
Edward Creef65b1842017-08-07 15:27:12 +01007562 "bounds checks mixing signed and unsigned, variant 11",
Daniel Borkmann86412502017-07-21 00:00:25 +02007563 .insns = {
7564 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7565 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7566 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7567 BPF_LD_MAP_FD(BPF_REG_1, 0),
7568 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7569 BPF_FUNC_map_lookup_elem),
7570 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7571 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7572 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7573 BPF_MOV64_IMM(BPF_REG_2, -1),
7574 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7575 /* Dead branch. */
7576 BPF_MOV64_IMM(BPF_REG_0, 0),
7577 BPF_EXIT_INSN(),
7578 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7579 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7580 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7581 BPF_MOV64_IMM(BPF_REG_0, 0),
7582 BPF_EXIT_INSN(),
7583 },
7584 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007585 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007586 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007587 },
7588 {
Edward Creef65b1842017-08-07 15:27:12 +01007589 "bounds checks mixing signed and unsigned, variant 12",
Daniel Borkmann86412502017-07-21 00:00:25 +02007590 .insns = {
7591 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7592 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7594 BPF_LD_MAP_FD(BPF_REG_1, 0),
7595 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7596 BPF_FUNC_map_lookup_elem),
7597 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7598 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7599 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7600 BPF_MOV64_IMM(BPF_REG_2, -6),
7601 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7602 BPF_MOV64_IMM(BPF_REG_0, 0),
7603 BPF_EXIT_INSN(),
7604 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7605 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7606 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7607 BPF_MOV64_IMM(BPF_REG_0, 0),
7608 BPF_EXIT_INSN(),
7609 },
7610 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007611 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007612 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007613 },
7614 {
Edward Creef65b1842017-08-07 15:27:12 +01007615 "bounds checks mixing signed and unsigned, variant 13",
Daniel Borkmann86412502017-07-21 00:00:25 +02007616 .insns = {
7617 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7618 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7619 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7620 BPF_LD_MAP_FD(BPF_REG_1, 0),
7621 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7622 BPF_FUNC_map_lookup_elem),
7623 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7624 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7625 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7626 BPF_MOV64_IMM(BPF_REG_2, 2),
7627 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7628 BPF_MOV64_IMM(BPF_REG_7, 1),
7629 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
7630 BPF_MOV64_IMM(BPF_REG_0, 0),
7631 BPF_EXIT_INSN(),
7632 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
7633 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
7634 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
7635 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7636 BPF_MOV64_IMM(BPF_REG_0, 0),
7637 BPF_EXIT_INSN(),
7638 },
7639 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007640 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007641 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007642 },
7643 {
Edward Creef65b1842017-08-07 15:27:12 +01007644 "bounds checks mixing signed and unsigned, variant 14",
Daniel Borkmann86412502017-07-21 00:00:25 +02007645 .insns = {
7646 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
7647 offsetof(struct __sk_buff, mark)),
7648 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7649 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7650 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7651 BPF_LD_MAP_FD(BPF_REG_1, 0),
7652 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7653 BPF_FUNC_map_lookup_elem),
7654 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7655 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7656 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7657 BPF_MOV64_IMM(BPF_REG_2, -1),
7658 BPF_MOV64_IMM(BPF_REG_8, 2),
7659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
7660 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
7661 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7662 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7663 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7664 BPF_MOV64_IMM(BPF_REG_0, 0),
7665 BPF_EXIT_INSN(),
7666 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
7667 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
7668 },
7669 .fixup_map1 = { 4 },
Daniel Borkmann6f161012018-01-18 01:15:21 +01007670 .errstr = "R0 invalid mem access 'inv'",
Daniel Borkmann86412502017-07-21 00:00:25 +02007671 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007672 },
7673 {
Edward Creef65b1842017-08-07 15:27:12 +01007674 "bounds checks mixing signed and unsigned, variant 15",
Daniel Borkmann86412502017-07-21 00:00:25 +02007675 .insns = {
7676 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7677 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7679 BPF_LD_MAP_FD(BPF_REG_1, 0),
7680 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7681 BPF_FUNC_map_lookup_elem),
7682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7683 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7684 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7685 BPF_MOV64_IMM(BPF_REG_2, -6),
7686 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7687 BPF_MOV64_IMM(BPF_REG_0, 0),
7688 BPF_EXIT_INSN(),
7689 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7690 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
7691 BPF_MOV64_IMM(BPF_REG_0, 0),
7692 BPF_EXIT_INSN(),
7693 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7694 BPF_MOV64_IMM(BPF_REG_0, 0),
7695 BPF_EXIT_INSN(),
7696 },
7697 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007698 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007699 .result = REJECT,
7700 .result_unpriv = REJECT,
7701 },
Edward Cree545722c2017-07-21 14:36:57 +01007702 {
Edward Creef65b1842017-08-07 15:27:12 +01007703 "subtraction bounds (map value) variant 1",
Edward Cree545722c2017-07-21 14:36:57 +01007704 .insns = {
7705 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7706 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7707 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7708 BPF_LD_MAP_FD(BPF_REG_1, 0),
7709 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7710 BPF_FUNC_map_lookup_elem),
7711 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7712 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7713 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
7714 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7715 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
7716 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7717 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
7718 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7719 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7720 BPF_EXIT_INSN(),
7721 BPF_MOV64_IMM(BPF_REG_0, 0),
7722 BPF_EXIT_INSN(),
7723 },
7724 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007725 .errstr = "R0 max value is outside of the array range",
7726 .result = REJECT,
7727 },
7728 {
7729 "subtraction bounds (map value) variant 2",
7730 .insns = {
7731 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7732 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7733 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7734 BPF_LD_MAP_FD(BPF_REG_1, 0),
7735 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7736 BPF_FUNC_map_lookup_elem),
7737 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7738 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7739 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
7740 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7741 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
7742 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7743 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7744 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7745 BPF_EXIT_INSN(),
7746 BPF_MOV64_IMM(BPF_REG_0, 0),
7747 BPF_EXIT_INSN(),
7748 },
7749 .fixup_map1 = { 3 },
Edward Cree545722c2017-07-21 14:36:57 +01007750 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
7751 .result = REJECT,
Edward Cree545722c2017-07-21 14:36:57 +01007752 },
Edward Cree69c4e8a2017-08-07 15:29:51 +01007753 {
Jann Horn2255f8d2017-12-18 20:12:01 -08007754 "bounds check based on zero-extended MOV",
7755 .insns = {
7756 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7757 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7758 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7759 BPF_LD_MAP_FD(BPF_REG_1, 0),
7760 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7761 BPF_FUNC_map_lookup_elem),
7762 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7763 /* r2 = 0x0000'0000'ffff'ffff */
7764 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
7765 /* r2 = 0 */
7766 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
7767 /* no-op */
7768 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7769 /* access at offset 0 */
7770 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7771 /* exit */
7772 BPF_MOV64_IMM(BPF_REG_0, 0),
7773 BPF_EXIT_INSN(),
7774 },
7775 .fixup_map1 = { 3 },
7776 .result = ACCEPT
7777 },
7778 {
7779 "bounds check based on sign-extended MOV. test1",
7780 .insns = {
7781 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7782 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7784 BPF_LD_MAP_FD(BPF_REG_1, 0),
7785 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7786 BPF_FUNC_map_lookup_elem),
7787 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7788 /* r2 = 0xffff'ffff'ffff'ffff */
7789 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
7790 /* r2 = 0xffff'ffff */
7791 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
7792 /* r0 = <oob pointer> */
7793 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7794 /* access to OOB pointer */
7795 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7796 /* exit */
7797 BPF_MOV64_IMM(BPF_REG_0, 0),
7798 BPF_EXIT_INSN(),
7799 },
7800 .fixup_map1 = { 3 },
7801 .errstr = "map_value pointer and 4294967295",
7802 .result = REJECT
7803 },
7804 {
7805 "bounds check based on sign-extended MOV. test2",
7806 .insns = {
7807 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7808 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7809 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7810 BPF_LD_MAP_FD(BPF_REG_1, 0),
7811 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7812 BPF_FUNC_map_lookup_elem),
7813 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7814 /* r2 = 0xffff'ffff'ffff'ffff */
7815 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
7816 /* r2 = 0xfff'ffff */
7817 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
7818 /* r0 = <oob pointer> */
7819 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
7820 /* access to OOB pointer */
7821 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7822 /* exit */
7823 BPF_MOV64_IMM(BPF_REG_0, 0),
7824 BPF_EXIT_INSN(),
7825 },
7826 .fixup_map1 = { 3 },
7827 .errstr = "R0 min value is outside of the array range",
7828 .result = REJECT
7829 },
7830 {
7831 "bounds check based on reg_off + var_off + insn_off. test1",
7832 .insns = {
7833 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
7834 offsetof(struct __sk_buff, mark)),
7835 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7836 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7837 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7838 BPF_LD_MAP_FD(BPF_REG_1, 0),
7839 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7840 BPF_FUNC_map_lookup_elem),
7841 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7842 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
7843 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
7844 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
7845 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
7846 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
7847 BPF_MOV64_IMM(BPF_REG_0, 0),
7848 BPF_EXIT_INSN(),
7849 },
7850 .fixup_map1 = { 4 },
7851 .errstr = "value_size=8 off=1073741825",
7852 .result = REJECT,
7853 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7854 },
7855 {
7856 "bounds check based on reg_off + var_off + insn_off. test2",
7857 .insns = {
7858 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
7859 offsetof(struct __sk_buff, mark)),
7860 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7861 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7863 BPF_LD_MAP_FD(BPF_REG_1, 0),
7864 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7865 BPF_FUNC_map_lookup_elem),
7866 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7867 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
7868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
7869 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
7870 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
7871 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
7872 BPF_MOV64_IMM(BPF_REG_0, 0),
7873 BPF_EXIT_INSN(),
7874 },
7875 .fixup_map1 = { 4 },
7876 .errstr = "value 1073741823",
7877 .result = REJECT,
7878 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7879 },
7880 {
7881 "bounds check after truncation of non-boundary-crossing range",
7882 .insns = {
7883 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7884 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7885 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7886 BPF_LD_MAP_FD(BPF_REG_1, 0),
7887 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7888 BPF_FUNC_map_lookup_elem),
7889 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7890 /* r1 = [0x00, 0xff] */
7891 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7892 BPF_MOV64_IMM(BPF_REG_2, 1),
7893 /* r2 = 0x10'0000'0000 */
7894 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
7895 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
7896 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
7897 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
7898 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
7899 /* r1 = [0x00, 0xff] */
7900 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
7901 /* r1 = 0 */
7902 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7903 /* no-op */
7904 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7905 /* access at offset 0 */
7906 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7907 /* exit */
7908 BPF_MOV64_IMM(BPF_REG_0, 0),
7909 BPF_EXIT_INSN(),
7910 },
7911 .fixup_map1 = { 3 },
7912 .result = ACCEPT
7913 },
7914 {
7915 "bounds check after truncation of boundary-crossing range (1)",
7916 .insns = {
7917 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7918 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7919 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7920 BPF_LD_MAP_FD(BPF_REG_1, 0),
7921 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7922 BPF_FUNC_map_lookup_elem),
7923 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7924 /* r1 = [0x00, 0xff] */
7925 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7926 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7927 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7928 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7929 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7930 * [0x0000'0000, 0x0000'007f]
7931 */
7932 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
7933 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7934 /* r1 = [0x00, 0xff] or
7935 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7936 */
7937 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7938 /* r1 = 0 or
7939 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7940 */
7941 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7942 /* no-op or OOB pointer computation */
7943 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7944 /* potentially OOB access */
7945 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7946 /* exit */
7947 BPF_MOV64_IMM(BPF_REG_0, 0),
7948 BPF_EXIT_INSN(),
7949 },
7950 .fixup_map1 = { 3 },
7951 /* not actually fully unbounded, but the bound is very high */
7952 .errstr = "R0 unbounded memory access",
7953 .result = REJECT
7954 },
7955 {
7956 "bounds check after truncation of boundary-crossing range (2)",
7957 .insns = {
7958 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7959 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7960 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7961 BPF_LD_MAP_FD(BPF_REG_1, 0),
7962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7963 BPF_FUNC_map_lookup_elem),
7964 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7965 /* r1 = [0x00, 0xff] */
7966 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7968 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
7969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
7970 /* r1 = [0xffff'ff80, 0xffff'ffff] or
7971 * [0x0000'0000, 0x0000'007f]
7972 * difference to previous test: truncation via MOV32
7973 * instead of ALU32.
7974 */
7975 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
7976 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7977 /* r1 = [0x00, 0xff] or
7978 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
7979 */
7980 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
7981 /* r1 = 0 or
7982 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
7983 */
7984 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
7985 /* no-op or OOB pointer computation */
7986 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7987 /* potentially OOB access */
7988 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7989 /* exit */
7990 BPF_MOV64_IMM(BPF_REG_0, 0),
7991 BPF_EXIT_INSN(),
7992 },
7993 .fixup_map1 = { 3 },
7994 /* not actually fully unbounded, but the bound is very high */
7995 .errstr = "R0 unbounded memory access",
7996 .result = REJECT
7997 },
7998 {
7999 "bounds check after wrapping 32-bit addition",
8000 .insns = {
8001 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8002 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8003 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8004 BPF_LD_MAP_FD(BPF_REG_1, 0),
8005 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8006 BPF_FUNC_map_lookup_elem),
8007 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
8008 /* r1 = 0x7fff'ffff */
8009 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
8010 /* r1 = 0xffff'fffe */
8011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8012 /* r1 = 0 */
8013 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
8014 /* no-op */
8015 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8016 /* access at offset 0 */
8017 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8018 /* exit */
8019 BPF_MOV64_IMM(BPF_REG_0, 0),
8020 BPF_EXIT_INSN(),
8021 },
8022 .fixup_map1 = { 3 },
8023 .result = ACCEPT
8024 },
8025 {
8026 "bounds check after shift with oversized count operand",
8027 .insns = {
8028 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8029 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8030 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8031 BPF_LD_MAP_FD(BPF_REG_1, 0),
8032 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8033 BPF_FUNC_map_lookup_elem),
8034 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8035 BPF_MOV64_IMM(BPF_REG_2, 32),
8036 BPF_MOV64_IMM(BPF_REG_1, 1),
8037 /* r1 = (u32)1 << (u32)32 = ? */
8038 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
8039 /* r1 = [0x0000, 0xffff] */
8040 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
8041 /* computes unknown pointer, potentially OOB */
8042 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8043 /* potentially OOB access */
8044 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8045 /* exit */
8046 BPF_MOV64_IMM(BPF_REG_0, 0),
8047 BPF_EXIT_INSN(),
8048 },
8049 .fixup_map1 = { 3 },
8050 .errstr = "R0 max value is outside of the array range",
8051 .result = REJECT
8052 },
8053 {
8054 "bounds check after right shift of maybe-negative number",
8055 .insns = {
8056 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8057 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8059 BPF_LD_MAP_FD(BPF_REG_1, 0),
8060 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8061 BPF_FUNC_map_lookup_elem),
8062 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8063 /* r1 = [0x00, 0xff] */
8064 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8065 /* r1 = [-0x01, 0xfe] */
8066 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
8067 /* r1 = 0 or 0xff'ffff'ffff'ffff */
8068 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8069 /* r1 = 0 or 0xffff'ffff'ffff */
8070 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8071 /* computes unknown pointer, potentially OOB */
8072 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8073 /* potentially OOB access */
8074 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8075 /* exit */
8076 BPF_MOV64_IMM(BPF_REG_0, 0),
8077 BPF_EXIT_INSN(),
8078 },
8079 .fixup_map1 = { 3 },
8080 .errstr = "R0 unbounded memory access",
8081 .result = REJECT
8082 },
8083 {
8084 "bounds check map access with off+size signed 32bit overflow. test1",
8085 .insns = {
8086 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8087 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8088 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8089 BPF_LD_MAP_FD(BPF_REG_1, 0),
8090 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8091 BPF_FUNC_map_lookup_elem),
8092 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8093 BPF_EXIT_INSN(),
8094 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
8095 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8096 BPF_JMP_A(0),
8097 BPF_EXIT_INSN(),
8098 },
8099 .fixup_map1 = { 3 },
8100 .errstr = "map_value pointer and 2147483646",
8101 .result = REJECT
8102 },
8103 {
8104 "bounds check map access with off+size signed 32bit overflow. test2",
8105 .insns = {
8106 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8107 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8108 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8109 BPF_LD_MAP_FD(BPF_REG_1, 0),
8110 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8111 BPF_FUNC_map_lookup_elem),
8112 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8113 BPF_EXIT_INSN(),
8114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8117 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8118 BPF_JMP_A(0),
8119 BPF_EXIT_INSN(),
8120 },
8121 .fixup_map1 = { 3 },
8122 .errstr = "pointer offset 1073741822",
8123 .result = REJECT
8124 },
8125 {
8126 "bounds check map access with off+size signed 32bit overflow. test3",
8127 .insns = {
8128 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8129 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8131 BPF_LD_MAP_FD(BPF_REG_1, 0),
8132 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8133 BPF_FUNC_map_lookup_elem),
8134 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8135 BPF_EXIT_INSN(),
8136 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8137 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8138 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8139 BPF_JMP_A(0),
8140 BPF_EXIT_INSN(),
8141 },
8142 .fixup_map1 = { 3 },
8143 .errstr = "pointer offset -1073741822",
8144 .result = REJECT
8145 },
8146 {
8147 "bounds check map access with off+size signed 32bit overflow. test4",
8148 .insns = {
8149 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8150 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8151 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8152 BPF_LD_MAP_FD(BPF_REG_1, 0),
8153 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8154 BPF_FUNC_map_lookup_elem),
8155 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8156 BPF_EXIT_INSN(),
8157 BPF_MOV64_IMM(BPF_REG_1, 1000000),
8158 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
8159 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8160 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8161 BPF_JMP_A(0),
8162 BPF_EXIT_INSN(),
8163 },
8164 .fixup_map1 = { 3 },
8165 .errstr = "map_value pointer and 1000000000000",
8166 .result = REJECT
8167 },
8168 {
8169 "pointer/scalar confusion in state equality check (way 1)",
8170 .insns = {
8171 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8172 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8173 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8174 BPF_LD_MAP_FD(BPF_REG_1, 0),
8175 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8176 BPF_FUNC_map_lookup_elem),
8177 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
8178 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8179 BPF_JMP_A(1),
8180 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8181 BPF_JMP_A(0),
8182 BPF_EXIT_INSN(),
8183 },
8184 .fixup_map1 = { 3 },
8185 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008186 .retval = POINTER_VALUE,
Jann Horn2255f8d2017-12-18 20:12:01 -08008187 .result_unpriv = REJECT,
8188 .errstr_unpriv = "R0 leaks addr as return value"
8189 },
8190 {
8191 "pointer/scalar confusion in state equality check (way 2)",
8192 .insns = {
8193 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8194 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8196 BPF_LD_MAP_FD(BPF_REG_1, 0),
8197 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8198 BPF_FUNC_map_lookup_elem),
8199 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8200 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8201 BPF_JMP_A(1),
8202 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8203 BPF_EXIT_INSN(),
8204 },
8205 .fixup_map1 = { 3 },
8206 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008207 .retval = POINTER_VALUE,
Jann Horn2255f8d2017-12-18 20:12:01 -08008208 .result_unpriv = REJECT,
8209 .errstr_unpriv = "R0 leaks addr as return value"
8210 },
8211 {
Edward Cree69c4e8a2017-08-07 15:29:51 +01008212 "variable-offset ctx access",
8213 .insns = {
8214 /* Get an unknown value */
8215 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8216 /* Make it small and 4-byte aligned */
8217 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8218 /* add it to skb. We now have either &skb->len or
8219 * &skb->pkt_type, but we don't know which
8220 */
8221 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
8222 /* dereference it */
8223 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8224 BPF_EXIT_INSN(),
8225 },
8226 .errstr = "variable ctx access var_off=(0x0; 0x4)",
8227 .result = REJECT,
8228 .prog_type = BPF_PROG_TYPE_LWT_IN,
8229 },
8230 {
8231 "variable-offset stack access",
8232 .insns = {
8233 /* Fill the top 8 bytes of the stack */
8234 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8235 /* Get an unknown value */
8236 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8237 /* Make it small and 4-byte aligned */
8238 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8239 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8240 /* add it to fp. We now have either fp-4 or fp-8, but
8241 * we don't know which
8242 */
8243 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8244 /* dereference it */
8245 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
8246 BPF_EXIT_INSN(),
8247 },
8248 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
8249 .result = REJECT,
8250 .prog_type = BPF_PROG_TYPE_LWT_IN,
8251 },
Edward Creed893dc22017-08-23 15:09:46 +01008252 {
Jann Horn2255f8d2017-12-18 20:12:01 -08008253 "indirect variable-offset stack access",
8254 .insns = {
8255 /* Fill the top 8 bytes of the stack */
8256 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8257 /* Get an unknown value */
8258 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8259 /* Make it small and 4-byte aligned */
8260 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8261 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8262 /* add it to fp. We now have either fp-4 or fp-8, but
8263 * we don't know which
8264 */
8265 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8266 /* dereference it indirectly */
8267 BPF_LD_MAP_FD(BPF_REG_1, 0),
8268 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8269 BPF_FUNC_map_lookup_elem),
8270 BPF_MOV64_IMM(BPF_REG_0, 0),
8271 BPF_EXIT_INSN(),
8272 },
8273 .fixup_map1 = { 5 },
8274 .errstr = "variable stack read R2",
8275 .result = REJECT,
8276 .prog_type = BPF_PROG_TYPE_LWT_IN,
8277 },
8278 {
8279 "direct stack access with 32-bit wraparound. test1",
8280 .insns = {
8281 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8284 BPF_MOV32_IMM(BPF_REG_0, 0),
8285 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8286 BPF_EXIT_INSN()
8287 },
8288 .errstr = "fp pointer and 2147483647",
8289 .result = REJECT
8290 },
8291 {
8292 "direct stack access with 32-bit wraparound. test2",
8293 .insns = {
8294 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8295 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8296 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8297 BPF_MOV32_IMM(BPF_REG_0, 0),
8298 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8299 BPF_EXIT_INSN()
8300 },
8301 .errstr = "fp pointer and 1073741823",
8302 .result = REJECT
8303 },
8304 {
8305 "direct stack access with 32-bit wraparound. test3",
8306 .insns = {
8307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8308 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8309 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8310 BPF_MOV32_IMM(BPF_REG_0, 0),
8311 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8312 BPF_EXIT_INSN()
8313 },
8314 .errstr = "fp pointer offset 1073741822",
8315 .result = REJECT
8316 },
8317 {
Edward Creed893dc22017-08-23 15:09:46 +01008318 "liveness pruning and write screening",
8319 .insns = {
8320 /* Get an unknown value */
8321 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8322 /* branch conditions teach us nothing about R2 */
8323 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8324 BPF_MOV64_IMM(BPF_REG_0, 0),
8325 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8326 BPF_MOV64_IMM(BPF_REG_0, 0),
8327 BPF_EXIT_INSN(),
8328 },
8329 .errstr = "R0 !read_ok",
8330 .result = REJECT,
8331 .prog_type = BPF_PROG_TYPE_LWT_IN,
8332 },
Alexei Starovoitovdf20cb72017-08-23 15:10:26 +01008333 {
8334 "varlen_map_value_access pruning",
8335 .insns = {
8336 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8337 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8339 BPF_LD_MAP_FD(BPF_REG_1, 0),
8340 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8341 BPF_FUNC_map_lookup_elem),
8342 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8343 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
8344 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
8345 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
8346 BPF_MOV32_IMM(BPF_REG_1, 0),
8347 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
8348 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8349 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
8350 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
8351 offsetof(struct test_val, foo)),
8352 BPF_EXIT_INSN(),
8353 },
8354 .fixup_map2 = { 3 },
8355 .errstr_unpriv = "R0 leaks addr",
8356 .errstr = "R0 unbounded memory access",
8357 .result_unpriv = REJECT,
8358 .result = REJECT,
8359 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8360 },
Edward Creee67b8a62017-09-15 14:37:38 +01008361 {
8362 "invalid 64-bit BPF_END",
8363 .insns = {
8364 BPF_MOV32_IMM(BPF_REG_0, 0),
8365 {
8366 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
8367 .dst_reg = BPF_REG_0,
8368 .src_reg = 0,
8369 .off = 0,
8370 .imm = 32,
8371 },
8372 BPF_EXIT_INSN(),
8373 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01008374 .errstr = "unknown opcode d7",
Edward Creee67b8a62017-09-15 14:37:38 +01008375 .result = REJECT,
8376 },
Daniel Borkmann22c88522017-09-25 02:25:53 +02008377 {
Daniel Borkmann65073a62018-01-31 12:58:56 +01008378 "XDP, using ifindex from netdev",
8379 .insns = {
8380 BPF_MOV64_IMM(BPF_REG_0, 0),
8381 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8382 offsetof(struct xdp_md, ingress_ifindex)),
8383 BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
8384 BPF_MOV64_IMM(BPF_REG_0, 1),
8385 BPF_EXIT_INSN(),
8386 },
8387 .result = ACCEPT,
8388 .prog_type = BPF_PROG_TYPE_XDP,
8389 .retval = 1,
8390 },
8391 {
Daniel Borkmann22c88522017-09-25 02:25:53 +02008392 "meta access, test1",
8393 .insns = {
8394 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8395 offsetof(struct xdp_md, data_meta)),
8396 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8397 offsetof(struct xdp_md, data)),
8398 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8400 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8401 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8402 BPF_MOV64_IMM(BPF_REG_0, 0),
8403 BPF_EXIT_INSN(),
8404 },
8405 .result = ACCEPT,
8406 .prog_type = BPF_PROG_TYPE_XDP,
8407 },
8408 {
8409 "meta access, test2",
8410 .insns = {
8411 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8412 offsetof(struct xdp_md, data_meta)),
8413 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8414 offsetof(struct xdp_md, data)),
8415 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8416 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
8417 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8418 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8419 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8420 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8421 BPF_MOV64_IMM(BPF_REG_0, 0),
8422 BPF_EXIT_INSN(),
8423 },
8424 .result = REJECT,
8425 .errstr = "invalid access to packet, off=-8",
8426 .prog_type = BPF_PROG_TYPE_XDP,
8427 },
8428 {
8429 "meta access, test3",
8430 .insns = {
8431 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8432 offsetof(struct xdp_md, data_meta)),
8433 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8434 offsetof(struct xdp_md, data_end)),
8435 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8437 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8438 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8439 BPF_MOV64_IMM(BPF_REG_0, 0),
8440 BPF_EXIT_INSN(),
8441 },
8442 .result = REJECT,
8443 .errstr = "invalid access to packet",
8444 .prog_type = BPF_PROG_TYPE_XDP,
8445 },
8446 {
8447 "meta access, test4",
8448 .insns = {
8449 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8450 offsetof(struct xdp_md, data_meta)),
8451 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8452 offsetof(struct xdp_md, data_end)),
8453 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8454 offsetof(struct xdp_md, data)),
8455 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
8456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8457 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8458 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8459 BPF_MOV64_IMM(BPF_REG_0, 0),
8460 BPF_EXIT_INSN(),
8461 },
8462 .result = REJECT,
8463 .errstr = "invalid access to packet",
8464 .prog_type = BPF_PROG_TYPE_XDP,
8465 },
8466 {
8467 "meta access, test5",
8468 .insns = {
8469 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8470 offsetof(struct xdp_md, data_meta)),
8471 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8472 offsetof(struct xdp_md, data)),
8473 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8474 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8475 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
8476 BPF_MOV64_IMM(BPF_REG_2, -8),
8477 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8478 BPF_FUNC_xdp_adjust_meta),
8479 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8480 BPF_MOV64_IMM(BPF_REG_0, 0),
8481 BPF_EXIT_INSN(),
8482 },
8483 .result = REJECT,
8484 .errstr = "R3 !read_ok",
8485 .prog_type = BPF_PROG_TYPE_XDP,
8486 },
8487 {
8488 "meta access, test6",
8489 .insns = {
8490 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8491 offsetof(struct xdp_md, data_meta)),
8492 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8493 offsetof(struct xdp_md, data)),
8494 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8495 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8496 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8497 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8498 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
8499 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8500 BPF_MOV64_IMM(BPF_REG_0, 0),
8501 BPF_EXIT_INSN(),
8502 },
8503 .result = REJECT,
8504 .errstr = "invalid access to packet",
8505 .prog_type = BPF_PROG_TYPE_XDP,
8506 },
8507 {
8508 "meta access, test7",
8509 .insns = {
8510 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8511 offsetof(struct xdp_md, data_meta)),
8512 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8513 offsetof(struct xdp_md, data)),
8514 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8516 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8517 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8518 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8519 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8520 BPF_MOV64_IMM(BPF_REG_0, 0),
8521 BPF_EXIT_INSN(),
8522 },
8523 .result = ACCEPT,
8524 .prog_type = BPF_PROG_TYPE_XDP,
8525 },
8526 {
8527 "meta access, test8",
8528 .insns = {
8529 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8530 offsetof(struct xdp_md, data_meta)),
8531 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8532 offsetof(struct xdp_md, data)),
8533 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8535 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8536 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8537 BPF_MOV64_IMM(BPF_REG_0, 0),
8538 BPF_EXIT_INSN(),
8539 },
8540 .result = ACCEPT,
8541 .prog_type = BPF_PROG_TYPE_XDP,
8542 },
8543 {
8544 "meta access, test9",
8545 .insns = {
8546 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8547 offsetof(struct xdp_md, data_meta)),
8548 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8549 offsetof(struct xdp_md, data)),
8550 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8552 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
8553 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8554 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8555 BPF_MOV64_IMM(BPF_REG_0, 0),
8556 BPF_EXIT_INSN(),
8557 },
8558 .result = REJECT,
8559 .errstr = "invalid access to packet",
8560 .prog_type = BPF_PROG_TYPE_XDP,
8561 },
8562 {
8563 "meta access, test10",
8564 .insns = {
8565 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8566 offsetof(struct xdp_md, data_meta)),
8567 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8568 offsetof(struct xdp_md, data)),
8569 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8570 offsetof(struct xdp_md, data_end)),
8571 BPF_MOV64_IMM(BPF_REG_5, 42),
8572 BPF_MOV64_IMM(BPF_REG_6, 24),
8573 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8574 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8575 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8576 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8577 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
8578 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8579 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8581 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
8582 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
8583 BPF_MOV64_IMM(BPF_REG_0, 0),
8584 BPF_EXIT_INSN(),
8585 },
8586 .result = REJECT,
8587 .errstr = "invalid access to packet",
8588 .prog_type = BPF_PROG_TYPE_XDP,
8589 },
8590 {
8591 "meta access, test11",
8592 .insns = {
8593 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8594 offsetof(struct xdp_md, data_meta)),
8595 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8596 offsetof(struct xdp_md, data)),
8597 BPF_MOV64_IMM(BPF_REG_5, 42),
8598 BPF_MOV64_IMM(BPF_REG_6, 24),
8599 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8600 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8601 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8602 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8603 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
8604 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8605 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8606 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8607 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
8608 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
8609 BPF_MOV64_IMM(BPF_REG_0, 0),
8610 BPF_EXIT_INSN(),
8611 },
8612 .result = ACCEPT,
8613 .prog_type = BPF_PROG_TYPE_XDP,
8614 },
8615 {
8616 "meta access, test12",
8617 .insns = {
8618 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8619 offsetof(struct xdp_md, data_meta)),
8620 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8621 offsetof(struct xdp_md, data)),
8622 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8623 offsetof(struct xdp_md, data_end)),
8624 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8625 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8626 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
8627 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8628 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8629 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8630 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
8631 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8632 BPF_MOV64_IMM(BPF_REG_0, 0),
8633 BPF_EXIT_INSN(),
8634 },
8635 .result = ACCEPT,
8636 .prog_type = BPF_PROG_TYPE_XDP,
8637 },
Alexei Starovoitov390ee7e2017-10-02 22:50:23 -07008638 {
Jakub Kicinski28e33f92017-10-16 11:16:55 -07008639 "arithmetic ops make PTR_TO_CTX unusable",
8640 .insns = {
8641 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
8642 offsetof(struct __sk_buff, data) -
8643 offsetof(struct __sk_buff, mark)),
8644 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8645 offsetof(struct __sk_buff, mark)),
8646 BPF_EXIT_INSN(),
8647 },
8648 .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
8649 .result = REJECT,
8650 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8651 },
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008652 {
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008653 "pkt_end - pkt_start is allowed",
8654 .insns = {
8655 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8656 offsetof(struct __sk_buff, data_end)),
8657 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8658 offsetof(struct __sk_buff, data)),
8659 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
8660 BPF_EXIT_INSN(),
8661 },
8662 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008663 .retval = TEST_DATA_LEN,
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008664 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8665 },
8666 {
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008667 "XDP pkt read, pkt_end mangling, bad access 1",
8668 .insns = {
8669 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8670 offsetof(struct xdp_md, data)),
8671 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8672 offsetof(struct xdp_md, data_end)),
8673 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8675 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
8676 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8677 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8678 BPF_MOV64_IMM(BPF_REG_0, 0),
8679 BPF_EXIT_INSN(),
8680 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008681 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008682 .result = REJECT,
8683 .prog_type = BPF_PROG_TYPE_XDP,
8684 },
8685 {
8686 "XDP pkt read, pkt_end mangling, bad access 2",
8687 .insns = {
8688 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8689 offsetof(struct xdp_md, data)),
8690 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8691 offsetof(struct xdp_md, data_end)),
8692 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8694 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
8695 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8696 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8697 BPF_MOV64_IMM(BPF_REG_0, 0),
8698 BPF_EXIT_INSN(),
8699 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008700 .errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008701 .result = REJECT,
8702 .prog_type = BPF_PROG_TYPE_XDP,
8703 },
8704 {
8705 "XDP pkt read, pkt_data' > pkt_end, good access",
8706 .insns = {
8707 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8708 offsetof(struct xdp_md, data)),
8709 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8710 offsetof(struct xdp_md, data_end)),
8711 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8712 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8713 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8714 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8715 BPF_MOV64_IMM(BPF_REG_0, 0),
8716 BPF_EXIT_INSN(),
8717 },
8718 .result = ACCEPT,
8719 .prog_type = BPF_PROG_TYPE_XDP,
8720 },
8721 {
8722 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
8723 .insns = {
8724 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8725 offsetof(struct xdp_md, data)),
8726 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8727 offsetof(struct xdp_md, data_end)),
8728 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8729 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8730 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8731 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8732 BPF_MOV64_IMM(BPF_REG_0, 0),
8733 BPF_EXIT_INSN(),
8734 },
8735 .errstr = "R1 offset is outside of the packet",
8736 .result = REJECT,
8737 .prog_type = BPF_PROG_TYPE_XDP,
8738 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8739 },
8740 {
8741 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
8742 .insns = {
8743 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8744 offsetof(struct xdp_md, data)),
8745 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8746 offsetof(struct xdp_md, data_end)),
8747 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8748 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8749 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8750 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8751 BPF_MOV64_IMM(BPF_REG_0, 0),
8752 BPF_EXIT_INSN(),
8753 },
8754 .errstr = "R1 offset is outside of the packet",
8755 .result = REJECT,
8756 .prog_type = BPF_PROG_TYPE_XDP,
8757 },
8758 {
8759 "XDP pkt read, pkt_end > pkt_data', good access",
8760 .insns = {
8761 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8762 offsetof(struct xdp_md, data)),
8763 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8764 offsetof(struct xdp_md, data_end)),
8765 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8766 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8767 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8768 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8769 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8770 BPF_MOV64_IMM(BPF_REG_0, 0),
8771 BPF_EXIT_INSN(),
8772 },
8773 .result = ACCEPT,
8774 .prog_type = BPF_PROG_TYPE_XDP,
8775 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8776 },
8777 {
8778 "XDP pkt read, pkt_end > pkt_data', bad access 1",
8779 .insns = {
8780 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8781 offsetof(struct xdp_md, data)),
8782 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8783 offsetof(struct xdp_md, data_end)),
8784 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8785 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8786 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8787 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8788 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8789 BPF_MOV64_IMM(BPF_REG_0, 0),
8790 BPF_EXIT_INSN(),
8791 },
8792 .errstr = "R1 offset is outside of the packet",
8793 .result = REJECT,
8794 .prog_type = BPF_PROG_TYPE_XDP,
8795 },
8796 {
8797 "XDP pkt read, pkt_end > pkt_data', bad access 2",
8798 .insns = {
8799 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8800 offsetof(struct xdp_md, data)),
8801 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8802 offsetof(struct xdp_md, data_end)),
8803 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8804 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8805 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8806 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8807 BPF_MOV64_IMM(BPF_REG_0, 0),
8808 BPF_EXIT_INSN(),
8809 },
8810 .errstr = "R1 offset is outside of the packet",
8811 .result = REJECT,
8812 .prog_type = BPF_PROG_TYPE_XDP,
8813 },
8814 {
8815 "XDP pkt read, pkt_data' < pkt_end, good access",
8816 .insns = {
8817 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8818 offsetof(struct xdp_md, data)),
8819 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8820 offsetof(struct xdp_md, data_end)),
8821 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8823 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8824 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8825 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8826 BPF_MOV64_IMM(BPF_REG_0, 0),
8827 BPF_EXIT_INSN(),
8828 },
8829 .result = ACCEPT,
8830 .prog_type = BPF_PROG_TYPE_XDP,
8831 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8832 },
8833 {
8834 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
8835 .insns = {
8836 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8837 offsetof(struct xdp_md, data)),
8838 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8839 offsetof(struct xdp_md, data_end)),
8840 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8842 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8843 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8844 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8845 BPF_MOV64_IMM(BPF_REG_0, 0),
8846 BPF_EXIT_INSN(),
8847 },
8848 .errstr = "R1 offset is outside of the packet",
8849 .result = REJECT,
8850 .prog_type = BPF_PROG_TYPE_XDP,
8851 },
8852 {
8853 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
8854 .insns = {
8855 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8856 offsetof(struct xdp_md, data)),
8857 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8858 offsetof(struct xdp_md, data_end)),
8859 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8860 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8861 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8862 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8863 BPF_MOV64_IMM(BPF_REG_0, 0),
8864 BPF_EXIT_INSN(),
8865 },
8866 .errstr = "R1 offset is outside of the packet",
8867 .result = REJECT,
8868 .prog_type = BPF_PROG_TYPE_XDP,
8869 },
8870 {
8871 "XDP pkt read, pkt_end < pkt_data', good access",
8872 .insns = {
8873 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8874 offsetof(struct xdp_md, data)),
8875 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8876 offsetof(struct xdp_md, data_end)),
8877 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8879 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8880 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8881 BPF_MOV64_IMM(BPF_REG_0, 0),
8882 BPF_EXIT_INSN(),
8883 },
8884 .result = ACCEPT,
8885 .prog_type = BPF_PROG_TYPE_XDP,
8886 },
8887 {
8888 "XDP pkt read, pkt_end < pkt_data', bad access 1",
8889 .insns = {
8890 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8891 offsetof(struct xdp_md, data)),
8892 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8893 offsetof(struct xdp_md, data_end)),
8894 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8895 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8896 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8897 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8898 BPF_MOV64_IMM(BPF_REG_0, 0),
8899 BPF_EXIT_INSN(),
8900 },
8901 .errstr = "R1 offset is outside of the packet",
8902 .result = REJECT,
8903 .prog_type = BPF_PROG_TYPE_XDP,
8904 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8905 },
8906 {
8907 "XDP pkt read, pkt_end < pkt_data', bad access 2",
8908 .insns = {
8909 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8910 offsetof(struct xdp_md, data)),
8911 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8912 offsetof(struct xdp_md, data_end)),
8913 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8914 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8915 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
8916 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8917 BPF_MOV64_IMM(BPF_REG_0, 0),
8918 BPF_EXIT_INSN(),
8919 },
8920 .errstr = "R1 offset is outside of the packet",
8921 .result = REJECT,
8922 .prog_type = BPF_PROG_TYPE_XDP,
8923 },
8924 {
8925 "XDP pkt read, pkt_data' >= pkt_end, good access",
8926 .insns = {
8927 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8928 offsetof(struct xdp_md, data)),
8929 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8930 offsetof(struct xdp_md, data_end)),
8931 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8932 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8933 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8934 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8935 BPF_MOV64_IMM(BPF_REG_0, 0),
8936 BPF_EXIT_INSN(),
8937 },
8938 .result = ACCEPT,
8939 .prog_type = BPF_PROG_TYPE_XDP,
8940 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8941 },
8942 {
8943 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
8944 .insns = {
8945 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8946 offsetof(struct xdp_md, data)),
8947 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8948 offsetof(struct xdp_md, data_end)),
8949 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8950 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8951 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8952 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8953 BPF_MOV64_IMM(BPF_REG_0, 0),
8954 BPF_EXIT_INSN(),
8955 },
8956 .errstr = "R1 offset is outside of the packet",
8957 .result = REJECT,
8958 .prog_type = BPF_PROG_TYPE_XDP,
8959 },
8960 {
8961 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
8962 .insns = {
8963 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8964 offsetof(struct xdp_md, data)),
8965 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8966 offsetof(struct xdp_md, data_end)),
8967 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8969 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8970 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8971 BPF_MOV64_IMM(BPF_REG_0, 0),
8972 BPF_EXIT_INSN(),
8973 },
8974 .errstr = "R1 offset is outside of the packet",
8975 .result = REJECT,
8976 .prog_type = BPF_PROG_TYPE_XDP,
8977 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8978 },
8979 {
8980 "XDP pkt read, pkt_end >= pkt_data', good access",
8981 .insns = {
8982 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8983 offsetof(struct xdp_md, data)),
8984 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8985 offsetof(struct xdp_md, data_end)),
8986 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8987 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8988 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8989 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8990 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8991 BPF_MOV64_IMM(BPF_REG_0, 0),
8992 BPF_EXIT_INSN(),
8993 },
8994 .result = ACCEPT,
8995 .prog_type = BPF_PROG_TYPE_XDP,
8996 },
8997 {
8998 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
8999 .insns = {
9000 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9001 offsetof(struct xdp_md, data)),
9002 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9003 offsetof(struct xdp_md, data_end)),
9004 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9005 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9006 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9007 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9008 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9009 BPF_MOV64_IMM(BPF_REG_0, 0),
9010 BPF_EXIT_INSN(),
9011 },
9012 .errstr = "R1 offset is outside of the packet",
9013 .result = REJECT,
9014 .prog_type = BPF_PROG_TYPE_XDP,
9015 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9016 },
9017 {
9018 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
9019 .insns = {
9020 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9021 offsetof(struct xdp_md, data)),
9022 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9023 offsetof(struct xdp_md, data_end)),
9024 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9026 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9027 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9028 BPF_MOV64_IMM(BPF_REG_0, 0),
9029 BPF_EXIT_INSN(),
9030 },
9031 .errstr = "R1 offset is outside of the packet",
9032 .result = REJECT,
9033 .prog_type = BPF_PROG_TYPE_XDP,
9034 },
9035 {
9036 "XDP pkt read, pkt_data' <= pkt_end, good access",
9037 .insns = {
9038 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9039 offsetof(struct xdp_md, data)),
9040 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9041 offsetof(struct xdp_md, data_end)),
9042 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9044 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9045 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9046 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9047 BPF_MOV64_IMM(BPF_REG_0, 0),
9048 BPF_EXIT_INSN(),
9049 },
9050 .result = ACCEPT,
9051 .prog_type = BPF_PROG_TYPE_XDP,
9052 },
9053 {
9054 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
9055 .insns = {
9056 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9057 offsetof(struct xdp_md, data)),
9058 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9059 offsetof(struct xdp_md, data_end)),
9060 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9061 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9062 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9063 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9064 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9065 BPF_MOV64_IMM(BPF_REG_0, 0),
9066 BPF_EXIT_INSN(),
9067 },
9068 .errstr = "R1 offset is outside of the packet",
9069 .result = REJECT,
9070 .prog_type = BPF_PROG_TYPE_XDP,
9071 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9072 },
9073 {
9074 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
9075 .insns = {
9076 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9077 offsetof(struct xdp_md, data)),
9078 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9079 offsetof(struct xdp_md, data_end)),
9080 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9081 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9082 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9083 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9084 BPF_MOV64_IMM(BPF_REG_0, 0),
9085 BPF_EXIT_INSN(),
9086 },
9087 .errstr = "R1 offset is outside of the packet",
9088 .result = REJECT,
9089 .prog_type = BPF_PROG_TYPE_XDP,
9090 },
9091 {
9092 "XDP pkt read, pkt_end <= pkt_data', good access",
9093 .insns = {
9094 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9095 offsetof(struct xdp_md, data)),
9096 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9097 offsetof(struct xdp_md, data_end)),
9098 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9099 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9100 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9101 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9102 BPF_MOV64_IMM(BPF_REG_0, 0),
9103 BPF_EXIT_INSN(),
9104 },
9105 .result = ACCEPT,
9106 .prog_type = BPF_PROG_TYPE_XDP,
9107 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9108 },
9109 {
9110 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
9111 .insns = {
9112 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9113 offsetof(struct xdp_md, data)),
9114 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9115 offsetof(struct xdp_md, data_end)),
9116 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9118 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9119 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9120 BPF_MOV64_IMM(BPF_REG_0, 0),
9121 BPF_EXIT_INSN(),
9122 },
9123 .errstr = "R1 offset is outside of the packet",
9124 .result = REJECT,
9125 .prog_type = BPF_PROG_TYPE_XDP,
9126 },
9127 {
9128 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
9129 .insns = {
9130 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9131 offsetof(struct xdp_md, data)),
9132 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9133 offsetof(struct xdp_md, data_end)),
9134 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9136 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9137 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9138 BPF_MOV64_IMM(BPF_REG_0, 0),
9139 BPF_EXIT_INSN(),
9140 },
9141 .errstr = "R1 offset is outside of the packet",
9142 .result = REJECT,
9143 .prog_type = BPF_PROG_TYPE_XDP,
9144 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9145 },
Daniel Borkmannb06723d2017-11-01 23:58:09 +01009146 {
Daniel Borkmann634eab12017-11-01 23:58:11 +01009147 "XDP pkt read, pkt_meta' > pkt_data, good access",
9148 .insns = {
9149 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9150 offsetof(struct xdp_md, data_meta)),
9151 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9152 offsetof(struct xdp_md, data)),
9153 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9155 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9156 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9157 BPF_MOV64_IMM(BPF_REG_0, 0),
9158 BPF_EXIT_INSN(),
9159 },
9160 .result = ACCEPT,
9161 .prog_type = BPF_PROG_TYPE_XDP,
9162 },
9163 {
9164 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
9165 .insns = {
9166 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9167 offsetof(struct xdp_md, data_meta)),
9168 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9169 offsetof(struct xdp_md, data)),
9170 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9171 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9172 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9173 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9174 BPF_MOV64_IMM(BPF_REG_0, 0),
9175 BPF_EXIT_INSN(),
9176 },
9177 .errstr = "R1 offset is outside of the packet",
9178 .result = REJECT,
9179 .prog_type = BPF_PROG_TYPE_XDP,
9180 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9181 },
9182 {
9183 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
9184 .insns = {
9185 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9186 offsetof(struct xdp_md, data_meta)),
9187 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9188 offsetof(struct xdp_md, data)),
9189 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9190 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9191 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
9192 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9193 BPF_MOV64_IMM(BPF_REG_0, 0),
9194 BPF_EXIT_INSN(),
9195 },
9196 .errstr = "R1 offset is outside of the packet",
9197 .result = REJECT,
9198 .prog_type = BPF_PROG_TYPE_XDP,
9199 },
9200 {
9201 "XDP pkt read, pkt_data > pkt_meta', good access",
9202 .insns = {
9203 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9204 offsetof(struct xdp_md, data_meta)),
9205 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9206 offsetof(struct xdp_md, data)),
9207 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9209 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9210 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9211 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9212 BPF_MOV64_IMM(BPF_REG_0, 0),
9213 BPF_EXIT_INSN(),
9214 },
9215 .result = ACCEPT,
9216 .prog_type = BPF_PROG_TYPE_XDP,
9217 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9218 },
9219 {
9220 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
9221 .insns = {
9222 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9223 offsetof(struct xdp_md, data_meta)),
9224 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9225 offsetof(struct xdp_md, data)),
9226 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9228 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9229 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9230 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9231 BPF_MOV64_IMM(BPF_REG_0, 0),
9232 BPF_EXIT_INSN(),
9233 },
9234 .errstr = "R1 offset is outside of the packet",
9235 .result = REJECT,
9236 .prog_type = BPF_PROG_TYPE_XDP,
9237 },
9238 {
9239 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
9240 .insns = {
9241 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9242 offsetof(struct xdp_md, data_meta)),
9243 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9244 offsetof(struct xdp_md, data)),
9245 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9247 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9248 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9249 BPF_MOV64_IMM(BPF_REG_0, 0),
9250 BPF_EXIT_INSN(),
9251 },
9252 .errstr = "R1 offset is outside of the packet",
9253 .result = REJECT,
9254 .prog_type = BPF_PROG_TYPE_XDP,
9255 },
9256 {
9257 "XDP pkt read, pkt_meta' < pkt_data, good access",
9258 .insns = {
9259 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9260 offsetof(struct xdp_md, data_meta)),
9261 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9262 offsetof(struct xdp_md, data)),
9263 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9264 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9265 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9266 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9267 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9268 BPF_MOV64_IMM(BPF_REG_0, 0),
9269 BPF_EXIT_INSN(),
9270 },
9271 .result = ACCEPT,
9272 .prog_type = BPF_PROG_TYPE_XDP,
9273 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9274 },
9275 {
9276 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
9277 .insns = {
9278 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9279 offsetof(struct xdp_md, data_meta)),
9280 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9281 offsetof(struct xdp_md, data)),
9282 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9284 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9285 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9286 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9287 BPF_MOV64_IMM(BPF_REG_0, 0),
9288 BPF_EXIT_INSN(),
9289 },
9290 .errstr = "R1 offset is outside of the packet",
9291 .result = REJECT,
9292 .prog_type = BPF_PROG_TYPE_XDP,
9293 },
9294 {
9295 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
9296 .insns = {
9297 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9298 offsetof(struct xdp_md, data_meta)),
9299 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9300 offsetof(struct xdp_md, data)),
9301 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9303 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9304 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9305 BPF_MOV64_IMM(BPF_REG_0, 0),
9306 BPF_EXIT_INSN(),
9307 },
9308 .errstr = "R1 offset is outside of the packet",
9309 .result = REJECT,
9310 .prog_type = BPF_PROG_TYPE_XDP,
9311 },
9312 {
9313 "XDP pkt read, pkt_data < pkt_meta', good access",
9314 .insns = {
9315 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9316 offsetof(struct xdp_md, data_meta)),
9317 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9318 offsetof(struct xdp_md, data)),
9319 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9320 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9321 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9322 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9323 BPF_MOV64_IMM(BPF_REG_0, 0),
9324 BPF_EXIT_INSN(),
9325 },
9326 .result = ACCEPT,
9327 .prog_type = BPF_PROG_TYPE_XDP,
9328 },
9329 {
9330 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
9331 .insns = {
9332 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9333 offsetof(struct xdp_md, data_meta)),
9334 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9335 offsetof(struct xdp_md, data)),
9336 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9337 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9338 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9339 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9340 BPF_MOV64_IMM(BPF_REG_0, 0),
9341 BPF_EXIT_INSN(),
9342 },
9343 .errstr = "R1 offset is outside of the packet",
9344 .result = REJECT,
9345 .prog_type = BPF_PROG_TYPE_XDP,
9346 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9347 },
9348 {
9349 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
9350 .insns = {
9351 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9352 offsetof(struct xdp_md, data_meta)),
9353 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9354 offsetof(struct xdp_md, data)),
9355 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9356 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9357 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9358 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9359 BPF_MOV64_IMM(BPF_REG_0, 0),
9360 BPF_EXIT_INSN(),
9361 },
9362 .errstr = "R1 offset is outside of the packet",
9363 .result = REJECT,
9364 .prog_type = BPF_PROG_TYPE_XDP,
9365 },
9366 {
9367 "XDP pkt read, pkt_meta' >= pkt_data, good access",
9368 .insns = {
9369 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9370 offsetof(struct xdp_md, data_meta)),
9371 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9372 offsetof(struct xdp_md, data)),
9373 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9374 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9375 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9376 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9377 BPF_MOV64_IMM(BPF_REG_0, 0),
9378 BPF_EXIT_INSN(),
9379 },
9380 .result = ACCEPT,
9381 .prog_type = BPF_PROG_TYPE_XDP,
9382 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9383 },
9384 {
9385 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
9386 .insns = {
9387 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9388 offsetof(struct xdp_md, data_meta)),
9389 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9390 offsetof(struct xdp_md, data)),
9391 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9392 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9393 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9394 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9395 BPF_MOV64_IMM(BPF_REG_0, 0),
9396 BPF_EXIT_INSN(),
9397 },
9398 .errstr = "R1 offset is outside of the packet",
9399 .result = REJECT,
9400 .prog_type = BPF_PROG_TYPE_XDP,
9401 },
9402 {
9403 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
9404 .insns = {
9405 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9406 offsetof(struct xdp_md, data_meta)),
9407 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9408 offsetof(struct xdp_md, data)),
9409 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9411 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9412 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9413 BPF_MOV64_IMM(BPF_REG_0, 0),
9414 BPF_EXIT_INSN(),
9415 },
9416 .errstr = "R1 offset is outside of the packet",
9417 .result = REJECT,
9418 .prog_type = BPF_PROG_TYPE_XDP,
9419 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9420 },
9421 {
9422 "XDP pkt read, pkt_data >= pkt_meta', good access",
9423 .insns = {
9424 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9425 offsetof(struct xdp_md, data_meta)),
9426 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9427 offsetof(struct xdp_md, data)),
9428 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9429 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9430 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9431 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9432 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9433 BPF_MOV64_IMM(BPF_REG_0, 0),
9434 BPF_EXIT_INSN(),
9435 },
9436 .result = ACCEPT,
9437 .prog_type = BPF_PROG_TYPE_XDP,
9438 },
9439 {
9440 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
9441 .insns = {
9442 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9443 offsetof(struct xdp_md, data_meta)),
9444 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9445 offsetof(struct xdp_md, data)),
9446 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9447 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9448 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9449 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9450 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9451 BPF_MOV64_IMM(BPF_REG_0, 0),
9452 BPF_EXIT_INSN(),
9453 },
9454 .errstr = "R1 offset is outside of the packet",
9455 .result = REJECT,
9456 .prog_type = BPF_PROG_TYPE_XDP,
9457 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9458 },
9459 {
9460 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
9461 .insns = {
9462 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9463 offsetof(struct xdp_md, data_meta)),
9464 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9465 offsetof(struct xdp_md, data)),
9466 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9468 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9469 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9470 BPF_MOV64_IMM(BPF_REG_0, 0),
9471 BPF_EXIT_INSN(),
9472 },
9473 .errstr = "R1 offset is outside of the packet",
9474 .result = REJECT,
9475 .prog_type = BPF_PROG_TYPE_XDP,
9476 },
9477 {
9478 "XDP pkt read, pkt_meta' <= pkt_data, good access",
9479 .insns = {
9480 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9481 offsetof(struct xdp_md, data_meta)),
9482 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9483 offsetof(struct xdp_md, data)),
9484 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9485 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9486 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9487 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9488 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9489 BPF_MOV64_IMM(BPF_REG_0, 0),
9490 BPF_EXIT_INSN(),
9491 },
9492 .result = ACCEPT,
9493 .prog_type = BPF_PROG_TYPE_XDP,
9494 },
9495 {
9496 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
9497 .insns = {
9498 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9499 offsetof(struct xdp_md, data_meta)),
9500 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9501 offsetof(struct xdp_md, data)),
9502 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9503 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9504 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9505 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9506 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9507 BPF_MOV64_IMM(BPF_REG_0, 0),
9508 BPF_EXIT_INSN(),
9509 },
9510 .errstr = "R1 offset is outside of the packet",
9511 .result = REJECT,
9512 .prog_type = BPF_PROG_TYPE_XDP,
9513 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9514 },
9515 {
9516 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
9517 .insns = {
9518 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9519 offsetof(struct xdp_md, data_meta)),
9520 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9521 offsetof(struct xdp_md, data)),
9522 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9523 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9524 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9525 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9526 BPF_MOV64_IMM(BPF_REG_0, 0),
9527 BPF_EXIT_INSN(),
9528 },
9529 .errstr = "R1 offset is outside of the packet",
9530 .result = REJECT,
9531 .prog_type = BPF_PROG_TYPE_XDP,
9532 },
9533 {
9534 "XDP pkt read, pkt_data <= pkt_meta', good access",
9535 .insns = {
9536 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9537 offsetof(struct xdp_md, data_meta)),
9538 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9539 offsetof(struct xdp_md, data)),
9540 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9541 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9542 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9543 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9544 BPF_MOV64_IMM(BPF_REG_0, 0),
9545 BPF_EXIT_INSN(),
9546 },
9547 .result = ACCEPT,
9548 .prog_type = BPF_PROG_TYPE_XDP,
9549 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9550 },
9551 {
9552 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
9553 .insns = {
9554 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9555 offsetof(struct xdp_md, data_meta)),
9556 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9557 offsetof(struct xdp_md, data)),
9558 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9559 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9560 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9561 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9562 BPF_MOV64_IMM(BPF_REG_0, 0),
9563 BPF_EXIT_INSN(),
9564 },
9565 .errstr = "R1 offset is outside of the packet",
9566 .result = REJECT,
9567 .prog_type = BPF_PROG_TYPE_XDP,
9568 },
9569 {
9570 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
9571 .insns = {
9572 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9573 offsetof(struct xdp_md, data_meta)),
9574 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9575 offsetof(struct xdp_md, data)),
9576 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9577 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9578 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9579 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9580 BPF_MOV64_IMM(BPF_REG_0, 0),
9581 BPF_EXIT_INSN(),
9582 },
9583 .errstr = "R1 offset is outside of the packet",
9584 .result = REJECT,
9585 .prog_type = BPF_PROG_TYPE_XDP,
9586 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9587 },
9588 {
Daniel Borkmann6f161012018-01-18 01:15:21 +01009589 "check deducing bounds from const, 1",
9590 .insns = {
9591 BPF_MOV64_IMM(BPF_REG_0, 1),
9592 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
9593 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9594 BPF_EXIT_INSN(),
9595 },
9596 .result = REJECT,
9597 .errstr = "R0 tried to subtract pointer from scalar",
9598 },
9599 {
9600 "check deducing bounds from const, 2",
9601 .insns = {
9602 BPF_MOV64_IMM(BPF_REG_0, 1),
9603 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
9604 BPF_EXIT_INSN(),
9605 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
9606 BPF_EXIT_INSN(),
9607 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9608 BPF_EXIT_INSN(),
9609 },
9610 .result = ACCEPT,
Yonghong Song35136922018-01-22 22:10:59 -08009611 .retval = 1,
Daniel Borkmann6f161012018-01-18 01:15:21 +01009612 },
9613 {
9614 "check deducing bounds from const, 3",
9615 .insns = {
9616 BPF_MOV64_IMM(BPF_REG_0, 0),
9617 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9618 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9619 BPF_EXIT_INSN(),
9620 },
9621 .result = REJECT,
9622 .errstr = "R0 tried to subtract pointer from scalar",
9623 },
9624 {
9625 "check deducing bounds from const, 4",
9626 .insns = {
9627 BPF_MOV64_IMM(BPF_REG_0, 0),
9628 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
9629 BPF_EXIT_INSN(),
9630 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9631 BPF_EXIT_INSN(),
9632 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9633 BPF_EXIT_INSN(),
9634 },
9635 .result = ACCEPT,
9636 },
9637 {
9638 "check deducing bounds from const, 5",
9639 .insns = {
9640 BPF_MOV64_IMM(BPF_REG_0, 0),
9641 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9642 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9643 BPF_EXIT_INSN(),
9644 },
9645 .result = REJECT,
9646 .errstr = "R0 tried to subtract pointer from scalar",
9647 },
9648 {
9649 "check deducing bounds from const, 6",
9650 .insns = {
9651 BPF_MOV64_IMM(BPF_REG_0, 0),
9652 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9653 BPF_EXIT_INSN(),
9654 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9655 BPF_EXIT_INSN(),
9656 },
9657 .result = REJECT,
9658 .errstr = "R0 tried to subtract pointer from scalar",
9659 },
9660 {
9661 "check deducing bounds from const, 7",
9662 .insns = {
9663 BPF_MOV64_IMM(BPF_REG_0, ~0),
9664 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9665 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9666 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9667 offsetof(struct __sk_buff, mark)),
9668 BPF_EXIT_INSN(),
9669 },
9670 .result = REJECT,
9671 .errstr = "dereference of modified ctx ptr",
9672 },
9673 {
9674 "check deducing bounds from const, 8",
9675 .insns = {
9676 BPF_MOV64_IMM(BPF_REG_0, ~0),
9677 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9678 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
9679 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9680 offsetof(struct __sk_buff, mark)),
9681 BPF_EXIT_INSN(),
9682 },
9683 .result = REJECT,
9684 .errstr = "dereference of modified ctx ptr",
9685 },
9686 {
9687 "check deducing bounds from const, 9",
9688 .insns = {
9689 BPF_MOV64_IMM(BPF_REG_0, 0),
9690 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9691 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9692 BPF_EXIT_INSN(),
9693 },
9694 .result = REJECT,
9695 .errstr = "R0 tried to subtract pointer from scalar",
9696 },
9697 {
9698 "check deducing bounds from const, 10",
9699 .insns = {
9700 BPF_MOV64_IMM(BPF_REG_0, 0),
9701 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9702 /* Marks reg as unknown. */
9703 BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
9704 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9705 BPF_EXIT_INSN(),
9706 },
9707 .result = REJECT,
9708 .errstr = "math between ctx pointer and register with unbounded min value is not allowed",
9709 },
9710 {
Daniel Borkmannb06723d2017-11-01 23:58:09 +01009711 "bpf_exit with invalid return code. test1",
9712 .insns = {
9713 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9714 BPF_EXIT_INSN(),
9715 },
9716 .errstr = "R0 has value (0x0; 0xffffffff)",
9717 .result = REJECT,
9718 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9719 },
9720 {
9721 "bpf_exit with invalid return code. test2",
9722 .insns = {
9723 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9724 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
9725 BPF_EXIT_INSN(),
9726 },
9727 .result = ACCEPT,
9728 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9729 },
9730 {
9731 "bpf_exit with invalid return code. test3",
9732 .insns = {
9733 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9734 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
9735 BPF_EXIT_INSN(),
9736 },
9737 .errstr = "R0 has value (0x0; 0x3)",
9738 .result = REJECT,
9739 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9740 },
9741 {
9742 "bpf_exit with invalid return code. test4",
9743 .insns = {
9744 BPF_MOV64_IMM(BPF_REG_0, 1),
9745 BPF_EXIT_INSN(),
9746 },
9747 .result = ACCEPT,
9748 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9749 },
9750 {
9751 "bpf_exit with invalid return code. test5",
9752 .insns = {
9753 BPF_MOV64_IMM(BPF_REG_0, 2),
9754 BPF_EXIT_INSN(),
9755 },
9756 .errstr = "R0 has value (0x2; 0x0)",
9757 .result = REJECT,
9758 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9759 },
9760 {
9761 "bpf_exit with invalid return code. test6",
9762 .insns = {
9763 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9764 BPF_EXIT_INSN(),
9765 },
9766 .errstr = "R0 is not a known value (ctx)",
9767 .result = REJECT,
9768 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9769 },
9770 {
9771 "bpf_exit with invalid return code. test7",
9772 .insns = {
9773 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9774 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
9775 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
9776 BPF_EXIT_INSN(),
9777 },
9778 .errstr = "R0 has unknown scalar value",
9779 .result = REJECT,
9780 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9781 },
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -08009782 {
9783 "calls: basic sanity",
9784 .insns = {
9785 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9786 BPF_MOV64_IMM(BPF_REG_0, 1),
9787 BPF_EXIT_INSN(),
9788 BPF_MOV64_IMM(BPF_REG_0, 2),
9789 BPF_EXIT_INSN(),
9790 },
9791 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9792 .result = ACCEPT,
9793 },
9794 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -08009795 "calls: not on unpriviledged",
9796 .insns = {
9797 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9798 BPF_MOV64_IMM(BPF_REG_0, 1),
9799 BPF_EXIT_INSN(),
9800 BPF_MOV64_IMM(BPF_REG_0, 2),
9801 BPF_EXIT_INSN(),
9802 },
9803 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
9804 .result_unpriv = REJECT,
9805 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08009806 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -08009807 },
9808 {
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01009809 "calls: div by 0 in subprog",
9810 .insns = {
9811 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9812 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9813 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9814 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9815 offsetof(struct __sk_buff, data_end)),
9816 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9818 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9819 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9820 BPF_MOV64_IMM(BPF_REG_0, 1),
9821 BPF_EXIT_INSN(),
9822 BPF_MOV32_IMM(BPF_REG_2, 0),
9823 BPF_MOV32_IMM(BPF_REG_3, 1),
9824 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
9825 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9826 offsetof(struct __sk_buff, data)),
9827 BPF_EXIT_INSN(),
9828 },
9829 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9830 .result = ACCEPT,
9831 .retval = 1,
9832 },
9833 {
9834 "calls: multiple ret types in subprog 1",
9835 .insns = {
9836 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9837 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9838 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9839 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9840 offsetof(struct __sk_buff, data_end)),
9841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9843 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9844 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9845 BPF_MOV64_IMM(BPF_REG_0, 1),
9846 BPF_EXIT_INSN(),
9847 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9848 offsetof(struct __sk_buff, data)),
9849 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9850 BPF_MOV32_IMM(BPF_REG_0, 42),
9851 BPF_EXIT_INSN(),
9852 },
9853 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9854 .result = REJECT,
9855 .errstr = "R0 invalid mem access 'inv'",
9856 },
9857 {
9858 "calls: multiple ret types in subprog 2",
9859 .insns = {
9860 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9861 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
9862 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9863 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
9864 offsetof(struct __sk_buff, data_end)),
9865 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
9866 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
9867 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
9868 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
9869 BPF_MOV64_IMM(BPF_REG_0, 1),
9870 BPF_EXIT_INSN(),
9871 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9872 offsetof(struct __sk_buff, data)),
9873 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
9874 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
9875 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
9876 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
9877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9878 BPF_LD_MAP_FD(BPF_REG_1, 0),
9879 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9880 BPF_FUNC_map_lookup_elem),
9881 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
9882 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
9883 offsetof(struct __sk_buff, data)),
9884 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
9885 BPF_EXIT_INSN(),
9886 },
9887 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9888 .fixup_map1 = { 16 },
9889 .result = REJECT,
9890 .errstr = "R0 min value is outside of the array range",
9891 },
9892 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -08009893 "calls: overlapping caller/callee",
9894 .insns = {
9895 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
9896 BPF_MOV64_IMM(BPF_REG_0, 1),
9897 BPF_EXIT_INSN(),
9898 },
9899 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9900 .errstr = "last insn is not an exit or jmp",
9901 .result = REJECT,
9902 },
9903 {
9904 "calls: wrong recursive calls",
9905 .insns = {
9906 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9907 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9908 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9909 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9910 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
9911 BPF_MOV64_IMM(BPF_REG_0, 1),
9912 BPF_EXIT_INSN(),
9913 },
9914 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9915 .errstr = "jump out of range",
9916 .result = REJECT,
9917 },
9918 {
9919 "calls: wrong src reg",
9920 .insns = {
9921 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
9922 BPF_MOV64_IMM(BPF_REG_0, 1),
9923 BPF_EXIT_INSN(),
9924 },
9925 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9926 .errstr = "BPF_CALL uses reserved fields",
9927 .result = REJECT,
9928 },
9929 {
9930 "calls: wrong off value",
9931 .insns = {
9932 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
9933 BPF_MOV64_IMM(BPF_REG_0, 1),
9934 BPF_EXIT_INSN(),
9935 BPF_MOV64_IMM(BPF_REG_0, 2),
9936 BPF_EXIT_INSN(),
9937 },
9938 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9939 .errstr = "BPF_CALL uses reserved fields",
9940 .result = REJECT,
9941 },
9942 {
9943 "calls: jump back loop",
9944 .insns = {
9945 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
9946 BPF_MOV64_IMM(BPF_REG_0, 1),
9947 BPF_EXIT_INSN(),
9948 },
9949 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9950 .errstr = "back-edge from insn 0 to 0",
9951 .result = REJECT,
9952 },
9953 {
9954 "calls: conditional call",
9955 .insns = {
9956 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9957 offsetof(struct __sk_buff, mark)),
9958 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9959 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9960 BPF_MOV64_IMM(BPF_REG_0, 1),
9961 BPF_EXIT_INSN(),
9962 BPF_MOV64_IMM(BPF_REG_0, 2),
9963 BPF_EXIT_INSN(),
9964 },
9965 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9966 .errstr = "jump out of range",
9967 .result = REJECT,
9968 },
9969 {
9970 "calls: conditional call 2",
9971 .insns = {
9972 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9973 offsetof(struct __sk_buff, mark)),
9974 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9975 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
9976 BPF_MOV64_IMM(BPF_REG_0, 1),
9977 BPF_EXIT_INSN(),
9978 BPF_MOV64_IMM(BPF_REG_0, 2),
9979 BPF_EXIT_INSN(),
9980 BPF_MOV64_IMM(BPF_REG_0, 3),
9981 BPF_EXIT_INSN(),
9982 },
9983 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
9984 .result = ACCEPT,
9985 },
9986 {
9987 "calls: conditional call 3",
9988 .insns = {
9989 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9990 offsetof(struct __sk_buff, mark)),
9991 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
9992 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
9993 BPF_MOV64_IMM(BPF_REG_0, 1),
9994 BPF_EXIT_INSN(),
9995 BPF_MOV64_IMM(BPF_REG_0, 1),
9996 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
9997 BPF_MOV64_IMM(BPF_REG_0, 3),
9998 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
9999 },
10000 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10001 .errstr = "back-edge from insn",
10002 .result = REJECT,
10003 },
10004 {
10005 "calls: conditional call 4",
10006 .insns = {
10007 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10008 offsetof(struct __sk_buff, mark)),
10009 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10010 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10011 BPF_MOV64_IMM(BPF_REG_0, 1),
10012 BPF_EXIT_INSN(),
10013 BPF_MOV64_IMM(BPF_REG_0, 1),
10014 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
10015 BPF_MOV64_IMM(BPF_REG_0, 3),
10016 BPF_EXIT_INSN(),
10017 },
10018 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10019 .result = ACCEPT,
10020 },
10021 {
10022 "calls: conditional call 5",
10023 .insns = {
10024 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10025 offsetof(struct __sk_buff, mark)),
10026 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10027 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10028 BPF_MOV64_IMM(BPF_REG_0, 1),
10029 BPF_EXIT_INSN(),
10030 BPF_MOV64_IMM(BPF_REG_0, 1),
10031 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10032 BPF_MOV64_IMM(BPF_REG_0, 3),
10033 BPF_EXIT_INSN(),
10034 },
10035 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10036 .errstr = "back-edge from insn",
10037 .result = REJECT,
10038 },
10039 {
10040 "calls: conditional call 6",
10041 .insns = {
10042 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10043 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
10044 BPF_EXIT_INSN(),
10045 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10046 offsetof(struct __sk_buff, mark)),
10047 BPF_EXIT_INSN(),
10048 },
10049 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10050 .errstr = "back-edge from insn",
10051 .result = REJECT,
10052 },
10053 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010054 "calls: using r0 returned by callee",
10055 .insns = {
10056 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10057 BPF_EXIT_INSN(),
10058 BPF_MOV64_IMM(BPF_REG_0, 2),
10059 BPF_EXIT_INSN(),
10060 },
10061 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10062 .result = ACCEPT,
10063 },
10064 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010065 "calls: using uninit r0 from callee",
10066 .insns = {
10067 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10068 BPF_EXIT_INSN(),
10069 BPF_EXIT_INSN(),
10070 },
10071 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10072 .errstr = "!read_ok",
10073 .result = REJECT,
10074 },
10075 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010076 "calls: callee is using r1",
10077 .insns = {
10078 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10079 BPF_EXIT_INSN(),
10080 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10081 offsetof(struct __sk_buff, len)),
10082 BPF_EXIT_INSN(),
10083 },
10084 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
10085 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010086 .retval = TEST_DATA_LEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010087 },
10088 {
10089 "calls: callee using args1",
10090 .insns = {
10091 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10092 BPF_EXIT_INSN(),
10093 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10094 BPF_EXIT_INSN(),
10095 },
10096 .errstr_unpriv = "allowed for root only",
10097 .result_unpriv = REJECT,
10098 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010099 .retval = POINTER_VALUE,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010100 },
10101 {
10102 "calls: callee using wrong args2",
10103 .insns = {
10104 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10105 BPF_EXIT_INSN(),
10106 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10107 BPF_EXIT_INSN(),
10108 },
10109 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10110 .errstr = "R2 !read_ok",
10111 .result = REJECT,
10112 },
10113 {
10114 "calls: callee using two args",
10115 .insns = {
10116 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10117 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
10118 offsetof(struct __sk_buff, len)),
10119 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
10120 offsetof(struct __sk_buff, len)),
10121 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10122 BPF_EXIT_INSN(),
10123 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10124 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
10125 BPF_EXIT_INSN(),
10126 },
10127 .errstr_unpriv = "allowed for root only",
10128 .result_unpriv = REJECT,
10129 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010130 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010131 },
10132 {
10133 "calls: callee changing pkt pointers",
10134 .insns = {
10135 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
10136 offsetof(struct xdp_md, data)),
10137 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
10138 offsetof(struct xdp_md, data_end)),
10139 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
10140 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
10141 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
10142 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10143 /* clear_all_pkt_pointers() has to walk all frames
10144 * to make sure that pkt pointers in the caller
10145 * are cleared when callee is calling a helper that
10146 * adjusts packet size
10147 */
10148 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10149 BPF_MOV32_IMM(BPF_REG_0, 0),
10150 BPF_EXIT_INSN(),
10151 BPF_MOV64_IMM(BPF_REG_2, 0),
10152 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10153 BPF_FUNC_xdp_adjust_head),
10154 BPF_EXIT_INSN(),
10155 },
10156 .result = REJECT,
10157 .errstr = "R6 invalid mem access 'inv'",
10158 .prog_type = BPF_PROG_TYPE_XDP,
10159 },
10160 {
10161 "calls: two calls with args",
10162 .insns = {
10163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10164 BPF_EXIT_INSN(),
10165 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10166 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10167 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10168 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10169 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10170 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10171 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10172 BPF_EXIT_INSN(),
10173 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10174 offsetof(struct __sk_buff, len)),
10175 BPF_EXIT_INSN(),
10176 },
10177 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10178 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010179 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010180 },
10181 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010182 "calls: calls with stack arith",
10183 .insns = {
10184 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10186 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10187 BPF_EXIT_INSN(),
10188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10190 BPF_EXIT_INSN(),
10191 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10192 BPF_MOV64_IMM(BPF_REG_0, 42),
10193 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10194 BPF_EXIT_INSN(),
10195 },
10196 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10197 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010198 .retval = 42,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010199 },
10200 {
10201 "calls: calls with misaligned stack access",
10202 .insns = {
10203 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10205 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10206 BPF_EXIT_INSN(),
10207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
10208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10209 BPF_EXIT_INSN(),
10210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10211 BPF_MOV64_IMM(BPF_REG_0, 42),
10212 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10213 BPF_EXIT_INSN(),
10214 },
10215 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10216 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
10217 .errstr = "misaligned stack access",
10218 .result = REJECT,
10219 },
10220 {
10221 "calls: calls control flow, jump test",
10222 .insns = {
10223 BPF_MOV64_IMM(BPF_REG_0, 42),
10224 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10225 BPF_MOV64_IMM(BPF_REG_0, 43),
10226 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10227 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10228 BPF_EXIT_INSN(),
10229 },
10230 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10231 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010232 .retval = 43,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010233 },
10234 {
10235 "calls: calls control flow, jump test 2",
10236 .insns = {
10237 BPF_MOV64_IMM(BPF_REG_0, 42),
10238 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10239 BPF_MOV64_IMM(BPF_REG_0, 43),
10240 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10241 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10242 BPF_EXIT_INSN(),
10243 },
10244 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10245 .errstr = "jump out of range from insn 1 to 4",
10246 .result = REJECT,
10247 },
10248 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010249 "calls: two calls with bad jump",
10250 .insns = {
10251 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10252 BPF_EXIT_INSN(),
10253 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10254 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10255 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10256 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10257 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10258 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10259 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10260 BPF_EXIT_INSN(),
10261 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10262 offsetof(struct __sk_buff, len)),
10263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
10264 BPF_EXIT_INSN(),
10265 },
10266 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10267 .errstr = "jump out of range from insn 11 to 9",
10268 .result = REJECT,
10269 },
10270 {
10271 "calls: recursive call. test1",
10272 .insns = {
10273 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10274 BPF_EXIT_INSN(),
10275 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10276 BPF_EXIT_INSN(),
10277 },
10278 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10279 .errstr = "back-edge",
10280 .result = REJECT,
10281 },
10282 {
10283 "calls: recursive call. test2",
10284 .insns = {
10285 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10286 BPF_EXIT_INSN(),
10287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10288 BPF_EXIT_INSN(),
10289 },
10290 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10291 .errstr = "back-edge",
10292 .result = REJECT,
10293 },
10294 {
10295 "calls: unreachable code",
10296 .insns = {
10297 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10298 BPF_EXIT_INSN(),
10299 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10300 BPF_EXIT_INSN(),
10301 BPF_MOV64_IMM(BPF_REG_0, 0),
10302 BPF_EXIT_INSN(),
10303 BPF_MOV64_IMM(BPF_REG_0, 0),
10304 BPF_EXIT_INSN(),
10305 },
10306 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10307 .errstr = "unreachable insn 6",
10308 .result = REJECT,
10309 },
10310 {
10311 "calls: invalid call",
10312 .insns = {
10313 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10314 BPF_EXIT_INSN(),
10315 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
10316 BPF_EXIT_INSN(),
10317 },
10318 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10319 .errstr = "invalid destination",
10320 .result = REJECT,
10321 },
10322 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010323 "calls: invalid call 2",
10324 .insns = {
10325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10326 BPF_EXIT_INSN(),
10327 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
10328 BPF_EXIT_INSN(),
10329 },
10330 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10331 .errstr = "invalid destination",
10332 .result = REJECT,
10333 },
10334 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010335 "calls: jumping across function bodies. test1",
10336 .insns = {
10337 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10338 BPF_MOV64_IMM(BPF_REG_0, 0),
10339 BPF_EXIT_INSN(),
10340 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
10341 BPF_EXIT_INSN(),
10342 },
10343 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10344 .errstr = "jump out of range",
10345 .result = REJECT,
10346 },
10347 {
10348 "calls: jumping across function bodies. test2",
10349 .insns = {
10350 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
10351 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10352 BPF_MOV64_IMM(BPF_REG_0, 0),
10353 BPF_EXIT_INSN(),
10354 BPF_EXIT_INSN(),
10355 },
10356 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10357 .errstr = "jump out of range",
10358 .result = REJECT,
10359 },
10360 {
10361 "calls: call without exit",
10362 .insns = {
10363 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10364 BPF_EXIT_INSN(),
10365 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10366 BPF_EXIT_INSN(),
10367 BPF_MOV64_IMM(BPF_REG_0, 0),
10368 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
10369 },
10370 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10371 .errstr = "not an exit",
10372 .result = REJECT,
10373 },
10374 {
10375 "calls: call into middle of ld_imm64",
10376 .insns = {
10377 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10378 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10379 BPF_MOV64_IMM(BPF_REG_0, 0),
10380 BPF_EXIT_INSN(),
10381 BPF_LD_IMM64(BPF_REG_0, 0),
10382 BPF_EXIT_INSN(),
10383 },
10384 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10385 .errstr = "last insn",
10386 .result = REJECT,
10387 },
10388 {
10389 "calls: call into middle of other call",
10390 .insns = {
10391 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10392 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10393 BPF_MOV64_IMM(BPF_REG_0, 0),
10394 BPF_EXIT_INSN(),
10395 BPF_MOV64_IMM(BPF_REG_0, 0),
10396 BPF_MOV64_IMM(BPF_REG_0, 0),
10397 BPF_EXIT_INSN(),
10398 },
10399 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10400 .errstr = "last insn",
10401 .result = REJECT,
10402 },
10403 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010404 "calls: ld_abs with changing ctx data in callee",
10405 .insns = {
10406 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10407 BPF_LD_ABS(BPF_B, 0),
10408 BPF_LD_ABS(BPF_H, 0),
10409 BPF_LD_ABS(BPF_W, 0),
10410 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
10411 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10412 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
10413 BPF_LD_ABS(BPF_B, 0),
10414 BPF_LD_ABS(BPF_H, 0),
10415 BPF_LD_ABS(BPF_W, 0),
10416 BPF_EXIT_INSN(),
10417 BPF_MOV64_IMM(BPF_REG_2, 1),
10418 BPF_MOV64_IMM(BPF_REG_3, 2),
10419 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10420 BPF_FUNC_skb_vlan_push),
10421 BPF_EXIT_INSN(),
10422 },
10423 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10424 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
10425 .result = REJECT,
10426 },
10427 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010428 "calls: two calls with bad fallthrough",
10429 .insns = {
10430 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10431 BPF_EXIT_INSN(),
10432 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10433 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10434 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10435 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10436 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10437 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10438 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10439 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
10440 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10441 offsetof(struct __sk_buff, len)),
10442 BPF_EXIT_INSN(),
10443 },
10444 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10445 .errstr = "not an exit",
10446 .result = REJECT,
10447 },
10448 {
10449 "calls: two calls with stack read",
10450 .insns = {
10451 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10452 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10453 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10454 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10455 BPF_EXIT_INSN(),
10456 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10457 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10458 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10459 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10460 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10461 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10462 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10463 BPF_EXIT_INSN(),
10464 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10465 BPF_EXIT_INSN(),
10466 },
10467 .prog_type = BPF_PROG_TYPE_XDP,
10468 .result = ACCEPT,
10469 },
10470 {
10471 "calls: two calls with stack write",
10472 .insns = {
10473 /* main prog */
10474 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10475 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10476 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10477 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10479 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10480 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10481 BPF_EXIT_INSN(),
10482
10483 /* subprog 1 */
10484 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10485 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10486 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
10487 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
10488 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10489 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10490 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
10491 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
10492 /* write into stack frame of main prog */
10493 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10494 BPF_EXIT_INSN(),
10495
10496 /* subprog 2 */
10497 /* read from stack frame of main prog */
10498 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10499 BPF_EXIT_INSN(),
10500 },
10501 .prog_type = BPF_PROG_TYPE_XDP,
10502 .result = ACCEPT,
10503 },
10504 {
Jann Horn6b80ad22017-12-22 19:12:35 +010010505 "calls: stack overflow using two frames (pre-call access)",
10506 .insns = {
10507 /* prog 1 */
10508 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10509 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
10510 BPF_EXIT_INSN(),
10511
10512 /* prog 2 */
10513 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10514 BPF_MOV64_IMM(BPF_REG_0, 0),
10515 BPF_EXIT_INSN(),
10516 },
10517 .prog_type = BPF_PROG_TYPE_XDP,
10518 .errstr = "combined stack size",
10519 .result = REJECT,
10520 },
10521 {
10522 "calls: stack overflow using two frames (post-call access)",
10523 .insns = {
10524 /* prog 1 */
10525 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
10526 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10527 BPF_EXIT_INSN(),
10528
10529 /* prog 2 */
10530 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10531 BPF_MOV64_IMM(BPF_REG_0, 0),
10532 BPF_EXIT_INSN(),
10533 },
10534 .prog_type = BPF_PROG_TYPE_XDP,
10535 .errstr = "combined stack size",
10536 .result = REJECT,
10537 },
10538 {
Alexei Starovoitov6b86c422017-12-25 13:15:41 -080010539 "calls: stack depth check using three frames. test1",
10540 .insns = {
10541 /* main */
10542 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10543 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10544 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10545 BPF_MOV64_IMM(BPF_REG_0, 0),
10546 BPF_EXIT_INSN(),
10547 /* A */
10548 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10549 BPF_EXIT_INSN(),
10550 /* B */
10551 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10552 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10553 BPF_EXIT_INSN(),
10554 },
10555 .prog_type = BPF_PROG_TYPE_XDP,
10556 /* stack_main=32, stack_A=256, stack_B=64
10557 * and max(main+A, main+A+B) < 512
10558 */
10559 .result = ACCEPT,
10560 },
10561 {
10562 "calls: stack depth check using three frames. test2",
10563 .insns = {
10564 /* main */
10565 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10566 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10567 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10568 BPF_MOV64_IMM(BPF_REG_0, 0),
10569 BPF_EXIT_INSN(),
10570 /* A */
10571 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10572 BPF_EXIT_INSN(),
10573 /* B */
10574 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10575 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10576 BPF_EXIT_INSN(),
10577 },
10578 .prog_type = BPF_PROG_TYPE_XDP,
10579 /* stack_main=32, stack_A=64, stack_B=256
10580 * and max(main+A, main+A+B) < 512
10581 */
10582 .result = ACCEPT,
10583 },
10584 {
10585 "calls: stack depth check using three frames. test3",
10586 .insns = {
10587 /* main */
10588 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10589 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10590 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10591 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
10592 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
10593 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10594 BPF_MOV64_IMM(BPF_REG_0, 0),
10595 BPF_EXIT_INSN(),
10596 /* A */
10597 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
10598 BPF_EXIT_INSN(),
10599 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
10600 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10601 /* B */
10602 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
10603 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
10604 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10605 BPF_EXIT_INSN(),
10606 },
10607 .prog_type = BPF_PROG_TYPE_XDP,
10608 /* stack_main=64, stack_A=224, stack_B=256
10609 * and max(main+A, main+A+B) > 512
10610 */
10611 .errstr = "combined stack",
10612 .result = REJECT,
10613 },
10614 {
10615 "calls: stack depth check using three frames. test4",
10616 /* void main(void) {
10617 * func1(0);
10618 * func1(1);
10619 * func2(1);
10620 * }
10621 * void func1(int alloc_or_recurse) {
10622 * if (alloc_or_recurse) {
10623 * frame_pointer[-300] = 1;
10624 * } else {
10625 * func2(alloc_or_recurse);
10626 * }
10627 * }
10628 * void func2(int alloc_or_recurse) {
10629 * if (alloc_or_recurse) {
10630 * frame_pointer[-300] = 1;
10631 * }
10632 * }
10633 */
10634 .insns = {
10635 /* main */
10636 BPF_MOV64_IMM(BPF_REG_1, 0),
10637 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10638 BPF_MOV64_IMM(BPF_REG_1, 1),
10639 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10640 BPF_MOV64_IMM(BPF_REG_1, 1),
10641 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
10642 BPF_MOV64_IMM(BPF_REG_0, 0),
10643 BPF_EXIT_INSN(),
10644 /* A */
10645 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
10646 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10647 BPF_EXIT_INSN(),
10648 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10649 BPF_EXIT_INSN(),
10650 /* B */
10651 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10652 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10653 BPF_EXIT_INSN(),
10654 },
10655 .prog_type = BPF_PROG_TYPE_XDP,
10656 .result = REJECT,
10657 .errstr = "combined stack",
10658 },
10659 {
Alexei Starovoitovaada9ce2017-12-25 13:15:42 -080010660 "calls: stack depth check using three frames. test5",
10661 .insns = {
10662 /* main */
10663 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
10664 BPF_EXIT_INSN(),
10665 /* A */
10666 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10667 BPF_EXIT_INSN(),
10668 /* B */
10669 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
10670 BPF_EXIT_INSN(),
10671 /* C */
10672 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
10673 BPF_EXIT_INSN(),
10674 /* D */
10675 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
10676 BPF_EXIT_INSN(),
10677 /* E */
10678 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
10679 BPF_EXIT_INSN(),
10680 /* F */
10681 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
10682 BPF_EXIT_INSN(),
10683 /* G */
10684 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
10685 BPF_EXIT_INSN(),
10686 /* H */
10687 BPF_MOV64_IMM(BPF_REG_0, 0),
10688 BPF_EXIT_INSN(),
10689 },
10690 .prog_type = BPF_PROG_TYPE_XDP,
10691 .errstr = "call stack",
10692 .result = REJECT,
10693 },
10694 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010695 "calls: spill into caller stack frame",
10696 .insns = {
10697 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10698 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10700 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10701 BPF_EXIT_INSN(),
10702 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
10703 BPF_MOV64_IMM(BPF_REG_0, 0),
10704 BPF_EXIT_INSN(),
10705 },
10706 .prog_type = BPF_PROG_TYPE_XDP,
10707 .errstr = "cannot spill",
10708 .result = REJECT,
10709 },
10710 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010711 "calls: write into caller stack frame",
10712 .insns = {
10713 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10714 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10715 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10716 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10717 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10718 BPF_EXIT_INSN(),
10719 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
10720 BPF_MOV64_IMM(BPF_REG_0, 0),
10721 BPF_EXIT_INSN(),
10722 },
10723 .prog_type = BPF_PROG_TYPE_XDP,
10724 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010725 .retval = 42,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010726 },
10727 {
10728 "calls: write into callee stack frame",
10729 .insns = {
10730 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10731 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
10732 BPF_EXIT_INSN(),
10733 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
10734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
10735 BPF_EXIT_INSN(),
10736 },
10737 .prog_type = BPF_PROG_TYPE_XDP,
10738 .errstr = "cannot return stack pointer",
10739 .result = REJECT,
10740 },
10741 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010742 "calls: two calls with stack write and void return",
10743 .insns = {
10744 /* main prog */
10745 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10746 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10747 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10748 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10749 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10750 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10751 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10752 BPF_EXIT_INSN(),
10753
10754 /* subprog 1 */
10755 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10756 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10757 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10758 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10759 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10760 BPF_EXIT_INSN(),
10761
10762 /* subprog 2 */
10763 /* write into stack frame of main prog */
10764 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
10765 BPF_EXIT_INSN(), /* void return */
10766 },
10767 .prog_type = BPF_PROG_TYPE_XDP,
10768 .result = ACCEPT,
10769 },
10770 {
10771 "calls: ambiguous return value",
10772 .insns = {
10773 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10774 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10775 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10776 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10777 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10778 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10779 BPF_EXIT_INSN(),
10780 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10781 BPF_MOV64_IMM(BPF_REG_0, 0),
10782 BPF_EXIT_INSN(),
10783 },
10784 .errstr_unpriv = "allowed for root only",
10785 .result_unpriv = REJECT,
10786 .errstr = "R0 !read_ok",
10787 .result = REJECT,
10788 },
10789 {
10790 "calls: two calls that return map_value",
10791 .insns = {
10792 /* main prog */
10793 /* pass fp-16, fp-8 into a function */
10794 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10796 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10798 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10799
10800 /* fetch map_value_ptr from the stack of this function */
10801 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
10802 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10803 /* write into map value */
10804 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10805 /* fetch secound map_value_ptr from the stack */
10806 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10807 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10808 /* write into map value */
10809 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10810 BPF_MOV64_IMM(BPF_REG_0, 0),
10811 BPF_EXIT_INSN(),
10812
10813 /* subprog 1 */
10814 /* call 3rd function twice */
10815 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10816 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10817 /* first time with fp-8 */
10818 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10819 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10820 /* second time with fp-16 */
10821 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10822 BPF_EXIT_INSN(),
10823
10824 /* subprog 2 */
10825 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10826 /* lookup from map */
10827 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10828 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10830 BPF_LD_MAP_FD(BPF_REG_1, 0),
10831 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10832 BPF_FUNC_map_lookup_elem),
10833 /* write map_value_ptr into stack frame of main prog */
10834 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10835 BPF_MOV64_IMM(BPF_REG_0, 0),
10836 BPF_EXIT_INSN(), /* return 0 */
10837 },
10838 .prog_type = BPF_PROG_TYPE_XDP,
10839 .fixup_map1 = { 23 },
10840 .result = ACCEPT,
10841 },
10842 {
10843 "calls: two calls that return map_value with bool condition",
10844 .insns = {
10845 /* main prog */
10846 /* pass fp-16, fp-8 into a function */
10847 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10849 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10851 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10852 BPF_MOV64_IMM(BPF_REG_0, 0),
10853 BPF_EXIT_INSN(),
10854
10855 /* subprog 1 */
10856 /* call 3rd function twice */
10857 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10858 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10859 /* first time with fp-8 */
10860 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10861 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10862 /* fetch map_value_ptr from the stack of this function */
10863 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10864 /* write into map value */
10865 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10866 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10867 /* second time with fp-16 */
10868 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10869 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10870 /* fetch secound map_value_ptr from the stack */
10871 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10872 /* write into map value */
10873 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10874 BPF_EXIT_INSN(),
10875
10876 /* subprog 2 */
10877 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10878 /* lookup from map */
10879 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10880 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10881 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10882 BPF_LD_MAP_FD(BPF_REG_1, 0),
10883 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10884 BPF_FUNC_map_lookup_elem),
10885 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10886 BPF_MOV64_IMM(BPF_REG_0, 0),
10887 BPF_EXIT_INSN(), /* return 0 */
10888 /* write map_value_ptr into stack frame of main prog */
10889 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10890 BPF_MOV64_IMM(BPF_REG_0, 1),
10891 BPF_EXIT_INSN(), /* return 1 */
10892 },
10893 .prog_type = BPF_PROG_TYPE_XDP,
10894 .fixup_map1 = { 23 },
10895 .result = ACCEPT,
10896 },
10897 {
10898 "calls: two calls that return map_value with incorrect bool check",
10899 .insns = {
10900 /* main prog */
10901 /* pass fp-16, fp-8 into a function */
10902 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10903 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10904 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10905 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10906 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10907 BPF_MOV64_IMM(BPF_REG_0, 0),
10908 BPF_EXIT_INSN(),
10909
10910 /* subprog 1 */
10911 /* call 3rd function twice */
10912 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10913 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10914 /* first time with fp-8 */
10915 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10916 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10917 /* fetch map_value_ptr from the stack of this function */
10918 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10919 /* write into map value */
10920 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10921 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10922 /* second time with fp-16 */
10923 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10924 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10925 /* fetch secound map_value_ptr from the stack */
10926 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10927 /* write into map value */
10928 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10929 BPF_EXIT_INSN(),
10930
10931 /* subprog 2 */
10932 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10933 /* lookup from map */
10934 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10935 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10936 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10937 BPF_LD_MAP_FD(BPF_REG_1, 0),
10938 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10939 BPF_FUNC_map_lookup_elem),
10940 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10941 BPF_MOV64_IMM(BPF_REG_0, 0),
10942 BPF_EXIT_INSN(), /* return 0 */
10943 /* write map_value_ptr into stack frame of main prog */
10944 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10945 BPF_MOV64_IMM(BPF_REG_0, 1),
10946 BPF_EXIT_INSN(), /* return 1 */
10947 },
10948 .prog_type = BPF_PROG_TYPE_XDP,
10949 .fixup_map1 = { 23 },
10950 .result = REJECT,
10951 .errstr = "invalid read from stack off -16+0 size 8",
10952 },
10953 {
10954 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
10955 .insns = {
10956 /* main prog */
10957 /* pass fp-16, fp-8 into a function */
10958 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10960 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10961 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10962 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10963 BPF_MOV64_IMM(BPF_REG_0, 0),
10964 BPF_EXIT_INSN(),
10965
10966 /* subprog 1 */
10967 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10968 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10969 /* 1st lookup from map */
10970 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10971 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10972 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10973 BPF_LD_MAP_FD(BPF_REG_1, 0),
10974 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10975 BPF_FUNC_map_lookup_elem),
10976 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10977 BPF_MOV64_IMM(BPF_REG_8, 0),
10978 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10979 /* write map_value_ptr into stack frame of main prog at fp-8 */
10980 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10981 BPF_MOV64_IMM(BPF_REG_8, 1),
10982
10983 /* 2nd lookup from map */
10984 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
10985 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10986 BPF_LD_MAP_FD(BPF_REG_1, 0),
10987 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
10988 BPF_FUNC_map_lookup_elem),
10989 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10990 BPF_MOV64_IMM(BPF_REG_9, 0),
10991 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10992 /* write map_value_ptr into stack frame of main prog at fp-16 */
10993 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10994 BPF_MOV64_IMM(BPF_REG_9, 1),
10995
10996 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10997 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
10998 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10999 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11000 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11001 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11002 BPF_EXIT_INSN(),
11003
11004 /* subprog 2 */
11005 /* if arg2 == 1 do *arg1 = 0 */
11006 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11007 /* fetch map_value_ptr from the stack of this function */
11008 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11009 /* write into map value */
11010 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11011
11012 /* if arg4 == 1 do *arg3 = 0 */
11013 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11014 /* fetch map_value_ptr from the stack of this function */
11015 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11016 /* write into map value */
11017 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11018 BPF_EXIT_INSN(),
11019 },
11020 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11021 .fixup_map1 = { 12, 22 },
11022 .result = REJECT,
11023 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11024 },
11025 {
11026 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
11027 .insns = {
11028 /* main prog */
11029 /* pass fp-16, fp-8 into a function */
11030 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11031 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11032 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11033 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11034 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11035 BPF_MOV64_IMM(BPF_REG_0, 0),
11036 BPF_EXIT_INSN(),
11037
11038 /* subprog 1 */
11039 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11040 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11041 /* 1st lookup from map */
11042 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11043 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11045 BPF_LD_MAP_FD(BPF_REG_1, 0),
11046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11047 BPF_FUNC_map_lookup_elem),
11048 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11049 BPF_MOV64_IMM(BPF_REG_8, 0),
11050 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11051 /* write map_value_ptr into stack frame of main prog at fp-8 */
11052 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11053 BPF_MOV64_IMM(BPF_REG_8, 1),
11054
11055 /* 2nd lookup from map */
11056 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11058 BPF_LD_MAP_FD(BPF_REG_1, 0),
11059 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11060 BPF_FUNC_map_lookup_elem),
11061 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11062 BPF_MOV64_IMM(BPF_REG_9, 0),
11063 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11064 /* write map_value_ptr into stack frame of main prog at fp-16 */
11065 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11066 BPF_MOV64_IMM(BPF_REG_9, 1),
11067
11068 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11069 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11070 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11071 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11072 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11073 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11074 BPF_EXIT_INSN(),
11075
11076 /* subprog 2 */
11077 /* if arg2 == 1 do *arg1 = 0 */
11078 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11079 /* fetch map_value_ptr from the stack of this function */
11080 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11081 /* write into map value */
11082 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11083
11084 /* if arg4 == 1 do *arg3 = 0 */
11085 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11086 /* fetch map_value_ptr from the stack of this function */
11087 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11088 /* write into map value */
11089 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11090 BPF_EXIT_INSN(),
11091 },
11092 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11093 .fixup_map1 = { 12, 22 },
11094 .result = ACCEPT,
11095 },
11096 {
11097 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
11098 .insns = {
11099 /* main prog */
11100 /* pass fp-16, fp-8 into a function */
11101 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11105 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11106 BPF_MOV64_IMM(BPF_REG_0, 0),
11107 BPF_EXIT_INSN(),
11108
11109 /* subprog 1 */
11110 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11111 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11112 /* 1st lookup from map */
11113 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
11114 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11116 BPF_LD_MAP_FD(BPF_REG_1, 0),
11117 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11118 BPF_FUNC_map_lookup_elem),
11119 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11120 BPF_MOV64_IMM(BPF_REG_8, 0),
11121 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11122 /* write map_value_ptr into stack frame of main prog at fp-8 */
11123 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11124 BPF_MOV64_IMM(BPF_REG_8, 1),
11125
11126 /* 2nd lookup from map */
11127 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11128 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11129 BPF_LD_MAP_FD(BPF_REG_1, 0),
11130 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11131 BPF_FUNC_map_lookup_elem),
11132 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11133 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
11134 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11135 /* write map_value_ptr into stack frame of main prog at fp-16 */
11136 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11137 BPF_MOV64_IMM(BPF_REG_9, 1),
11138
11139 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11140 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
11141 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11142 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11143 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11144 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
11145 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
11146
11147 /* subprog 2 */
11148 /* if arg2 == 1 do *arg1 = 0 */
11149 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11150 /* fetch map_value_ptr from the stack of this function */
11151 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11152 /* write into map value */
11153 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11154
11155 /* if arg4 == 1 do *arg3 = 0 */
11156 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11157 /* fetch map_value_ptr from the stack of this function */
11158 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11159 /* write into map value */
11160 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11161 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
11162 },
11163 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11164 .fixup_map1 = { 12, 22 },
11165 .result = REJECT,
11166 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11167 },
11168 {
11169 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
11170 .insns = {
11171 /* main prog */
11172 /* pass fp-16, fp-8 into a function */
11173 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11175 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11176 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11177 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11178 BPF_MOV64_IMM(BPF_REG_0, 0),
11179 BPF_EXIT_INSN(),
11180
11181 /* subprog 1 */
11182 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11183 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11184 /* 1st lookup from map */
11185 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11186 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11187 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11188 BPF_LD_MAP_FD(BPF_REG_1, 0),
11189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11190 BPF_FUNC_map_lookup_elem),
11191 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11192 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11193 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11194 BPF_MOV64_IMM(BPF_REG_8, 0),
11195 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11196 BPF_MOV64_IMM(BPF_REG_8, 1),
11197
11198 /* 2nd lookup from map */
11199 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11200 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11201 BPF_LD_MAP_FD(BPF_REG_1, 0),
11202 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11203 BPF_FUNC_map_lookup_elem),
11204 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11205 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11206 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11207 BPF_MOV64_IMM(BPF_REG_9, 0),
11208 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11209 BPF_MOV64_IMM(BPF_REG_9, 1),
11210
11211 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11212 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11213 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11214 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11215 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11216 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11217 BPF_EXIT_INSN(),
11218
11219 /* subprog 2 */
11220 /* if arg2 == 1 do *arg1 = 0 */
11221 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11222 /* fetch map_value_ptr from the stack of this function */
11223 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11224 /* write into map value */
11225 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11226
11227 /* if arg4 == 1 do *arg3 = 0 */
11228 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11229 /* fetch map_value_ptr from the stack of this function */
11230 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11231 /* write into map value */
11232 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11233 BPF_EXIT_INSN(),
11234 },
11235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11236 .fixup_map1 = { 12, 22 },
11237 .result = ACCEPT,
11238 },
11239 {
11240 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
11241 .insns = {
11242 /* main prog */
11243 /* pass fp-16, fp-8 into a function */
11244 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11245 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11246 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11248 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11249 BPF_MOV64_IMM(BPF_REG_0, 0),
11250 BPF_EXIT_INSN(),
11251
11252 /* subprog 1 */
11253 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11254 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11255 /* 1st lookup from map */
11256 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11257 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11258 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11259 BPF_LD_MAP_FD(BPF_REG_1, 0),
11260 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11261 BPF_FUNC_map_lookup_elem),
11262 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11263 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11264 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11265 BPF_MOV64_IMM(BPF_REG_8, 0),
11266 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11267 BPF_MOV64_IMM(BPF_REG_8, 1),
11268
11269 /* 2nd lookup from map */
11270 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11271 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11272 BPF_LD_MAP_FD(BPF_REG_1, 0),
11273 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11274 BPF_FUNC_map_lookup_elem),
11275 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11276 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11277 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11278 BPF_MOV64_IMM(BPF_REG_9, 0),
11279 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11280 BPF_MOV64_IMM(BPF_REG_9, 1),
11281
11282 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11283 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11284 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11285 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11286 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11288 BPF_EXIT_INSN(),
11289
11290 /* subprog 2 */
11291 /* if arg2 == 1 do *arg1 = 0 */
11292 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11293 /* fetch map_value_ptr from the stack of this function */
11294 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11295 /* write into map value */
11296 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11297
11298 /* if arg4 == 0 do *arg3 = 0 */
11299 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
11300 /* fetch map_value_ptr from the stack of this function */
11301 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11302 /* write into map value */
11303 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11304 BPF_EXIT_INSN(),
11305 },
11306 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11307 .fixup_map1 = { 12, 22 },
11308 .result = REJECT,
11309 .errstr = "R0 invalid mem access 'inv'",
11310 },
11311 {
11312 "calls: pkt_ptr spill into caller stack",
11313 .insns = {
11314 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11316 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11317 BPF_EXIT_INSN(),
11318
11319 /* subprog 1 */
11320 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11321 offsetof(struct __sk_buff, data)),
11322 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11323 offsetof(struct __sk_buff, data_end)),
11324 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11325 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11326 /* spill unchecked pkt_ptr into stack of caller */
11327 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11328 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11329 /* now the pkt range is verified, read pkt_ptr from stack */
11330 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11331 /* write 4 bytes into packet */
11332 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11333 BPF_EXIT_INSN(),
11334 },
11335 .result = ACCEPT,
11336 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011337 .retval = POINTER_VALUE,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080011338 },
Alexei Starovoitovd98588c2017-12-14 17:55:09 -080011339 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011340 "calls: pkt_ptr spill into caller stack 2",
11341 .insns = {
11342 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11344 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11345 /* Marking is still kept, but not in all cases safe. */
11346 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11347 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11348 BPF_EXIT_INSN(),
11349
11350 /* subprog 1 */
11351 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11352 offsetof(struct __sk_buff, data)),
11353 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11354 offsetof(struct __sk_buff, data_end)),
11355 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11356 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11357 /* spill unchecked pkt_ptr into stack of caller */
11358 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11359 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11360 /* now the pkt range is verified, read pkt_ptr from stack */
11361 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11362 /* write 4 bytes into packet */
11363 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11364 BPF_EXIT_INSN(),
11365 },
11366 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11367 .errstr = "invalid access to packet",
11368 .result = REJECT,
11369 },
11370 {
11371 "calls: pkt_ptr spill into caller stack 3",
11372 .insns = {
11373 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11374 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11375 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11376 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11377 /* Marking is still kept and safe here. */
11378 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11379 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11380 BPF_EXIT_INSN(),
11381
11382 /* subprog 1 */
11383 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11384 offsetof(struct __sk_buff, data)),
11385 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11386 offsetof(struct __sk_buff, data_end)),
11387 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11388 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11389 /* spill unchecked pkt_ptr into stack of caller */
11390 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11391 BPF_MOV64_IMM(BPF_REG_5, 0),
11392 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11393 BPF_MOV64_IMM(BPF_REG_5, 1),
11394 /* now the pkt range is verified, read pkt_ptr from stack */
11395 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11396 /* write 4 bytes into packet */
11397 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11398 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11399 BPF_EXIT_INSN(),
11400 },
11401 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11402 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011403 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011404 },
11405 {
11406 "calls: pkt_ptr spill into caller stack 4",
11407 .insns = {
11408 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11409 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11410 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11411 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11412 /* Check marking propagated. */
11413 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11414 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11415 BPF_EXIT_INSN(),
11416
11417 /* subprog 1 */
11418 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11419 offsetof(struct __sk_buff, data)),
11420 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11421 offsetof(struct __sk_buff, data_end)),
11422 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11424 /* spill unchecked pkt_ptr into stack of caller */
11425 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11426 BPF_MOV64_IMM(BPF_REG_5, 0),
11427 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11428 BPF_MOV64_IMM(BPF_REG_5, 1),
11429 /* don't read back pkt_ptr from stack here */
11430 /* write 4 bytes into packet */
11431 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11432 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11433 BPF_EXIT_INSN(),
11434 },
11435 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11436 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011437 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011438 },
11439 {
11440 "calls: pkt_ptr spill into caller stack 5",
11441 .insns = {
11442 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11444 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
11445 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11446 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11447 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11448 BPF_EXIT_INSN(),
11449
11450 /* subprog 1 */
11451 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11452 offsetof(struct __sk_buff, data)),
11453 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11454 offsetof(struct __sk_buff, data_end)),
11455 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11457 BPF_MOV64_IMM(BPF_REG_5, 0),
11458 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11459 /* spill checked pkt_ptr into stack of caller */
11460 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11461 BPF_MOV64_IMM(BPF_REG_5, 1),
11462 /* don't read back pkt_ptr from stack here */
11463 /* write 4 bytes into packet */
11464 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11465 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11466 BPF_EXIT_INSN(),
11467 },
11468 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11469 .errstr = "same insn cannot be used with different",
11470 .result = REJECT,
11471 },
11472 {
11473 "calls: pkt_ptr spill into caller stack 6",
11474 .insns = {
11475 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11476 offsetof(struct __sk_buff, data_end)),
11477 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11479 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11481 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11482 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11483 BPF_EXIT_INSN(),
11484
11485 /* subprog 1 */
11486 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11487 offsetof(struct __sk_buff, data)),
11488 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11489 offsetof(struct __sk_buff, data_end)),
11490 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11492 BPF_MOV64_IMM(BPF_REG_5, 0),
11493 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11494 /* spill checked pkt_ptr into stack of caller */
11495 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11496 BPF_MOV64_IMM(BPF_REG_5, 1),
11497 /* don't read back pkt_ptr from stack here */
11498 /* write 4 bytes into packet */
11499 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11500 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11501 BPF_EXIT_INSN(),
11502 },
11503 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11504 .errstr = "R4 invalid mem access",
11505 .result = REJECT,
11506 },
11507 {
11508 "calls: pkt_ptr spill into caller stack 7",
11509 .insns = {
11510 BPF_MOV64_IMM(BPF_REG_2, 0),
11511 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11513 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11514 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11515 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11516 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11517 BPF_EXIT_INSN(),
11518
11519 /* subprog 1 */
11520 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11521 offsetof(struct __sk_buff, data)),
11522 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11523 offsetof(struct __sk_buff, data_end)),
11524 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11525 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11526 BPF_MOV64_IMM(BPF_REG_5, 0),
11527 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11528 /* spill checked pkt_ptr into stack of caller */
11529 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11530 BPF_MOV64_IMM(BPF_REG_5, 1),
11531 /* don't read back pkt_ptr from stack here */
11532 /* write 4 bytes into packet */
11533 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11534 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11535 BPF_EXIT_INSN(),
11536 },
11537 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11538 .errstr = "R4 invalid mem access",
11539 .result = REJECT,
11540 },
11541 {
11542 "calls: pkt_ptr spill into caller stack 8",
11543 .insns = {
11544 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11545 offsetof(struct __sk_buff, data)),
11546 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11547 offsetof(struct __sk_buff, data_end)),
11548 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11549 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11550 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11551 BPF_EXIT_INSN(),
11552 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11553 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11554 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11555 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11556 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11557 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11558 BPF_EXIT_INSN(),
11559
11560 /* subprog 1 */
11561 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11562 offsetof(struct __sk_buff, data)),
11563 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11564 offsetof(struct __sk_buff, data_end)),
11565 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11566 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11567 BPF_MOV64_IMM(BPF_REG_5, 0),
11568 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11569 /* spill checked pkt_ptr into stack of caller */
11570 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11571 BPF_MOV64_IMM(BPF_REG_5, 1),
11572 /* don't read back pkt_ptr from stack here */
11573 /* write 4 bytes into packet */
11574 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11575 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11576 BPF_EXIT_INSN(),
11577 },
11578 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11579 .result = ACCEPT,
11580 },
11581 {
11582 "calls: pkt_ptr spill into caller stack 9",
11583 .insns = {
11584 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11585 offsetof(struct __sk_buff, data)),
11586 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11587 offsetof(struct __sk_buff, data_end)),
11588 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11590 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11591 BPF_EXIT_INSN(),
11592 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11594 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11595 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11596 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11597 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11598 BPF_EXIT_INSN(),
11599
11600 /* subprog 1 */
11601 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11602 offsetof(struct __sk_buff, data)),
11603 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11604 offsetof(struct __sk_buff, data_end)),
11605 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11606 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11607 BPF_MOV64_IMM(BPF_REG_5, 0),
11608 /* spill unchecked pkt_ptr into stack of caller */
11609 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11610 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11611 BPF_MOV64_IMM(BPF_REG_5, 1),
11612 /* don't read back pkt_ptr from stack here */
11613 /* write 4 bytes into packet */
11614 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11615 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11616 BPF_EXIT_INSN(),
11617 },
11618 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11619 .errstr = "invalid access to packet",
11620 .result = REJECT,
11621 },
11622 {
Alexei Starovoitovd98588c2017-12-14 17:55:09 -080011623 "calls: caller stack init to zero or map_value_or_null",
11624 .insns = {
11625 BPF_MOV64_IMM(BPF_REG_0, 0),
11626 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11627 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11628 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11629 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11630 /* fetch map_value_or_null or const_zero from stack */
11631 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11632 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11633 /* store into map_value */
11634 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
11635 BPF_EXIT_INSN(),
11636
11637 /* subprog 1 */
11638 /* if (ctx == 0) return; */
11639 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
11640 /* else bpf_map_lookup() and *(fp - 8) = r0 */
11641 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
11642 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11643 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11644 BPF_LD_MAP_FD(BPF_REG_1, 0),
11645 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11646 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11647 BPF_FUNC_map_lookup_elem),
11648 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11649 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11650 BPF_EXIT_INSN(),
11651 },
11652 .fixup_map1 = { 13 },
11653 .result = ACCEPT,
11654 .prog_type = BPF_PROG_TYPE_XDP,
11655 },
11656 {
11657 "calls: stack init to zero and pruning",
11658 .insns = {
11659 /* first make allocated_stack 16 byte */
11660 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
11661 /* now fork the execution such that the false branch
11662 * of JGT insn will be verified second and it skisp zero
11663 * init of fp-8 stack slot. If stack liveness marking
11664 * is missing live_read marks from call map_lookup
11665 * processing then pruning will incorrectly assume
11666 * that fp-8 stack slot was unused in the fall-through
11667 * branch and will accept the program incorrectly
11668 */
11669 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
11670 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11671 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
11672 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11673 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11674 BPF_LD_MAP_FD(BPF_REG_1, 0),
11675 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11676 BPF_FUNC_map_lookup_elem),
11677 BPF_EXIT_INSN(),
11678 },
11679 .fixup_map2 = { 6 },
11680 .errstr = "invalid indirect read from stack off -8+0 size 8",
11681 .result = REJECT,
11682 .prog_type = BPF_PROG_TYPE_XDP,
11683 },
Gianluca Borellofd05e572017-12-23 10:09:55 +000011684 {
11685 "search pruning: all branches should be verified (nop operation)",
11686 .insns = {
11687 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11688 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11689 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11690 BPF_LD_MAP_FD(BPF_REG_1, 0),
11691 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11692 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
11693 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11694 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11695 BPF_MOV64_IMM(BPF_REG_4, 0),
11696 BPF_JMP_A(1),
11697 BPF_MOV64_IMM(BPF_REG_4, 1),
11698 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11699 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11700 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11701 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
11702 BPF_MOV64_IMM(BPF_REG_6, 0),
11703 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
11704 BPF_EXIT_INSN(),
11705 },
11706 .fixup_map1 = { 3 },
11707 .errstr = "R6 invalid mem access 'inv'",
11708 .result = REJECT,
11709 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11710 },
11711 {
11712 "search pruning: all branches should be verified (invalid stack access)",
11713 .insns = {
11714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11716 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11717 BPF_LD_MAP_FD(BPF_REG_1, 0),
11718 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
11720 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11721 BPF_MOV64_IMM(BPF_REG_4, 0),
11722 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11723 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11724 BPF_JMP_A(1),
11725 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
11726 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11727 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11728 BPF_EXIT_INSN(),
11729 },
11730 .fixup_map1 = { 3 },
11731 .errstr = "invalid read from stack off -16+0 size 8",
11732 .result = REJECT,
11733 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11734 },
Daniel Borkmann23d191a2018-02-24 01:08:03 +010011735 {
11736 "jit: lsh, rsh, arsh by 1",
11737 .insns = {
11738 BPF_MOV64_IMM(BPF_REG_0, 1),
11739 BPF_MOV64_IMM(BPF_REG_1, 0xff),
11740 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
11741 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
11742 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
11743 BPF_EXIT_INSN(),
11744 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
11745 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
11746 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
11747 BPF_EXIT_INSN(),
11748 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
11749 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
11750 BPF_EXIT_INSN(),
11751 BPF_MOV64_IMM(BPF_REG_0, 2),
11752 BPF_EXIT_INSN(),
11753 },
11754 .result = ACCEPT,
11755 .retval = 2,
11756 },
11757 {
11758 "jit: mov32 for ldimm64, 1",
11759 .insns = {
11760 BPF_MOV64_IMM(BPF_REG_0, 2),
11761 BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
11762 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
11763 BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
11764 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11765 BPF_MOV64_IMM(BPF_REG_0, 1),
11766 BPF_EXIT_INSN(),
11767 },
11768 .result = ACCEPT,
11769 .retval = 2,
11770 },
11771 {
11772 "jit: mov32 for ldimm64, 2",
11773 .insns = {
11774 BPF_MOV64_IMM(BPF_REG_0, 1),
11775 BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
11776 BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
11777 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11778 BPF_MOV64_IMM(BPF_REG_0, 2),
11779 BPF_EXIT_INSN(),
11780 },
11781 .result = ACCEPT,
11782 .retval = 2,
11783 },
11784 {
11785 "jit: various mul tests",
11786 .insns = {
11787 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11788 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11789 BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
11790 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11791 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11792 BPF_MOV64_IMM(BPF_REG_0, 1),
11793 BPF_EXIT_INSN(),
11794 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11795 BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11796 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11797 BPF_MOV64_IMM(BPF_REG_0, 1),
11798 BPF_EXIT_INSN(),
11799 BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
11800 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11801 BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11802 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11803 BPF_MOV64_IMM(BPF_REG_0, 1),
11804 BPF_EXIT_INSN(),
11805 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11806 BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11807 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11808 BPF_MOV64_IMM(BPF_REG_0, 1),
11809 BPF_EXIT_INSN(),
11810 BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
11811 BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
11812 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11813 BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
11814 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
11815 BPF_MOV64_IMM(BPF_REG_0, 1),
11816 BPF_EXIT_INSN(),
11817 BPF_MOV64_IMM(BPF_REG_0, 2),
11818 BPF_EXIT_INSN(),
11819 },
11820 .result = ACCEPT,
11821 .retval = 2,
11822 },
David S. Miller0f3e9c92018-03-06 00:53:44 -050011823 {
Daniel Borkmannca369602018-02-23 22:29:05 +010011824 "xadd/w check unaligned stack",
11825 .insns = {
11826 BPF_MOV64_IMM(BPF_REG_0, 1),
11827 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11828 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
11829 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11830 BPF_EXIT_INSN(),
11831 },
11832 .result = REJECT,
11833 .errstr = "misaligned stack access off",
11834 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11835 },
11836 {
11837 "xadd/w check unaligned map",
11838 .insns = {
11839 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11840 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11842 BPF_LD_MAP_FD(BPF_REG_1, 0),
11843 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11844 BPF_FUNC_map_lookup_elem),
11845 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
11846 BPF_EXIT_INSN(),
11847 BPF_MOV64_IMM(BPF_REG_1, 1),
11848 BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
11849 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
11850 BPF_EXIT_INSN(),
11851 },
11852 .fixup_map1 = { 3 },
11853 .result = REJECT,
11854 .errstr = "misaligned value access off",
11855 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11856 },
11857 {
11858 "xadd/w check unaligned pkt",
11859 .insns = {
11860 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11861 offsetof(struct xdp_md, data)),
11862 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11863 offsetof(struct xdp_md, data_end)),
11864 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
11865 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
11866 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
11867 BPF_MOV64_IMM(BPF_REG_0, 99),
11868 BPF_JMP_IMM(BPF_JA, 0, 0, 6),
11869 BPF_MOV64_IMM(BPF_REG_0, 1),
11870 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11871 BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
11872 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
11873 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
11874 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
11875 BPF_EXIT_INSN(),
11876 },
11877 .result = REJECT,
11878 .errstr = "BPF_XADD stores into R2 packet",
11879 .prog_type = BPF_PROG_TYPE_XDP,
11880 },
Yonghong Song2abe611c2018-04-28 22:28:14 -070011881 {
11882 "bpf_get_stack return R0 within range",
11883 .insns = {
11884 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11885 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11886 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11888 BPF_LD_MAP_FD(BPF_REG_1, 0),
11889 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11890 BPF_FUNC_map_lookup_elem),
11891 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
11892 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
11893 BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
11894 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11895 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
11896 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
11897 BPF_MOV64_IMM(BPF_REG_4, 256),
11898 BPF_EMIT_CALL(BPF_FUNC_get_stack),
11899 BPF_MOV64_IMM(BPF_REG_1, 0),
11900 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
11901 BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
11902 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
11903 BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
11904 BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
11905 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
11906 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
11907 BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
11908 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
11909 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 32),
11910 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
11911 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
11912 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11913 BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
11914 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
11915 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
11916 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11917 BPF_MOV64_REG(BPF_REG_3, BPF_REG_9),
11918 BPF_MOV64_IMM(BPF_REG_4, 0),
11919 BPF_EMIT_CALL(BPF_FUNC_get_stack),
11920 BPF_EXIT_INSN(),
11921 },
11922 .fixup_map2 = { 4 },
11923 .result = ACCEPT,
11924 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11925 },
Daniel Borkmann93731ef2018-05-04 01:08:13 +020011926 {
11927 "ld_abs: invalid op 1",
11928 .insns = {
11929 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11930 BPF_LD_ABS(BPF_DW, 0),
11931 BPF_EXIT_INSN(),
11932 },
11933 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11934 .result = REJECT,
11935 .errstr = "unknown opcode",
11936 },
11937 {
11938 "ld_abs: invalid op 2",
11939 .insns = {
11940 BPF_MOV32_IMM(BPF_REG_0, 256),
11941 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11942 BPF_LD_IND(BPF_DW, BPF_REG_0, 0),
11943 BPF_EXIT_INSN(),
11944 },
11945 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11946 .result = REJECT,
11947 .errstr = "unknown opcode",
11948 },
11949 {
11950 "ld_abs: nmap reduced",
11951 .insns = {
11952 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11953 BPF_LD_ABS(BPF_H, 12),
11954 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 28),
11955 BPF_LD_ABS(BPF_H, 12),
11956 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 26),
11957 BPF_MOV32_IMM(BPF_REG_0, 18),
11958 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -64),
11959 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -64),
11960 BPF_LD_IND(BPF_W, BPF_REG_7, 14),
11961 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -60),
11962 BPF_MOV32_IMM(BPF_REG_0, 280971478),
11963 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
11964 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
11965 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -60),
11966 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
11967 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 15),
11968 BPF_LD_ABS(BPF_H, 12),
11969 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 13),
11970 BPF_MOV32_IMM(BPF_REG_0, 22),
11971 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
11972 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
11973 BPF_LD_IND(BPF_H, BPF_REG_7, 14),
11974 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -52),
11975 BPF_MOV32_IMM(BPF_REG_0, 17366),
11976 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -48),
11977 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -48),
11978 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -52),
11979 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
11980 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11981 BPF_MOV32_IMM(BPF_REG_0, 256),
11982 BPF_EXIT_INSN(),
11983 BPF_MOV32_IMM(BPF_REG_0, 0),
11984 BPF_EXIT_INSN(),
11985 },
11986 .data = {
11987 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0,
11988 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11989 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
11990 },
11991 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11992 .result = ACCEPT,
11993 .retval = 256,
11994 },
11995 {
11996 "ld_abs: div + abs, test 1",
11997 .insns = {
11998 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
11999 BPF_LD_ABS(BPF_B, 3),
12000 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12001 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12002 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12003 BPF_LD_ABS(BPF_B, 4),
12004 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12005 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12006 BPF_EXIT_INSN(),
12007 },
12008 .data = {
12009 10, 20, 30, 40, 50,
12010 },
12011 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12012 .result = ACCEPT,
12013 .retval = 10,
12014 },
12015 {
12016 "ld_abs: div + abs, test 2",
12017 .insns = {
12018 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12019 BPF_LD_ABS(BPF_B, 3),
12020 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12021 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12022 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12023 BPF_LD_ABS(BPF_B, 128),
12024 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12025 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12026 BPF_EXIT_INSN(),
12027 },
12028 .data = {
12029 10, 20, 30, 40, 50,
12030 },
12031 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12032 .result = ACCEPT,
12033 .retval = 0,
12034 },
12035 {
12036 "ld_abs: div + abs, test 3",
12037 .insns = {
12038 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12039 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12040 BPF_LD_ABS(BPF_B, 3),
12041 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12042 BPF_EXIT_INSN(),
12043 },
12044 .data = {
12045 10, 20, 30, 40, 50,
12046 },
12047 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12048 .result = ACCEPT,
12049 .retval = 0,
12050 },
12051 {
12052 "ld_abs: div + abs, test 4",
12053 .insns = {
12054 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12055 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12056 BPF_LD_ABS(BPF_B, 256),
12057 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12058 BPF_EXIT_INSN(),
12059 },
12060 .data = {
12061 10, 20, 30, 40, 50,
12062 },
12063 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12064 .result = ACCEPT,
12065 .retval = 0,
12066 },
12067 {
12068 "ld_abs: vlan + abs, test 1",
12069 .insns = { },
12070 .data = {
12071 0x34,
12072 },
12073 .fill_helper = bpf_fill_ld_abs_vlan_push_pop,
12074 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12075 .result = ACCEPT,
12076 .retval = 0xbef,
12077 },
12078 {
12079 "ld_abs: vlan + abs, test 2",
12080 .insns = {
12081 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12082 BPF_LD_ABS(BPF_B, 0),
12083 BPF_LD_ABS(BPF_H, 0),
12084 BPF_LD_ABS(BPF_W, 0),
12085 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
12086 BPF_MOV64_IMM(BPF_REG_6, 0),
12087 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12088 BPF_MOV64_IMM(BPF_REG_2, 1),
12089 BPF_MOV64_IMM(BPF_REG_3, 2),
12090 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12091 BPF_FUNC_skb_vlan_push),
12092 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
12093 BPF_LD_ABS(BPF_B, 0),
12094 BPF_LD_ABS(BPF_H, 0),
12095 BPF_LD_ABS(BPF_W, 0),
12096 BPF_MOV64_IMM(BPF_REG_0, 42),
12097 BPF_EXIT_INSN(),
12098 },
12099 .data = {
12100 0x34,
12101 },
12102 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12103 .result = ACCEPT,
12104 .retval = 42,
12105 },
12106 {
12107 "ld_abs: jump around ld_abs",
12108 .insns = { },
12109 .data = {
12110 10, 11,
12111 },
12112 .fill_helper = bpf_fill_jump_around_ld_abs,
12113 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12114 .result = ACCEPT,
12115 .retval = 10,
12116 },
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +020012117 {
12118 "ld_dw: xor semi-random 64 bit imms, test 1",
12119 .insns = { },
12120 .data = { },
12121 .fill_helper = bpf_fill_rand_ld_dw,
12122 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12123 .result = ACCEPT,
12124 .retval = 4090,
12125 },
12126 {
12127 "ld_dw: xor semi-random 64 bit imms, test 2",
12128 .insns = { },
12129 .data = { },
12130 .fill_helper = bpf_fill_rand_ld_dw,
12131 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12132 .result = ACCEPT,
12133 .retval = 2047,
12134 },
12135 {
12136 "ld_dw: xor semi-random 64 bit imms, test 3",
12137 .insns = { },
12138 .data = { },
12139 .fill_helper = bpf_fill_rand_ld_dw,
12140 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12141 .result = ACCEPT,
12142 .retval = 511,
12143 },
12144 {
12145 "ld_dw: xor semi-random 64 bit imms, test 4",
12146 .insns = { },
12147 .data = { },
12148 .fill_helper = bpf_fill_rand_ld_dw,
12149 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12150 .result = ACCEPT,
12151 .retval = 5,
12152 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012153};
12154
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012155static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012156{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012157 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012158
12159 for (len = MAX_INSNS - 1; len > 0; --len)
12160 if (fp[len].code != 0 || fp[len].imm != 0)
12161 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012162 return len + 1;
12163}
12164
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012165static int create_map(uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012166{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012167 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012168
Mickaël Salaünf4874d02017-02-10 00:21:43 +010012169 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012170 size_value, max_elem, BPF_F_NO_PREALLOC);
12171 if (fd < 0)
12172 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012173
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012174 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012175}
12176
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012177static int create_prog_dummy1(void)
12178{
12179 struct bpf_insn prog[] = {
12180 BPF_MOV64_IMM(BPF_REG_0, 42),
12181 BPF_EXIT_INSN(),
12182 };
12183
12184 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12185 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12186}
12187
12188static int create_prog_dummy2(int mfd, int idx)
12189{
12190 struct bpf_insn prog[] = {
12191 BPF_MOV64_IMM(BPF_REG_3, idx),
12192 BPF_LD_MAP_FD(BPF_REG_2, mfd),
12193 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12194 BPF_FUNC_tail_call),
12195 BPF_MOV64_IMM(BPF_REG_0, 41),
12196 BPF_EXIT_INSN(),
12197 };
12198
12199 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12200 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12201}
12202
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012203static int create_prog_array(void)
12204{
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012205 int p1key = 0, p2key = 1;
12206 int mfd, p1fd, p2fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012207
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012208 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
12209 sizeof(int), 4, 0);
12210 if (mfd < 0) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012211 printf("Failed to create prog array '%s'!\n", strerror(errno));
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012212 return -1;
12213 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012214
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012215 p1fd = create_prog_dummy1();
12216 p2fd = create_prog_dummy2(mfd, p2key);
12217 if (p1fd < 0 || p2fd < 0)
12218 goto out;
12219 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
12220 goto out;
12221 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
12222 goto out;
12223 close(p2fd);
12224 close(p1fd);
12225
12226 return mfd;
12227out:
12228 close(p2fd);
12229 close(p1fd);
12230 close(mfd);
12231 return -1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012232}
12233
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012234static int create_map_in_map(void)
12235{
12236 int inner_map_fd, outer_map_fd;
12237
12238 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12239 sizeof(int), 1, 0);
12240 if (inner_map_fd < 0) {
12241 printf("Failed to create array '%s'!\n", strerror(errno));
12242 return inner_map_fd;
12243 }
12244
Martin KaFai Lau88cda1c2017-09-27 14:37:54 -070012245 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012246 sizeof(int), inner_map_fd, 1, 0);
12247 if (outer_map_fd < 0)
12248 printf("Failed to create array of maps '%s'!\n",
12249 strerror(errno));
12250
12251 close(inner_map_fd);
12252
12253 return outer_map_fd;
12254}
12255
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012256static char bpf_vlog[UINT_MAX >> 8];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012257
12258static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012259 int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012260{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012261 int *fixup_map1 = test->fixup_map1;
12262 int *fixup_map2 = test->fixup_map2;
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012263 int *fixup_map3 = test->fixup_map3;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012264 int *fixup_prog = test->fixup_prog;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012265 int *fixup_map_in_map = test->fixup_map_in_map;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012266
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012267 if (test->fill_helper)
12268 test->fill_helper(test);
12269
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012270 /* Allocating HTs with 1 elem is fine here, since we only test
12271 * for verifier and not do a runtime lookup, so the only thing
12272 * that really matters is value size in this case.
12273 */
12274 if (*fixup_map1) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012275 map_fds[0] = create_map(sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012276 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012277 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012278 fixup_map1++;
12279 } while (*fixup_map1);
12280 }
12281
12282 if (*fixup_map2) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012283 map_fds[1] = create_map(sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012284 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012285 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012286 fixup_map2++;
12287 } while (*fixup_map2);
12288 }
12289
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012290 if (*fixup_map3) {
12291 map_fds[1] = create_map(sizeof(struct other_val), 1);
12292 do {
12293 prog[*fixup_map3].imm = map_fds[1];
12294 fixup_map3++;
12295 } while (*fixup_map3);
12296 }
12297
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012298 if (*fixup_prog) {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012299 map_fds[2] = create_prog_array();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012300 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012301 prog[*fixup_prog].imm = map_fds[2];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012302 fixup_prog++;
12303 } while (*fixup_prog);
12304 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012305
12306 if (*fixup_map_in_map) {
12307 map_fds[3] = create_map_in_map();
12308 do {
12309 prog[*fixup_map_in_map].imm = map_fds[3];
12310 fixup_map_in_map++;
12311 } while (*fixup_map_in_map);
12312 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012313}
12314
12315static void do_test_single(struct bpf_test *test, bool unpriv,
12316 int *passes, int *errors)
12317{
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012318 int fd_prog, expected_ret, reject_from_alignment;
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012319 int prog_len, prog_type = test->prog_type;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012320 struct bpf_insn *prog = test->insns;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012321 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012322 const char *expected_err;
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012323 uint32_t retval;
12324 int i, err;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012325
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012326 for (i = 0; i < MAX_NR_MAPS; i++)
12327 map_fds[i] = -1;
12328
12329 do_test_fixup(test, prog, map_fds);
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012330 prog_len = probe_filter_length(prog);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012331
Daniel Borkmann614d0d72017-05-25 01:05:09 +020012332 fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
12333 prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmannd6554902017-07-21 00:00:22 +020012334 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012335
12336 expected_ret = unpriv && test->result_unpriv != UNDEF ?
12337 test->result_unpriv : test->result;
12338 expected_err = unpriv && test->errstr_unpriv ?
12339 test->errstr_unpriv : test->errstr;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012340
12341 reject_from_alignment = fd_prog < 0 &&
12342 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
12343 strstr(bpf_vlog, "Unknown alignment.");
12344#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
12345 if (reject_from_alignment) {
12346 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
12347 strerror(errno));
12348 goto fail_log;
12349 }
12350#endif
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012351 if (expected_ret == ACCEPT) {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012352 if (fd_prog < 0 && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012353 printf("FAIL\nFailed to load prog '%s'!\n",
12354 strerror(errno));
12355 goto fail_log;
12356 }
12357 } else {
12358 if (fd_prog >= 0) {
12359 printf("FAIL\nUnexpected success to load!\n");
12360 goto fail_log;
12361 }
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012362 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
Joe Stringer95f87a92018-02-14 13:50:34 -080012363 printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
12364 expected_err, bpf_vlog);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012365 goto fail_log;
12366 }
12367 }
12368
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012369 if (fd_prog >= 0) {
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012370 err = bpf_prog_test_run(fd_prog, 1, test->data,
12371 sizeof(test->data), NULL, NULL,
12372 &retval, NULL);
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012373 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
12374 printf("Unexpected bpf_prog_test_run error\n");
12375 goto fail_log;
12376 }
12377 if (!err && retval != test->retval &&
12378 test->retval != POINTER_VALUE) {
12379 printf("FAIL retval %d != %d\n", retval, test->retval);
12380 goto fail_log;
12381 }
12382 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012383 (*passes)++;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012384 printf("OK%s\n", reject_from_alignment ?
12385 " (NOTE: reject due to unknown alignment)" : "");
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012386close_fds:
12387 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012388 for (i = 0; i < MAX_NR_MAPS; i++)
12389 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012390 sched_yield();
12391 return;
12392fail_log:
12393 (*errors)++;
12394 printf("%s", bpf_vlog);
12395 goto close_fds;
12396}
12397
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012398static bool is_admin(void)
12399{
12400 cap_t caps;
12401 cap_flag_value_t sysadmin = CAP_CLEAR;
12402 const cap_value_t cap_val = CAP_SYS_ADMIN;
12403
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080012404#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012405 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
12406 perror("cap_get_flag");
12407 return false;
12408 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080012409#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012410 caps = cap_get_proc();
12411 if (!caps) {
12412 perror("cap_get_proc");
12413 return false;
12414 }
12415 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
12416 perror("cap_get_flag");
12417 if (cap_free(caps))
12418 perror("cap_free");
12419 return (sysadmin == CAP_SET);
12420}
12421
12422static int set_admin(bool admin)
12423{
12424 cap_t caps;
12425 const cap_value_t cap_val = CAP_SYS_ADMIN;
12426 int ret = -1;
12427
12428 caps = cap_get_proc();
12429 if (!caps) {
12430 perror("cap_get_proc");
12431 return -1;
12432 }
12433 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
12434 admin ? CAP_SET : CAP_CLEAR)) {
12435 perror("cap_set_flag");
12436 goto out;
12437 }
12438 if (cap_set_proc(caps)) {
12439 perror("cap_set_proc");
12440 goto out;
12441 }
12442 ret = 0;
12443out:
12444 if (cap_free(caps))
12445 perror("cap_free");
12446 return ret;
12447}
12448
Joe Stringer0a6748742018-02-14 13:50:36 -080012449static void get_unpriv_disabled()
12450{
12451 char buf[2];
12452 FILE *fd;
12453
12454 fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
12455 if (fgets(buf, 2, fd) == buf && atoi(buf))
12456 unpriv_disabled = true;
12457 fclose(fd);
12458}
12459
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012460static int do_test(bool unpriv, unsigned int from, unsigned int to)
12461{
Joe Stringerd0a0e492018-02-14 13:50:35 -080012462 int i, passes = 0, errors = 0, skips = 0;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012463
12464 for (i = from; i < to; i++) {
12465 struct bpf_test *test = &tests[i];
12466
12467 /* Program types that are not supported by non-root we
12468 * skip right away.
12469 */
Joe Stringer0a6748742018-02-14 13:50:36 -080012470 if (!test->prog_type && unpriv_disabled) {
12471 printf("#%d/u %s SKIP\n", i, test->descr);
12472 skips++;
12473 } else if (!test->prog_type) {
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012474 if (!unpriv)
12475 set_admin(false);
12476 printf("#%d/u %s ", i, test->descr);
12477 do_test_single(test, true, &passes, &errors);
12478 if (!unpriv)
12479 set_admin(true);
12480 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012481
Joe Stringerd0a0e492018-02-14 13:50:35 -080012482 if (unpriv) {
12483 printf("#%d/p %s SKIP\n", i, test->descr);
12484 skips++;
12485 } else {
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012486 printf("#%d/p %s ", i, test->descr);
12487 do_test_single(test, false, &passes, &errors);
12488 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012489 }
12490
Joe Stringerd0a0e492018-02-14 13:50:35 -080012491 printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
12492 skips, errors);
Jesper Dangaard Brouerefe5f9c2017-06-13 15:17:19 +020012493 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012494}
12495
12496int main(int argc, char **argv)
12497{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012498 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012499 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012500
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012501 if (argc == 3) {
12502 unsigned int l = atoi(argv[argc - 2]);
12503 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012504
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012505 if (l < to && u < to) {
12506 from = l;
12507 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012508 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012509 } else if (argc == 2) {
12510 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012511
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012512 if (t < to) {
12513 from = t;
12514 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012515 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012516 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012517
Joe Stringer0a6748742018-02-14 13:50:36 -080012518 get_unpriv_disabled();
12519 if (unpriv && unpriv_disabled) {
12520 printf("Cannot run as unprivileged user with sysctl %s.\n",
12521 UNPRIV_SYSCTL);
12522 return EXIT_FAILURE;
12523 }
12524
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +020012525 bpf_semi_rand_init();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012526 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012527}