blob: 163fd1c0062c7e52c6add71738187b7065918a2d [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"
Martin KaFai Lauaa5f0c92018-08-08 01:01:27 -070045#include "bpf_util.h"
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020046#include "../../../include/linux/filter.h"
47
Daniel Borkmann93731ef2018-05-04 01:08:13 +020048#define MAX_INSNS BPF_MAXINSNS
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020049#define MAX_FIXUPS 8
Roman Gushchind4c9f572018-08-02 14:27:28 -070050#define MAX_NR_MAPS 8
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080051#define POINTER_VALUE 0xcafe4all
52#define TEST_DATA_LEN 64
Alexei Starovoitovbf508872015-10-07 22:23:23 -070053
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020054#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
Daniel Borkmann614d0d72017-05-25 01:05:09 +020055#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020056
Joe Stringer0a6748742018-02-14 13:50:36 -080057#define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
58static bool unpriv_disabled = false;
59
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070060struct bpf_test {
61 const char *descr;
62 struct bpf_insn insns[MAX_INSNS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020063 int fixup_map1[MAX_FIXUPS];
64 int fixup_map2[MAX_FIXUPS];
Paul Chaignon5f90dd62018-04-24 15:08:19 +020065 int fixup_map3[MAX_FIXUPS];
Daniel Borkmann06be0862018-06-02 23:06:31 +020066 int fixup_map4[MAX_FIXUPS];
67 int fixup_prog1[MAX_FIXUPS];
68 int fixup_prog2[MAX_FIXUPS];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070069 int fixup_map_in_map[MAX_FIXUPS];
Roman Gushchind4c9f572018-08-02 14:27:28 -070070 int fixup_cgroup_storage[MAX_FIXUPS];
Roman Gushchina3c60542018-09-28 14:45:53 +000071 int fixup_percpu_cgroup_storage[MAX_FIXUPS];
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070072 const char *errstr;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070073 const char *errstr_unpriv;
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080074 uint32_t retval;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070075 enum {
Alexei Starovoitovbf508872015-10-07 22:23:23 -070076 UNDEF,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070077 ACCEPT,
78 REJECT
Alexei Starovoitovbf508872015-10-07 22:23:23 -070079 } result, result_unpriv;
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -070080 enum bpf_prog_type prog_type;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020081 uint8_t flags;
Daniel Borkmann93731ef2018-05-04 01:08:13 +020082 __u8 data[TEST_DATA_LEN];
83 void (*fill_helper)(struct bpf_test *self);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070084};
85
Josef Bacik48461132016-09-28 10:54:32 -040086/* Note we want this to be 64 bit aligned so that the end of our array is
87 * actually the end of the structure.
88 */
89#define MAX_ENTRIES 11
Josef Bacik48461132016-09-28 10:54:32 -040090
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020091struct test_val {
92 unsigned int index;
93 int foo[MAX_ENTRIES];
Josef Bacik48461132016-09-28 10:54:32 -040094};
95
Paul Chaignon5f90dd62018-04-24 15:08:19 +020096struct other_val {
97 long long foo;
98 long long bar;
99};
100
Daniel Borkmann93731ef2018-05-04 01:08:13 +0200101static void bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
102{
103 /* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
104#define PUSH_CNT 51
105 unsigned int len = BPF_MAXINSNS;
106 struct bpf_insn *insn = self->insns;
107 int i = 0, j, k = 0;
108
109 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
110loop:
111 for (j = 0; j < PUSH_CNT; j++) {
112 insn[i++] = BPF_LD_ABS(BPF_B, 0);
113 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
114 i++;
115 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
116 insn[i++] = BPF_MOV64_IMM(BPF_REG_2, 1);
117 insn[i++] = BPF_MOV64_IMM(BPF_REG_3, 2);
118 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
119 BPF_FUNC_skb_vlan_push),
120 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
121 i++;
122 }
123
124 for (j = 0; j < PUSH_CNT; j++) {
125 insn[i++] = BPF_LD_ABS(BPF_B, 0);
126 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
127 i++;
128 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
129 insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
130 BPF_FUNC_skb_vlan_pop),
131 insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
132 i++;
133 }
134 if (++k < 5)
135 goto loop;
136
137 for (; i < len - 1; i++)
138 insn[i] = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, 0xbef);
139 insn[len - 1] = BPF_EXIT_INSN();
140}
141
142static void bpf_fill_jump_around_ld_abs(struct bpf_test *self)
143{
144 struct bpf_insn *insn = self->insns;
145 unsigned int len = BPF_MAXINSNS;
146 int i = 0;
147
148 insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
149 insn[i++] = BPF_LD_ABS(BPF_B, 0);
150 insn[i] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 10, len - i - 2);
151 i++;
152 while (i < len - 1)
153 insn[i++] = BPF_LD_ABS(BPF_B, 1);
154 insn[i] = BPF_EXIT_INSN();
155}
156
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +0200157static void bpf_fill_rand_ld_dw(struct bpf_test *self)
158{
159 struct bpf_insn *insn = self->insns;
160 uint64_t res = 0;
161 int i = 0;
162
163 insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0);
164 while (i < self->retval) {
165 uint64_t val = bpf_semi_rand_get();
166 struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) };
167
168 res ^= val;
169 insn[i++] = tmp[0];
170 insn[i++] = tmp[1];
171 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
172 }
173 insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
174 insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32);
175 insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
176 insn[i] = BPF_EXIT_INSN();
177 res ^= (res >> 32);
178 self->retval = (uint32_t)res;
179}
180
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700181static struct bpf_test tests[] = {
182 {
183 "add+sub+mul",
184 .insns = {
185 BPF_MOV64_IMM(BPF_REG_1, 1),
186 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
187 BPF_MOV64_IMM(BPF_REG_2, 3),
188 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
189 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
190 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
191 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
192 BPF_EXIT_INSN(),
193 },
194 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800195 .retval = -3,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700196 },
197 {
Daniel Borkmann87c17932018-01-20 01:24:32 +0100198 "DIV32 by 0, zero check 1",
199 .insns = {
200 BPF_MOV32_IMM(BPF_REG_0, 42),
201 BPF_MOV32_IMM(BPF_REG_1, 0),
202 BPF_MOV32_IMM(BPF_REG_2, 1),
203 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
204 BPF_EXIT_INSN(),
205 },
206 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100207 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100208 },
209 {
210 "DIV32 by 0, zero check 2",
211 .insns = {
212 BPF_MOV32_IMM(BPF_REG_0, 42),
213 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
214 BPF_MOV32_IMM(BPF_REG_2, 1),
215 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
216 BPF_EXIT_INSN(),
217 },
218 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100219 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100220 },
221 {
222 "DIV64 by 0, zero check",
223 .insns = {
224 BPF_MOV32_IMM(BPF_REG_0, 42),
225 BPF_MOV32_IMM(BPF_REG_1, 0),
226 BPF_MOV32_IMM(BPF_REG_2, 1),
227 BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
228 BPF_EXIT_INSN(),
229 },
230 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100231 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100232 },
233 {
234 "MOD32 by 0, zero check 1",
235 .insns = {
236 BPF_MOV32_IMM(BPF_REG_0, 42),
237 BPF_MOV32_IMM(BPF_REG_1, 0),
238 BPF_MOV32_IMM(BPF_REG_2, 1),
239 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
240 BPF_EXIT_INSN(),
241 },
242 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100243 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100244 },
245 {
246 "MOD32 by 0, zero check 2",
247 .insns = {
248 BPF_MOV32_IMM(BPF_REG_0, 42),
249 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
250 BPF_MOV32_IMM(BPF_REG_2, 1),
251 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
252 BPF_EXIT_INSN(),
253 },
254 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100255 .retval = 42,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100256 },
257 {
258 "MOD64 by 0, zero check",
259 .insns = {
260 BPF_MOV32_IMM(BPF_REG_0, 42),
261 BPF_MOV32_IMM(BPF_REG_1, 0),
262 BPF_MOV32_IMM(BPF_REG_2, 1),
263 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
264 BPF_EXIT_INSN(),
265 },
266 .result = ACCEPT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100267 .retval = 42,
268 },
269 {
270 "DIV32 by 0, zero check ok, cls",
271 .insns = {
272 BPF_MOV32_IMM(BPF_REG_0, 42),
273 BPF_MOV32_IMM(BPF_REG_1, 2),
274 BPF_MOV32_IMM(BPF_REG_2, 16),
275 BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
276 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
277 BPF_EXIT_INSN(),
278 },
279 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
280 .result = ACCEPT,
281 .retval = 8,
282 },
283 {
284 "DIV32 by 0, zero check 1, cls",
285 .insns = {
286 BPF_MOV32_IMM(BPF_REG_1, 0),
287 BPF_MOV32_IMM(BPF_REG_0, 1),
288 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
289 BPF_EXIT_INSN(),
290 },
291 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
292 .result = ACCEPT,
Daniel Borkmann87c17932018-01-20 01:24:32 +0100293 .retval = 0,
294 },
295 {
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100296 "DIV32 by 0, zero check 2, cls",
297 .insns = {
298 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
299 BPF_MOV32_IMM(BPF_REG_0, 1),
300 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
301 BPF_EXIT_INSN(),
302 },
303 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
304 .result = ACCEPT,
305 .retval = 0,
306 },
307 {
308 "DIV64 by 0, zero check, cls",
309 .insns = {
310 BPF_MOV32_IMM(BPF_REG_1, 0),
311 BPF_MOV32_IMM(BPF_REG_0, 1),
312 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
313 BPF_EXIT_INSN(),
314 },
315 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
316 .result = ACCEPT,
317 .retval = 0,
318 },
319 {
320 "MOD32 by 0, zero check ok, cls",
321 .insns = {
322 BPF_MOV32_IMM(BPF_REG_0, 42),
323 BPF_MOV32_IMM(BPF_REG_1, 3),
324 BPF_MOV32_IMM(BPF_REG_2, 5),
325 BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
326 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
327 BPF_EXIT_INSN(),
328 },
329 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
330 .result = ACCEPT,
331 .retval = 2,
332 },
333 {
334 "MOD32 by 0, zero check 1, cls",
335 .insns = {
336 BPF_MOV32_IMM(BPF_REG_1, 0),
337 BPF_MOV32_IMM(BPF_REG_0, 1),
338 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
339 BPF_EXIT_INSN(),
340 },
341 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
342 .result = ACCEPT,
343 .retval = 1,
344 },
345 {
346 "MOD32 by 0, zero check 2, cls",
347 .insns = {
348 BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
349 BPF_MOV32_IMM(BPF_REG_0, 1),
350 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
351 BPF_EXIT_INSN(),
352 },
353 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
354 .result = ACCEPT,
355 .retval = 1,
356 },
357 {
358 "MOD64 by 0, zero check 1, cls",
359 .insns = {
360 BPF_MOV32_IMM(BPF_REG_1, 0),
361 BPF_MOV32_IMM(BPF_REG_0, 2),
362 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
363 BPF_EXIT_INSN(),
364 },
365 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
366 .result = ACCEPT,
367 .retval = 2,
368 },
369 {
370 "MOD64 by 0, zero check 2, cls",
371 .insns = {
372 BPF_MOV32_IMM(BPF_REG_1, 0),
373 BPF_MOV32_IMM(BPF_REG_0, -1),
374 BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
375 BPF_EXIT_INSN(),
376 },
377 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
378 .result = ACCEPT,
379 .retval = -1,
380 },
381 /* Just make sure that JITs used udiv/umod as otherwise we get
382 * an exception from INT_MIN/-1 overflow similarly as with div
383 * by zero.
384 */
385 {
386 "DIV32 overflow, check 1",
387 .insns = {
388 BPF_MOV32_IMM(BPF_REG_1, -1),
389 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
390 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
391 BPF_EXIT_INSN(),
392 },
393 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
394 .result = ACCEPT,
395 .retval = 0,
396 },
397 {
398 "DIV32 overflow, check 2",
399 .insns = {
400 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
401 BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
402 BPF_EXIT_INSN(),
403 },
404 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
405 .result = ACCEPT,
406 .retval = 0,
407 },
408 {
409 "DIV64 overflow, check 1",
410 .insns = {
411 BPF_MOV64_IMM(BPF_REG_1, -1),
412 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
413 BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
414 BPF_EXIT_INSN(),
415 },
416 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
417 .result = ACCEPT,
418 .retval = 0,
419 },
420 {
421 "DIV64 overflow, check 2",
422 .insns = {
423 BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
424 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
425 BPF_EXIT_INSN(),
426 },
427 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
428 .result = ACCEPT,
429 .retval = 0,
430 },
431 {
432 "MOD32 overflow, check 1",
433 .insns = {
434 BPF_MOV32_IMM(BPF_REG_1, -1),
435 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
436 BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
437 BPF_EXIT_INSN(),
438 },
439 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
440 .result = ACCEPT,
441 .retval = INT_MIN,
442 },
443 {
444 "MOD32 overflow, check 2",
445 .insns = {
446 BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
447 BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
448 BPF_EXIT_INSN(),
449 },
450 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
451 .result = ACCEPT,
452 .retval = INT_MIN,
453 },
454 {
455 "MOD64 overflow, check 1",
456 .insns = {
457 BPF_MOV64_IMM(BPF_REG_1, -1),
458 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
459 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
460 BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
461 BPF_MOV32_IMM(BPF_REG_0, 0),
462 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
463 BPF_MOV32_IMM(BPF_REG_0, 1),
464 BPF_EXIT_INSN(),
465 },
466 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
467 .result = ACCEPT,
468 .retval = 1,
469 },
470 {
471 "MOD64 overflow, check 2",
472 .insns = {
473 BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
474 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
475 BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
476 BPF_MOV32_IMM(BPF_REG_0, 0),
477 BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
478 BPF_MOV32_IMM(BPF_REG_0, 1),
479 BPF_EXIT_INSN(),
480 },
481 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
482 .result = ACCEPT,
483 .retval = 1,
484 },
485 {
486 "xor32 zero extend check",
487 .insns = {
488 BPF_MOV32_IMM(BPF_REG_2, -1),
489 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
490 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
491 BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
492 BPF_MOV32_IMM(BPF_REG_0, 2),
493 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
494 BPF_MOV32_IMM(BPF_REG_0, 1),
495 BPF_EXIT_INSN(),
496 },
497 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
498 .result = ACCEPT,
499 .retval = 1,
500 },
501 {
Daniel Borkmann87c17932018-01-20 01:24:32 +0100502 "empty prog",
503 .insns = {
504 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100505 .errstr = "unknown opcode 00",
Daniel Borkmann87c17932018-01-20 01:24:32 +0100506 .result = REJECT,
507 },
508 {
509 "only exit insn",
510 .insns = {
511 BPF_EXIT_INSN(),
512 },
513 .errstr = "R0 !read_ok",
514 .result = REJECT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700515 },
516 {
517 "unreachable",
518 .insns = {
519 BPF_EXIT_INSN(),
520 BPF_EXIT_INSN(),
521 },
522 .errstr = "unreachable",
523 .result = REJECT,
524 },
525 {
526 "unreachable2",
527 .insns = {
528 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
529 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
530 BPF_EXIT_INSN(),
531 },
532 .errstr = "unreachable",
533 .result = REJECT,
534 },
535 {
536 "out of range jump",
537 .insns = {
538 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
539 BPF_EXIT_INSN(),
540 },
541 .errstr = "jump out of range",
542 .result = REJECT,
543 },
544 {
545 "out of range jump2",
546 .insns = {
547 BPF_JMP_IMM(BPF_JA, 0, 0, -2),
548 BPF_EXIT_INSN(),
549 },
550 .errstr = "jump out of range",
551 .result = REJECT,
552 },
553 {
554 "test1 ld_imm64",
555 .insns = {
556 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
557 BPF_LD_IMM64(BPF_REG_0, 0),
558 BPF_LD_IMM64(BPF_REG_0, 0),
559 BPF_LD_IMM64(BPF_REG_0, 1),
560 BPF_LD_IMM64(BPF_REG_0, 1),
561 BPF_MOV64_IMM(BPF_REG_0, 2),
562 BPF_EXIT_INSN(),
563 },
564 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700565 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700566 .result = REJECT,
567 },
568 {
569 "test2 ld_imm64",
570 .insns = {
571 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
572 BPF_LD_IMM64(BPF_REG_0, 0),
573 BPF_LD_IMM64(BPF_REG_0, 0),
574 BPF_LD_IMM64(BPF_REG_0, 1),
575 BPF_LD_IMM64(BPF_REG_0, 1),
576 BPF_EXIT_INSN(),
577 },
578 .errstr = "invalid BPF_LD_IMM insn",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700579 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700580 .result = REJECT,
581 },
582 {
583 "test3 ld_imm64",
584 .insns = {
585 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
586 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
587 BPF_LD_IMM64(BPF_REG_0, 0),
588 BPF_LD_IMM64(BPF_REG_0, 0),
589 BPF_LD_IMM64(BPF_REG_0, 1),
590 BPF_LD_IMM64(BPF_REG_0, 1),
591 BPF_EXIT_INSN(),
592 },
593 .errstr = "invalid bpf_ld_imm64 insn",
594 .result = REJECT,
595 },
596 {
597 "test4 ld_imm64",
598 .insns = {
599 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
600 BPF_EXIT_INSN(),
601 },
602 .errstr = "invalid bpf_ld_imm64 insn",
603 .result = REJECT,
604 },
605 {
606 "test5 ld_imm64",
607 .insns = {
608 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
609 },
610 .errstr = "invalid bpf_ld_imm64 insn",
611 .result = REJECT,
612 },
613 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200614 "test6 ld_imm64",
615 .insns = {
616 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
617 BPF_RAW_INSN(0, 0, 0, 0, 0),
618 BPF_EXIT_INSN(),
619 },
620 .result = ACCEPT,
621 },
622 {
623 "test7 ld_imm64",
624 .insns = {
625 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
626 BPF_RAW_INSN(0, 0, 0, 0, 1),
627 BPF_EXIT_INSN(),
628 },
629 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800630 .retval = 1,
Daniel Borkmann728a8532017-04-27 01:39:32 +0200631 },
632 {
633 "test8 ld_imm64",
634 .insns = {
635 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
636 BPF_RAW_INSN(0, 0, 0, 0, 1),
637 BPF_EXIT_INSN(),
638 },
639 .errstr = "uses reserved fields",
640 .result = REJECT,
641 },
642 {
643 "test9 ld_imm64",
644 .insns = {
645 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
646 BPF_RAW_INSN(0, 0, 0, 1, 1),
647 BPF_EXIT_INSN(),
648 },
649 .errstr = "invalid bpf_ld_imm64 insn",
650 .result = REJECT,
651 },
652 {
653 "test10 ld_imm64",
654 .insns = {
655 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
656 BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
657 BPF_EXIT_INSN(),
658 },
659 .errstr = "invalid bpf_ld_imm64 insn",
660 .result = REJECT,
661 },
662 {
663 "test11 ld_imm64",
664 .insns = {
665 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
666 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
667 BPF_EXIT_INSN(),
668 },
669 .errstr = "invalid bpf_ld_imm64 insn",
670 .result = REJECT,
671 },
672 {
673 "test12 ld_imm64",
674 .insns = {
675 BPF_MOV64_IMM(BPF_REG_1, 0),
676 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
677 BPF_RAW_INSN(0, 0, 0, 0, 1),
678 BPF_EXIT_INSN(),
679 },
680 .errstr = "not pointing to valid bpf_map",
681 .result = REJECT,
682 },
683 {
684 "test13 ld_imm64",
685 .insns = {
686 BPF_MOV64_IMM(BPF_REG_1, 0),
687 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
688 BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
689 BPF_EXIT_INSN(),
690 },
691 .errstr = "invalid bpf_ld_imm64 insn",
692 .result = REJECT,
693 },
694 {
Daniel Borkmann7891a872018-01-10 20:04:37 +0100695 "arsh32 on imm",
696 .insns = {
697 BPF_MOV64_IMM(BPF_REG_0, 1),
698 BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
699 BPF_EXIT_INSN(),
700 },
701 .result = REJECT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100702 .errstr = "unknown opcode c4",
Daniel Borkmann7891a872018-01-10 20:04:37 +0100703 },
704 {
705 "arsh32 on reg",
706 .insns = {
707 BPF_MOV64_IMM(BPF_REG_0, 1),
708 BPF_MOV64_IMM(BPF_REG_1, 5),
709 BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
710 BPF_EXIT_INSN(),
711 },
712 .result = REJECT,
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100713 .errstr = "unknown opcode cc",
Daniel Borkmann7891a872018-01-10 20:04:37 +0100714 },
715 {
716 "arsh64 on imm",
717 .insns = {
718 BPF_MOV64_IMM(BPF_REG_0, 1),
719 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
720 BPF_EXIT_INSN(),
721 },
722 .result = ACCEPT,
723 },
724 {
725 "arsh64 on reg",
726 .insns = {
727 BPF_MOV64_IMM(BPF_REG_0, 1),
728 BPF_MOV64_IMM(BPF_REG_1, 5),
729 BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
730 BPF_EXIT_INSN(),
731 },
732 .result = ACCEPT,
733 },
734 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700735 "no bpf_exit",
736 .insns = {
737 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
738 },
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -0800739 .errstr = "not an exit",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700740 .result = REJECT,
741 },
742 {
743 "loop (back-edge)",
744 .insns = {
745 BPF_JMP_IMM(BPF_JA, 0, 0, -1),
746 BPF_EXIT_INSN(),
747 },
748 .errstr = "back-edge",
749 .result = REJECT,
750 },
751 {
752 "loop2 (back-edge)",
753 .insns = {
754 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
755 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
756 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
757 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
758 BPF_EXIT_INSN(),
759 },
760 .errstr = "back-edge",
761 .result = REJECT,
762 },
763 {
764 "conditional loop",
765 .insns = {
766 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
767 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
768 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
769 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
770 BPF_EXIT_INSN(),
771 },
772 .errstr = "back-edge",
773 .result = REJECT,
774 },
775 {
776 "read uninitialized register",
777 .insns = {
778 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
779 BPF_EXIT_INSN(),
780 },
781 .errstr = "R2 !read_ok",
782 .result = REJECT,
783 },
784 {
785 "read invalid register",
786 .insns = {
787 BPF_MOV64_REG(BPF_REG_0, -1),
788 BPF_EXIT_INSN(),
789 },
790 .errstr = "R15 is invalid",
791 .result = REJECT,
792 },
793 {
794 "program doesn't init R0 before exit",
795 .insns = {
796 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
797 BPF_EXIT_INSN(),
798 },
799 .errstr = "R0 !read_ok",
800 .result = REJECT,
801 },
802 {
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700803 "program doesn't init R0 before exit in all branches",
804 .insns = {
805 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
806 BPF_MOV64_IMM(BPF_REG_0, 1),
807 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
808 BPF_EXIT_INSN(),
809 },
810 .errstr = "R0 !read_ok",
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700811 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov32bf08a2014-10-20 14:54:57 -0700812 .result = REJECT,
813 },
814 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700815 "stack out of bounds",
816 .insns = {
817 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
818 BPF_EXIT_INSN(),
819 },
820 .errstr = "invalid stack",
821 .result = REJECT,
822 },
823 {
824 "invalid call insn1",
825 .insns = {
826 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
827 BPF_EXIT_INSN(),
828 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +0100829 .errstr = "unknown opcode 8d",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700830 .result = REJECT,
831 },
832 {
833 "invalid call insn2",
834 .insns = {
835 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
836 BPF_EXIT_INSN(),
837 },
838 .errstr = "BPF_CALL uses reserved",
839 .result = REJECT,
840 },
841 {
842 "invalid function call",
843 .insns = {
844 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
845 BPF_EXIT_INSN(),
846 },
Daniel Borkmanne00c7b22016-11-26 01:28:09 +0100847 .errstr = "invalid func unknown#1234567",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700848 .result = REJECT,
849 },
850 {
851 "uninitialized stack1",
852 .insns = {
853 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
854 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
855 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200856 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
857 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700858 BPF_EXIT_INSN(),
859 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200860 .fixup_map1 = { 2 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700861 .errstr = "invalid indirect read from stack",
862 .result = REJECT,
863 },
864 {
865 "uninitialized stack2",
866 .insns = {
867 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
868 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
869 BPF_EXIT_INSN(),
870 },
871 .errstr = "invalid read from stack",
872 .result = REJECT,
873 },
874 {
Daniel Borkmann728a8532017-04-27 01:39:32 +0200875 "invalid fp arithmetic",
876 /* If this gets ever changed, make sure JITs can deal with it. */
877 .insns = {
878 BPF_MOV64_IMM(BPF_REG_0, 0),
879 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
880 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
881 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
882 BPF_EXIT_INSN(),
883 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -0800884 .errstr = "R1 subtraction from stack pointer",
Daniel Borkmann728a8532017-04-27 01:39:32 +0200885 .result = REJECT,
886 },
887 {
888 "non-invalid fp arithmetic",
889 .insns = {
890 BPF_MOV64_IMM(BPF_REG_0, 0),
891 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
892 BPF_EXIT_INSN(),
893 },
894 .result = ACCEPT,
895 },
896 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200897 "invalid argument register",
898 .insns = {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200899 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
900 BPF_FUNC_get_cgroup_classid),
901 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
902 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200903 BPF_EXIT_INSN(),
904 },
905 .errstr = "R1 !read_ok",
906 .result = REJECT,
907 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
908 },
909 {
910 "non-invalid argument register",
911 .insns = {
912 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200913 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
914 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200915 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +0200916 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
917 BPF_FUNC_get_cgroup_classid),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +0200918 BPF_EXIT_INSN(),
919 },
920 .result = ACCEPT,
921 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
922 },
923 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700924 "check valid spill/fill",
925 .insns = {
926 /* spill R1(ctx) into stack */
927 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700928 /* fill it back into R2 */
929 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700930 /* should be able to access R0 = *(R2 + 8) */
Daniel Borkmannf91fe172015-03-01 12:31:41 +0100931 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
932 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700933 BPF_EXIT_INSN(),
934 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700935 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700936 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700937 .result_unpriv = REJECT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -0800938 .retval = POINTER_VALUE,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700939 },
940 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +0200941 "check valid spill/fill, skb mark",
942 .insns = {
943 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
944 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
945 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
946 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
947 offsetof(struct __sk_buff, mark)),
948 BPF_EXIT_INSN(),
949 },
950 .result = ACCEPT,
951 .result_unpriv = ACCEPT,
952 },
953 {
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700954 "check corrupted spill/fill",
955 .insns = {
956 /* spill R1(ctx) into stack */
957 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700958 /* mess up with R1 pointer on stack */
959 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700960 /* fill back into R0 should fail */
961 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700962 BPF_EXIT_INSN(),
963 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -0700964 .errstr_unpriv = "attempt to corrupt spilled",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -0700965 .errstr = "corrupted spill",
966 .result = REJECT,
967 },
968 {
969 "invalid src register in STX",
970 .insns = {
971 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
972 BPF_EXIT_INSN(),
973 },
974 .errstr = "R15 is invalid",
975 .result = REJECT,
976 },
977 {
978 "invalid dst register in STX",
979 .insns = {
980 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
981 BPF_EXIT_INSN(),
982 },
983 .errstr = "R14 is invalid",
984 .result = REJECT,
985 },
986 {
987 "invalid dst register in ST",
988 .insns = {
989 BPF_ST_MEM(BPF_B, 14, -1, -1),
990 BPF_EXIT_INSN(),
991 },
992 .errstr = "R14 is invalid",
993 .result = REJECT,
994 },
995 {
996 "invalid src register in LDX",
997 .insns = {
998 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
999 BPF_EXIT_INSN(),
1000 },
1001 .errstr = "R12 is invalid",
1002 .result = REJECT,
1003 },
1004 {
1005 "invalid dst register in LDX",
1006 .insns = {
1007 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
1008 BPF_EXIT_INSN(),
1009 },
1010 .errstr = "R11 is invalid",
1011 .result = REJECT,
1012 },
1013 {
1014 "junk insn",
1015 .insns = {
1016 BPF_RAW_INSN(0, 0, 0, 0, 0),
1017 BPF_EXIT_INSN(),
1018 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001019 .errstr = "unknown opcode 00",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001020 .result = REJECT,
1021 },
1022 {
1023 "junk insn2",
1024 .insns = {
1025 BPF_RAW_INSN(1, 0, 0, 0, 0),
1026 BPF_EXIT_INSN(),
1027 },
1028 .errstr = "BPF_LDX uses reserved fields",
1029 .result = REJECT,
1030 },
1031 {
1032 "junk insn3",
1033 .insns = {
1034 BPF_RAW_INSN(-1, 0, 0, 0, 0),
1035 BPF_EXIT_INSN(),
1036 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001037 .errstr = "unknown opcode ff",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001038 .result = REJECT,
1039 },
1040 {
1041 "junk insn4",
1042 .insns = {
1043 BPF_RAW_INSN(-1, -1, -1, -1, -1),
1044 BPF_EXIT_INSN(),
1045 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01001046 .errstr = "unknown opcode ff",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001047 .result = REJECT,
1048 },
1049 {
1050 "junk insn5",
1051 .insns = {
1052 BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
1053 BPF_EXIT_INSN(),
1054 },
1055 .errstr = "BPF_ALU uses reserved fields",
1056 .result = REJECT,
1057 },
1058 {
1059 "misaligned read from stack",
1060 .insns = {
1061 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1062 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
1063 BPF_EXIT_INSN(),
1064 },
Edward Creef65b1842017-08-07 15:27:12 +01001065 .errstr = "misaligned stack access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001066 .result = REJECT,
1067 },
1068 {
1069 "invalid map_fd for function call",
1070 .insns = {
1071 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1072 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
1073 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1074 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1076 BPF_FUNC_map_delete_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001077 BPF_EXIT_INSN(),
1078 },
1079 .errstr = "fd 0 is not pointing to valid bpf_map",
1080 .result = REJECT,
1081 },
1082 {
1083 "don't check return value before access",
1084 .insns = {
1085 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1086 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1087 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1088 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001089 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1090 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001091 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1092 BPF_EXIT_INSN(),
1093 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001094 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001095 .errstr = "R0 invalid mem access 'map_value_or_null'",
1096 .result = REJECT,
1097 },
1098 {
1099 "access memory with incorrect alignment",
1100 .insns = {
1101 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1102 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1104 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001105 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1106 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001107 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1108 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
1109 BPF_EXIT_INSN(),
1110 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001111 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01001112 .errstr = "misaligned value access",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001113 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001114 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001115 },
1116 {
1117 "sometimes access memory with incorrect alignment",
1118 .insns = {
1119 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1120 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1122 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001123 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1124 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001125 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1126 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1127 BPF_EXIT_INSN(),
1128 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
1129 BPF_EXIT_INSN(),
1130 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001131 .fixup_map1 = { 3 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001132 .errstr = "R0 invalid mem access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001133 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001134 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01001135 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -07001136 },
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001137 {
1138 "jump test 1",
1139 .insns = {
1140 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1141 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
1142 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1143 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1144 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
1145 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
1146 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
1147 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
1148 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
1149 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
1150 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
1151 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
1152 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1153 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
1154 BPF_MOV64_IMM(BPF_REG_0, 0),
1155 BPF_EXIT_INSN(),
1156 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001157 .errstr_unpriv = "R1 pointer comparison",
1158 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001159 .result = ACCEPT,
1160 },
1161 {
1162 "jump test 2",
1163 .insns = {
1164 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1165 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
1166 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1167 BPF_JMP_IMM(BPF_JA, 0, 0, 14),
1168 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
1169 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1170 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1171 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
1172 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1173 BPF_JMP_IMM(BPF_JA, 0, 0, 8),
1174 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
1175 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1176 BPF_JMP_IMM(BPF_JA, 0, 0, 5),
1177 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
1178 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1179 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1180 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
1181 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1182 BPF_MOV64_IMM(BPF_REG_0, 0),
1183 BPF_EXIT_INSN(),
1184 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001185 .errstr_unpriv = "R1 pointer comparison",
1186 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001187 .result = ACCEPT,
1188 },
1189 {
1190 "jump test 3",
1191 .insns = {
1192 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1193 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
1194 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
1195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1196 BPF_JMP_IMM(BPF_JA, 0, 0, 19),
1197 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
1198 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
1199 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1200 BPF_JMP_IMM(BPF_JA, 0, 0, 15),
1201 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
1202 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
1203 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
1204 BPF_JMP_IMM(BPF_JA, 0, 0, 11),
1205 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
1206 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
1207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
1208 BPF_JMP_IMM(BPF_JA, 0, 0, 7),
1209 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
1210 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
1211 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
1212 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1213 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
1214 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
1215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
1216 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001217 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1218 BPF_FUNC_map_delete_elem),
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001219 BPF_EXIT_INSN(),
1220 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001221 .fixup_map1 = { 24 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001222 .errstr_unpriv = "R1 pointer comparison",
1223 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001224 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08001225 .retval = -ENOENT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001226 },
1227 {
1228 "jump test 4",
1229 .insns = {
1230 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1231 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1232 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1233 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1234 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1235 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1236 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1237 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1238 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1239 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1240 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1243 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1244 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1245 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1246 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1247 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1248 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1249 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1250 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1251 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1252 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1253 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1254 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1255 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1257 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1260 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1261 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
1262 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
1263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
1264 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
1265 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
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_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
1270 BPF_MOV64_IMM(BPF_REG_0, 0),
1271 BPF_EXIT_INSN(),
1272 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001273 .errstr_unpriv = "R1 pointer comparison",
1274 .result_unpriv = REJECT,
Alexei Starovoitovfd10c2e2014-09-29 18:50:02 -07001275 .result = ACCEPT,
1276 },
Alexei Starovoitov342ded42014-10-28 15:11:42 -07001277 {
1278 "jump test 5",
1279 .insns = {
1280 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1281 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
1282 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1283 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1284 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1285 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1286 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1287 BPF_MOV64_IMM(BPF_REG_0, 0),
1288 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1289 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1290 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1291 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1292 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1293 BPF_MOV64_IMM(BPF_REG_0, 0),
1294 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1295 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1296 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1297 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1298 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1299 BPF_MOV64_IMM(BPF_REG_0, 0),
1300 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1301 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1302 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1303 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1304 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1305 BPF_MOV64_IMM(BPF_REG_0, 0),
1306 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1307 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
1308 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1309 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
1310 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
1311 BPF_MOV64_IMM(BPF_REG_0, 0),
1312 BPF_EXIT_INSN(),
1313 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001314 .errstr_unpriv = "R1 pointer comparison",
1315 .result_unpriv = REJECT,
Alexei Starovoitov342ded42014-10-28 15:11:42 -07001316 .result = ACCEPT,
1317 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001318 {
1319 "access skb fields ok",
1320 .insns = {
1321 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1322 offsetof(struct __sk_buff, len)),
1323 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1324 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1325 offsetof(struct __sk_buff, mark)),
1326 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1327 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1328 offsetof(struct __sk_buff, pkt_type)),
1329 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
1330 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1331 offsetof(struct __sk_buff, queue_mapping)),
1332 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitovc2497392015-03-16 18:06:02 -07001333 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1334 offsetof(struct __sk_buff, protocol)),
1335 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1336 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1337 offsetof(struct __sk_buff, vlan_present)),
1338 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1339 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1340 offsetof(struct __sk_buff, vlan_tci)),
1341 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Daniel Borkmannb1d9fc42017-04-19 23:01:17 +02001342 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1343 offsetof(struct __sk_buff, napi_id)),
1344 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001345 BPF_EXIT_INSN(),
1346 },
1347 .result = ACCEPT,
1348 },
1349 {
1350 "access skb fields bad1",
1351 .insns = {
1352 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
1353 BPF_EXIT_INSN(),
1354 },
1355 .errstr = "invalid bpf_context access",
1356 .result = REJECT,
1357 },
1358 {
1359 "access skb fields bad2",
1360 .insns = {
1361 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
1362 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1363 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1365 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001366 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1367 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001368 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1369 BPF_EXIT_INSN(),
1370 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1371 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1372 offsetof(struct __sk_buff, pkt_type)),
1373 BPF_EXIT_INSN(),
1374 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001375 .fixup_map1 = { 4 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001376 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001377 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001378 .result = REJECT,
1379 },
1380 {
1381 "access skb fields bad3",
1382 .insns = {
1383 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
1384 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1385 offsetof(struct __sk_buff, pkt_type)),
1386 BPF_EXIT_INSN(),
1387 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1388 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1390 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001391 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1392 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001393 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1394 BPF_EXIT_INSN(),
1395 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1396 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
1397 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001398 .fixup_map1 = { 6 },
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001399 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001400 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov614cd3b2015-03-13 11:57:43 -07001401 .result = REJECT,
1402 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001403 {
1404 "access skb fields bad4",
1405 .insns = {
1406 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
1407 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1408 offsetof(struct __sk_buff, len)),
1409 BPF_MOV64_IMM(BPF_REG_0, 0),
1410 BPF_EXIT_INSN(),
1411 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1412 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1413 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1414 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1416 BPF_FUNC_map_lookup_elem),
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001417 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1418 BPF_EXIT_INSN(),
1419 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1420 BPF_JMP_IMM(BPF_JA, 0, 0, -13),
1421 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02001422 .fixup_map1 = { 7 },
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001423 .errstr = "different pointers",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001424 .errstr_unpriv = "R1 pointer comparison",
Alexei Starovoitov725f9dc2015-04-15 16:19:33 -07001425 .result = REJECT,
1426 },
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001427 {
John Fastabend41bc94f2017-08-15 22:33:56 -07001428 "invalid access __sk_buff family",
1429 .insns = {
1430 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1431 offsetof(struct __sk_buff, family)),
1432 BPF_EXIT_INSN(),
1433 },
1434 .errstr = "invalid bpf_context access",
1435 .result = REJECT,
1436 },
1437 {
1438 "invalid access __sk_buff remote_ip4",
1439 .insns = {
1440 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1441 offsetof(struct __sk_buff, remote_ip4)),
1442 BPF_EXIT_INSN(),
1443 },
1444 .errstr = "invalid bpf_context access",
1445 .result = REJECT,
1446 },
1447 {
1448 "invalid access __sk_buff local_ip4",
1449 .insns = {
1450 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1451 offsetof(struct __sk_buff, local_ip4)),
1452 BPF_EXIT_INSN(),
1453 },
1454 .errstr = "invalid bpf_context access",
1455 .result = REJECT,
1456 },
1457 {
1458 "invalid access __sk_buff remote_ip6",
1459 .insns = {
1460 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1461 offsetof(struct __sk_buff, remote_ip6)),
1462 BPF_EXIT_INSN(),
1463 },
1464 .errstr = "invalid bpf_context access",
1465 .result = REJECT,
1466 },
1467 {
1468 "invalid access __sk_buff local_ip6",
1469 .insns = {
1470 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1471 offsetof(struct __sk_buff, local_ip6)),
1472 BPF_EXIT_INSN(),
1473 },
1474 .errstr = "invalid bpf_context access",
1475 .result = REJECT,
1476 },
1477 {
1478 "invalid access __sk_buff remote_port",
1479 .insns = {
1480 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1481 offsetof(struct __sk_buff, remote_port)),
1482 BPF_EXIT_INSN(),
1483 },
1484 .errstr = "invalid bpf_context access",
1485 .result = REJECT,
1486 },
1487 {
1488 "invalid access __sk_buff remote_port",
1489 .insns = {
1490 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1491 offsetof(struct __sk_buff, local_port)),
1492 BPF_EXIT_INSN(),
1493 },
1494 .errstr = "invalid bpf_context access",
1495 .result = REJECT,
1496 },
1497 {
1498 "valid access __sk_buff family",
1499 .insns = {
1500 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1501 offsetof(struct __sk_buff, family)),
1502 BPF_EXIT_INSN(),
1503 },
1504 .result = ACCEPT,
1505 .prog_type = BPF_PROG_TYPE_SK_SKB,
1506 },
1507 {
1508 "valid access __sk_buff remote_ip4",
1509 .insns = {
1510 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1511 offsetof(struct __sk_buff, remote_ip4)),
1512 BPF_EXIT_INSN(),
1513 },
1514 .result = ACCEPT,
1515 .prog_type = BPF_PROG_TYPE_SK_SKB,
1516 },
1517 {
1518 "valid access __sk_buff local_ip4",
1519 .insns = {
1520 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1521 offsetof(struct __sk_buff, local_ip4)),
1522 BPF_EXIT_INSN(),
1523 },
1524 .result = ACCEPT,
1525 .prog_type = BPF_PROG_TYPE_SK_SKB,
1526 },
1527 {
1528 "valid access __sk_buff remote_ip6",
1529 .insns = {
1530 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1531 offsetof(struct __sk_buff, remote_ip6[0])),
1532 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1533 offsetof(struct __sk_buff, remote_ip6[1])),
1534 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1535 offsetof(struct __sk_buff, remote_ip6[2])),
1536 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1537 offsetof(struct __sk_buff, remote_ip6[3])),
1538 BPF_EXIT_INSN(),
1539 },
1540 .result = ACCEPT,
1541 .prog_type = BPF_PROG_TYPE_SK_SKB,
1542 },
1543 {
1544 "valid access __sk_buff local_ip6",
1545 .insns = {
1546 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1547 offsetof(struct __sk_buff, local_ip6[0])),
1548 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1549 offsetof(struct __sk_buff, local_ip6[1])),
1550 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1551 offsetof(struct __sk_buff, local_ip6[2])),
1552 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1553 offsetof(struct __sk_buff, local_ip6[3])),
1554 BPF_EXIT_INSN(),
1555 },
1556 .result = ACCEPT,
1557 .prog_type = BPF_PROG_TYPE_SK_SKB,
1558 },
1559 {
1560 "valid access __sk_buff remote_port",
1561 .insns = {
1562 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1563 offsetof(struct __sk_buff, remote_port)),
1564 BPF_EXIT_INSN(),
1565 },
1566 .result = ACCEPT,
1567 .prog_type = BPF_PROG_TYPE_SK_SKB,
1568 },
1569 {
1570 "valid access __sk_buff remote_port",
1571 .insns = {
1572 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1573 offsetof(struct __sk_buff, local_port)),
1574 BPF_EXIT_INSN(),
1575 },
1576 .result = ACCEPT,
1577 .prog_type = BPF_PROG_TYPE_SK_SKB,
1578 },
1579 {
John Fastabended850542017-08-28 07:11:24 -07001580 "invalid access of tc_classid for SK_SKB",
1581 .insns = {
1582 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1583 offsetof(struct __sk_buff, tc_classid)),
1584 BPF_EXIT_INSN(),
1585 },
1586 .result = REJECT,
1587 .prog_type = BPF_PROG_TYPE_SK_SKB,
1588 .errstr = "invalid bpf_context access",
1589 },
1590 {
John Fastabendf7e9cb12017-10-18 07:10:58 -07001591 "invalid access of skb->mark for SK_SKB",
1592 .insns = {
1593 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1594 offsetof(struct __sk_buff, mark)),
1595 BPF_EXIT_INSN(),
1596 },
1597 .result = REJECT,
1598 .prog_type = BPF_PROG_TYPE_SK_SKB,
1599 .errstr = "invalid bpf_context access",
1600 },
1601 {
1602 "check skb->mark is not writeable by SK_SKB",
John Fastabended850542017-08-28 07:11:24 -07001603 .insns = {
1604 BPF_MOV64_IMM(BPF_REG_0, 0),
1605 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1606 offsetof(struct __sk_buff, mark)),
1607 BPF_EXIT_INSN(),
1608 },
John Fastabendf7e9cb12017-10-18 07:10:58 -07001609 .result = REJECT,
John Fastabended850542017-08-28 07:11:24 -07001610 .prog_type = BPF_PROG_TYPE_SK_SKB,
John Fastabendf7e9cb12017-10-18 07:10:58 -07001611 .errstr = "invalid bpf_context access",
John Fastabended850542017-08-28 07:11:24 -07001612 },
1613 {
1614 "check skb->tc_index is writeable by SK_SKB",
1615 .insns = {
1616 BPF_MOV64_IMM(BPF_REG_0, 0),
1617 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1618 offsetof(struct __sk_buff, tc_index)),
1619 BPF_EXIT_INSN(),
1620 },
1621 .result = ACCEPT,
1622 .prog_type = BPF_PROG_TYPE_SK_SKB,
1623 },
1624 {
1625 "check skb->priority is writeable by SK_SKB",
1626 .insns = {
1627 BPF_MOV64_IMM(BPF_REG_0, 0),
1628 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1629 offsetof(struct __sk_buff, priority)),
1630 BPF_EXIT_INSN(),
1631 },
1632 .result = ACCEPT,
1633 .prog_type = BPF_PROG_TYPE_SK_SKB,
1634 },
1635 {
1636 "direct packet read for SK_SKB",
1637 .insns = {
1638 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1639 offsetof(struct __sk_buff, data)),
1640 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1641 offsetof(struct __sk_buff, data_end)),
1642 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1643 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1644 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1645 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1646 BPF_MOV64_IMM(BPF_REG_0, 0),
1647 BPF_EXIT_INSN(),
1648 },
1649 .result = ACCEPT,
1650 .prog_type = BPF_PROG_TYPE_SK_SKB,
1651 },
1652 {
1653 "direct packet write for SK_SKB",
1654 .insns = {
1655 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1656 offsetof(struct __sk_buff, data)),
1657 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1658 offsetof(struct __sk_buff, data_end)),
1659 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1660 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1661 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1662 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1663 BPF_MOV64_IMM(BPF_REG_0, 0),
1664 BPF_EXIT_INSN(),
1665 },
1666 .result = ACCEPT,
1667 .prog_type = BPF_PROG_TYPE_SK_SKB,
1668 },
1669 {
1670 "overlapping checks for direct packet access SK_SKB",
1671 .insns = {
1672 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1673 offsetof(struct __sk_buff, data)),
1674 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1675 offsetof(struct __sk_buff, data_end)),
1676 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1677 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1678 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1679 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1681 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1682 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1683 BPF_MOV64_IMM(BPF_REG_0, 0),
1684 BPF_EXIT_INSN(),
1685 },
1686 .result = ACCEPT,
1687 .prog_type = BPF_PROG_TYPE_SK_SKB,
1688 },
1689 {
John Fastabend4da0dca2018-05-17 14:17:03 -07001690 "valid access family in SK_MSG",
1691 .insns = {
1692 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1693 offsetof(struct sk_msg_md, family)),
1694 BPF_EXIT_INSN(),
1695 },
1696 .result = ACCEPT,
1697 .prog_type = BPF_PROG_TYPE_SK_MSG,
1698 },
1699 {
1700 "valid access remote_ip4 in SK_MSG",
1701 .insns = {
1702 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1703 offsetof(struct sk_msg_md, remote_ip4)),
1704 BPF_EXIT_INSN(),
1705 },
1706 .result = ACCEPT,
1707 .prog_type = BPF_PROG_TYPE_SK_MSG,
1708 },
1709 {
1710 "valid access local_ip4 in SK_MSG",
1711 .insns = {
1712 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1713 offsetof(struct sk_msg_md, local_ip4)),
1714 BPF_EXIT_INSN(),
1715 },
1716 .result = ACCEPT,
1717 .prog_type = BPF_PROG_TYPE_SK_MSG,
1718 },
1719 {
1720 "valid access remote_port in SK_MSG",
1721 .insns = {
1722 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1723 offsetof(struct sk_msg_md, remote_port)),
1724 BPF_EXIT_INSN(),
1725 },
1726 .result = ACCEPT,
1727 .prog_type = BPF_PROG_TYPE_SK_MSG,
1728 },
1729 {
1730 "valid access local_port in SK_MSG",
1731 .insns = {
1732 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1733 offsetof(struct sk_msg_md, local_port)),
1734 BPF_EXIT_INSN(),
1735 },
1736 .result = ACCEPT,
1737 .prog_type = BPF_PROG_TYPE_SK_MSG,
1738 },
1739 {
1740 "valid access remote_ip6 in SK_MSG",
1741 .insns = {
1742 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1743 offsetof(struct sk_msg_md, remote_ip6[0])),
1744 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1745 offsetof(struct sk_msg_md, remote_ip6[1])),
1746 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1747 offsetof(struct sk_msg_md, remote_ip6[2])),
1748 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1749 offsetof(struct sk_msg_md, remote_ip6[3])),
1750 BPF_EXIT_INSN(),
1751 },
1752 .result = ACCEPT,
1753 .prog_type = BPF_PROG_TYPE_SK_SKB,
1754 },
1755 {
1756 "valid access local_ip6 in SK_MSG",
1757 .insns = {
1758 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1759 offsetof(struct sk_msg_md, local_ip6[0])),
1760 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1761 offsetof(struct sk_msg_md, local_ip6[1])),
1762 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1763 offsetof(struct sk_msg_md, local_ip6[2])),
1764 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1765 offsetof(struct sk_msg_md, local_ip6[3])),
1766 BPF_EXIT_INSN(),
1767 },
1768 .result = ACCEPT,
1769 .prog_type = BPF_PROG_TYPE_SK_SKB,
1770 },
1771 {
1772 "invalid 64B read of family in SK_MSG",
1773 .insns = {
1774 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1775 offsetof(struct sk_msg_md, family)),
1776 BPF_EXIT_INSN(),
1777 },
1778 .errstr = "invalid bpf_context access",
1779 .result = REJECT,
1780 .prog_type = BPF_PROG_TYPE_SK_MSG,
1781 },
1782 {
1783 "invalid read past end of SK_MSG",
1784 .insns = {
1785 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1786 offsetof(struct sk_msg_md, local_port) + 4),
1787 BPF_EXIT_INSN(),
1788 },
1789 .errstr = "R0 !read_ok",
1790 .result = REJECT,
1791 .prog_type = BPF_PROG_TYPE_SK_MSG,
1792 },
1793 {
1794 "invalid read offset in SK_MSG",
1795 .insns = {
1796 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1797 offsetof(struct sk_msg_md, family) + 1),
1798 BPF_EXIT_INSN(),
1799 },
1800 .errstr = "invalid bpf_context access",
1801 .result = REJECT,
1802 .prog_type = BPF_PROG_TYPE_SK_MSG,
1803 },
1804 {
John Fastabend1acc60b2018-03-18 12:57:36 -07001805 "direct packet read for SK_MSG",
1806 .insns = {
1807 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1808 offsetof(struct sk_msg_md, data)),
1809 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1810 offsetof(struct sk_msg_md, data_end)),
1811 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1813 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1814 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1815 BPF_MOV64_IMM(BPF_REG_0, 0),
1816 BPF_EXIT_INSN(),
1817 },
1818 .result = ACCEPT,
1819 .prog_type = BPF_PROG_TYPE_SK_MSG,
1820 },
1821 {
1822 "direct packet write for SK_MSG",
1823 .insns = {
1824 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1825 offsetof(struct sk_msg_md, data)),
1826 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1827 offsetof(struct sk_msg_md, data_end)),
1828 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1830 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1831 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1832 BPF_MOV64_IMM(BPF_REG_0, 0),
1833 BPF_EXIT_INSN(),
1834 },
1835 .result = ACCEPT,
1836 .prog_type = BPF_PROG_TYPE_SK_MSG,
1837 },
1838 {
1839 "overlapping checks for direct packet access SK_MSG",
1840 .insns = {
1841 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1842 offsetof(struct sk_msg_md, data)),
1843 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1844 offsetof(struct sk_msg_md, data_end)),
1845 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1846 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1847 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1848 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1850 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1851 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1852 BPF_MOV64_IMM(BPF_REG_0, 0),
1853 BPF_EXIT_INSN(),
1854 },
1855 .result = ACCEPT,
1856 .prog_type = BPF_PROG_TYPE_SK_MSG,
1857 },
1858 {
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001859 "check skb->mark is not writeable by sockets",
1860 .insns = {
1861 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1862 offsetof(struct __sk_buff, mark)),
1863 BPF_EXIT_INSN(),
1864 },
1865 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001866 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001867 .result = REJECT,
1868 },
1869 {
1870 "check skb->tc_index is not writeable by sockets",
1871 .insns = {
1872 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
1873 offsetof(struct __sk_buff, tc_index)),
1874 BPF_EXIT_INSN(),
1875 },
1876 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07001877 .errstr_unpriv = "R1 leaks addr",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001878 .result = REJECT,
1879 },
1880 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001881 "check cb access: byte",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07001882 .insns = {
Daniel Borkmann62c79892017-01-12 11:51:33 +01001883 BPF_MOV64_IMM(BPF_REG_0, 0),
1884 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1885 offsetof(struct __sk_buff, cb[0])),
1886 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1887 offsetof(struct __sk_buff, cb[0]) + 1),
1888 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1889 offsetof(struct __sk_buff, cb[0]) + 2),
1890 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1891 offsetof(struct __sk_buff, cb[0]) + 3),
1892 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1893 offsetof(struct __sk_buff, cb[1])),
1894 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1895 offsetof(struct __sk_buff, cb[1]) + 1),
1896 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1897 offsetof(struct __sk_buff, cb[1]) + 2),
1898 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1899 offsetof(struct __sk_buff, cb[1]) + 3),
1900 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1901 offsetof(struct __sk_buff, cb[2])),
1902 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1903 offsetof(struct __sk_buff, cb[2]) + 1),
1904 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1905 offsetof(struct __sk_buff, cb[2]) + 2),
1906 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1907 offsetof(struct __sk_buff, cb[2]) + 3),
1908 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1909 offsetof(struct __sk_buff, cb[3])),
1910 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1911 offsetof(struct __sk_buff, cb[3]) + 1),
1912 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1913 offsetof(struct __sk_buff, cb[3]) + 2),
1914 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1915 offsetof(struct __sk_buff, cb[3]) + 3),
1916 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1917 offsetof(struct __sk_buff, cb[4])),
1918 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1919 offsetof(struct __sk_buff, cb[4]) + 1),
1920 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1921 offsetof(struct __sk_buff, cb[4]) + 2),
1922 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1923 offsetof(struct __sk_buff, cb[4]) + 3),
1924 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1925 offsetof(struct __sk_buff, cb[0])),
1926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1927 offsetof(struct __sk_buff, cb[0]) + 1),
1928 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1929 offsetof(struct __sk_buff, cb[0]) + 2),
1930 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1931 offsetof(struct __sk_buff, cb[0]) + 3),
1932 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1933 offsetof(struct __sk_buff, cb[1])),
1934 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1935 offsetof(struct __sk_buff, cb[1]) + 1),
1936 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1937 offsetof(struct __sk_buff, cb[1]) + 2),
1938 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1939 offsetof(struct __sk_buff, cb[1]) + 3),
1940 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1941 offsetof(struct __sk_buff, cb[2])),
1942 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1943 offsetof(struct __sk_buff, cb[2]) + 1),
1944 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1945 offsetof(struct __sk_buff, cb[2]) + 2),
1946 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1947 offsetof(struct __sk_buff, cb[2]) + 3),
1948 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1949 offsetof(struct __sk_buff, cb[3])),
1950 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1951 offsetof(struct __sk_buff, cb[3]) + 1),
1952 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1953 offsetof(struct __sk_buff, cb[3]) + 2),
1954 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1955 offsetof(struct __sk_buff, cb[3]) + 3),
1956 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1957 offsetof(struct __sk_buff, cb[4])),
1958 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1959 offsetof(struct __sk_buff, cb[4]) + 1),
1960 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1961 offsetof(struct __sk_buff, cb[4]) + 2),
1962 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1963 offsetof(struct __sk_buff, cb[4]) + 3),
1964 BPF_EXIT_INSN(),
1965 },
1966 .result = ACCEPT,
1967 },
1968 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001969 "__sk_buff->hash, offset 0, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001970 .insns = {
1971 BPF_MOV64_IMM(BPF_REG_0, 0),
1972 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001973 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001974 BPF_EXIT_INSN(),
1975 },
1976 .errstr = "invalid bpf_context access",
1977 .result = REJECT,
1978 },
1979 {
Yonghong Song31fd8582017-06-13 15:52:13 -07001980 "__sk_buff->tc_index, offset 3, byte store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01001981 .insns = {
1982 BPF_MOV64_IMM(BPF_REG_0, 0),
1983 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07001984 offsetof(struct __sk_buff, tc_index) + 3),
Daniel Borkmann62c79892017-01-12 11:51:33 +01001985 BPF_EXIT_INSN(),
1986 },
1987 .errstr = "invalid bpf_context access",
1988 .result = REJECT,
1989 },
1990 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001991 "check skb->hash byte load permitted",
1992 .insns = {
1993 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02001994#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07001995 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1996 offsetof(struct __sk_buff, hash)),
1997#else
1998 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1999 offsetof(struct __sk_buff, hash) + 3),
2000#endif
2001 BPF_EXIT_INSN(),
2002 },
2003 .result = ACCEPT,
2004 },
2005 {
2006 "check skb->hash byte load not permitted 1",
2007 .insns = {
2008 BPF_MOV64_IMM(BPF_REG_0, 0),
2009 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2010 offsetof(struct __sk_buff, hash) + 1),
2011 BPF_EXIT_INSN(),
2012 },
2013 .errstr = "invalid bpf_context access",
2014 .result = REJECT,
2015 },
2016 {
2017 "check skb->hash byte load not permitted 2",
2018 .insns = {
2019 BPF_MOV64_IMM(BPF_REG_0, 0),
2020 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2021 offsetof(struct __sk_buff, hash) + 2),
2022 BPF_EXIT_INSN(),
2023 },
2024 .errstr = "invalid bpf_context access",
2025 .result = REJECT,
2026 },
2027 {
2028 "check skb->hash byte load not permitted 3",
2029 .insns = {
2030 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002031#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002032 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2033 offsetof(struct __sk_buff, hash) + 3),
2034#else
2035 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
2036 offsetof(struct __sk_buff, hash)),
2037#endif
2038 BPF_EXIT_INSN(),
2039 },
2040 .errstr = "invalid bpf_context access",
2041 .result = REJECT,
2042 },
2043 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01002044 "check cb access: byte, wrong type",
2045 .insns = {
2046 BPF_MOV64_IMM(BPF_REG_0, 0),
2047 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002048 offsetof(struct __sk_buff, cb[0])),
2049 BPF_EXIT_INSN(),
2050 },
2051 .errstr = "invalid bpf_context access",
2052 .result = REJECT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002053 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2054 },
2055 {
2056 "check cb access: half",
2057 .insns = {
2058 BPF_MOV64_IMM(BPF_REG_0, 0),
2059 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2060 offsetof(struct __sk_buff, cb[0])),
2061 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2062 offsetof(struct __sk_buff, cb[0]) + 2),
2063 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2064 offsetof(struct __sk_buff, cb[1])),
2065 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2066 offsetof(struct __sk_buff, cb[1]) + 2),
2067 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2068 offsetof(struct __sk_buff, cb[2])),
2069 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2070 offsetof(struct __sk_buff, cb[2]) + 2),
2071 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2072 offsetof(struct __sk_buff, cb[3])),
2073 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2074 offsetof(struct __sk_buff, cb[3]) + 2),
2075 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2076 offsetof(struct __sk_buff, cb[4])),
2077 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2078 offsetof(struct __sk_buff, cb[4]) + 2),
2079 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2080 offsetof(struct __sk_buff, cb[0])),
2081 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2082 offsetof(struct __sk_buff, cb[0]) + 2),
2083 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2084 offsetof(struct __sk_buff, cb[1])),
2085 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2086 offsetof(struct __sk_buff, cb[1]) + 2),
2087 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2088 offsetof(struct __sk_buff, cb[2])),
2089 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2090 offsetof(struct __sk_buff, cb[2]) + 2),
2091 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2092 offsetof(struct __sk_buff, cb[3])),
2093 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2094 offsetof(struct __sk_buff, cb[3]) + 2),
2095 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2096 offsetof(struct __sk_buff, cb[4])),
2097 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2098 offsetof(struct __sk_buff, cb[4]) + 2),
2099 BPF_EXIT_INSN(),
2100 },
2101 .result = ACCEPT,
2102 },
2103 {
2104 "check cb access: half, unaligned",
2105 .insns = {
2106 BPF_MOV64_IMM(BPF_REG_0, 0),
2107 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2108 offsetof(struct __sk_buff, cb[0]) + 1),
2109 BPF_EXIT_INSN(),
2110 },
Edward Creef65b1842017-08-07 15:27:12 +01002111 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002112 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002113 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002114 },
2115 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002116 "check __sk_buff->hash, offset 0, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002117 .insns = {
2118 BPF_MOV64_IMM(BPF_REG_0, 0),
2119 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07002120 offsetof(struct __sk_buff, hash)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002121 BPF_EXIT_INSN(),
2122 },
2123 .errstr = "invalid bpf_context access",
2124 .result = REJECT,
2125 },
2126 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002127 "check __sk_buff->tc_index, offset 2, half store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002128 .insns = {
2129 BPF_MOV64_IMM(BPF_REG_0, 0),
2130 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
Yonghong Song31fd8582017-06-13 15:52:13 -07002131 offsetof(struct __sk_buff, tc_index) + 2),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002132 BPF_EXIT_INSN(),
2133 },
2134 .errstr = "invalid bpf_context access",
2135 .result = REJECT,
2136 },
2137 {
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002138 "check skb->hash half load permitted",
2139 .insns = {
2140 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002141#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002142 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2143 offsetof(struct __sk_buff, hash)),
2144#else
2145 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2146 offsetof(struct __sk_buff, hash) + 2),
2147#endif
2148 BPF_EXIT_INSN(),
2149 },
2150 .result = ACCEPT,
2151 },
2152 {
2153 "check skb->hash half load not permitted",
2154 .insns = {
2155 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02002156#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07002157 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2158 offsetof(struct __sk_buff, hash) + 2),
2159#else
2160 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
2161 offsetof(struct __sk_buff, hash)),
2162#endif
2163 BPF_EXIT_INSN(),
2164 },
2165 .errstr = "invalid bpf_context access",
2166 .result = REJECT,
2167 },
2168 {
Daniel Borkmann62c79892017-01-12 11:51:33 +01002169 "check cb access: half, wrong type",
2170 .insns = {
2171 BPF_MOV64_IMM(BPF_REG_0, 0),
2172 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
2173 offsetof(struct __sk_buff, cb[0])),
2174 BPF_EXIT_INSN(),
2175 },
2176 .errstr = "invalid bpf_context access",
2177 .result = REJECT,
2178 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
2179 },
2180 {
2181 "check cb access: word",
2182 .insns = {
2183 BPF_MOV64_IMM(BPF_REG_0, 0),
2184 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2185 offsetof(struct __sk_buff, cb[0])),
2186 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2187 offsetof(struct __sk_buff, cb[1])),
2188 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2189 offsetof(struct __sk_buff, cb[2])),
2190 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2191 offsetof(struct __sk_buff, cb[3])),
2192 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2193 offsetof(struct __sk_buff, cb[4])),
2194 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2195 offsetof(struct __sk_buff, cb[0])),
2196 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2197 offsetof(struct __sk_buff, cb[1])),
2198 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2199 offsetof(struct __sk_buff, cb[2])),
2200 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2201 offsetof(struct __sk_buff, cb[3])),
2202 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2203 offsetof(struct __sk_buff, cb[4])),
2204 BPF_EXIT_INSN(),
2205 },
2206 .result = ACCEPT,
2207 },
2208 {
2209 "check cb access: word, unaligned 1",
2210 .insns = {
2211 BPF_MOV64_IMM(BPF_REG_0, 0),
2212 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2213 offsetof(struct __sk_buff, cb[0]) + 2),
2214 BPF_EXIT_INSN(),
2215 },
Edward Creef65b1842017-08-07 15:27:12 +01002216 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002217 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002218 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002219 },
2220 {
2221 "check cb access: word, unaligned 2",
2222 .insns = {
2223 BPF_MOV64_IMM(BPF_REG_0, 0),
2224 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2225 offsetof(struct __sk_buff, cb[4]) + 1),
2226 BPF_EXIT_INSN(),
2227 },
Edward Creef65b1842017-08-07 15:27:12 +01002228 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002229 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002230 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002231 },
2232 {
2233 "check cb access: word, unaligned 3",
2234 .insns = {
2235 BPF_MOV64_IMM(BPF_REG_0, 0),
2236 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2237 offsetof(struct __sk_buff, cb[4]) + 2),
2238 BPF_EXIT_INSN(),
2239 },
Edward Creef65b1842017-08-07 15:27:12 +01002240 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002241 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002242 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002243 },
2244 {
2245 "check cb access: word, unaligned 4",
2246 .insns = {
2247 BPF_MOV64_IMM(BPF_REG_0, 0),
2248 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2249 offsetof(struct __sk_buff, cb[4]) + 3),
2250 BPF_EXIT_INSN(),
2251 },
Edward Creef65b1842017-08-07 15:27:12 +01002252 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002253 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002254 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002255 },
2256 {
2257 "check cb access: double",
2258 .insns = {
2259 BPF_MOV64_IMM(BPF_REG_0, 0),
2260 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2261 offsetof(struct __sk_buff, cb[0])),
2262 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2263 offsetof(struct __sk_buff, cb[2])),
2264 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2265 offsetof(struct __sk_buff, cb[0])),
2266 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2267 offsetof(struct __sk_buff, cb[2])),
2268 BPF_EXIT_INSN(),
2269 },
2270 .result = ACCEPT,
2271 },
2272 {
2273 "check cb access: double, unaligned 1",
2274 .insns = {
2275 BPF_MOV64_IMM(BPF_REG_0, 0),
2276 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2277 offsetof(struct __sk_buff, cb[1])),
2278 BPF_EXIT_INSN(),
2279 },
Edward Creef65b1842017-08-07 15:27:12 +01002280 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002281 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002282 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002283 },
2284 {
2285 "check cb access: double, unaligned 2",
2286 .insns = {
2287 BPF_MOV64_IMM(BPF_REG_0, 0),
2288 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2289 offsetof(struct __sk_buff, cb[3])),
2290 BPF_EXIT_INSN(),
2291 },
Edward Creef65b1842017-08-07 15:27:12 +01002292 .errstr = "misaligned context access",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002293 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002294 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmann62c79892017-01-12 11:51:33 +01002295 },
2296 {
2297 "check cb access: double, oob 1",
2298 .insns = {
2299 BPF_MOV64_IMM(BPF_REG_0, 0),
2300 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2301 offsetof(struct __sk_buff, cb[4])),
2302 BPF_EXIT_INSN(),
2303 },
2304 .errstr = "invalid bpf_context access",
2305 .result = REJECT,
2306 },
2307 {
2308 "check cb access: double, oob 2",
2309 .insns = {
2310 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002311 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
2312 offsetof(struct __sk_buff, cb[4])),
2313 BPF_EXIT_INSN(),
2314 },
2315 .errstr = "invalid bpf_context access",
2316 .result = REJECT,
2317 },
2318 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002319 "check __sk_buff->ifindex dw store not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002320 .insns = {
2321 BPF_MOV64_IMM(BPF_REG_0, 0),
Yonghong Song31fd8582017-06-13 15:52:13 -07002322 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2323 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002324 BPF_EXIT_INSN(),
2325 },
2326 .errstr = "invalid bpf_context access",
2327 .result = REJECT,
2328 },
2329 {
Yonghong Song31fd8582017-06-13 15:52:13 -07002330 "check __sk_buff->ifindex dw load not permitted",
Daniel Borkmann62c79892017-01-12 11:51:33 +01002331 .insns = {
2332 BPF_MOV64_IMM(BPF_REG_0, 0),
2333 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
Yonghong Song31fd8582017-06-13 15:52:13 -07002334 offsetof(struct __sk_buff, ifindex)),
Daniel Borkmann62c79892017-01-12 11:51:33 +01002335 BPF_EXIT_INSN(),
2336 },
2337 .errstr = "invalid bpf_context access",
2338 .result = REJECT,
2339 },
2340 {
2341 "check cb access: double, wrong type",
2342 .insns = {
2343 BPF_MOV64_IMM(BPF_REG_0, 0),
2344 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
2345 offsetof(struct __sk_buff, cb[0])),
2346 BPF_EXIT_INSN(),
2347 },
2348 .errstr = "invalid bpf_context access",
2349 .result = REJECT,
2350 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002351 },
2352 {
2353 "check out of range skb->cb access",
2354 .insns = {
2355 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002356 offsetof(struct __sk_buff, cb[0]) + 256),
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002357 BPF_EXIT_INSN(),
2358 },
2359 .errstr = "invalid bpf_context access",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002360 .errstr_unpriv = "",
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002361 .result = REJECT,
2362 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
2363 },
2364 {
2365 "write skb fields from socket prog",
2366 .insns = {
2367 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2368 offsetof(struct __sk_buff, cb[4])),
2369 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2370 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2371 offsetof(struct __sk_buff, mark)),
2372 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2373 offsetof(struct __sk_buff, tc_index)),
2374 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
2375 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2376 offsetof(struct __sk_buff, cb[0])),
2377 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
2378 offsetof(struct __sk_buff, cb[2])),
2379 BPF_EXIT_INSN(),
2380 },
2381 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002382 .errstr_unpriv = "R1 leaks addr",
2383 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002384 },
2385 {
2386 "write skb fields from tc_cls_act prog",
2387 .insns = {
2388 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2389 offsetof(struct __sk_buff, cb[0])),
2390 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2391 offsetof(struct __sk_buff, mark)),
2392 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
2393 offsetof(struct __sk_buff, tc_index)),
2394 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2395 offsetof(struct __sk_buff, tc_index)),
2396 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2397 offsetof(struct __sk_buff, cb[3])),
2398 BPF_EXIT_INSN(),
2399 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002400 .errstr_unpriv = "",
2401 .result_unpriv = REJECT,
Alexei Starovoitovd691f9e2015-06-04 10:11:54 -07002402 .result = ACCEPT,
2403 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2404 },
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002405 {
2406 "PTR_TO_STACK store/load",
2407 .insns = {
2408 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2409 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2410 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2411 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2412 BPF_EXIT_INSN(),
2413 },
2414 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002415 .retval = 0xfaceb00c,
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002416 },
2417 {
2418 "PTR_TO_STACK store/load - bad alignment on off",
2419 .insns = {
2420 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2422 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
2423 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
2424 BPF_EXIT_INSN(),
2425 },
2426 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002427 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002428 },
2429 {
2430 "PTR_TO_STACK store/load - bad alignment on reg",
2431 .insns = {
2432 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2433 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
2434 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2435 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2436 BPF_EXIT_INSN(),
2437 },
2438 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002439 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
Alex Gartrell24b4d2a2015-07-23 14:24:40 -07002440 },
2441 {
2442 "PTR_TO_STACK store/load - out of bounds low",
2443 .insns = {
2444 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2445 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
2446 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2447 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2448 BPF_EXIT_INSN(),
2449 },
2450 .result = REJECT,
2451 .errstr = "invalid stack off=-79992 size=8",
2452 },
2453 {
2454 "PTR_TO_STACK store/load - out of bounds high",
2455 .insns = {
2456 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2458 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
2459 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
2460 BPF_EXIT_INSN(),
2461 },
2462 .result = REJECT,
2463 .errstr = "invalid stack off=0 size=8",
2464 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002465 {
2466 "unpriv: return pointer",
2467 .insns = {
2468 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
2469 BPF_EXIT_INSN(),
2470 },
2471 .result = ACCEPT,
2472 .result_unpriv = REJECT,
2473 .errstr_unpriv = "R0 leaks addr",
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002474 .retval = POINTER_VALUE,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002475 },
2476 {
2477 "unpriv: add const to pointer",
2478 .insns = {
2479 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
2480 BPF_MOV64_IMM(BPF_REG_0, 0),
2481 BPF_EXIT_INSN(),
2482 },
2483 .result = ACCEPT,
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002484 },
2485 {
2486 "unpriv: add pointer to pointer",
2487 .insns = {
2488 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2489 BPF_MOV64_IMM(BPF_REG_0, 0),
2490 BPF_EXIT_INSN(),
2491 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08002492 .result = REJECT,
2493 .errstr = "R1 pointer += pointer",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002494 },
2495 {
2496 "unpriv: neg pointer",
2497 .insns = {
2498 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
2499 BPF_MOV64_IMM(BPF_REG_0, 0),
2500 BPF_EXIT_INSN(),
2501 },
2502 .result = ACCEPT,
2503 .result_unpriv = REJECT,
2504 .errstr_unpriv = "R1 pointer arithmetic",
2505 },
2506 {
2507 "unpriv: cmp pointer with const",
2508 .insns = {
2509 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2510 BPF_MOV64_IMM(BPF_REG_0, 0),
2511 BPF_EXIT_INSN(),
2512 },
2513 .result = ACCEPT,
2514 .result_unpriv = REJECT,
2515 .errstr_unpriv = "R1 pointer comparison",
2516 },
2517 {
2518 "unpriv: cmp pointer with pointer",
2519 .insns = {
2520 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
2521 BPF_MOV64_IMM(BPF_REG_0, 0),
2522 BPF_EXIT_INSN(),
2523 },
2524 .result = ACCEPT,
2525 .result_unpriv = REJECT,
2526 .errstr_unpriv = "R10 pointer comparison",
2527 },
2528 {
2529 "unpriv: check that printk is disallowed",
2530 .insns = {
2531 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2532 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2534 BPF_MOV64_IMM(BPF_REG_2, 8),
2535 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2537 BPF_FUNC_trace_printk),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002538 BPF_MOV64_IMM(BPF_REG_0, 0),
2539 BPF_EXIT_INSN(),
2540 },
Daniel Borkmann0eb69842016-12-15 01:39:10 +01002541 .errstr_unpriv = "unknown func bpf_trace_printk#6",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002542 .result_unpriv = REJECT,
2543 .result = ACCEPT,
2544 },
2545 {
2546 "unpriv: pass pointer to helper function",
2547 .insns = {
2548 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2549 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2550 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2551 BPF_LD_MAP_FD(BPF_REG_1, 0),
2552 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
2553 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002554 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2555 BPF_FUNC_map_update_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002556 BPF_MOV64_IMM(BPF_REG_0, 0),
2557 BPF_EXIT_INSN(),
2558 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002559 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002560 .errstr_unpriv = "R4 leaks addr",
2561 .result_unpriv = REJECT,
2562 .result = ACCEPT,
2563 },
2564 {
2565 "unpriv: indirectly pass pointer on stack to helper function",
2566 .insns = {
2567 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2568 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2569 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2570 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002571 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2572 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002573 BPF_MOV64_IMM(BPF_REG_0, 0),
2574 BPF_EXIT_INSN(),
2575 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002576 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002577 .errstr = "invalid indirect read from stack off -8+0 size 8",
2578 .result = REJECT,
2579 },
2580 {
2581 "unpriv: mangle pointer on stack 1",
2582 .insns = {
2583 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2584 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
2585 BPF_MOV64_IMM(BPF_REG_0, 0),
2586 BPF_EXIT_INSN(),
2587 },
2588 .errstr_unpriv = "attempt to corrupt spilled",
2589 .result_unpriv = REJECT,
2590 .result = ACCEPT,
2591 },
2592 {
2593 "unpriv: mangle pointer on stack 2",
2594 .insns = {
2595 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2596 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
2597 BPF_MOV64_IMM(BPF_REG_0, 0),
2598 BPF_EXIT_INSN(),
2599 },
2600 .errstr_unpriv = "attempt to corrupt spilled",
2601 .result_unpriv = REJECT,
2602 .result = ACCEPT,
2603 },
2604 {
2605 "unpriv: read pointer from stack in small chunks",
2606 .insns = {
2607 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
2608 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
2609 BPF_MOV64_IMM(BPF_REG_0, 0),
2610 BPF_EXIT_INSN(),
2611 },
2612 .errstr = "invalid size",
2613 .result = REJECT,
2614 },
2615 {
2616 "unpriv: write pointer into ctx",
2617 .insns = {
2618 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
2619 BPF_MOV64_IMM(BPF_REG_0, 0),
2620 BPF_EXIT_INSN(),
2621 },
2622 .errstr_unpriv = "R1 leaks addr",
2623 .result_unpriv = REJECT,
2624 .errstr = "invalid bpf_context access",
2625 .result = REJECT,
2626 },
2627 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002628 "unpriv: spill/fill of ctx",
2629 .insns = {
2630 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2632 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2633 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2634 BPF_MOV64_IMM(BPF_REG_0, 0),
2635 BPF_EXIT_INSN(),
2636 },
2637 .result = ACCEPT,
2638 },
2639 {
2640 "unpriv: spill/fill of ctx 2",
2641 .insns = {
2642 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2643 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2644 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2645 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002646 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2647 BPF_FUNC_get_hash_recalc),
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08002648 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002649 BPF_EXIT_INSN(),
2650 },
2651 .result = ACCEPT,
2652 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2653 },
2654 {
2655 "unpriv: spill/fill of ctx 3",
2656 .insns = {
2657 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2659 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2660 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2661 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002662 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2663 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002664 BPF_EXIT_INSN(),
2665 },
2666 .result = REJECT,
2667 .errstr = "R1 type=fp expected=ctx",
2668 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2669 },
2670 {
2671 "unpriv: spill/fill of ctx 4",
2672 .insns = {
2673 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2675 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2676 BPF_MOV64_IMM(BPF_REG_0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002677 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
2678 BPF_REG_0, -8, 0),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002679 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002680 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2681 BPF_FUNC_get_hash_recalc),
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002682 BPF_EXIT_INSN(),
2683 },
2684 .result = REJECT,
2685 .errstr = "R1 type=inv expected=ctx",
2686 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2687 },
2688 {
2689 "unpriv: spill/fill of different pointers stx",
2690 .insns = {
2691 BPF_MOV64_IMM(BPF_REG_3, 42),
2692 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2694 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2695 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2696 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
2697 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2698 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2699 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2700 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2701 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
2702 offsetof(struct __sk_buff, mark)),
2703 BPF_MOV64_IMM(BPF_REG_0, 0),
2704 BPF_EXIT_INSN(),
2705 },
2706 .result = REJECT,
2707 .errstr = "same insn cannot be used with different pointers",
2708 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2709 },
2710 {
2711 "unpriv: spill/fill of different pointers ldx",
2712 .insns = {
2713 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2714 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2715 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
2716 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
2718 -(__s32)offsetof(struct bpf_perf_event_data,
2719 sample_period) - 8),
2720 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
2721 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
2722 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
2723 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2724 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
2725 offsetof(struct bpf_perf_event_data,
2726 sample_period)),
2727 BPF_MOV64_IMM(BPF_REG_0, 0),
2728 BPF_EXIT_INSN(),
2729 },
2730 .result = REJECT,
2731 .errstr = "same insn cannot be used with different pointers",
2732 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
2733 },
2734 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002735 "unpriv: write pointer into map elem value",
2736 .insns = {
2737 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2738 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2739 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2740 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002741 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2742 BPF_FUNC_map_lookup_elem),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002743 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2744 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
2745 BPF_EXIT_INSN(),
2746 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002747 .fixup_map1 = { 3 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002748 .errstr_unpriv = "R0 leaks addr",
2749 .result_unpriv = REJECT,
2750 .result = ACCEPT,
2751 },
2752 {
2753 "unpriv: partial copy of pointer",
2754 .insns = {
2755 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
2756 BPF_MOV64_IMM(BPF_REG_0, 0),
2757 BPF_EXIT_INSN(),
2758 },
2759 .errstr_unpriv = "R10 partial copy",
2760 .result_unpriv = REJECT,
2761 .result = ACCEPT,
2762 },
2763 {
2764 "unpriv: pass pointer to tail_call",
2765 .insns = {
2766 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
2767 BPF_LD_MAP_FD(BPF_REG_2, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002768 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2769 BPF_FUNC_tail_call),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002770 BPF_MOV64_IMM(BPF_REG_0, 0),
2771 BPF_EXIT_INSN(),
2772 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002773 .fixup_prog1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002774 .errstr_unpriv = "R3 leaks addr into helper",
2775 .result_unpriv = REJECT,
2776 .result = ACCEPT,
2777 },
2778 {
2779 "unpriv: cmp map pointer with zero",
2780 .insns = {
2781 BPF_MOV64_IMM(BPF_REG_1, 0),
2782 BPF_LD_MAP_FD(BPF_REG_1, 0),
2783 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2784 BPF_MOV64_IMM(BPF_REG_0, 0),
2785 BPF_EXIT_INSN(),
2786 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002787 .fixup_map1 = { 1 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002788 .errstr_unpriv = "R1 pointer comparison",
2789 .result_unpriv = REJECT,
2790 .result = ACCEPT,
2791 },
2792 {
2793 "unpriv: write into frame pointer",
2794 .insns = {
2795 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
2796 BPF_MOV64_IMM(BPF_REG_0, 0),
2797 BPF_EXIT_INSN(),
2798 },
2799 .errstr = "frame pointer is read only",
2800 .result = REJECT,
2801 },
2802 {
Daniel Borkmann1a776b92016-10-17 14:28:35 +02002803 "unpriv: spill/fill frame pointer",
2804 .insns = {
2805 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2807 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
2808 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
2809 BPF_MOV64_IMM(BPF_REG_0, 0),
2810 BPF_EXIT_INSN(),
2811 },
2812 .errstr = "frame pointer is read only",
2813 .result = REJECT,
2814 },
2815 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002816 "unpriv: cmp of frame pointer",
2817 .insns = {
2818 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
2819 BPF_MOV64_IMM(BPF_REG_0, 0),
2820 BPF_EXIT_INSN(),
2821 },
2822 .errstr_unpriv = "R10 pointer comparison",
2823 .result_unpriv = REJECT,
2824 .result = ACCEPT,
2825 },
2826 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02002827 "unpriv: adding of fp",
2828 .insns = {
2829 BPF_MOV64_IMM(BPF_REG_0, 0),
2830 BPF_MOV64_IMM(BPF_REG_1, 0),
2831 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2832 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2833 BPF_EXIT_INSN(),
2834 },
Edward Creef65b1842017-08-07 15:27:12 +01002835 .result = ACCEPT,
Daniel Borkmann728a8532017-04-27 01:39:32 +02002836 },
2837 {
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002838 "unpriv: cmp of stack pointer",
2839 .insns = {
2840 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2841 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2842 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
2843 BPF_MOV64_IMM(BPF_REG_0, 0),
2844 BPF_EXIT_INSN(),
2845 },
2846 .errstr_unpriv = "R2 pointer comparison",
2847 .result_unpriv = REJECT,
2848 .result = ACCEPT,
2849 },
2850 {
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002851 "runtime/jit: tail_call within bounds, prog once",
2852 .insns = {
2853 BPF_MOV64_IMM(BPF_REG_3, 0),
2854 BPF_LD_MAP_FD(BPF_REG_2, 0),
2855 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2856 BPF_FUNC_tail_call),
2857 BPF_MOV64_IMM(BPF_REG_0, 1),
2858 BPF_EXIT_INSN(),
2859 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002860 .fixup_prog1 = { 1 },
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002861 .result = ACCEPT,
2862 .retval = 42,
2863 },
2864 {
2865 "runtime/jit: tail_call within bounds, prog loop",
2866 .insns = {
2867 BPF_MOV64_IMM(BPF_REG_3, 1),
2868 BPF_LD_MAP_FD(BPF_REG_2, 0),
2869 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2870 BPF_FUNC_tail_call),
2871 BPF_MOV64_IMM(BPF_REG_0, 1),
2872 BPF_EXIT_INSN(),
2873 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002874 .fixup_prog1 = { 1 },
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002875 .result = ACCEPT,
2876 .retval = 41,
2877 },
2878 {
2879 "runtime/jit: tail_call within bounds, no prog",
2880 .insns = {
2881 BPF_MOV64_IMM(BPF_REG_3, 2),
2882 BPF_LD_MAP_FD(BPF_REG_2, 0),
2883 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2884 BPF_FUNC_tail_call),
2885 BPF_MOV64_IMM(BPF_REG_0, 1),
2886 BPF_EXIT_INSN(),
2887 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002888 .fixup_prog1 = { 1 },
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002889 .result = ACCEPT,
2890 .retval = 1,
2891 },
2892 {
2893 "runtime/jit: tail_call out of bounds",
2894 .insns = {
2895 BPF_MOV64_IMM(BPF_REG_3, 256),
2896 BPF_LD_MAP_FD(BPF_REG_2, 0),
2897 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2898 BPF_FUNC_tail_call),
2899 BPF_MOV64_IMM(BPF_REG_0, 2),
2900 BPF_EXIT_INSN(),
2901 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002902 .fixup_prog1 = { 1 },
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002903 .result = ACCEPT,
2904 .retval = 2,
2905 },
2906 {
Daniel Borkmann16338a92018-02-23 01:03:43 +01002907 "runtime/jit: pass negative index to tail_call",
2908 .insns = {
2909 BPF_MOV64_IMM(BPF_REG_3, -1),
2910 BPF_LD_MAP_FD(BPF_REG_2, 0),
2911 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2912 BPF_FUNC_tail_call),
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002913 BPF_MOV64_IMM(BPF_REG_0, 2),
Daniel Borkmann16338a92018-02-23 01:03:43 +01002914 BPF_EXIT_INSN(),
2915 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002916 .fixup_prog1 = { 1 },
Daniel Borkmann16338a92018-02-23 01:03:43 +01002917 .result = ACCEPT,
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002918 .retval = 2,
Daniel Borkmann16338a92018-02-23 01:03:43 +01002919 },
2920 {
2921 "runtime/jit: pass > 32bit index to tail_call",
2922 .insns = {
2923 BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
2924 BPF_LD_MAP_FD(BPF_REG_2, 0),
2925 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2926 BPF_FUNC_tail_call),
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002927 BPF_MOV64_IMM(BPF_REG_0, 2),
Daniel Borkmann16338a92018-02-23 01:03:43 +01002928 BPF_EXIT_INSN(),
2929 },
Daniel Borkmann06be0862018-06-02 23:06:31 +02002930 .fixup_prog1 = { 2 },
Daniel Borkmann16338a92018-02-23 01:03:43 +01002931 .result = ACCEPT,
Daniel Borkmannb33eb732018-02-26 22:34:33 +01002932 .retval = 42,
Daniel Borkmann16338a92018-02-23 01:03:43 +01002933 },
2934 {
Yonghong Song332270f2017-04-29 22:52:42 -07002935 "stack pointer arithmetic",
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002936 .insns = {
Yonghong Song332270f2017-04-29 22:52:42 -07002937 BPF_MOV64_IMM(BPF_REG_1, 4),
2938 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2939 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2941 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2942 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2943 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2944 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2945 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2946 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2947 BPF_ST_MEM(0, BPF_REG_2, 4, 0),
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002948 BPF_MOV64_IMM(BPF_REG_0, 0),
2949 BPF_EXIT_INSN(),
2950 },
Alexei Starovoitovbf508872015-10-07 22:23:23 -07002951 .result = ACCEPT,
2952 },
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02002953 {
2954 "raw_stack: no skb_load_bytes",
2955 .insns = {
2956 BPF_MOV64_IMM(BPF_REG_2, 4),
2957 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2959 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2960 BPF_MOV64_IMM(BPF_REG_4, 8),
2961 /* Call to skb_load_bytes() omitted. */
2962 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2963 BPF_EXIT_INSN(),
2964 },
2965 .result = REJECT,
2966 .errstr = "invalid read from stack off -8+0 size 8",
2967 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2968 },
2969 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002970 "raw_stack: skb_load_bytes, negative len",
2971 .insns = {
2972 BPF_MOV64_IMM(BPF_REG_2, 4),
2973 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2974 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2975 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2976 BPF_MOV64_IMM(BPF_REG_4, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002977 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2978 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002979 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2980 BPF_EXIT_INSN(),
2981 },
2982 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01002983 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002984 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2985 },
2986 {
2987 "raw_stack: skb_load_bytes, negative len 2",
2988 .insns = {
2989 BPF_MOV64_IMM(BPF_REG_2, 4),
2990 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
2991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
2992 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
2993 BPF_MOV64_IMM(BPF_REG_4, ~0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02002994 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2995 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02002996 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
2997 BPF_EXIT_INSN(),
2998 },
2999 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003000 .errstr = "R4 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003001 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3002 },
3003 {
3004 "raw_stack: skb_load_bytes, zero len",
3005 .insns = {
3006 BPF_MOV64_IMM(BPF_REG_2, 4),
3007 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3008 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3009 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3010 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003011 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3012 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003013 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3014 BPF_EXIT_INSN(),
3015 },
3016 .result = REJECT,
3017 .errstr = "invalid stack type R3",
3018 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3019 },
3020 {
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003021 "raw_stack: skb_load_bytes, no init",
3022 .insns = {
3023 BPF_MOV64_IMM(BPF_REG_2, 4),
3024 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3025 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3026 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3027 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003028 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3029 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003030 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3031 BPF_EXIT_INSN(),
3032 },
3033 .result = ACCEPT,
3034 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3035 },
3036 {
3037 "raw_stack: skb_load_bytes, init",
3038 .insns = {
3039 BPF_MOV64_IMM(BPF_REG_2, 4),
3040 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
3042 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
3043 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3044 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003045 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3046 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003047 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3048 BPF_EXIT_INSN(),
3049 },
3050 .result = ACCEPT,
3051 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3052 },
3053 {
3054 "raw_stack: skb_load_bytes, spilled regs around bounds",
3055 .insns = {
3056 BPF_MOV64_IMM(BPF_REG_2, 4),
3057 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3058 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003059 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3060 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003061 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3062 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003063 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3064 BPF_FUNC_skb_load_bytes),
3065 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3066 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003067 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3068 offsetof(struct __sk_buff, mark)),
3069 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3070 offsetof(struct __sk_buff, priority)),
3071 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3072 BPF_EXIT_INSN(),
3073 },
3074 .result = ACCEPT,
3075 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3076 },
3077 {
3078 "raw_stack: skb_load_bytes, spilled regs corruption",
3079 .insns = {
3080 BPF_MOV64_IMM(BPF_REG_2, 4),
3081 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3082 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003083 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003084 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3085 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003086 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3087 BPF_FUNC_skb_load_bytes),
3088 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003089 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3090 offsetof(struct __sk_buff, mark)),
3091 BPF_EXIT_INSN(),
3092 },
3093 .result = REJECT,
3094 .errstr = "R0 invalid mem access 'inv'",
3095 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3096 },
3097 {
3098 "raw_stack: skb_load_bytes, spilled regs corruption 2",
3099 .insns = {
3100 BPF_MOV64_IMM(BPF_REG_2, 4),
3101 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3102 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003103 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3104 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3105 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003106 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3107 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003108 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3109 BPF_FUNC_skb_load_bytes),
3110 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3111 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3112 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003113 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3114 offsetof(struct __sk_buff, mark)),
3115 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3116 offsetof(struct __sk_buff, priority)),
3117 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3118 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
3119 offsetof(struct __sk_buff, pkt_type)),
3120 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3121 BPF_EXIT_INSN(),
3122 },
3123 .result = REJECT,
3124 .errstr = "R3 invalid mem access 'inv'",
3125 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3126 },
3127 {
3128 "raw_stack: skb_load_bytes, spilled regs + data",
3129 .insns = {
3130 BPF_MOV64_IMM(BPF_REG_2, 4),
3131 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3132 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003133 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
3134 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
3135 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003136 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3137 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003138 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3139 BPF_FUNC_skb_load_bytes),
3140 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
3141 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8),
3142 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003143 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
3144 offsetof(struct __sk_buff, mark)),
3145 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
3146 offsetof(struct __sk_buff, priority)),
3147 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3148 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
3149 BPF_EXIT_INSN(),
3150 },
3151 .result = ACCEPT,
3152 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3153 },
3154 {
3155 "raw_stack: skb_load_bytes, invalid access 1",
3156 .insns = {
3157 BPF_MOV64_IMM(BPF_REG_2, 4),
3158 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3159 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
3160 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3161 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003162 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3163 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003164 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3165 BPF_EXIT_INSN(),
3166 },
3167 .result = REJECT,
3168 .errstr = "invalid stack type R3 off=-513 access_size=8",
3169 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3170 },
3171 {
3172 "raw_stack: skb_load_bytes, invalid access 2",
3173 .insns = {
3174 BPF_MOV64_IMM(BPF_REG_2, 4),
3175 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3176 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3177 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3178 BPF_MOV64_IMM(BPF_REG_4, 8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003179 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3180 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003181 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3182 BPF_EXIT_INSN(),
3183 },
3184 .result = REJECT,
3185 .errstr = "invalid stack type R3 off=-1 access_size=8",
3186 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3187 },
3188 {
3189 "raw_stack: skb_load_bytes, invalid access 3",
3190 .insns = {
3191 BPF_MOV64_IMM(BPF_REG_2, 4),
3192 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3193 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
3194 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3195 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3197 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003198 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3199 BPF_EXIT_INSN(),
3200 },
3201 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003202 .errstr = "R4 min value is negative",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003203 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3204 },
3205 {
3206 "raw_stack: skb_load_bytes, invalid access 4",
3207 .insns = {
3208 BPF_MOV64_IMM(BPF_REG_2, 4),
3209 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
3211 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3212 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003213 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3214 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003215 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3216 BPF_EXIT_INSN(),
3217 },
3218 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003219 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003220 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3221 },
3222 {
3223 "raw_stack: skb_load_bytes, invalid access 5",
3224 .insns = {
3225 BPF_MOV64_IMM(BPF_REG_2, 4),
3226 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3228 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3229 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003230 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3231 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003232 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3233 BPF_EXIT_INSN(),
3234 },
3235 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003236 .errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003237 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3238 },
3239 {
3240 "raw_stack: skb_load_bytes, invalid access 6",
3241 .insns = {
3242 BPF_MOV64_IMM(BPF_REG_2, 4),
3243 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3244 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3245 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3246 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003247 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3248 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003249 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3250 BPF_EXIT_INSN(),
3251 },
3252 .result = REJECT,
3253 .errstr = "invalid stack type R3 off=-512 access_size=0",
3254 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3255 },
3256 {
3257 "raw_stack: skb_load_bytes, large access",
3258 .insns = {
3259 BPF_MOV64_IMM(BPF_REG_2, 4),
3260 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
3261 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
3262 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
3263 BPF_MOV64_IMM(BPF_REG_4, 512),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003264 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3265 BPF_FUNC_skb_load_bytes),
Daniel Borkmann3f2050e2016-04-13 00:10:54 +02003266 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
3267 BPF_EXIT_INSN(),
3268 },
3269 .result = ACCEPT,
3270 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3271 },
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003272 {
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01003273 "context stores via ST",
3274 .insns = {
3275 BPF_MOV64_IMM(BPF_REG_0, 0),
3276 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
3277 BPF_EXIT_INSN(),
3278 },
Joe Stringer9d2be442018-10-02 13:35:31 -07003279 .errstr = "BPF_ST stores into R1 inv is not allowed",
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01003280 .result = REJECT,
3281 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3282 },
3283 {
3284 "context stores via XADD",
3285 .insns = {
3286 BPF_MOV64_IMM(BPF_REG_0, 0),
3287 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
3288 BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
3289 BPF_EXIT_INSN(),
3290 },
Joe Stringer9d2be442018-10-02 13:35:31 -07003291 .errstr = "BPF_XADD stores into R1 inv is not allowed",
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01003292 .result = REJECT,
3293 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3294 },
3295 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003296 "direct packet access: test1",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003297 .insns = {
3298 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3299 offsetof(struct __sk_buff, data)),
3300 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3301 offsetof(struct __sk_buff, data_end)),
3302 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3304 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3305 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3306 BPF_MOV64_IMM(BPF_REG_0, 0),
3307 BPF_EXIT_INSN(),
3308 },
3309 .result = ACCEPT,
3310 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3311 },
3312 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003313 "direct packet access: test2",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003314 .insns = {
3315 BPF_MOV64_IMM(BPF_REG_0, 1),
3316 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
3317 offsetof(struct __sk_buff, data_end)),
3318 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3319 offsetof(struct __sk_buff, data)),
3320 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3321 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
3322 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
3323 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
3324 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
3325 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
3326 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3327 offsetof(struct __sk_buff, data)),
3328 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08003329 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3330 offsetof(struct __sk_buff, len)),
Edward Cree1f9ab382017-08-07 15:29:11 +01003331 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
3332 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003333 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
3334 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
3335 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
3336 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
3337 offsetof(struct __sk_buff, data_end)),
3338 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
3339 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
3340 BPF_MOV64_IMM(BPF_REG_0, 0),
3341 BPF_EXIT_INSN(),
3342 },
3343 .result = ACCEPT,
3344 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3345 },
3346 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003347 "direct packet access: test3",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003348 .insns = {
3349 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3350 offsetof(struct __sk_buff, data)),
3351 BPF_MOV64_IMM(BPF_REG_0, 0),
3352 BPF_EXIT_INSN(),
3353 },
3354 .errstr = "invalid bpf_context access off=76",
3355 .result = REJECT,
3356 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
3357 },
3358 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003359 "direct packet access: test4 (write)",
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003360 .insns = {
3361 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3362 offsetof(struct __sk_buff, data)),
3363 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3364 offsetof(struct __sk_buff, data_end)),
3365 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3367 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3368 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3369 BPF_MOV64_IMM(BPF_REG_0, 0),
3370 BPF_EXIT_INSN(),
3371 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003372 .result = ACCEPT,
Alexei Starovoitov883e44e2016-05-05 19:49:15 -07003373 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3374 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003375 {
Daniel Borkmann2d2be8c2016-09-08 01:03:42 +02003376 "direct packet access: test5 (pkt_end >= reg, good access)",
3377 .insns = {
3378 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3379 offsetof(struct __sk_buff, data)),
3380 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3381 offsetof(struct __sk_buff, data_end)),
3382 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3384 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3385 BPF_MOV64_IMM(BPF_REG_0, 1),
3386 BPF_EXIT_INSN(),
3387 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3388 BPF_MOV64_IMM(BPF_REG_0, 0),
3389 BPF_EXIT_INSN(),
3390 },
3391 .result = ACCEPT,
3392 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3393 },
3394 {
3395 "direct packet access: test6 (pkt_end >= reg, bad access)",
3396 .insns = {
3397 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3398 offsetof(struct __sk_buff, data)),
3399 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3400 offsetof(struct __sk_buff, data_end)),
3401 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3402 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3403 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3404 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3405 BPF_MOV64_IMM(BPF_REG_0, 1),
3406 BPF_EXIT_INSN(),
3407 BPF_MOV64_IMM(BPF_REG_0, 0),
3408 BPF_EXIT_INSN(),
3409 },
3410 .errstr = "invalid access to packet",
3411 .result = REJECT,
3412 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3413 },
3414 {
3415 "direct packet access: test7 (pkt_end >= reg, both accesses)",
3416 .insns = {
3417 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3418 offsetof(struct __sk_buff, data)),
3419 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3420 offsetof(struct __sk_buff, data_end)),
3421 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3423 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
3424 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3425 BPF_MOV64_IMM(BPF_REG_0, 1),
3426 BPF_EXIT_INSN(),
3427 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3428 BPF_MOV64_IMM(BPF_REG_0, 0),
3429 BPF_EXIT_INSN(),
3430 },
3431 .errstr = "invalid access to packet",
3432 .result = REJECT,
3433 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3434 },
3435 {
3436 "direct packet access: test8 (double test, variant 1)",
3437 .insns = {
3438 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3439 offsetof(struct __sk_buff, data)),
3440 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3441 offsetof(struct __sk_buff, data_end)),
3442 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3443 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3444 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
3445 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3446 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3447 BPF_MOV64_IMM(BPF_REG_0, 1),
3448 BPF_EXIT_INSN(),
3449 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3450 BPF_MOV64_IMM(BPF_REG_0, 0),
3451 BPF_EXIT_INSN(),
3452 },
3453 .result = ACCEPT,
3454 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3455 },
3456 {
3457 "direct packet access: test9 (double test, variant 2)",
3458 .insns = {
3459 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3460 offsetof(struct __sk_buff, data)),
3461 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3462 offsetof(struct __sk_buff, data_end)),
3463 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3464 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3465 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
3466 BPF_MOV64_IMM(BPF_REG_0, 1),
3467 BPF_EXIT_INSN(),
3468 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3469 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3470 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3471 BPF_MOV64_IMM(BPF_REG_0, 0),
3472 BPF_EXIT_INSN(),
3473 },
3474 .result = ACCEPT,
3475 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3476 },
3477 {
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02003478 "direct packet access: test10 (write invalid)",
3479 .insns = {
3480 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3481 offsetof(struct __sk_buff, data)),
3482 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3483 offsetof(struct __sk_buff, data_end)),
3484 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3485 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3486 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3487 BPF_MOV64_IMM(BPF_REG_0, 0),
3488 BPF_EXIT_INSN(),
3489 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3490 BPF_MOV64_IMM(BPF_REG_0, 0),
3491 BPF_EXIT_INSN(),
3492 },
3493 .errstr = "invalid access to packet",
3494 .result = REJECT,
3495 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3496 },
3497 {
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003498 "direct packet access: test11 (shift, good access)",
3499 .insns = {
3500 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3501 offsetof(struct __sk_buff, data)),
3502 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3503 offsetof(struct __sk_buff, data_end)),
3504 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3506 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3507 BPF_MOV64_IMM(BPF_REG_3, 144),
3508 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3509 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3510 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
3511 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3512 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3513 BPF_MOV64_IMM(BPF_REG_0, 1),
3514 BPF_EXIT_INSN(),
3515 BPF_MOV64_IMM(BPF_REG_0, 0),
3516 BPF_EXIT_INSN(),
3517 },
3518 .result = ACCEPT,
3519 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003520 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003521 },
3522 {
3523 "direct packet access: test12 (and, good access)",
3524 .insns = {
3525 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3526 offsetof(struct __sk_buff, data)),
3527 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3528 offsetof(struct __sk_buff, data_end)),
3529 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3530 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3531 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3532 BPF_MOV64_IMM(BPF_REG_3, 144),
3533 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3535 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3536 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3537 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3538 BPF_MOV64_IMM(BPF_REG_0, 1),
3539 BPF_EXIT_INSN(),
3540 BPF_MOV64_IMM(BPF_REG_0, 0),
3541 BPF_EXIT_INSN(),
3542 },
3543 .result = ACCEPT,
3544 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003545 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003546 },
3547 {
3548 "direct packet access: test13 (branches, good access)",
3549 .insns = {
3550 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3551 offsetof(struct __sk_buff, data)),
3552 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3553 offsetof(struct __sk_buff, data_end)),
3554 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3556 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
3557 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3558 offsetof(struct __sk_buff, mark)),
3559 BPF_MOV64_IMM(BPF_REG_4, 1),
3560 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
3561 BPF_MOV64_IMM(BPF_REG_3, 14),
3562 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
3563 BPF_MOV64_IMM(BPF_REG_3, 24),
3564 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
3565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
3566 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
3567 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3568 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3569 BPF_MOV64_IMM(BPF_REG_0, 1),
3570 BPF_EXIT_INSN(),
3571 BPF_MOV64_IMM(BPF_REG_0, 0),
3572 BPF_EXIT_INSN(),
3573 },
3574 .result = ACCEPT,
3575 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003576 .retval = 1,
Daniel Borkmann3fadc802017-01-24 01:06:30 +01003577 },
3578 {
William Tu63dfef72017-02-04 08:37:29 -08003579 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
3580 .insns = {
3581 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3582 offsetof(struct __sk_buff, data)),
3583 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3584 offsetof(struct __sk_buff, data_end)),
3585 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
3587 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
3588 BPF_MOV64_IMM(BPF_REG_5, 12),
3589 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
3590 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
3591 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
3592 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
3593 BPF_MOV64_IMM(BPF_REG_0, 1),
3594 BPF_EXIT_INSN(),
3595 BPF_MOV64_IMM(BPF_REG_0, 0),
3596 BPF_EXIT_INSN(),
3597 },
3598 .result = ACCEPT,
3599 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003600 .retval = 1,
William Tu63dfef72017-02-04 08:37:29 -08003601 },
3602 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02003603 "direct packet access: test15 (spill with xadd)",
3604 .insns = {
3605 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3606 offsetof(struct __sk_buff, data)),
3607 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3608 offsetof(struct __sk_buff, data_end)),
3609 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3610 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3611 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
3612 BPF_MOV64_IMM(BPF_REG_5, 4096),
3613 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
3614 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
3615 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
3616 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
3617 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
3618 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
3619 BPF_MOV64_IMM(BPF_REG_0, 0),
3620 BPF_EXIT_INSN(),
3621 },
3622 .errstr = "R2 invalid mem access 'inv'",
3623 .result = REJECT,
3624 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3625 },
3626 {
Daniel Borkmann728a8532017-04-27 01:39:32 +02003627 "direct packet access: test16 (arith on data_end)",
3628 .insns = {
3629 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3630 offsetof(struct __sk_buff, data)),
3631 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3632 offsetof(struct __sk_buff, data_end)),
3633 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3634 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3635 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
3636 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3637 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3638 BPF_MOV64_IMM(BPF_REG_0, 0),
3639 BPF_EXIT_INSN(),
3640 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07003641 .errstr = "R3 pointer arithmetic on pkt_end",
Daniel Borkmann728a8532017-04-27 01:39:32 +02003642 .result = REJECT,
3643 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3644 },
3645 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003646 "direct packet access: test17 (pruning, alignment)",
3647 .insns = {
3648 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3649 offsetof(struct __sk_buff, data)),
3650 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3651 offsetof(struct __sk_buff, data_end)),
3652 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3653 offsetof(struct __sk_buff, mark)),
3654 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3655 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
3656 BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
3657 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3658 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
3659 BPF_MOV64_IMM(BPF_REG_0, 0),
3660 BPF_EXIT_INSN(),
3661 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3662 BPF_JMP_A(-6),
3663 },
Edward Creef65b1842017-08-07 15:27:12 +01003664 .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02003665 .result = REJECT,
3666 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3667 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
3668 },
3669 {
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003670 "direct packet access: test18 (imm += pkt_ptr, 1)",
3671 .insns = {
3672 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3673 offsetof(struct __sk_buff, data)),
3674 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3675 offsetof(struct __sk_buff, data_end)),
3676 BPF_MOV64_IMM(BPF_REG_0, 8),
3677 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3678 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3679 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3680 BPF_MOV64_IMM(BPF_REG_0, 0),
3681 BPF_EXIT_INSN(),
3682 },
3683 .result = ACCEPT,
3684 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3685 },
3686 {
3687 "direct packet access: test19 (imm += pkt_ptr, 2)",
3688 .insns = {
3689 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3690 offsetof(struct __sk_buff, data)),
3691 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3692 offsetof(struct __sk_buff, data_end)),
3693 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3695 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
3696 BPF_MOV64_IMM(BPF_REG_4, 4),
3697 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3698 BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
3699 BPF_MOV64_IMM(BPF_REG_0, 0),
3700 BPF_EXIT_INSN(),
3701 },
3702 .result = ACCEPT,
3703 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3704 },
3705 {
3706 "direct packet access: test20 (x += pkt_ptr, 1)",
3707 .insns = {
3708 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3709 offsetof(struct __sk_buff, data)),
3710 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3711 offsetof(struct __sk_buff, data_end)),
3712 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3713 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3714 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003715 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003716 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3717 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3718 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003719 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003720 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3721 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3722 BPF_MOV64_IMM(BPF_REG_0, 0),
3723 BPF_EXIT_INSN(),
3724 },
3725 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3726 .result = ACCEPT,
3727 },
3728 {
3729 "direct packet access: test21 (x += pkt_ptr, 2)",
3730 .insns = {
3731 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3732 offsetof(struct __sk_buff, data)),
3733 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3734 offsetof(struct __sk_buff, data_end)),
3735 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3736 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3737 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
3738 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3739 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3740 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003741 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003742 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3743 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
Edward Cree1f9ab382017-08-07 15:29:11 +01003744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003745 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
3746 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
3747 BPF_MOV64_IMM(BPF_REG_0, 0),
3748 BPF_EXIT_INSN(),
3749 },
3750 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3751 .result = ACCEPT,
3752 },
3753 {
3754 "direct packet access: test22 (x += pkt_ptr, 3)",
3755 .insns = {
3756 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3757 offsetof(struct __sk_buff, data)),
3758 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3759 offsetof(struct __sk_buff, data_end)),
3760 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3762 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
3763 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
3764 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
3765 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
3766 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
3767 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
3768 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
3769 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
Edward Cree1f9ab382017-08-07 15:29:11 +01003770 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003771 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
3772 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
3773 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
3774 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
3775 BPF_MOV64_IMM(BPF_REG_2, 1),
3776 BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
3777 BPF_MOV64_IMM(BPF_REG_0, 0),
3778 BPF_EXIT_INSN(),
3779 },
3780 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3781 .result = ACCEPT,
3782 },
3783 {
3784 "direct packet access: test23 (x += pkt_ptr, 4)",
3785 .insns = {
3786 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3787 offsetof(struct __sk_buff, data)),
3788 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3789 offsetof(struct __sk_buff, data_end)),
3790 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3791 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3792 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3793 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
3794 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3795 BPF_MOV64_IMM(BPF_REG_0, 31),
3796 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3797 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3798 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
3799 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
3800 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3801 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3802 BPF_MOV64_IMM(BPF_REG_0, 0),
3803 BPF_EXIT_INSN(),
3804 },
3805 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3806 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01003807 .errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003808 },
3809 {
3810 "direct packet access: test24 (x += pkt_ptr, 5)",
3811 .insns = {
3812 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3813 offsetof(struct __sk_buff, data)),
3814 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3815 offsetof(struct __sk_buff, data_end)),
3816 BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
3817 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
3818 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
3819 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
3820 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
3821 BPF_MOV64_IMM(BPF_REG_0, 64),
3822 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
3823 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
3824 BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
Edward Cree1f9ab382017-08-07 15:29:11 +01003825 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
Daniel Borkmann6d191ed42017-07-02 02:13:31 +02003826 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3827 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
3828 BPF_MOV64_IMM(BPF_REG_0, 0),
3829 BPF_EXIT_INSN(),
3830 },
3831 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3832 .result = ACCEPT,
3833 },
3834 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02003835 "direct packet access: test25 (marking on <, good access)",
3836 .insns = {
3837 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3838 offsetof(struct __sk_buff, data)),
3839 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3840 offsetof(struct __sk_buff, data_end)),
3841 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3843 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
3844 BPF_MOV64_IMM(BPF_REG_0, 0),
3845 BPF_EXIT_INSN(),
3846 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3847 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3848 },
3849 .result = ACCEPT,
3850 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3851 },
3852 {
3853 "direct packet access: test26 (marking on <, bad access)",
3854 .insns = {
3855 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3856 offsetof(struct __sk_buff, data)),
3857 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3858 offsetof(struct __sk_buff, data_end)),
3859 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3860 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3861 BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
3862 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3863 BPF_MOV64_IMM(BPF_REG_0, 0),
3864 BPF_EXIT_INSN(),
3865 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
3866 },
3867 .result = REJECT,
3868 .errstr = "invalid access to packet",
3869 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3870 },
3871 {
3872 "direct packet access: test27 (marking on <=, good access)",
3873 .insns = {
3874 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3875 offsetof(struct __sk_buff, data)),
3876 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3877 offsetof(struct __sk_buff, data_end)),
3878 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3879 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3880 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
3881 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3882 BPF_MOV64_IMM(BPF_REG_0, 1),
3883 BPF_EXIT_INSN(),
3884 },
3885 .result = ACCEPT,
3886 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08003887 .retval = 1,
Daniel Borkmann31e482b2017-08-10 01:40:03 +02003888 },
3889 {
3890 "direct packet access: test28 (marking on <=, bad access)",
3891 .insns = {
3892 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3893 offsetof(struct __sk_buff, data)),
3894 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3895 offsetof(struct __sk_buff, data_end)),
3896 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3898 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
3899 BPF_MOV64_IMM(BPF_REG_0, 1),
3900 BPF_EXIT_INSN(),
3901 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
3902 BPF_JMP_IMM(BPF_JA, 0, 0, -4),
3903 },
3904 .result = REJECT,
3905 .errstr = "invalid access to packet",
3906 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3907 },
3908 {
Aaron Yue1633ac02016-08-11 18:17:17 -07003909 "helper access to packet: test1, valid packet_ptr range",
3910 .insns = {
3911 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3912 offsetof(struct xdp_md, data)),
3913 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3914 offsetof(struct xdp_md, data_end)),
3915 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3916 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
3917 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
3918 BPF_LD_MAP_FD(BPF_REG_1, 0),
3919 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
3920 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003921 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3922 BPF_FUNC_map_update_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003923 BPF_MOV64_IMM(BPF_REG_0, 0),
3924 BPF_EXIT_INSN(),
3925 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003926 .fixup_map1 = { 5 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003927 .result_unpriv = ACCEPT,
3928 .result = ACCEPT,
3929 .prog_type = BPF_PROG_TYPE_XDP,
3930 },
3931 {
3932 "helper access to packet: test2, unchecked packet_ptr",
3933 .insns = {
3934 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3935 offsetof(struct xdp_md, data)),
3936 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003937 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3938 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003939 BPF_MOV64_IMM(BPF_REG_0, 0),
3940 BPF_EXIT_INSN(),
3941 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003942 .fixup_map1 = { 1 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003943 .result = REJECT,
3944 .errstr = "invalid access to packet",
3945 .prog_type = BPF_PROG_TYPE_XDP,
3946 },
3947 {
3948 "helper access to packet: test3, variable add",
3949 .insns = {
3950 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3951 offsetof(struct xdp_md, data)),
3952 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3953 offsetof(struct xdp_md, data_end)),
3954 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3955 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
3956 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
3957 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
3958 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3959 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
3960 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
3961 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
3962 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
3963 BPF_LD_MAP_FD(BPF_REG_1, 0),
3964 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3966 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003967 BPF_MOV64_IMM(BPF_REG_0, 0),
3968 BPF_EXIT_INSN(),
3969 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003970 .fixup_map1 = { 11 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003971 .result = ACCEPT,
3972 .prog_type = BPF_PROG_TYPE_XDP,
3973 },
3974 {
3975 "helper access to packet: test4, packet_ptr with bad range",
3976 .insns = {
3977 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3978 offsetof(struct xdp_md, data)),
3979 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3980 offsetof(struct xdp_md, data_end)),
3981 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
3982 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
3983 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
3984 BPF_MOV64_IMM(BPF_REG_0, 0),
3985 BPF_EXIT_INSN(),
3986 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003987 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
3988 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07003989 BPF_MOV64_IMM(BPF_REG_0, 0),
3990 BPF_EXIT_INSN(),
3991 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02003992 .fixup_map1 = { 7 },
Aaron Yue1633ac02016-08-11 18:17:17 -07003993 .result = REJECT,
3994 .errstr = "invalid access to packet",
3995 .prog_type = BPF_PROG_TYPE_XDP,
3996 },
3997 {
3998 "helper access to packet: test5, packet_ptr with too short range",
3999 .insns = {
4000 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4001 offsetof(struct xdp_md, data)),
4002 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4003 offsetof(struct xdp_md, data_end)),
4004 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4005 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4006 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4007 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4008 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004009 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4010 BPF_FUNC_map_lookup_elem),
Aaron Yue1633ac02016-08-11 18:17:17 -07004011 BPF_MOV64_IMM(BPF_REG_0, 0),
4012 BPF_EXIT_INSN(),
4013 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004014 .fixup_map1 = { 6 },
Aaron Yue1633ac02016-08-11 18:17:17 -07004015 .result = REJECT,
4016 .errstr = "invalid access to packet",
4017 .prog_type = BPF_PROG_TYPE_XDP,
4018 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004019 {
4020 "helper access to packet: test6, cls valid packet_ptr range",
4021 .insns = {
4022 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4023 offsetof(struct __sk_buff, data)),
4024 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4025 offsetof(struct __sk_buff, data_end)),
4026 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4027 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
4028 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
4029 BPF_LD_MAP_FD(BPF_REG_1, 0),
4030 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
4031 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004032 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4033 BPF_FUNC_map_update_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004034 BPF_MOV64_IMM(BPF_REG_0, 0),
4035 BPF_EXIT_INSN(),
4036 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004037 .fixup_map1 = { 5 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004038 .result = ACCEPT,
4039 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4040 },
4041 {
4042 "helper access to packet: test7, cls unchecked packet_ptr",
4043 .insns = {
4044 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4045 offsetof(struct __sk_buff, data)),
4046 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004047 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4048 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004049 BPF_MOV64_IMM(BPF_REG_0, 0),
4050 BPF_EXIT_INSN(),
4051 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004052 .fixup_map1 = { 1 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004053 .result = REJECT,
4054 .errstr = "invalid access to packet",
4055 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4056 },
4057 {
4058 "helper access to packet: test8, cls variable add",
4059 .insns = {
4060 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4061 offsetof(struct __sk_buff, data)),
4062 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4063 offsetof(struct __sk_buff, data_end)),
4064 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4065 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
4066 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
4067 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
4068 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4069 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
4070 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
4071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
4072 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
4073 BPF_LD_MAP_FD(BPF_REG_1, 0),
4074 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4076 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004077 BPF_MOV64_IMM(BPF_REG_0, 0),
4078 BPF_EXIT_INSN(),
4079 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004080 .fixup_map1 = { 11 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004081 .result = ACCEPT,
4082 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4083 },
4084 {
4085 "helper access to packet: test9, cls packet_ptr with bad range",
4086 .insns = {
4087 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4088 offsetof(struct __sk_buff, data)),
4089 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4090 offsetof(struct __sk_buff, data_end)),
4091 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
4093 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
4094 BPF_MOV64_IMM(BPF_REG_0, 0),
4095 BPF_EXIT_INSN(),
4096 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004097 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4098 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004099 BPF_MOV64_IMM(BPF_REG_0, 0),
4100 BPF_EXIT_INSN(),
4101 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004102 .fixup_map1 = { 7 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004103 .result = REJECT,
4104 .errstr = "invalid access to packet",
4105 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4106 },
4107 {
4108 "helper access to packet: test10, cls packet_ptr with too short range",
4109 .insns = {
4110 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4111 offsetof(struct __sk_buff, data)),
4112 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4113 offsetof(struct __sk_buff, data_end)),
4114 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4115 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
4116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
4117 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
4118 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004119 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4120 BPF_FUNC_map_lookup_elem),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004121 BPF_MOV64_IMM(BPF_REG_0, 0),
4122 BPF_EXIT_INSN(),
4123 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004124 .fixup_map1 = { 6 },
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004125 .result = REJECT,
4126 .errstr = "invalid access to packet",
4127 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4128 },
4129 {
4130 "helper access to packet: test11, cls unsuitable helper 1",
4131 .insns = {
4132 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4133 offsetof(struct __sk_buff, data)),
4134 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4135 offsetof(struct __sk_buff, data_end)),
4136 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4137 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4138 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
4139 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
4140 BPF_MOV64_IMM(BPF_REG_2, 0),
4141 BPF_MOV64_IMM(BPF_REG_4, 42),
4142 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004143 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4144 BPF_FUNC_skb_store_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004145 BPF_MOV64_IMM(BPF_REG_0, 0),
4146 BPF_EXIT_INSN(),
4147 },
4148 .result = REJECT,
4149 .errstr = "helper access to the packet",
4150 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4151 },
4152 {
4153 "helper access to packet: test12, cls unsuitable helper 2",
4154 .insns = {
4155 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4156 offsetof(struct __sk_buff, data)),
4157 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4158 offsetof(struct __sk_buff, data_end)),
4159 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
4160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
4161 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
4162 BPF_MOV64_IMM(BPF_REG_2, 0),
4163 BPF_MOV64_IMM(BPF_REG_4, 4),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004164 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4165 BPF_FUNC_skb_load_bytes),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004166 BPF_MOV64_IMM(BPF_REG_0, 0),
4167 BPF_EXIT_INSN(),
4168 },
4169 .result = REJECT,
4170 .errstr = "helper access to the packet",
4171 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4172 },
4173 {
4174 "helper access to packet: test13, cls helper ok",
4175 .insns = {
4176 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4177 offsetof(struct __sk_buff, data)),
4178 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4179 offsetof(struct __sk_buff, data_end)),
4180 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4181 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4182 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4183 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4184 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4185 BPF_MOV64_IMM(BPF_REG_2, 4),
4186 BPF_MOV64_IMM(BPF_REG_3, 0),
4187 BPF_MOV64_IMM(BPF_REG_4, 0),
4188 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4190 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004191 BPF_MOV64_IMM(BPF_REG_0, 0),
4192 BPF_EXIT_INSN(),
4193 },
4194 .result = ACCEPT,
4195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4196 },
4197 {
Edward Creef65b1842017-08-07 15:27:12 +01004198 "helper access to packet: test14, cls helper ok sub",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004199 .insns = {
4200 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4201 offsetof(struct __sk_buff, data)),
4202 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4203 offsetof(struct __sk_buff, data_end)),
4204 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4205 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4207 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4208 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
4209 BPF_MOV64_IMM(BPF_REG_2, 4),
4210 BPF_MOV64_IMM(BPF_REG_3, 0),
4211 BPF_MOV64_IMM(BPF_REG_4, 0),
4212 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004213 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4214 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004215 BPF_MOV64_IMM(BPF_REG_0, 0),
4216 BPF_EXIT_INSN(),
4217 },
Edward Creef65b1842017-08-07 15:27:12 +01004218 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004219 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4220 },
4221 {
Edward Creef65b1842017-08-07 15:27:12 +01004222 "helper access to packet: test15, cls helper fail sub",
4223 .insns = {
4224 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4225 offsetof(struct __sk_buff, data)),
4226 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4227 offsetof(struct __sk_buff, data_end)),
4228 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4229 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4230 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4231 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4232 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
4233 BPF_MOV64_IMM(BPF_REG_2, 4),
4234 BPF_MOV64_IMM(BPF_REG_3, 0),
4235 BPF_MOV64_IMM(BPF_REG_4, 0),
4236 BPF_MOV64_IMM(BPF_REG_5, 0),
4237 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4238 BPF_FUNC_csum_diff),
4239 BPF_MOV64_IMM(BPF_REG_0, 0),
4240 BPF_EXIT_INSN(),
4241 },
4242 .result = REJECT,
4243 .errstr = "invalid access to packet",
4244 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4245 },
4246 {
4247 "helper access to packet: test16, cls helper fail range 1",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004248 .insns = {
4249 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4250 offsetof(struct __sk_buff, data)),
4251 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4252 offsetof(struct __sk_buff, data_end)),
4253 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4254 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4255 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4256 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4257 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4258 BPF_MOV64_IMM(BPF_REG_2, 8),
4259 BPF_MOV64_IMM(BPF_REG_3, 0),
4260 BPF_MOV64_IMM(BPF_REG_4, 0),
4261 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004262 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4263 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004264 BPF_MOV64_IMM(BPF_REG_0, 0),
4265 BPF_EXIT_INSN(),
4266 },
4267 .result = REJECT,
4268 .errstr = "invalid access to packet",
4269 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4270 },
4271 {
Edward Creef65b1842017-08-07 15:27:12 +01004272 "helper access to packet: test17, cls helper fail range 2",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004273 .insns = {
4274 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4275 offsetof(struct __sk_buff, data)),
4276 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4277 offsetof(struct __sk_buff, data_end)),
4278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4279 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4280 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4281 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4282 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4283 BPF_MOV64_IMM(BPF_REG_2, -9),
4284 BPF_MOV64_IMM(BPF_REG_3, 0),
4285 BPF_MOV64_IMM(BPF_REG_4, 0),
4286 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004287 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4288 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004289 BPF_MOV64_IMM(BPF_REG_0, 0),
4290 BPF_EXIT_INSN(),
4291 },
4292 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004293 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004294 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4295 },
4296 {
Edward Creef65b1842017-08-07 15:27:12 +01004297 "helper access to packet: test18, cls helper fail range 3",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004298 .insns = {
4299 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4300 offsetof(struct __sk_buff, data)),
4301 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4302 offsetof(struct __sk_buff, data_end)),
4303 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4304 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4305 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4306 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4308 BPF_MOV64_IMM(BPF_REG_2, ~0),
4309 BPF_MOV64_IMM(BPF_REG_3, 0),
4310 BPF_MOV64_IMM(BPF_REG_4, 0),
4311 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004312 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4313 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004314 BPF_MOV64_IMM(BPF_REG_0, 0),
4315 BPF_EXIT_INSN(),
4316 },
4317 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01004318 .errstr = "R2 min value is negative",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004319 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4320 },
4321 {
Yonghong Songb6ff6392017-11-12 14:49:11 -08004322 "helper access to packet: test19, cls helper range zero",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004323 .insns = {
4324 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4325 offsetof(struct __sk_buff, data)),
4326 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4327 offsetof(struct __sk_buff, data_end)),
4328 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4329 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4330 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4331 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4332 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4333 BPF_MOV64_IMM(BPF_REG_2, 0),
4334 BPF_MOV64_IMM(BPF_REG_3, 0),
4335 BPF_MOV64_IMM(BPF_REG_4, 0),
4336 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004337 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4338 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004339 BPF_MOV64_IMM(BPF_REG_0, 0),
4340 BPF_EXIT_INSN(),
4341 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08004342 .result = ACCEPT,
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004343 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4344 },
4345 {
Edward Creef65b1842017-08-07 15:27:12 +01004346 "helper access to packet: test20, pkt end as input",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004347 .insns = {
4348 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4349 offsetof(struct __sk_buff, data)),
4350 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4351 offsetof(struct __sk_buff, data_end)),
4352 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4353 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4354 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4355 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4356 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
4357 BPF_MOV64_IMM(BPF_REG_2, 4),
4358 BPF_MOV64_IMM(BPF_REG_3, 0),
4359 BPF_MOV64_IMM(BPF_REG_4, 0),
4360 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004361 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4362 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004363 BPF_MOV64_IMM(BPF_REG_0, 0),
4364 BPF_EXIT_INSN(),
4365 },
4366 .result = REJECT,
4367 .errstr = "R1 type=pkt_end expected=fp",
4368 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4369 },
4370 {
Edward Creef65b1842017-08-07 15:27:12 +01004371 "helper access to packet: test21, wrong reg",
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004372 .insns = {
4373 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4374 offsetof(struct __sk_buff, data)),
4375 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4376 offsetof(struct __sk_buff, data_end)),
4377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4378 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4379 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4380 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4381 BPF_MOV64_IMM(BPF_REG_2, 4),
4382 BPF_MOV64_IMM(BPF_REG_3, 0),
4383 BPF_MOV64_IMM(BPF_REG_4, 0),
4384 BPF_MOV64_IMM(BPF_REG_5, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004385 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4386 BPF_FUNC_csum_diff),
Daniel Borkmann7d95b0a2016-09-20 00:26:14 +02004387 BPF_MOV64_IMM(BPF_REG_0, 0),
4388 BPF_EXIT_INSN(),
4389 },
4390 .result = REJECT,
4391 .errstr = "invalid access to packet",
4392 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4393 },
Josef Bacik48461132016-09-28 10:54:32 -04004394 {
4395 "valid map access into an array with a constant",
4396 .insns = {
4397 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4398 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4400 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004401 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4402 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004403 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004404 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4405 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004406 BPF_EXIT_INSN(),
4407 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004408 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004409 .errstr_unpriv = "R0 leaks addr",
4410 .result_unpriv = REJECT,
4411 .result = ACCEPT,
4412 },
4413 {
4414 "valid map access into an array with a register",
4415 .insns = {
4416 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4417 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4418 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4419 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004420 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4421 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004422 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4423 BPF_MOV64_IMM(BPF_REG_1, 4),
4424 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4425 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004426 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4427 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004428 BPF_EXIT_INSN(),
4429 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004430 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004431 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004432 .result_unpriv = REJECT,
4433 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004434 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004435 },
4436 {
4437 "valid map access into an array with a variable",
4438 .insns = {
4439 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4440 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4441 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4442 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004443 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4444 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004445 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
4446 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4447 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
4448 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4449 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004450 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4451 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004452 BPF_EXIT_INSN(),
4453 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004454 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004455 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004456 .result_unpriv = REJECT,
4457 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004458 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004459 },
4460 {
4461 "valid map access into an array with a signed variable",
4462 .insns = {
4463 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4464 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4465 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4466 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004467 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4468 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004469 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
4470 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4471 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
4472 BPF_MOV32_IMM(BPF_REG_1, 0),
4473 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4474 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4475 BPF_MOV32_IMM(BPF_REG_1, 0),
4476 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4477 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004478 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4479 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004480 BPF_EXIT_INSN(),
4481 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004482 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004483 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004484 .result_unpriv = REJECT,
4485 .result = ACCEPT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004486 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004487 },
4488 {
4489 "invalid map access into an array with a constant",
4490 .insns = {
4491 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4492 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4493 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4494 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004495 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4496 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004497 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4498 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
4499 offsetof(struct test_val, foo)),
4500 BPF_EXIT_INSN(),
4501 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004502 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004503 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
4504 .result = REJECT,
4505 },
4506 {
4507 "invalid map access into an array with a register",
4508 .insns = {
4509 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4510 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4511 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4512 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004513 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4514 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004515 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4516 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
4517 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4518 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004519 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4520 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004521 BPF_EXIT_INSN(),
4522 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004523 .fixup_map2 = { 3 },
Josef Bacik48461132016-09-28 10:54:32 -04004524 .errstr = "R0 min value is outside of the array range",
4525 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004526 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004527 },
4528 {
4529 "invalid map access into an array with a variable",
4530 .insns = {
4531 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4532 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4533 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4534 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004535 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4536 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004537 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4538 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4539 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4540 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004541 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4542 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004543 BPF_EXIT_INSN(),
4544 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004545 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004546 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
Josef Bacik48461132016-09-28 10:54:32 -04004547 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004548 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004549 },
4550 {
4551 "invalid map access into an array with no floor check",
4552 .insns = {
4553 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4554 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4556 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004557 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4558 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004559 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
Edward Creef65b1842017-08-07 15:27:12 +01004560 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik48461132016-09-28 10:54:32 -04004561 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
4562 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
4563 BPF_MOV32_IMM(BPF_REG_1, 0),
4564 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4565 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004566 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4567 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004568 BPF_EXIT_INSN(),
4569 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004570 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004571 .errstr_unpriv = "R0 leaks addr",
4572 .errstr = "R0 unbounded memory access",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004573 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04004574 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004575 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004576 },
4577 {
4578 "invalid map access into an array with a invalid max check",
4579 .insns = {
4580 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4581 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4582 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4583 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004584 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4585 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004586 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4587 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4588 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
4589 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
4590 BPF_MOV32_IMM(BPF_REG_1, 0),
4591 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
4592 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004593 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4594 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004595 BPF_EXIT_INSN(),
4596 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004597 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01004598 .errstr_unpriv = "R0 leaks addr",
Josef Bacik48461132016-09-28 10:54:32 -04004599 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004600 .result_unpriv = REJECT,
Josef Bacik48461132016-09-28 10:54:32 -04004601 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004602 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004603 },
4604 {
4605 "invalid map access into an array with a invalid max check",
4606 .insns = {
4607 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4608 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4610 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004611 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4612 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004613 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4614 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4615 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4616 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4617 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4618 BPF_LD_MAP_FD(BPF_REG_1, 0),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004619 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4620 BPF_FUNC_map_lookup_elem),
Josef Bacik48461132016-09-28 10:54:32 -04004621 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4622 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004623 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
4624 offsetof(struct test_val, foo)),
Josef Bacik48461132016-09-28 10:54:32 -04004625 BPF_EXIT_INSN(),
4626 },
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +02004627 .fixup_map2 = { 3, 11 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08004628 .errstr = "R0 pointer += pointer",
Josef Bacik48461132016-09-28 10:54:32 -04004629 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02004630 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik48461132016-09-28 10:54:32 -04004631 },
Thomas Graf57a09bf2016-10-18 19:51:19 +02004632 {
Roman Gushchind4c9f572018-08-02 14:27:28 -07004633 "valid cgroup storage access",
4634 .insns = {
4635 BPF_MOV64_IMM(BPF_REG_2, 0),
4636 BPF_LD_MAP_FD(BPF_REG_1, 0),
4637 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4638 BPF_FUNC_get_local_storage),
4639 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4640 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4641 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4642 BPF_EXIT_INSN(),
4643 },
4644 .fixup_cgroup_storage = { 1 },
4645 .result = ACCEPT,
4646 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4647 },
4648 {
4649 "invalid cgroup storage access 1",
4650 .insns = {
4651 BPF_MOV64_IMM(BPF_REG_2, 0),
4652 BPF_LD_MAP_FD(BPF_REG_1, 0),
4653 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4654 BPF_FUNC_get_local_storage),
4655 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4656 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4657 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4658 BPF_EXIT_INSN(),
4659 },
4660 .fixup_map1 = { 1 },
4661 .result = REJECT,
4662 .errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
4663 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4664 },
4665 {
4666 "invalid cgroup storage access 2",
4667 .insns = {
4668 BPF_MOV64_IMM(BPF_REG_2, 0),
4669 BPF_LD_MAP_FD(BPF_REG_1, 1),
4670 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4671 BPF_FUNC_get_local_storage),
4672 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4673 BPF_EXIT_INSN(),
4674 },
4675 .result = REJECT,
4676 .errstr = "fd 1 is not pointing to valid bpf_map",
4677 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4678 },
4679 {
Roman Gushchina3c60542018-09-28 14:45:53 +00004680 "invalid cgroup storage access 3",
Roman Gushchind4c9f572018-08-02 14:27:28 -07004681 .insns = {
4682 BPF_MOV64_IMM(BPF_REG_2, 0),
4683 BPF_LD_MAP_FD(BPF_REG_1, 0),
4684 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4685 BPF_FUNC_get_local_storage),
4686 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
4687 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4688 BPF_MOV64_IMM(BPF_REG_0, 0),
4689 BPF_EXIT_INSN(),
4690 },
4691 .fixup_cgroup_storage = { 1 },
4692 .result = REJECT,
4693 .errstr = "invalid access to map value, value_size=64 off=256 size=4",
4694 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4695 },
4696 {
4697 "invalid cgroup storage access 4",
4698 .insns = {
4699 BPF_MOV64_IMM(BPF_REG_2, 0),
4700 BPF_LD_MAP_FD(BPF_REG_1, 0),
4701 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4702 BPF_FUNC_get_local_storage),
4703 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
4704 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4705 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4706 BPF_EXIT_INSN(),
4707 },
4708 .fixup_cgroup_storage = { 1 },
4709 .result = REJECT,
4710 .errstr = "invalid access to map value, value_size=64 off=-2 size=4",
4711 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4712 },
4713 {
4714 "invalid cgroup storage access 5",
4715 .insns = {
4716 BPF_MOV64_IMM(BPF_REG_2, 7),
4717 BPF_LD_MAP_FD(BPF_REG_1, 0),
4718 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4719 BPF_FUNC_get_local_storage),
4720 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4721 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4722 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4723 BPF_EXIT_INSN(),
4724 },
4725 .fixup_cgroup_storage = { 1 },
4726 .result = REJECT,
4727 .errstr = "get_local_storage() doesn't support non-zero flags",
4728 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4729 },
4730 {
4731 "invalid cgroup storage access 6",
4732 .insns = {
4733 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
4734 BPF_LD_MAP_FD(BPF_REG_1, 0),
4735 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4736 BPF_FUNC_get_local_storage),
4737 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4738 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4739 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4740 BPF_EXIT_INSN(),
4741 },
4742 .fixup_cgroup_storage = { 1 },
4743 .result = REJECT,
4744 .errstr = "get_local_storage() doesn't support non-zero flags",
4745 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4746 },
4747 {
Roman Gushchina3c60542018-09-28 14:45:53 +00004748 "valid per-cpu cgroup storage access",
4749 .insns = {
4750 BPF_MOV64_IMM(BPF_REG_2, 0),
4751 BPF_LD_MAP_FD(BPF_REG_1, 0),
4752 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4753 BPF_FUNC_get_local_storage),
4754 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4755 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4756 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4757 BPF_EXIT_INSN(),
4758 },
4759 .fixup_percpu_cgroup_storage = { 1 },
4760 .result = ACCEPT,
4761 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4762 },
4763 {
4764 "invalid per-cpu cgroup storage access 1",
4765 .insns = {
4766 BPF_MOV64_IMM(BPF_REG_2, 0),
4767 BPF_LD_MAP_FD(BPF_REG_1, 0),
4768 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4769 BPF_FUNC_get_local_storage),
4770 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4771 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4772 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4773 BPF_EXIT_INSN(),
4774 },
4775 .fixup_map1 = { 1 },
4776 .result = REJECT,
4777 .errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
4778 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4779 },
4780 {
4781 "invalid per-cpu cgroup storage access 2",
4782 .insns = {
4783 BPF_MOV64_IMM(BPF_REG_2, 0),
4784 BPF_LD_MAP_FD(BPF_REG_1, 1),
4785 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4786 BPF_FUNC_get_local_storage),
4787 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4788 BPF_EXIT_INSN(),
4789 },
4790 .result = REJECT,
4791 .errstr = "fd 1 is not pointing to valid bpf_map",
4792 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4793 },
4794 {
4795 "invalid per-cpu cgroup storage access 3",
4796 .insns = {
4797 BPF_MOV64_IMM(BPF_REG_2, 0),
4798 BPF_LD_MAP_FD(BPF_REG_1, 0),
4799 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4800 BPF_FUNC_get_local_storage),
4801 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
4802 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4803 BPF_MOV64_IMM(BPF_REG_0, 0),
4804 BPF_EXIT_INSN(),
4805 },
4806 .fixup_percpu_cgroup_storage = { 1 },
4807 .result = REJECT,
4808 .errstr = "invalid access to map value, value_size=64 off=256 size=4",
4809 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4810 },
4811 {
4812 "invalid per-cpu cgroup storage access 4",
4813 .insns = {
4814 BPF_MOV64_IMM(BPF_REG_2, 0),
4815 BPF_LD_MAP_FD(BPF_REG_1, 0),
4816 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4817 BPF_FUNC_get_local_storage),
4818 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
4819 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4820 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4821 BPF_EXIT_INSN(),
4822 },
4823 .fixup_cgroup_storage = { 1 },
4824 .result = REJECT,
4825 .errstr = "invalid access to map value, value_size=64 off=-2 size=4",
4826 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4827 },
4828 {
4829 "invalid per-cpu cgroup storage access 5",
4830 .insns = {
4831 BPF_MOV64_IMM(BPF_REG_2, 7),
4832 BPF_LD_MAP_FD(BPF_REG_1, 0),
4833 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4834 BPF_FUNC_get_local_storage),
4835 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4836 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4837 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4838 BPF_EXIT_INSN(),
4839 },
4840 .fixup_percpu_cgroup_storage = { 1 },
4841 .result = REJECT,
4842 .errstr = "get_local_storage() doesn't support non-zero flags",
4843 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4844 },
4845 {
4846 "invalid per-cpu cgroup storage access 6",
4847 .insns = {
4848 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
4849 BPF_LD_MAP_FD(BPF_REG_1, 0),
4850 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4851 BPF_FUNC_get_local_storage),
4852 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4853 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4854 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4855 BPF_EXIT_INSN(),
4856 },
4857 .fixup_percpu_cgroup_storage = { 1 },
4858 .result = REJECT,
4859 .errstr = "get_local_storage() doesn't support non-zero flags",
4860 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4861 },
4862 {
Thomas Graf57a09bf2016-10-18 19:51:19 +02004863 "multiple registers share map_lookup_elem result",
4864 .insns = {
4865 BPF_MOV64_IMM(BPF_REG_1, 10),
4866 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4867 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4869 BPF_LD_MAP_FD(BPF_REG_1, 0),
4870 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4871 BPF_FUNC_map_lookup_elem),
4872 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4873 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4874 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4875 BPF_EXIT_INSN(),
4876 },
4877 .fixup_map1 = { 4 },
4878 .result = ACCEPT,
4879 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4880 },
4881 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004882 "alu ops on ptr_to_map_value_or_null, 1",
4883 .insns = {
4884 BPF_MOV64_IMM(BPF_REG_1, 10),
4885 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4886 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4888 BPF_LD_MAP_FD(BPF_REG_1, 0),
4889 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4890 BPF_FUNC_map_lookup_elem),
4891 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4892 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
4893 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
4894 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4895 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4896 BPF_EXIT_INSN(),
4897 },
4898 .fixup_map1 = { 4 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07004899 .errstr = "R4 pointer arithmetic on map_value_or_null",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004900 .result = REJECT,
4901 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4902 },
4903 {
4904 "alu ops on ptr_to_map_value_or_null, 2",
4905 .insns = {
4906 BPF_MOV64_IMM(BPF_REG_1, 10),
4907 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4908 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4909 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4910 BPF_LD_MAP_FD(BPF_REG_1, 0),
4911 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4912 BPF_FUNC_map_lookup_elem),
4913 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4914 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
4915 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4916 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4917 BPF_EXIT_INSN(),
4918 },
4919 .fixup_map1 = { 4 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07004920 .errstr = "R4 pointer arithmetic on map_value_or_null",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004921 .result = REJECT,
4922 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4923 },
4924 {
4925 "alu ops on ptr_to_map_value_or_null, 3",
4926 .insns = {
4927 BPF_MOV64_IMM(BPF_REG_1, 10),
4928 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4929 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4931 BPF_LD_MAP_FD(BPF_REG_1, 0),
4932 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4933 BPF_FUNC_map_lookup_elem),
4934 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4935 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4936 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4937 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4938 BPF_EXIT_INSN(),
4939 },
4940 .fixup_map1 = { 4 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07004941 .errstr = "R4 pointer arithmetic on map_value_or_null",
Daniel Borkmann614d0d72017-05-25 01:05:09 +02004942 .result = REJECT,
4943 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4944 },
4945 {
Thomas Graf57a09bf2016-10-18 19:51:19 +02004946 "invalid memory access with multiple map_lookup_elem calls",
4947 .insns = {
4948 BPF_MOV64_IMM(BPF_REG_1, 10),
4949 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4950 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4951 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4952 BPF_LD_MAP_FD(BPF_REG_1, 0),
4953 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4954 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4955 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4956 BPF_FUNC_map_lookup_elem),
4957 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4958 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4959 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4960 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4961 BPF_FUNC_map_lookup_elem),
4962 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4963 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4964 BPF_EXIT_INSN(),
4965 },
4966 .fixup_map1 = { 4 },
4967 .result = REJECT,
4968 .errstr = "R4 !read_ok",
4969 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4970 },
4971 {
4972 "valid indirect map_lookup_elem access with 2nd lookup in branch",
4973 .insns = {
4974 BPF_MOV64_IMM(BPF_REG_1, 10),
4975 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4976 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4977 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4978 BPF_LD_MAP_FD(BPF_REG_1, 0),
4979 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
4980 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
4981 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4982 BPF_FUNC_map_lookup_elem),
4983 BPF_MOV64_IMM(BPF_REG_2, 10),
4984 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
4985 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
4986 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4987 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4988 BPF_FUNC_map_lookup_elem),
4989 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4990 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4991 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4992 BPF_EXIT_INSN(),
4993 },
4994 .fixup_map1 = { 4 },
4995 .result = ACCEPT,
4996 .prog_type = BPF_PROG_TYPE_SCHED_CLS
4997 },
Josef Bacike9548902016-11-29 12:35:19 -05004998 {
4999 "invalid map access from else condition",
5000 .insns = {
5001 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5002 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5003 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5004 BPF_LD_MAP_FD(BPF_REG_1, 0),
5005 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
5006 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5007 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
5008 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
5009 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
5010 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
5011 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5012 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
5013 BPF_EXIT_INSN(),
5014 },
5015 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005016 .errstr = "R0 unbounded memory access",
Josef Bacike9548902016-11-29 12:35:19 -05005017 .result = REJECT,
Edward Creef65b1842017-08-07 15:27:12 +01005018 .errstr_unpriv = "R0 leaks addr",
Josef Bacike9548902016-11-29 12:35:19 -05005019 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02005020 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacike9548902016-11-29 12:35:19 -05005021 },
Gianluca Borello3c8397442016-12-03 12:31:33 -08005022 {
5023 "constant register |= constant should keep constant type",
5024 .insns = {
5025 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5027 BPF_MOV64_IMM(BPF_REG_2, 34),
5028 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
5029 BPF_MOV64_IMM(BPF_REG_3, 0),
5030 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5031 BPF_EXIT_INSN(),
5032 },
5033 .result = ACCEPT,
5034 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5035 },
5036 {
5037 "constant register |= constant should not bypass stack boundary checks",
5038 .insns = {
5039 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5040 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5041 BPF_MOV64_IMM(BPF_REG_2, 34),
5042 BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
5043 BPF_MOV64_IMM(BPF_REG_3, 0),
5044 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5045 BPF_EXIT_INSN(),
5046 },
5047 .errstr = "invalid stack type R1 off=-48 access_size=58",
5048 .result = REJECT,
5049 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5050 },
5051 {
5052 "constant register |= constant register should keep constant type",
5053 .insns = {
5054 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5056 BPF_MOV64_IMM(BPF_REG_2, 34),
5057 BPF_MOV64_IMM(BPF_REG_4, 13),
5058 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
5059 BPF_MOV64_IMM(BPF_REG_3, 0),
5060 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5061 BPF_EXIT_INSN(),
5062 },
5063 .result = ACCEPT,
5064 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5065 },
5066 {
5067 "constant register |= constant register should not bypass stack boundary checks",
5068 .insns = {
5069 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
5071 BPF_MOV64_IMM(BPF_REG_2, 34),
5072 BPF_MOV64_IMM(BPF_REG_4, 24),
5073 BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
5074 BPF_MOV64_IMM(BPF_REG_3, 0),
5075 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5076 BPF_EXIT_INSN(),
5077 },
5078 .errstr = "invalid stack type R1 off=-48 access_size=58",
5079 .result = REJECT,
5080 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5081 },
Thomas Graf3f731d82016-12-05 10:30:52 +01005082 {
5083 "invalid direct packet write for LWT_IN",
5084 .insns = {
5085 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5086 offsetof(struct __sk_buff, data)),
5087 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5088 offsetof(struct __sk_buff, data_end)),
5089 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5090 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5091 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5092 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5093 BPF_MOV64_IMM(BPF_REG_0, 0),
5094 BPF_EXIT_INSN(),
5095 },
5096 .errstr = "cannot write into packet",
5097 .result = REJECT,
5098 .prog_type = BPF_PROG_TYPE_LWT_IN,
5099 },
5100 {
5101 "invalid direct packet write for LWT_OUT",
5102 .insns = {
5103 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5104 offsetof(struct __sk_buff, data)),
5105 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5106 offsetof(struct __sk_buff, data_end)),
5107 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5108 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5109 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5110 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5111 BPF_MOV64_IMM(BPF_REG_0, 0),
5112 BPF_EXIT_INSN(),
5113 },
5114 .errstr = "cannot write into packet",
5115 .result = REJECT,
5116 .prog_type = BPF_PROG_TYPE_LWT_OUT,
5117 },
5118 {
5119 "direct packet write for LWT_XMIT",
5120 .insns = {
5121 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5122 offsetof(struct __sk_buff, data)),
5123 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5124 offsetof(struct __sk_buff, data_end)),
5125 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5126 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5127 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5128 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
5129 BPF_MOV64_IMM(BPF_REG_0, 0),
5130 BPF_EXIT_INSN(),
5131 },
5132 .result = ACCEPT,
5133 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5134 },
5135 {
5136 "direct packet read for LWT_IN",
5137 .insns = {
5138 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5139 offsetof(struct __sk_buff, data)),
5140 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5141 offsetof(struct __sk_buff, data_end)),
5142 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5143 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5144 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5145 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5146 BPF_MOV64_IMM(BPF_REG_0, 0),
5147 BPF_EXIT_INSN(),
5148 },
5149 .result = ACCEPT,
5150 .prog_type = BPF_PROG_TYPE_LWT_IN,
5151 },
5152 {
5153 "direct packet read for LWT_OUT",
5154 .insns = {
5155 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5156 offsetof(struct __sk_buff, data)),
5157 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5158 offsetof(struct __sk_buff, data_end)),
5159 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5161 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5162 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5163 BPF_MOV64_IMM(BPF_REG_0, 0),
5164 BPF_EXIT_INSN(),
5165 },
5166 .result = ACCEPT,
5167 .prog_type = BPF_PROG_TYPE_LWT_OUT,
5168 },
5169 {
5170 "direct packet read for LWT_XMIT",
5171 .insns = {
5172 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5173 offsetof(struct __sk_buff, data)),
5174 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5175 offsetof(struct __sk_buff, data_end)),
5176 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5177 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5178 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
5179 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
5180 BPF_MOV64_IMM(BPF_REG_0, 0),
5181 BPF_EXIT_INSN(),
5182 },
5183 .result = ACCEPT,
5184 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5185 },
5186 {
Alexei Starovoitovb1977682017-03-24 15:57:33 -07005187 "overlapping checks for direct packet access",
5188 .insns = {
5189 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
5190 offsetof(struct __sk_buff, data)),
5191 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
5192 offsetof(struct __sk_buff, data_end)),
5193 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
5194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
5195 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
5196 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5197 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
5198 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
5199 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
5200 BPF_MOV64_IMM(BPF_REG_0, 0),
5201 BPF_EXIT_INSN(),
5202 },
5203 .result = ACCEPT,
5204 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5205 },
5206 {
Daniel Borkmann6e6fddc2018-07-11 15:30:14 +02005207 "make headroom for LWT_XMIT",
5208 .insns = {
5209 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5210 BPF_MOV64_IMM(BPF_REG_2, 34),
5211 BPF_MOV64_IMM(BPF_REG_3, 0),
5212 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
5213 /* split for s390 to succeed */
5214 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
5215 BPF_MOV64_IMM(BPF_REG_2, 42),
5216 BPF_MOV64_IMM(BPF_REG_3, 0),
5217 BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
5218 BPF_MOV64_IMM(BPF_REG_0, 0),
5219 BPF_EXIT_INSN(),
5220 },
5221 .result = ACCEPT,
5222 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
5223 },
5224 {
Thomas Graf3f731d82016-12-05 10:30:52 +01005225 "invalid access of tc_classid for LWT_IN",
5226 .insns = {
5227 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5228 offsetof(struct __sk_buff, tc_classid)),
5229 BPF_EXIT_INSN(),
5230 },
5231 .result = REJECT,
5232 .errstr = "invalid bpf_context access",
5233 },
5234 {
5235 "invalid access of tc_classid for LWT_OUT",
5236 .insns = {
5237 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5238 offsetof(struct __sk_buff, tc_classid)),
5239 BPF_EXIT_INSN(),
5240 },
5241 .result = REJECT,
5242 .errstr = "invalid bpf_context access",
5243 },
5244 {
5245 "invalid access of tc_classid for LWT_XMIT",
5246 .insns = {
5247 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5248 offsetof(struct __sk_buff, tc_classid)),
5249 BPF_EXIT_INSN(),
5250 },
5251 .result = REJECT,
5252 .errstr = "invalid bpf_context access",
5253 },
Gianluca Borello57225692017-01-09 10:19:47 -08005254 {
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005255 "leak pointer into ctx 1",
5256 .insns = {
5257 BPF_MOV64_IMM(BPF_REG_0, 0),
5258 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5259 offsetof(struct __sk_buff, cb[0])),
5260 BPF_LD_MAP_FD(BPF_REG_2, 0),
5261 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
5262 offsetof(struct __sk_buff, cb[0])),
5263 BPF_EXIT_INSN(),
5264 },
5265 .fixup_map1 = { 2 },
5266 .errstr_unpriv = "R2 leaks addr into mem",
5267 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01005268 .result = REJECT,
Joe Stringer9d2be442018-10-02 13:35:31 -07005269 .errstr = "BPF_XADD stores into R1 inv is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005270 },
5271 {
5272 "leak pointer into ctx 2",
5273 .insns = {
5274 BPF_MOV64_IMM(BPF_REG_0, 0),
5275 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
5276 offsetof(struct __sk_buff, cb[0])),
5277 BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
5278 offsetof(struct __sk_buff, cb[0])),
5279 BPF_EXIT_INSN(),
5280 },
5281 .errstr_unpriv = "R10 leaks addr into mem",
5282 .result_unpriv = REJECT,
Daniel Borkmannf37a8cb2018-01-16 23:30:10 +01005283 .result = REJECT,
Joe Stringer9d2be442018-10-02 13:35:31 -07005284 .errstr = "BPF_XADD stores into R1 inv is not allowed",
Daniel Borkmann6bdf6ab2017-06-29 03:04:59 +02005285 },
5286 {
5287 "leak pointer into ctx 3",
5288 .insns = {
5289 BPF_MOV64_IMM(BPF_REG_0, 0),
5290 BPF_LD_MAP_FD(BPF_REG_2, 0),
5291 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
5292 offsetof(struct __sk_buff, cb[0])),
5293 BPF_EXIT_INSN(),
5294 },
5295 .fixup_map1 = { 1 },
5296 .errstr_unpriv = "R2 leaks addr into ctx",
5297 .result_unpriv = REJECT,
5298 .result = ACCEPT,
5299 },
5300 {
5301 "leak pointer into map val",
5302 .insns = {
5303 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5304 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5305 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5307 BPF_LD_MAP_FD(BPF_REG_1, 0),
5308 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
5309 BPF_FUNC_map_lookup_elem),
5310 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5311 BPF_MOV64_IMM(BPF_REG_3, 0),
5312 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
5313 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
5314 BPF_MOV64_IMM(BPF_REG_0, 0),
5315 BPF_EXIT_INSN(),
5316 },
5317 .fixup_map1 = { 4 },
5318 .errstr_unpriv = "R6 leaks addr into mem",
5319 .result_unpriv = REJECT,
5320 .result = ACCEPT,
5321 },
5322 {
Gianluca Borello57225692017-01-09 10:19:47 -08005323 "helper access to map: full range",
5324 .insns = {
5325 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5327 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5328 BPF_LD_MAP_FD(BPF_REG_1, 0),
5329 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5330 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5331 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5332 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
5333 BPF_MOV64_IMM(BPF_REG_3, 0),
5334 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5335 BPF_EXIT_INSN(),
5336 },
5337 .fixup_map2 = { 3 },
5338 .result = ACCEPT,
5339 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5340 },
5341 {
5342 "helper access to map: partial range",
5343 .insns = {
5344 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5346 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5347 BPF_LD_MAP_FD(BPF_REG_1, 0),
5348 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5349 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5350 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5351 BPF_MOV64_IMM(BPF_REG_2, 8),
5352 BPF_MOV64_IMM(BPF_REG_3, 0),
5353 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5354 BPF_EXIT_INSN(),
5355 },
5356 .fixup_map2 = { 3 },
5357 .result = ACCEPT,
5358 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5359 },
5360 {
5361 "helper access to map: empty range",
5362 .insns = {
5363 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5365 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5366 BPF_LD_MAP_FD(BPF_REG_1, 0),
5367 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005368 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5369 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5370 BPF_MOV64_IMM(BPF_REG_2, 0),
5371 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005372 BPF_EXIT_INSN(),
5373 },
5374 .fixup_map2 = { 3 },
5375 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
5376 .result = REJECT,
5377 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5378 },
5379 {
5380 "helper access to map: out-of-bound range",
5381 .insns = {
5382 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5384 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5385 BPF_LD_MAP_FD(BPF_REG_1, 0),
5386 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5387 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5388 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5389 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
5390 BPF_MOV64_IMM(BPF_REG_3, 0),
5391 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5392 BPF_EXIT_INSN(),
5393 },
5394 .fixup_map2 = { 3 },
5395 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
5396 .result = REJECT,
5397 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5398 },
5399 {
5400 "helper access to map: negative range",
5401 .insns = {
5402 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5403 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5404 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5405 BPF_LD_MAP_FD(BPF_REG_1, 0),
5406 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5407 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5408 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5409 BPF_MOV64_IMM(BPF_REG_2, -8),
5410 BPF_MOV64_IMM(BPF_REG_3, 0),
5411 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5412 BPF_EXIT_INSN(),
5413 },
5414 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005415 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005416 .result = REJECT,
5417 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5418 },
5419 {
5420 "helper access to adjusted map (via const imm): full range",
5421 .insns = {
5422 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5424 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5425 BPF_LD_MAP_FD(BPF_REG_1, 0),
5426 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5427 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5428 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5429 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5430 offsetof(struct test_val, foo)),
5431 BPF_MOV64_IMM(BPF_REG_2,
5432 sizeof(struct test_val) -
5433 offsetof(struct test_val, foo)),
5434 BPF_MOV64_IMM(BPF_REG_3, 0),
5435 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5436 BPF_EXIT_INSN(),
5437 },
5438 .fixup_map2 = { 3 },
5439 .result = ACCEPT,
5440 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5441 },
5442 {
5443 "helper access to adjusted map (via const imm): partial range",
5444 .insns = {
5445 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5446 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5447 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5448 BPF_LD_MAP_FD(BPF_REG_1, 0),
5449 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5450 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5451 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5452 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5453 offsetof(struct test_val, foo)),
5454 BPF_MOV64_IMM(BPF_REG_2, 8),
5455 BPF_MOV64_IMM(BPF_REG_3, 0),
5456 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5457 BPF_EXIT_INSN(),
5458 },
5459 .fixup_map2 = { 3 },
5460 .result = ACCEPT,
5461 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5462 },
5463 {
5464 "helper access to adjusted map (via const imm): empty range",
5465 .insns = {
5466 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5468 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5469 BPF_LD_MAP_FD(BPF_REG_1, 0),
5470 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005471 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Gianluca Borello57225692017-01-09 10:19:47 -08005472 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5474 offsetof(struct test_val, foo)),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005475 BPF_MOV64_IMM(BPF_REG_2, 0),
5476 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005477 BPF_EXIT_INSN(),
5478 },
5479 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005480 .errstr = "invalid access to map value, value_size=48 off=4 size=0",
Gianluca Borello57225692017-01-09 10:19:47 -08005481 .result = REJECT,
5482 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5483 },
5484 {
5485 "helper access to adjusted map (via const imm): out-of-bound range",
5486 .insns = {
5487 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5488 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5489 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5490 BPF_LD_MAP_FD(BPF_REG_1, 0),
5491 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5492 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5493 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5495 offsetof(struct test_val, foo)),
5496 BPF_MOV64_IMM(BPF_REG_2,
5497 sizeof(struct test_val) -
5498 offsetof(struct test_val, foo) + 8),
5499 BPF_MOV64_IMM(BPF_REG_3, 0),
5500 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5501 BPF_EXIT_INSN(),
5502 },
5503 .fixup_map2 = { 3 },
5504 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5505 .result = REJECT,
5506 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5507 },
5508 {
5509 "helper access to adjusted map (via const imm): negative range (> adjustment)",
5510 .insns = {
5511 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5513 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5514 BPF_LD_MAP_FD(BPF_REG_1, 0),
5515 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5516 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5517 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5518 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5519 offsetof(struct test_val, foo)),
5520 BPF_MOV64_IMM(BPF_REG_2, -8),
5521 BPF_MOV64_IMM(BPF_REG_3, 0),
5522 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5523 BPF_EXIT_INSN(),
5524 },
5525 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005526 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005527 .result = REJECT,
5528 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5529 },
5530 {
5531 "helper access to adjusted map (via const imm): negative range (< adjustment)",
5532 .insns = {
5533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5535 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5536 BPF_LD_MAP_FD(BPF_REG_1, 0),
5537 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5538 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
5539 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5540 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
5541 offsetof(struct test_val, foo)),
5542 BPF_MOV64_IMM(BPF_REG_2, -1),
5543 BPF_MOV64_IMM(BPF_REG_3, 0),
5544 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5545 BPF_EXIT_INSN(),
5546 },
5547 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005548 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005549 .result = REJECT,
5550 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5551 },
5552 {
5553 "helper access to adjusted map (via const reg): full range",
5554 .insns = {
5555 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5556 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5557 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5558 BPF_LD_MAP_FD(BPF_REG_1, 0),
5559 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5561 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5562 BPF_MOV64_IMM(BPF_REG_3,
5563 offsetof(struct test_val, foo)),
5564 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5565 BPF_MOV64_IMM(BPF_REG_2,
5566 sizeof(struct test_val) -
5567 offsetof(struct test_val, foo)),
5568 BPF_MOV64_IMM(BPF_REG_3, 0),
5569 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5570 BPF_EXIT_INSN(),
5571 },
5572 .fixup_map2 = { 3 },
5573 .result = ACCEPT,
5574 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5575 },
5576 {
5577 "helper access to adjusted map (via const reg): partial range",
5578 .insns = {
5579 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5581 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5582 BPF_LD_MAP_FD(BPF_REG_1, 0),
5583 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5585 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5586 BPF_MOV64_IMM(BPF_REG_3,
5587 offsetof(struct test_val, foo)),
5588 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5589 BPF_MOV64_IMM(BPF_REG_2, 8),
5590 BPF_MOV64_IMM(BPF_REG_3, 0),
5591 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5592 BPF_EXIT_INSN(),
5593 },
5594 .fixup_map2 = { 3 },
5595 .result = ACCEPT,
5596 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5597 },
5598 {
5599 "helper access to adjusted map (via const reg): empty range",
5600 .insns = {
5601 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5603 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5604 BPF_LD_MAP_FD(BPF_REG_1, 0),
5605 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005606 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
Gianluca Borello57225692017-01-09 10:19:47 -08005607 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5608 BPF_MOV64_IMM(BPF_REG_3, 0),
5609 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005610 BPF_MOV64_IMM(BPF_REG_2, 0),
5611 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005612 BPF_EXIT_INSN(),
5613 },
5614 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005615 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08005616 .result = REJECT,
5617 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5618 },
5619 {
5620 "helper access to adjusted map (via const reg): out-of-bound range",
5621 .insns = {
5622 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5624 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5625 BPF_LD_MAP_FD(BPF_REG_1, 0),
5626 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5627 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5628 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5629 BPF_MOV64_IMM(BPF_REG_3,
5630 offsetof(struct test_val, foo)),
5631 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5632 BPF_MOV64_IMM(BPF_REG_2,
5633 sizeof(struct test_val) -
5634 offsetof(struct test_val, foo) + 8),
5635 BPF_MOV64_IMM(BPF_REG_3, 0),
5636 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5637 BPF_EXIT_INSN(),
5638 },
5639 .fixup_map2 = { 3 },
5640 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
5641 .result = REJECT,
5642 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5643 },
5644 {
5645 "helper access to adjusted map (via const reg): negative range (> adjustment)",
5646 .insns = {
5647 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5649 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5650 BPF_LD_MAP_FD(BPF_REG_1, 0),
5651 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5653 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5654 BPF_MOV64_IMM(BPF_REG_3,
5655 offsetof(struct test_val, foo)),
5656 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5657 BPF_MOV64_IMM(BPF_REG_2, -8),
5658 BPF_MOV64_IMM(BPF_REG_3, 0),
5659 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5660 BPF_EXIT_INSN(),
5661 },
5662 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005663 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005664 .result = REJECT,
5665 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5666 },
5667 {
5668 "helper access to adjusted map (via const reg): negative range (< adjustment)",
5669 .insns = {
5670 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5671 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5672 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5673 BPF_LD_MAP_FD(BPF_REG_1, 0),
5674 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5675 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5676 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5677 BPF_MOV64_IMM(BPF_REG_3,
5678 offsetof(struct test_val, foo)),
5679 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5680 BPF_MOV64_IMM(BPF_REG_2, -1),
5681 BPF_MOV64_IMM(BPF_REG_3, 0),
5682 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5683 BPF_EXIT_INSN(),
5684 },
5685 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005686 .errstr = "R2 min value is negative",
Gianluca Borello57225692017-01-09 10:19:47 -08005687 .result = REJECT,
5688 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5689 },
5690 {
5691 "helper access to adjusted map (via variable): full range",
5692 .insns = {
5693 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5695 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5696 BPF_LD_MAP_FD(BPF_REG_1, 0),
5697 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5698 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5699 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5700 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5701 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5702 offsetof(struct test_val, foo), 4),
5703 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5704 BPF_MOV64_IMM(BPF_REG_2,
5705 sizeof(struct test_val) -
5706 offsetof(struct test_val, foo)),
5707 BPF_MOV64_IMM(BPF_REG_3, 0),
5708 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5709 BPF_EXIT_INSN(),
5710 },
5711 .fixup_map2 = { 3 },
5712 .result = ACCEPT,
5713 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5714 },
5715 {
5716 "helper access to adjusted map (via variable): partial range",
5717 .insns = {
5718 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5719 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5720 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5721 BPF_LD_MAP_FD(BPF_REG_1, 0),
5722 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5723 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5724 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5725 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5726 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5727 offsetof(struct test_val, foo), 4),
5728 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5729 BPF_MOV64_IMM(BPF_REG_2, 8),
5730 BPF_MOV64_IMM(BPF_REG_3, 0),
5731 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5732 BPF_EXIT_INSN(),
5733 },
5734 .fixup_map2 = { 3 },
5735 .result = ACCEPT,
5736 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5737 },
5738 {
5739 "helper access to adjusted map (via variable): empty range",
5740 .insns = {
5741 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5742 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5743 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5744 BPF_LD_MAP_FD(BPF_REG_1, 0),
5745 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005746 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
Gianluca Borello57225692017-01-09 10:19:47 -08005747 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5748 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5749 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005750 offsetof(struct test_val, foo), 3),
Gianluca Borello57225692017-01-09 10:19:47 -08005751 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005752 BPF_MOV64_IMM(BPF_REG_2, 0),
5753 BPF_EMIT_CALL(BPF_FUNC_trace_printk),
Gianluca Borello57225692017-01-09 10:19:47 -08005754 BPF_EXIT_INSN(),
5755 },
5756 .fixup_map2 = { 3 },
Yonghong Songf1a8b8e2017-11-21 11:23:40 -08005757 .errstr = "R1 min value is outside of the array range",
Gianluca Borello57225692017-01-09 10:19:47 -08005758 .result = REJECT,
5759 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5760 },
5761 {
5762 "helper access to adjusted map (via variable): no max check",
5763 .insns = {
5764 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5765 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5766 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5767 BPF_LD_MAP_FD(BPF_REG_1, 0),
5768 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5769 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5770 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5771 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5772 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
Edward Creef65b1842017-08-07 15:27:12 +01005773 BPF_MOV64_IMM(BPF_REG_2, 1),
Gianluca Borello57225692017-01-09 10:19:47 -08005774 BPF_MOV64_IMM(BPF_REG_3, 0),
5775 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5776 BPF_EXIT_INSN(),
5777 },
5778 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01005779 .errstr = "R1 unbounded memory access",
Gianluca Borello57225692017-01-09 10:19:47 -08005780 .result = REJECT,
5781 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5782 },
5783 {
5784 "helper access to adjusted map (via variable): wrong max check",
5785 .insns = {
5786 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5787 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5788 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5789 BPF_LD_MAP_FD(BPF_REG_1, 0),
5790 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5791 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
5792 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5793 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5794 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5795 offsetof(struct test_val, foo), 4),
5796 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5797 BPF_MOV64_IMM(BPF_REG_2,
5798 sizeof(struct test_val) -
5799 offsetof(struct test_val, foo) + 1),
5800 BPF_MOV64_IMM(BPF_REG_3, 0),
5801 BPF_EMIT_CALL(BPF_FUNC_probe_read),
5802 BPF_EXIT_INSN(),
5803 },
5804 .fixup_map2 = { 3 },
5805 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
5806 .result = REJECT,
5807 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5808 },
Gianluca Borellof0318d02017-01-09 10:19:48 -08005809 {
Daniel Borkmann31e482b2017-08-10 01:40:03 +02005810 "helper access to map: bounds check using <, good access",
5811 .insns = {
5812 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5813 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5814 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5815 BPF_LD_MAP_FD(BPF_REG_1, 0),
5816 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5817 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5818 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5819 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5820 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
5821 BPF_MOV64_IMM(BPF_REG_0, 0),
5822 BPF_EXIT_INSN(),
5823 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5824 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5825 BPF_MOV64_IMM(BPF_REG_0, 0),
5826 BPF_EXIT_INSN(),
5827 },
5828 .fixup_map2 = { 3 },
5829 .result = ACCEPT,
5830 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5831 },
5832 {
5833 "helper access to map: bounds check using <, bad access",
5834 .insns = {
5835 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5836 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5837 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5838 BPF_LD_MAP_FD(BPF_REG_1, 0),
5839 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5840 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5841 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5842 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5843 BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
5844 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5845 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5846 BPF_MOV64_IMM(BPF_REG_0, 0),
5847 BPF_EXIT_INSN(),
5848 BPF_MOV64_IMM(BPF_REG_0, 0),
5849 BPF_EXIT_INSN(),
5850 },
5851 .fixup_map2 = { 3 },
5852 .result = REJECT,
5853 .errstr = "R1 unbounded memory access",
5854 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5855 },
5856 {
5857 "helper access to map: bounds check using <=, good access",
5858 .insns = {
5859 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5860 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5861 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5862 BPF_LD_MAP_FD(BPF_REG_1, 0),
5863 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5864 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5865 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5866 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5867 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
5868 BPF_MOV64_IMM(BPF_REG_0, 0),
5869 BPF_EXIT_INSN(),
5870 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5871 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5872 BPF_MOV64_IMM(BPF_REG_0, 0),
5873 BPF_EXIT_INSN(),
5874 },
5875 .fixup_map2 = { 3 },
5876 .result = ACCEPT,
5877 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5878 },
5879 {
5880 "helper access to map: bounds check using <=, bad access",
5881 .insns = {
5882 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5883 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5884 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5885 BPF_LD_MAP_FD(BPF_REG_1, 0),
5886 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5887 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5888 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5889 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5890 BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
5891 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5892 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5893 BPF_MOV64_IMM(BPF_REG_0, 0),
5894 BPF_EXIT_INSN(),
5895 BPF_MOV64_IMM(BPF_REG_0, 0),
5896 BPF_EXIT_INSN(),
5897 },
5898 .fixup_map2 = { 3 },
5899 .result = REJECT,
5900 .errstr = "R1 unbounded memory access",
5901 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5902 },
5903 {
5904 "helper access to map: bounds check using s<, good access",
5905 .insns = {
5906 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5907 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5908 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5909 BPF_LD_MAP_FD(BPF_REG_1, 0),
5910 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5911 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5912 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5913 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5914 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5915 BPF_MOV64_IMM(BPF_REG_0, 0),
5916 BPF_EXIT_INSN(),
5917 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
5918 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5919 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5920 BPF_MOV64_IMM(BPF_REG_0, 0),
5921 BPF_EXIT_INSN(),
5922 },
5923 .fixup_map2 = { 3 },
5924 .result = ACCEPT,
5925 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5926 },
5927 {
5928 "helper access to map: bounds check using s<, good access 2",
5929 .insns = {
5930 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5931 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5932 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5933 BPF_LD_MAP_FD(BPF_REG_1, 0),
5934 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5935 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5936 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5937 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5938 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5939 BPF_MOV64_IMM(BPF_REG_0, 0),
5940 BPF_EXIT_INSN(),
5941 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5942 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5943 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5944 BPF_MOV64_IMM(BPF_REG_0, 0),
5945 BPF_EXIT_INSN(),
5946 },
5947 .fixup_map2 = { 3 },
5948 .result = ACCEPT,
5949 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5950 },
5951 {
5952 "helper access to map: bounds check using s<, bad access",
5953 .insns = {
5954 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5955 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5956 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5957 BPF_LD_MAP_FD(BPF_REG_1, 0),
5958 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5959 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5960 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5961 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
5962 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
5963 BPF_MOV64_IMM(BPF_REG_0, 0),
5964 BPF_EXIT_INSN(),
5965 BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
5966 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5967 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5968 BPF_MOV64_IMM(BPF_REG_0, 0),
5969 BPF_EXIT_INSN(),
5970 },
5971 .fixup_map2 = { 3 },
5972 .result = REJECT,
5973 .errstr = "R1 min value is negative",
5974 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5975 },
5976 {
5977 "helper access to map: bounds check using s<=, good access",
5978 .insns = {
5979 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5981 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5982 BPF_LD_MAP_FD(BPF_REG_1, 0),
5983 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5984 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
5985 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5986 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
5987 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
5988 BPF_MOV64_IMM(BPF_REG_0, 0),
5989 BPF_EXIT_INSN(),
5990 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
5991 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5992 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
5993 BPF_MOV64_IMM(BPF_REG_0, 0),
5994 BPF_EXIT_INSN(),
5995 },
5996 .fixup_map2 = { 3 },
5997 .result = ACCEPT,
5998 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5999 },
6000 {
6001 "helper access to map: bounds check using s<=, good access 2",
6002 .insns = {
6003 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6004 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6005 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6006 BPF_LD_MAP_FD(BPF_REG_1, 0),
6007 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6008 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6009 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6010 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6011 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
6012 BPF_MOV64_IMM(BPF_REG_0, 0),
6013 BPF_EXIT_INSN(),
6014 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
6015 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6016 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6017 BPF_MOV64_IMM(BPF_REG_0, 0),
6018 BPF_EXIT_INSN(),
6019 },
6020 .fixup_map2 = { 3 },
6021 .result = ACCEPT,
6022 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6023 },
6024 {
6025 "helper access to map: bounds check using s<=, bad access",
6026 .insns = {
6027 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6028 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6029 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6030 BPF_LD_MAP_FD(BPF_REG_1, 0),
6031 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6032 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6033 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6034 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
6035 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
6036 BPF_MOV64_IMM(BPF_REG_0, 0),
6037 BPF_EXIT_INSN(),
6038 BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
6039 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
6040 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
6041 BPF_MOV64_IMM(BPF_REG_0, 0),
6042 BPF_EXIT_INSN(),
6043 },
6044 .fixup_map2 = { 3 },
6045 .result = REJECT,
6046 .errstr = "R1 min value is negative",
6047 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6048 },
6049 {
Paul Chaignon5f90dd62018-04-24 15:08:19 +02006050 "map lookup helper access to map",
6051 .insns = {
6052 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6054 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6055 BPF_LD_MAP_FD(BPF_REG_1, 0),
6056 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6057 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6058 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6059 BPF_LD_MAP_FD(BPF_REG_1, 0),
6060 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6061 BPF_EXIT_INSN(),
6062 },
6063 .fixup_map3 = { 3, 8 },
6064 .result = ACCEPT,
6065 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6066 },
6067 {
6068 "map update helper access to map",
6069 .insns = {
6070 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6072 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6073 BPF_LD_MAP_FD(BPF_REG_1, 0),
6074 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6075 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6076 BPF_MOV64_IMM(BPF_REG_4, 0),
6077 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
6078 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6079 BPF_LD_MAP_FD(BPF_REG_1, 0),
6080 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
6081 BPF_EXIT_INSN(),
6082 },
6083 .fixup_map3 = { 3, 10 },
6084 .result = ACCEPT,
6085 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6086 },
6087 {
6088 "map update helper access to map: wrong size",
6089 .insns = {
6090 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6091 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6092 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6093 BPF_LD_MAP_FD(BPF_REG_1, 0),
6094 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6095 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6096 BPF_MOV64_IMM(BPF_REG_4, 0),
6097 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
6098 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6099 BPF_LD_MAP_FD(BPF_REG_1, 0),
6100 BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
6101 BPF_EXIT_INSN(),
6102 },
6103 .fixup_map1 = { 3 },
6104 .fixup_map3 = { 10 },
6105 .result = REJECT,
6106 .errstr = "invalid access to map value, value_size=8 off=0 size=16",
6107 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6108 },
6109 {
6110 "map helper access to adjusted map (via const imm)",
6111 .insns = {
6112 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6113 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6114 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6115 BPF_LD_MAP_FD(BPF_REG_1, 0),
6116 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6117 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6118 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
6120 offsetof(struct other_val, bar)),
6121 BPF_LD_MAP_FD(BPF_REG_1, 0),
6122 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6123 BPF_EXIT_INSN(),
6124 },
6125 .fixup_map3 = { 3, 9 },
6126 .result = ACCEPT,
6127 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6128 },
6129 {
6130 "map helper access to adjusted map (via const imm): out-of-bound 1",
6131 .insns = {
6132 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6134 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6135 BPF_LD_MAP_FD(BPF_REG_1, 0),
6136 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6137 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6138 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6139 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
6140 sizeof(struct other_val) - 4),
6141 BPF_LD_MAP_FD(BPF_REG_1, 0),
6142 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6143 BPF_EXIT_INSN(),
6144 },
6145 .fixup_map3 = { 3, 9 },
6146 .result = REJECT,
6147 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
6148 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6149 },
6150 {
6151 "map helper access to adjusted map (via const imm): out-of-bound 2",
6152 .insns = {
6153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6155 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6156 BPF_LD_MAP_FD(BPF_REG_1, 0),
6157 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6158 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6159 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6160 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6161 BPF_LD_MAP_FD(BPF_REG_1, 0),
6162 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6163 BPF_EXIT_INSN(),
6164 },
6165 .fixup_map3 = { 3, 9 },
6166 .result = REJECT,
6167 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
6168 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6169 },
6170 {
6171 "map helper access to adjusted map (via const reg)",
6172 .insns = {
6173 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6175 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6176 BPF_LD_MAP_FD(BPF_REG_1, 0),
6177 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6178 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6179 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6180 BPF_MOV64_IMM(BPF_REG_3,
6181 offsetof(struct other_val, bar)),
6182 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6183 BPF_LD_MAP_FD(BPF_REG_1, 0),
6184 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6185 BPF_EXIT_INSN(),
6186 },
6187 .fixup_map3 = { 3, 10 },
6188 .result = ACCEPT,
6189 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6190 },
6191 {
6192 "map helper access to adjusted map (via const reg): out-of-bound 1",
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, 6),
6200 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6201 BPF_MOV64_IMM(BPF_REG_3,
6202 sizeof(struct other_val) - 4),
6203 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6204 BPF_LD_MAP_FD(BPF_REG_1, 0),
6205 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6206 BPF_EXIT_INSN(),
6207 },
6208 .fixup_map3 = { 3, 10 },
6209 .result = REJECT,
6210 .errstr = "invalid access to map value, value_size=16 off=12 size=8",
6211 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6212 },
6213 {
6214 "map helper access to adjusted map (via const reg): out-of-bound 2",
6215 .insns = {
6216 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6218 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6219 BPF_LD_MAP_FD(BPF_REG_1, 0),
6220 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6221 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6222 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6223 BPF_MOV64_IMM(BPF_REG_3, -4),
6224 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6225 BPF_LD_MAP_FD(BPF_REG_1, 0),
6226 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6227 BPF_EXIT_INSN(),
6228 },
6229 .fixup_map3 = { 3, 10 },
6230 .result = REJECT,
6231 .errstr = "invalid access to map value, value_size=16 off=-4 size=8",
6232 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6233 },
6234 {
6235 "map helper access to adjusted map (via variable)",
6236 .insns = {
6237 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6239 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6240 BPF_LD_MAP_FD(BPF_REG_1, 0),
6241 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6242 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6243 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6244 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6245 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6246 offsetof(struct other_val, bar), 4),
6247 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6248 BPF_LD_MAP_FD(BPF_REG_1, 0),
6249 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6250 BPF_EXIT_INSN(),
6251 },
6252 .fixup_map3 = { 3, 11 },
6253 .result = ACCEPT,
6254 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6255 },
6256 {
6257 "map helper access to adjusted map (via variable): no max check",
6258 .insns = {
6259 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6261 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6262 BPF_LD_MAP_FD(BPF_REG_1, 0),
6263 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6264 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6265 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6266 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6267 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6268 BPF_LD_MAP_FD(BPF_REG_1, 0),
6269 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6270 BPF_EXIT_INSN(),
6271 },
6272 .fixup_map3 = { 3, 10 },
6273 .result = REJECT,
6274 .errstr = "R2 unbounded memory access, make sure to bounds check any array access into a map",
6275 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6276 },
6277 {
6278 "map helper access to adjusted map (via variable): wrong max check",
6279 .insns = {
6280 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6282 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6283 BPF_LD_MAP_FD(BPF_REG_1, 0),
6284 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6285 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6286 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
6287 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
6288 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
6289 offsetof(struct other_val, bar) + 1, 4),
6290 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
6291 BPF_LD_MAP_FD(BPF_REG_1, 0),
6292 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6293 BPF_EXIT_INSN(),
6294 },
6295 .fixup_map3 = { 3, 11 },
6296 .result = REJECT,
6297 .errstr = "invalid access to map value, value_size=16 off=9 size=8",
6298 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6299 },
6300 {
Gianluca Borellof0318d02017-01-09 10:19:48 -08006301 "map element value is preserved across register spilling",
6302 .insns = {
6303 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6304 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6305 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6306 BPF_LD_MAP_FD(BPF_REG_1, 0),
6307 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6308 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6309 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6310 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6311 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6312 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6313 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6314 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6315 BPF_EXIT_INSN(),
6316 },
6317 .fixup_map2 = { 3 },
6318 .errstr_unpriv = "R0 leaks addr",
6319 .result = ACCEPT,
6320 .result_unpriv = REJECT,
6321 },
6322 {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006323 "map element value or null is marked on register spilling",
6324 .insns = {
6325 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6327 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6328 BPF_LD_MAP_FD(BPF_REG_1, 0),
6329 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6330 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
6332 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6333 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6334 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6335 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6336 BPF_EXIT_INSN(),
6337 },
6338 .fixup_map2 = { 3 },
6339 .errstr_unpriv = "R0 leaks addr",
6340 .result = ACCEPT,
6341 .result_unpriv = REJECT,
6342 },
6343 {
6344 "map element value store of cleared call register",
6345 .insns = {
6346 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6347 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6348 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6349 BPF_LD_MAP_FD(BPF_REG_1, 0),
6350 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6351 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
6352 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
6353 BPF_EXIT_INSN(),
6354 },
6355 .fixup_map2 = { 3 },
6356 .errstr_unpriv = "R1 !read_ok",
6357 .errstr = "R1 !read_ok",
6358 .result = REJECT,
6359 .result_unpriv = REJECT,
6360 },
6361 {
6362 "map element value with unaligned store",
6363 .insns = {
6364 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6366 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6367 BPF_LD_MAP_FD(BPF_REG_1, 0),
6368 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6369 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
6370 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6371 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6372 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
6373 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
6374 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6375 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
6376 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
6377 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
6378 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
6379 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
6380 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
6381 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
6382 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
6383 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
6384 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
6385 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
6386 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
6387 BPF_EXIT_INSN(),
6388 },
6389 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006390 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006391 .result = ACCEPT,
6392 .result_unpriv = REJECT,
6393 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6394 },
6395 {
6396 "map element value with unaligned load",
6397 .insns = {
6398 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6400 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6401 BPF_LD_MAP_FD(BPF_REG_1, 0),
6402 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6403 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6404 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
6405 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
6406 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
6407 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6408 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
6409 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
6410 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
6411 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
6412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
6413 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
6414 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
6415 BPF_EXIT_INSN(),
6416 },
6417 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006418 .errstr_unpriv = "R0 leaks addr",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006419 .result = ACCEPT,
6420 .result_unpriv = REJECT,
6421 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6422 },
6423 {
6424 "map element value illegal alu op, 1",
6425 .insns = {
6426 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6427 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6428 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6429 BPF_LD_MAP_FD(BPF_REG_1, 0),
6430 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6431 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6432 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
6433 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6434 BPF_EXIT_INSN(),
6435 },
6436 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006437 .errstr = "R0 bitwise operator &= on pointer",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006438 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006439 },
6440 {
6441 "map element value illegal alu op, 2",
6442 .insns = {
6443 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6445 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6446 BPF_LD_MAP_FD(BPF_REG_1, 0),
6447 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6448 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6449 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
6450 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6451 BPF_EXIT_INSN(),
6452 },
6453 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006454 .errstr = "R0 32-bit pointer arithmetic prohibited",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006455 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006456 },
6457 {
6458 "map element value illegal alu op, 3",
6459 .insns = {
6460 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6461 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6462 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6463 BPF_LD_MAP_FD(BPF_REG_1, 0),
6464 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6465 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6466 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
6467 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6468 BPF_EXIT_INSN(),
6469 },
6470 .fixup_map2 = { 3 },
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08006471 .errstr = "R0 pointer arithmetic with /= operator",
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006472 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006473 },
6474 {
6475 "map element value illegal alu op, 4",
6476 .insns = {
6477 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6479 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6480 BPF_LD_MAP_FD(BPF_REG_1, 0),
6481 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6482 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
6483 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
6484 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6485 BPF_EXIT_INSN(),
6486 },
6487 .fixup_map2 = { 3 },
6488 .errstr_unpriv = "R0 pointer arithmetic prohibited",
6489 .errstr = "invalid mem access 'inv'",
6490 .result = REJECT,
6491 .result_unpriv = REJECT,
6492 },
6493 {
6494 "map element value illegal alu op, 5",
6495 .insns = {
6496 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6497 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6498 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6499 BPF_LD_MAP_FD(BPF_REG_1, 0),
6500 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6501 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6502 BPF_MOV64_IMM(BPF_REG_3, 4096),
6503 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6504 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6505 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6506 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
6507 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
6508 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
6509 BPF_EXIT_INSN(),
6510 },
6511 .fixup_map2 = { 3 },
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006512 .errstr = "R0 invalid mem access 'inv'",
6513 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006514 },
6515 {
6516 "map element value is preserved across register spilling",
Gianluca Borellof0318d02017-01-09 10:19:48 -08006517 .insns = {
6518 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6519 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6520 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6521 BPF_LD_MAP_FD(BPF_REG_1, 0),
6522 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6523 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6524 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
6525 offsetof(struct test_val, foo)),
6526 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6527 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6528 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6529 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6530 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6531 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6532 BPF_EXIT_INSN(),
6533 },
6534 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01006535 .errstr_unpriv = "R0 leaks addr",
Gianluca Borellof0318d02017-01-09 10:19:48 -08006536 .result = ACCEPT,
6537 .result_unpriv = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02006538 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Gianluca Borellof0318d02017-01-09 10:19:48 -08006539 },
Gianluca Borello06c1c042017-01-09 10:19:49 -08006540 {
6541 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
6542 .insns = {
6543 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6544 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6545 BPF_MOV64_IMM(BPF_REG_0, 0),
6546 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6547 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6548 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6549 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6550 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6551 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6552 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6553 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6554 BPF_MOV64_IMM(BPF_REG_2, 16),
6555 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6556 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6557 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6558 BPF_MOV64_IMM(BPF_REG_4, 0),
6559 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6560 BPF_MOV64_IMM(BPF_REG_3, 0),
6561 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6562 BPF_MOV64_IMM(BPF_REG_0, 0),
6563 BPF_EXIT_INSN(),
6564 },
6565 .result = ACCEPT,
6566 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6567 },
6568 {
6569 "helper access to variable memory: stack, bitwise AND, zero included",
6570 .insns = {
6571 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6573 BPF_MOV64_IMM(BPF_REG_2, 16),
6574 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6575 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6576 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6577 BPF_MOV64_IMM(BPF_REG_3, 0),
6578 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6579 BPF_EXIT_INSN(),
6580 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006581 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006582 .result = REJECT,
6583 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6584 },
6585 {
6586 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
6587 .insns = {
6588 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6589 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6590 BPF_MOV64_IMM(BPF_REG_2, 16),
6591 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6592 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6593 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
6594 BPF_MOV64_IMM(BPF_REG_4, 0),
6595 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6596 BPF_MOV64_IMM(BPF_REG_3, 0),
6597 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6598 BPF_MOV64_IMM(BPF_REG_0, 0),
6599 BPF_EXIT_INSN(),
6600 },
6601 .errstr = "invalid stack type R1 off=-64 access_size=65",
6602 .result = REJECT,
6603 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6604 },
6605 {
6606 "helper access to variable memory: stack, JMP, correct bounds",
6607 .insns = {
6608 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6609 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6610 BPF_MOV64_IMM(BPF_REG_0, 0),
6611 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6612 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6613 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6614 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6615 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6616 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6617 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6618 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6619 BPF_MOV64_IMM(BPF_REG_2, 16),
6620 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6621 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6622 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
6623 BPF_MOV64_IMM(BPF_REG_4, 0),
6624 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6625 BPF_MOV64_IMM(BPF_REG_3, 0),
6626 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6627 BPF_MOV64_IMM(BPF_REG_0, 0),
6628 BPF_EXIT_INSN(),
6629 },
6630 .result = ACCEPT,
6631 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6632 },
6633 {
6634 "helper access to variable memory: stack, JMP (signed), correct bounds",
6635 .insns = {
6636 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6638 BPF_MOV64_IMM(BPF_REG_0, 0),
6639 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
6640 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
6641 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
6642 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
6643 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
6644 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
6645 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
6646 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6647 BPF_MOV64_IMM(BPF_REG_2, 16),
6648 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6649 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6650 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
6651 BPF_MOV64_IMM(BPF_REG_4, 0),
6652 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
6653 BPF_MOV64_IMM(BPF_REG_3, 0),
6654 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6655 BPF_MOV64_IMM(BPF_REG_0, 0),
6656 BPF_EXIT_INSN(),
6657 },
6658 .result = ACCEPT,
6659 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6660 },
6661 {
6662 "helper access to variable memory: stack, JMP, bounds + offset",
6663 .insns = {
6664 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6665 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6666 BPF_MOV64_IMM(BPF_REG_2, 16),
6667 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6668 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6669 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
6670 BPF_MOV64_IMM(BPF_REG_4, 0),
6671 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
6672 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6673 BPF_MOV64_IMM(BPF_REG_3, 0),
6674 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6675 BPF_MOV64_IMM(BPF_REG_0, 0),
6676 BPF_EXIT_INSN(),
6677 },
6678 .errstr = "invalid stack type R1 off=-64 access_size=65",
6679 .result = REJECT,
6680 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6681 },
6682 {
6683 "helper access to variable memory: stack, JMP, wrong max",
6684 .insns = {
6685 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6686 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6687 BPF_MOV64_IMM(BPF_REG_2, 16),
6688 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6689 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6690 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
6691 BPF_MOV64_IMM(BPF_REG_4, 0),
6692 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6693 BPF_MOV64_IMM(BPF_REG_3, 0),
6694 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6695 BPF_MOV64_IMM(BPF_REG_0, 0),
6696 BPF_EXIT_INSN(),
6697 },
6698 .errstr = "invalid stack type R1 off=-64 access_size=65",
6699 .result = REJECT,
6700 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6701 },
6702 {
6703 "helper access to variable memory: stack, JMP, no max check",
6704 .insns = {
6705 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6707 BPF_MOV64_IMM(BPF_REG_2, 16),
6708 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6709 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6710 BPF_MOV64_IMM(BPF_REG_4, 0),
6711 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
6712 BPF_MOV64_IMM(BPF_REG_3, 0),
6713 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6714 BPF_MOV64_IMM(BPF_REG_0, 0),
6715 BPF_EXIT_INSN(),
6716 },
Edward Creef65b1842017-08-07 15:27:12 +01006717 /* because max wasn't checked, signed min is negative */
6718 .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006719 .result = REJECT,
6720 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6721 },
6722 {
6723 "helper access to variable memory: stack, JMP, no min check",
6724 .insns = {
6725 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6727 BPF_MOV64_IMM(BPF_REG_2, 16),
6728 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6729 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6730 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
6731 BPF_MOV64_IMM(BPF_REG_3, 0),
6732 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6733 BPF_MOV64_IMM(BPF_REG_0, 0),
6734 BPF_EXIT_INSN(),
6735 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006736 .errstr = "invalid indirect read from stack off -64+0 size 64",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006737 .result = REJECT,
6738 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6739 },
6740 {
6741 "helper access to variable memory: stack, JMP (signed), no min check",
6742 .insns = {
6743 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6745 BPF_MOV64_IMM(BPF_REG_2, 16),
6746 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
6747 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
6748 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
6749 BPF_MOV64_IMM(BPF_REG_3, 0),
6750 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6751 BPF_MOV64_IMM(BPF_REG_0, 0),
6752 BPF_EXIT_INSN(),
6753 },
6754 .errstr = "R2 min value is negative",
6755 .result = REJECT,
6756 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6757 },
6758 {
6759 "helper access to variable memory: map, JMP, correct bounds",
6760 .insns = {
6761 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6762 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6763 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6764 BPF_LD_MAP_FD(BPF_REG_1, 0),
6765 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6766 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6767 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6768 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6769 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6770 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6771 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6772 sizeof(struct test_val), 4),
6773 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006774 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006775 BPF_MOV64_IMM(BPF_REG_3, 0),
6776 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6777 BPF_MOV64_IMM(BPF_REG_0, 0),
6778 BPF_EXIT_INSN(),
6779 },
6780 .fixup_map2 = { 3 },
6781 .result = ACCEPT,
6782 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6783 },
6784 {
6785 "helper access to variable memory: map, JMP, wrong max",
6786 .insns = {
6787 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6788 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6789 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6790 BPF_LD_MAP_FD(BPF_REG_1, 0),
6791 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6792 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
6793 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6794 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6795 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6796 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6797 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6798 sizeof(struct test_val) + 1, 4),
6799 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006800 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006801 BPF_MOV64_IMM(BPF_REG_3, 0),
6802 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6803 BPF_MOV64_IMM(BPF_REG_0, 0),
6804 BPF_EXIT_INSN(),
6805 },
6806 .fixup_map2 = { 3 },
6807 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
6808 .result = REJECT,
6809 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6810 },
6811 {
6812 "helper access to variable memory: map adjusted, JMP, correct bounds",
6813 .insns = {
6814 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6815 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6816 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6817 BPF_LD_MAP_FD(BPF_REG_1, 0),
6818 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
6820 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6821 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6822 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6823 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6824 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6825 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6826 sizeof(struct test_val) - 20, 4),
6827 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006828 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006829 BPF_MOV64_IMM(BPF_REG_3, 0),
6830 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6831 BPF_MOV64_IMM(BPF_REG_0, 0),
6832 BPF_EXIT_INSN(),
6833 },
6834 .fixup_map2 = { 3 },
6835 .result = ACCEPT,
6836 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6837 },
6838 {
6839 "helper access to variable memory: map adjusted, JMP, wrong max",
6840 .insns = {
6841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6843 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
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, 11),
6847 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6848 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
6849 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
6850 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6851 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
6852 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
6853 sizeof(struct test_val) - 19, 4),
6854 BPF_MOV64_IMM(BPF_REG_4, 0),
Daniel Borkmanna1502132017-07-21 00:00:23 +02006855 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006856 BPF_MOV64_IMM(BPF_REG_3, 0),
6857 BPF_EMIT_CALL(BPF_FUNC_probe_read),
6858 BPF_MOV64_IMM(BPF_REG_0, 0),
6859 BPF_EXIT_INSN(),
6860 },
6861 .fixup_map2 = { 3 },
6862 .errstr = "R1 min value is outside of the array range",
6863 .result = REJECT,
6864 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6865 },
6866 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006867 "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Edward Creef65b1842017-08-07 15:27:12 +01006868 .insns = {
6869 BPF_MOV64_IMM(BPF_REG_1, 0),
6870 BPF_MOV64_IMM(BPF_REG_2, 0),
6871 BPF_MOV64_IMM(BPF_REG_3, 0),
6872 BPF_MOV64_IMM(BPF_REG_4, 0),
6873 BPF_MOV64_IMM(BPF_REG_5, 0),
6874 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6875 BPF_EXIT_INSN(),
6876 },
6877 .result = ACCEPT,
6878 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6879 },
6880 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006881 "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006882 .insns = {
6883 BPF_MOV64_IMM(BPF_REG_1, 0),
Alexei Starovoitovd98588c2017-12-14 17:55:09 -08006884 BPF_MOV64_IMM(BPF_REG_2, 1),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01006885 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
6886 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08006887 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
6888 BPF_MOV64_IMM(BPF_REG_3, 0),
6889 BPF_MOV64_IMM(BPF_REG_4, 0),
6890 BPF_MOV64_IMM(BPF_REG_5, 0),
6891 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6892 BPF_EXIT_INSN(),
6893 },
Edward Creef65b1842017-08-07 15:27:12 +01006894 .errstr = "R1 type=inv expected=fp",
Gianluca Borello06c1c042017-01-09 10:19:49 -08006895 .result = REJECT,
6896 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6897 },
6898 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006899 "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 -08006900 .insns = {
6901 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6902 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6903 BPF_MOV64_IMM(BPF_REG_2, 0),
6904 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6905 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
6906 BPF_MOV64_IMM(BPF_REG_3, 0),
6907 BPF_MOV64_IMM(BPF_REG_4, 0),
6908 BPF_MOV64_IMM(BPF_REG_5, 0),
6909 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6910 BPF_EXIT_INSN(),
6911 },
Yonghong Songb6ff6392017-11-12 14:49:11 -08006912 .result = ACCEPT,
6913 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6914 },
6915 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006916 "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 -08006917 .insns = {
6918 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6919 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6920 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6921 BPF_LD_MAP_FD(BPF_REG_1, 0),
6922 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6923 BPF_FUNC_map_lookup_elem),
6924 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6925 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6926 BPF_MOV64_IMM(BPF_REG_2, 0),
6927 BPF_MOV64_IMM(BPF_REG_3, 0),
6928 BPF_MOV64_IMM(BPF_REG_4, 0),
6929 BPF_MOV64_IMM(BPF_REG_5, 0),
6930 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6931 BPF_EXIT_INSN(),
6932 },
6933 .fixup_map1 = { 3 },
6934 .result = ACCEPT,
6935 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6936 },
6937 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006938 "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 -08006939 .insns = {
6940 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6941 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6943 BPF_LD_MAP_FD(BPF_REG_1, 0),
6944 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6945 BPF_FUNC_map_lookup_elem),
6946 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6947 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6948 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
6949 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6950 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6951 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6952 BPF_MOV64_IMM(BPF_REG_3, 0),
6953 BPF_MOV64_IMM(BPF_REG_4, 0),
6954 BPF_MOV64_IMM(BPF_REG_5, 0),
6955 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6956 BPF_EXIT_INSN(),
6957 },
6958 .fixup_map1 = { 3 },
6959 .result = ACCEPT,
6960 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6961 },
6962 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006963 "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 -08006964 .insns = {
6965 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6966 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6968 BPF_LD_MAP_FD(BPF_REG_1, 0),
6969 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6970 BPF_FUNC_map_lookup_elem),
6971 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6972 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6973 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6974 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6975 BPF_MOV64_IMM(BPF_REG_3, 0),
6976 BPF_MOV64_IMM(BPF_REG_4, 0),
6977 BPF_MOV64_IMM(BPF_REG_5, 0),
6978 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6979 BPF_EXIT_INSN(),
6980 },
6981 .fixup_map1 = { 3 },
6982 .result = ACCEPT,
6983 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6984 },
6985 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00006986 "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 -08006987 .insns = {
6988 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6989 offsetof(struct __sk_buff, data)),
6990 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6991 offsetof(struct __sk_buff, data_end)),
6992 BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
6993 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
6994 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
6995 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
6996 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
6997 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6998 BPF_MOV64_IMM(BPF_REG_3, 0),
6999 BPF_MOV64_IMM(BPF_REG_4, 0),
7000 BPF_MOV64_IMM(BPF_REG_5, 0),
7001 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
7002 BPF_EXIT_INSN(),
7003 },
7004 .result = ACCEPT,
Gianluca Borello06c1c042017-01-09 10:19:49 -08007005 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08007006 .retval = 0 /* csum_diff of 64-byte packet */,
Gianluca Borello06c1c042017-01-09 10:19:49 -08007007 },
7008 {
Gianluca Borellodb1ac492017-11-22 18:32:53 +00007009 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
7010 .insns = {
7011 BPF_MOV64_IMM(BPF_REG_1, 0),
7012 BPF_MOV64_IMM(BPF_REG_2, 0),
7013 BPF_MOV64_IMM(BPF_REG_3, 0),
7014 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7015 BPF_EXIT_INSN(),
7016 },
7017 .errstr = "R1 type=inv expected=fp",
7018 .result = REJECT,
7019 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7020 },
7021 {
7022 "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
7023 .insns = {
7024 BPF_MOV64_IMM(BPF_REG_1, 0),
7025 BPF_MOV64_IMM(BPF_REG_2, 1),
7026 BPF_MOV64_IMM(BPF_REG_3, 0),
7027 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7028 BPF_EXIT_INSN(),
7029 },
7030 .errstr = "R1 type=inv expected=fp",
7031 .result = REJECT,
7032 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7033 },
7034 {
7035 "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7036 .insns = {
7037 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7038 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7039 BPF_MOV64_IMM(BPF_REG_2, 0),
7040 BPF_MOV64_IMM(BPF_REG_3, 0),
7041 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7042 BPF_EXIT_INSN(),
7043 },
7044 .result = ACCEPT,
7045 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7046 },
7047 {
7048 "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7049 .insns = {
7050 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7051 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7053 BPF_LD_MAP_FD(BPF_REG_1, 0),
7054 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7055 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7056 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7057 BPF_MOV64_IMM(BPF_REG_2, 0),
7058 BPF_MOV64_IMM(BPF_REG_3, 0),
7059 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7060 BPF_EXIT_INSN(),
7061 },
7062 .fixup_map1 = { 3 },
7063 .result = ACCEPT,
7064 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7065 },
7066 {
7067 "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7068 .insns = {
7069 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7070 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7072 BPF_LD_MAP_FD(BPF_REG_1, 0),
7073 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7074 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7075 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7076 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
7077 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
7079 BPF_MOV64_IMM(BPF_REG_3, 0),
7080 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7081 BPF_EXIT_INSN(),
7082 },
7083 .fixup_map1 = { 3 },
7084 .result = ACCEPT,
7085 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7086 },
7087 {
7088 "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
7089 .insns = {
7090 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7091 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7093 BPF_LD_MAP_FD(BPF_REG_1, 0),
7094 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
7095 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7096 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7097 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
7098 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
7099 BPF_MOV64_IMM(BPF_REG_3, 0),
7100 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7101 BPF_EXIT_INSN(),
7102 },
7103 .fixup_map1 = { 3 },
7104 .result = ACCEPT,
7105 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7106 },
7107 {
Gianluca Borello06c1c042017-01-09 10:19:49 -08007108 "helper access to variable memory: 8 bytes leak",
7109 .insns = {
7110 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7112 BPF_MOV64_IMM(BPF_REG_0, 0),
7113 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7114 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7115 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7116 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7117 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7118 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7119 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
Alexei Starovoitovd98588c2017-12-14 17:55:09 -08007120 BPF_MOV64_IMM(BPF_REG_2, 1),
Daniel Borkmann3fadc802017-01-24 01:06:30 +01007121 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
7122 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
Gianluca Borello06c1c042017-01-09 10:19:49 -08007123 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
7124 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
7125 BPF_MOV64_IMM(BPF_REG_3, 0),
7126 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7127 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7128 BPF_EXIT_INSN(),
7129 },
7130 .errstr = "invalid indirect read from stack off -64+32 size 64",
7131 .result = REJECT,
7132 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7133 },
7134 {
7135 "helper access to variable memory: 8 bytes no leak (init memory)",
7136 .insns = {
7137 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
7138 BPF_MOV64_IMM(BPF_REG_0, 0),
7139 BPF_MOV64_IMM(BPF_REG_0, 0),
7140 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
7141 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
7142 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
7143 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
7144 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
7145 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
7146 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
7147 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
7148 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
7149 BPF_MOV64_IMM(BPF_REG_2, 0),
7150 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
7151 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
7152 BPF_MOV64_IMM(BPF_REG_3, 0),
7153 BPF_EMIT_CALL(BPF_FUNC_probe_read),
7154 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7155 BPF_EXIT_INSN(),
7156 },
7157 .result = ACCEPT,
7158 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
7159 },
Josef Bacik29200c12017-02-03 16:25:23 -05007160 {
7161 "invalid and of negative number",
7162 .insns = {
7163 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7164 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7165 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7166 BPF_LD_MAP_FD(BPF_REG_1, 0),
7167 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7168 BPF_FUNC_map_lookup_elem),
7169 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
Edward Creef65b1842017-08-07 15:27:12 +01007170 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
Josef Bacik29200c12017-02-03 16:25:23 -05007171 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
7172 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
7173 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7174 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
7175 offsetof(struct test_val, foo)),
7176 BPF_EXIT_INSN(),
7177 },
7178 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007179 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05007180 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02007181 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Josef Bacik29200c12017-02-03 16:25:23 -05007182 },
7183 {
7184 "invalid range check",
7185 .insns = {
7186 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7187 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7189 BPF_LD_MAP_FD(BPF_REG_1, 0),
7190 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7191 BPF_FUNC_map_lookup_elem),
7192 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
7193 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
7194 BPF_MOV64_IMM(BPF_REG_9, 1),
7195 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
7196 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
7197 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
7198 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
7199 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
7200 BPF_MOV32_IMM(BPF_REG_3, 1),
7201 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
7202 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
7203 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
7204 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
7205 BPF_MOV64_REG(BPF_REG_0, 0),
7206 BPF_EXIT_INSN(),
7207 },
7208 .fixup_map2 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007209 .errstr = "R0 max value is outside of the array range",
Josef Bacik29200c12017-02-03 16:25:23 -05007210 .result = REJECT,
Daniel Borkmann02ea80b2017-03-31 02:24:04 +02007211 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007212 },
7213 {
7214 "map in map access",
7215 .insns = {
7216 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7217 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7219 BPF_LD_MAP_FD(BPF_REG_1, 0),
7220 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7221 BPF_FUNC_map_lookup_elem),
7222 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
7223 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7224 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7225 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7226 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7227 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7228 BPF_FUNC_map_lookup_elem),
Roman Gushchin0069fb82018-08-02 15:47:10 -07007229 BPF_MOV64_IMM(BPF_REG_0, 0),
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007230 BPF_EXIT_INSN(),
7231 },
7232 .fixup_map_in_map = { 3 },
7233 .result = ACCEPT,
7234 },
7235 {
7236 "invalid inner map pointer",
7237 .insns = {
7238 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7239 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7240 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7241 BPF_LD_MAP_FD(BPF_REG_1, 0),
7242 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7243 BPF_FUNC_map_lookup_elem),
7244 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7245 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7246 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7248 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7249 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7250 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7251 BPF_FUNC_map_lookup_elem),
Roman Gushchin0069fb82018-08-02 15:47:10 -07007252 BPF_MOV64_IMM(BPF_REG_0, 0),
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007253 BPF_EXIT_INSN(),
7254 },
7255 .fixup_map_in_map = { 3 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07007256 .errstr = "R1 pointer arithmetic on map_ptr prohibited",
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007257 .result = REJECT,
7258 },
7259 {
7260 "forgot null checking on the inner map pointer",
7261 .insns = {
7262 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7263 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7264 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7265 BPF_LD_MAP_FD(BPF_REG_1, 0),
7266 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7267 BPF_FUNC_map_lookup_elem),
7268 BPF_ST_MEM(0, BPF_REG_10, -4, 0),
7269 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7271 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7272 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7273 BPF_FUNC_map_lookup_elem),
Roman Gushchin0069fb82018-08-02 15:47:10 -07007274 BPF_MOV64_IMM(BPF_REG_0, 0),
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -07007275 BPF_EXIT_INSN(),
7276 },
7277 .fixup_map_in_map = { 3 },
7278 .errstr = "R1 type=map_value_or_null expected=map_ptr",
7279 .result = REJECT,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007280 },
7281 {
7282 "ld_abs: check calling conv, r1",
7283 .insns = {
7284 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7285 BPF_MOV64_IMM(BPF_REG_1, 0),
7286 BPF_LD_ABS(BPF_W, -0x200000),
7287 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7288 BPF_EXIT_INSN(),
7289 },
7290 .errstr = "R1 !read_ok",
7291 .result = REJECT,
7292 },
7293 {
7294 "ld_abs: check calling conv, r2",
7295 .insns = {
7296 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7297 BPF_MOV64_IMM(BPF_REG_2, 0),
7298 BPF_LD_ABS(BPF_W, -0x200000),
7299 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7300 BPF_EXIT_INSN(),
7301 },
7302 .errstr = "R2 !read_ok",
7303 .result = REJECT,
7304 },
7305 {
7306 "ld_abs: check calling conv, r3",
7307 .insns = {
7308 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7309 BPF_MOV64_IMM(BPF_REG_3, 0),
7310 BPF_LD_ABS(BPF_W, -0x200000),
7311 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7312 BPF_EXIT_INSN(),
7313 },
7314 .errstr = "R3 !read_ok",
7315 .result = REJECT,
7316 },
7317 {
7318 "ld_abs: check calling conv, r4",
7319 .insns = {
7320 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7321 BPF_MOV64_IMM(BPF_REG_4, 0),
7322 BPF_LD_ABS(BPF_W, -0x200000),
7323 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7324 BPF_EXIT_INSN(),
7325 },
7326 .errstr = "R4 !read_ok",
7327 .result = REJECT,
7328 },
7329 {
7330 "ld_abs: check calling conv, r5",
7331 .insns = {
7332 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7333 BPF_MOV64_IMM(BPF_REG_5, 0),
7334 BPF_LD_ABS(BPF_W, -0x200000),
7335 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7336 BPF_EXIT_INSN(),
7337 },
7338 .errstr = "R5 !read_ok",
7339 .result = REJECT,
7340 },
7341 {
7342 "ld_abs: check calling conv, r7",
7343 .insns = {
7344 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7345 BPF_MOV64_IMM(BPF_REG_7, 0),
7346 BPF_LD_ABS(BPF_W, -0x200000),
7347 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7348 BPF_EXIT_INSN(),
7349 },
7350 .result = ACCEPT,
7351 },
7352 {
Daniel Borkmann87ab8192017-12-14 21:07:27 +01007353 "ld_abs: tests on r6 and skb data reload helper",
7354 .insns = {
7355 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7356 BPF_LD_ABS(BPF_B, 0),
7357 BPF_LD_ABS(BPF_H, 0),
7358 BPF_LD_ABS(BPF_W, 0),
7359 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
7360 BPF_MOV64_IMM(BPF_REG_6, 0),
7361 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
7362 BPF_MOV64_IMM(BPF_REG_2, 1),
7363 BPF_MOV64_IMM(BPF_REG_3, 2),
7364 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7365 BPF_FUNC_skb_vlan_push),
7366 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
7367 BPF_LD_ABS(BPF_B, 0),
7368 BPF_LD_ABS(BPF_H, 0),
7369 BPF_LD_ABS(BPF_W, 0),
7370 BPF_MOV64_IMM(BPF_REG_0, 42),
7371 BPF_EXIT_INSN(),
7372 },
7373 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7374 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08007375 .retval = 42 /* ultimate return value */,
Daniel Borkmann87ab8192017-12-14 21:07:27 +01007376 },
7377 {
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007378 "ld_ind: check calling conv, r1",
7379 .insns = {
7380 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7381 BPF_MOV64_IMM(BPF_REG_1, 1),
7382 BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
7383 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7384 BPF_EXIT_INSN(),
7385 },
7386 .errstr = "R1 !read_ok",
7387 .result = REJECT,
7388 },
7389 {
7390 "ld_ind: check calling conv, r2",
7391 .insns = {
7392 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7393 BPF_MOV64_IMM(BPF_REG_2, 1),
7394 BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
7395 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7396 BPF_EXIT_INSN(),
7397 },
7398 .errstr = "R2 !read_ok",
7399 .result = REJECT,
7400 },
7401 {
7402 "ld_ind: check calling conv, r3",
7403 .insns = {
7404 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7405 BPF_MOV64_IMM(BPF_REG_3, 1),
7406 BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
7407 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7408 BPF_EXIT_INSN(),
7409 },
7410 .errstr = "R3 !read_ok",
7411 .result = REJECT,
7412 },
7413 {
7414 "ld_ind: check calling conv, r4",
7415 .insns = {
7416 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7417 BPF_MOV64_IMM(BPF_REG_4, 1),
7418 BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
7419 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7420 BPF_EXIT_INSN(),
7421 },
7422 .errstr = "R4 !read_ok",
7423 .result = REJECT,
7424 },
7425 {
7426 "ld_ind: check calling conv, r5",
7427 .insns = {
7428 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7429 BPF_MOV64_IMM(BPF_REG_5, 1),
7430 BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
7431 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7432 BPF_EXIT_INSN(),
7433 },
7434 .errstr = "R5 !read_ok",
7435 .result = REJECT,
7436 },
7437 {
7438 "ld_ind: check calling conv, r7",
7439 .insns = {
7440 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7441 BPF_MOV64_IMM(BPF_REG_7, 1),
7442 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
7443 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7444 BPF_EXIT_INSN(),
7445 },
7446 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08007447 .retval = 1,
Daniel Borkmann614d0d72017-05-25 01:05:09 +02007448 },
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007449 {
7450 "check bpf_perf_event_data->sample_period byte load permitted",
7451 .insns = {
7452 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007453#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007454 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7455 offsetof(struct bpf_perf_event_data, sample_period)),
7456#else
7457 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
7458 offsetof(struct bpf_perf_event_data, sample_period) + 7),
7459#endif
7460 BPF_EXIT_INSN(),
7461 },
7462 .result = ACCEPT,
7463 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7464 },
7465 {
7466 "check bpf_perf_event_data->sample_period half load permitted",
7467 .insns = {
7468 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007469#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007470 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7471 offsetof(struct bpf_perf_event_data, sample_period)),
7472#else
7473 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7474 offsetof(struct bpf_perf_event_data, sample_period) + 6),
7475#endif
7476 BPF_EXIT_INSN(),
7477 },
7478 .result = ACCEPT,
7479 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7480 },
7481 {
7482 "check bpf_perf_event_data->sample_period word load permitted",
7483 .insns = {
7484 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007485#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007486 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7487 offsetof(struct bpf_perf_event_data, sample_period)),
7488#else
7489 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
7490 offsetof(struct bpf_perf_event_data, sample_period) + 4),
7491#endif
7492 BPF_EXIT_INSN(),
7493 },
7494 .result = ACCEPT,
7495 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7496 },
7497 {
7498 "check bpf_perf_event_data->sample_period dword load permitted",
7499 .insns = {
7500 BPF_MOV64_IMM(BPF_REG_0, 0),
7501 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
7502 offsetof(struct bpf_perf_event_data, sample_period)),
7503 BPF_EXIT_INSN(),
7504 },
7505 .result = ACCEPT,
7506 .prog_type = BPF_PROG_TYPE_PERF_EVENT,
7507 },
7508 {
7509 "check skb->data half load not permitted",
7510 .insns = {
7511 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007512#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007513 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7514 offsetof(struct __sk_buff, data)),
7515#else
7516 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7517 offsetof(struct __sk_buff, data) + 2),
7518#endif
7519 BPF_EXIT_INSN(),
7520 },
7521 .result = REJECT,
7522 .errstr = "invalid bpf_context access",
7523 },
7524 {
7525 "check skb->tc_classid half load not permitted for lwt prog",
7526 .insns = {
7527 BPF_MOV64_IMM(BPF_REG_0, 0),
Daniel Borkmann2c460622017-08-04 22:24:41 +02007528#if __BYTE_ORDER == __LITTLE_ENDIAN
Yonghong Song18f3d6b2017-06-13 15:52:14 -07007529 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7530 offsetof(struct __sk_buff, tc_classid)),
7531#else
7532 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
7533 offsetof(struct __sk_buff, tc_classid) + 2),
7534#endif
7535 BPF_EXIT_INSN(),
7536 },
7537 .result = REJECT,
7538 .errstr = "invalid bpf_context access",
7539 .prog_type = BPF_PROG_TYPE_LWT_IN,
7540 },
Edward Creeb7122962017-07-21 00:00:24 +02007541 {
7542 "bounds checks mixing signed and unsigned, positive bounds",
7543 .insns = {
7544 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7545 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7546 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7547 BPF_LD_MAP_FD(BPF_REG_1, 0),
7548 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7549 BPF_FUNC_map_lookup_elem),
7550 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7551 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7552 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7553 BPF_MOV64_IMM(BPF_REG_2, 2),
7554 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
7555 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
7556 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7557 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7558 BPF_MOV64_IMM(BPF_REG_0, 0),
7559 BPF_EXIT_INSN(),
7560 },
7561 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007562 .errstr = "unbounded min value",
Edward Creeb7122962017-07-21 00:00:24 +02007563 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02007564 },
7565 {
7566 "bounds checks mixing signed and unsigned",
7567 .insns = {
7568 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7569 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7570 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7571 BPF_LD_MAP_FD(BPF_REG_1, 0),
7572 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7573 BPF_FUNC_map_lookup_elem),
7574 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7575 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7576 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7577 BPF_MOV64_IMM(BPF_REG_2, -1),
7578 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7579 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7580 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7581 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7582 BPF_MOV64_IMM(BPF_REG_0, 0),
7583 BPF_EXIT_INSN(),
7584 },
7585 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007586 .errstr = "unbounded min value",
Edward Creeb7122962017-07-21 00:00:24 +02007587 .result = REJECT,
Edward Creeb7122962017-07-21 00:00:24 +02007588 },
Daniel Borkmann86412502017-07-21 00:00:25 +02007589 {
7590 "bounds checks mixing signed and unsigned, variant 2",
7591 .insns = {
7592 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7593 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7594 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7595 BPF_LD_MAP_FD(BPF_REG_1, 0),
7596 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7597 BPF_FUNC_map_lookup_elem),
7598 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7599 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7600 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7601 BPF_MOV64_IMM(BPF_REG_2, -1),
7602 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7603 BPF_MOV64_IMM(BPF_REG_8, 0),
7604 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
7605 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7606 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7607 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7608 BPF_MOV64_IMM(BPF_REG_0, 0),
7609 BPF_EXIT_INSN(),
7610 },
7611 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007612 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007613 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007614 },
7615 {
7616 "bounds checks mixing signed and unsigned, variant 3",
7617 .insns = {
7618 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7619 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7620 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7621 BPF_LD_MAP_FD(BPF_REG_1, 0),
7622 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7623 BPF_FUNC_map_lookup_elem),
7624 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7625 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7626 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7627 BPF_MOV64_IMM(BPF_REG_2, -1),
7628 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
7629 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
7630 BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
7631 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
7632 BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
7633 BPF_MOV64_IMM(BPF_REG_0, 0),
7634 BPF_EXIT_INSN(),
7635 },
7636 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007637 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007638 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007639 },
7640 {
7641 "bounds checks mixing signed and unsigned, variant 4",
7642 .insns = {
7643 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7644 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7645 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7646 BPF_LD_MAP_FD(BPF_REG_1, 0),
7647 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7648 BPF_FUNC_map_lookup_elem),
7649 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7650 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7651 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7652 BPF_MOV64_IMM(BPF_REG_2, 1),
7653 BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
7654 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7655 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7656 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7657 BPF_MOV64_IMM(BPF_REG_0, 0),
7658 BPF_EXIT_INSN(),
7659 },
7660 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007661 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007662 },
7663 {
7664 "bounds checks mixing signed and unsigned, variant 5",
7665 .insns = {
7666 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7667 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7668 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7669 BPF_LD_MAP_FD(BPF_REG_1, 0),
7670 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7671 BPF_FUNC_map_lookup_elem),
7672 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7673 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7674 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7675 BPF_MOV64_IMM(BPF_REG_2, -1),
7676 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
7677 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
7678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
7679 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
7680 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7681 BPF_MOV64_IMM(BPF_REG_0, 0),
7682 BPF_EXIT_INSN(),
7683 },
7684 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007685 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007686 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007687 },
7688 {
7689 "bounds checks mixing signed and unsigned, variant 6",
7690 .insns = {
7691 BPF_MOV64_IMM(BPF_REG_2, 0),
7692 BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
7693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
7694 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7695 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
7696 BPF_MOV64_IMM(BPF_REG_6, -1),
7697 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
7698 BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
7699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
7700 BPF_MOV64_IMM(BPF_REG_5, 0),
7701 BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
7702 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7703 BPF_FUNC_skb_load_bytes),
7704 BPF_MOV64_IMM(BPF_REG_0, 0),
7705 BPF_EXIT_INSN(),
7706 },
Daniel Borkmann86412502017-07-21 00:00:25 +02007707 .errstr = "R4 min value is negative, either use unsigned",
7708 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007709 },
7710 {
7711 "bounds checks mixing signed and unsigned, variant 7",
7712 .insns = {
7713 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7714 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7715 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7716 BPF_LD_MAP_FD(BPF_REG_1, 0),
7717 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7718 BPF_FUNC_map_lookup_elem),
7719 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7720 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7721 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7722 BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
7723 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7724 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7725 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7726 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7727 BPF_MOV64_IMM(BPF_REG_0, 0),
7728 BPF_EXIT_INSN(),
7729 },
7730 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007731 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007732 },
7733 {
7734 "bounds checks mixing signed and unsigned, variant 8",
7735 .insns = {
7736 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7737 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7739 BPF_LD_MAP_FD(BPF_REG_1, 0),
7740 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7741 BPF_FUNC_map_lookup_elem),
Daniel Borkmann86412502017-07-21 00:00:25 +02007742 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7743 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7744 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7745 BPF_MOV64_IMM(BPF_REG_2, -1),
7746 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7747 BPF_MOV64_IMM(BPF_REG_0, 0),
7748 BPF_EXIT_INSN(),
7749 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7750 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7751 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7752 BPF_MOV64_IMM(BPF_REG_0, 0),
7753 BPF_EXIT_INSN(),
7754 },
7755 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007756 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007757 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007758 },
7759 {
Edward Creef65b1842017-08-07 15:27:12 +01007760 "bounds checks mixing signed and unsigned, variant 9",
Daniel Borkmann86412502017-07-21 00:00:25 +02007761 .insns = {
7762 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7763 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7764 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7765 BPF_LD_MAP_FD(BPF_REG_1, 0),
7766 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7767 BPF_FUNC_map_lookup_elem),
7768 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
7769 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7770 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7771 BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
7772 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7773 BPF_MOV64_IMM(BPF_REG_0, 0),
7774 BPF_EXIT_INSN(),
7775 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7776 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7777 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7778 BPF_MOV64_IMM(BPF_REG_0, 0),
7779 BPF_EXIT_INSN(),
7780 },
7781 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007782 .result = ACCEPT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007783 },
7784 {
Edward Creef65b1842017-08-07 15:27:12 +01007785 "bounds checks mixing signed and unsigned, variant 10",
Daniel Borkmann86412502017-07-21 00:00:25 +02007786 .insns = {
7787 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7788 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7789 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7790 BPF_LD_MAP_FD(BPF_REG_1, 0),
7791 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7792 BPF_FUNC_map_lookup_elem),
7793 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7794 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7795 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7796 BPF_MOV64_IMM(BPF_REG_2, 0),
7797 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
7798 BPF_MOV64_IMM(BPF_REG_0, 0),
7799 BPF_EXIT_INSN(),
7800 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7801 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7802 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7803 BPF_MOV64_IMM(BPF_REG_0, 0),
7804 BPF_EXIT_INSN(),
7805 },
7806 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007807 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007808 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007809 },
7810 {
Edward Creef65b1842017-08-07 15:27:12 +01007811 "bounds checks mixing signed and unsigned, variant 11",
Daniel Borkmann86412502017-07-21 00:00:25 +02007812 .insns = {
7813 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7814 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7815 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7816 BPF_LD_MAP_FD(BPF_REG_1, 0),
7817 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7818 BPF_FUNC_map_lookup_elem),
7819 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7820 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7821 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7822 BPF_MOV64_IMM(BPF_REG_2, -1),
7823 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7824 /* Dead branch. */
7825 BPF_MOV64_IMM(BPF_REG_0, 0),
7826 BPF_EXIT_INSN(),
7827 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7828 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7829 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7830 BPF_MOV64_IMM(BPF_REG_0, 0),
7831 BPF_EXIT_INSN(),
7832 },
7833 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007834 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007835 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007836 },
7837 {
Edward Creef65b1842017-08-07 15:27:12 +01007838 "bounds checks mixing signed and unsigned, variant 12",
Daniel Borkmann86412502017-07-21 00:00:25 +02007839 .insns = {
7840 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7841 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7843 BPF_LD_MAP_FD(BPF_REG_1, 0),
7844 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7845 BPF_FUNC_map_lookup_elem),
7846 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7847 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7848 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7849 BPF_MOV64_IMM(BPF_REG_2, -6),
7850 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7851 BPF_MOV64_IMM(BPF_REG_0, 0),
7852 BPF_EXIT_INSN(),
7853 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7854 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7855 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7856 BPF_MOV64_IMM(BPF_REG_0, 0),
7857 BPF_EXIT_INSN(),
7858 },
7859 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007860 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007861 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007862 },
7863 {
Edward Creef65b1842017-08-07 15:27:12 +01007864 "bounds checks mixing signed and unsigned, variant 13",
Daniel Borkmann86412502017-07-21 00:00:25 +02007865 .insns = {
7866 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7867 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7869 BPF_LD_MAP_FD(BPF_REG_1, 0),
7870 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7871 BPF_FUNC_map_lookup_elem),
7872 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
7873 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7874 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7875 BPF_MOV64_IMM(BPF_REG_2, 2),
7876 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7877 BPF_MOV64_IMM(BPF_REG_7, 1),
7878 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
7879 BPF_MOV64_IMM(BPF_REG_0, 0),
7880 BPF_EXIT_INSN(),
7881 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
7882 BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
7883 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
7884 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7885 BPF_MOV64_IMM(BPF_REG_0, 0),
7886 BPF_EXIT_INSN(),
7887 },
7888 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007889 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007890 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007891 },
7892 {
Edward Creef65b1842017-08-07 15:27:12 +01007893 "bounds checks mixing signed and unsigned, variant 14",
Daniel Borkmann86412502017-07-21 00:00:25 +02007894 .insns = {
7895 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
7896 offsetof(struct __sk_buff, mark)),
7897 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7898 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7899 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7900 BPF_LD_MAP_FD(BPF_REG_1, 0),
7901 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7902 BPF_FUNC_map_lookup_elem),
7903 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7904 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7905 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7906 BPF_MOV64_IMM(BPF_REG_2, -1),
7907 BPF_MOV64_IMM(BPF_REG_8, 2),
7908 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
7909 BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
7910 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7911 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7912 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7913 BPF_MOV64_IMM(BPF_REG_0, 0),
7914 BPF_EXIT_INSN(),
7915 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
7916 BPF_JMP_IMM(BPF_JA, 0, 0, -7),
7917 },
7918 .fixup_map1 = { 4 },
Daniel Borkmann6f161012018-01-18 01:15:21 +01007919 .errstr = "R0 invalid mem access 'inv'",
Daniel Borkmann86412502017-07-21 00:00:25 +02007920 .result = REJECT,
Daniel Borkmann86412502017-07-21 00:00:25 +02007921 },
7922 {
Edward Creef65b1842017-08-07 15:27:12 +01007923 "bounds checks mixing signed and unsigned, variant 15",
Daniel Borkmann86412502017-07-21 00:00:25 +02007924 .insns = {
7925 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7926 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7927 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7928 BPF_LD_MAP_FD(BPF_REG_1, 0),
7929 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7930 BPF_FUNC_map_lookup_elem),
7931 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
7932 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7933 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7934 BPF_MOV64_IMM(BPF_REG_2, -6),
7935 BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
7936 BPF_MOV64_IMM(BPF_REG_0, 0),
7937 BPF_EXIT_INSN(),
7938 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7939 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
7940 BPF_MOV64_IMM(BPF_REG_0, 0),
7941 BPF_EXIT_INSN(),
7942 BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7943 BPF_MOV64_IMM(BPF_REG_0, 0),
7944 BPF_EXIT_INSN(),
7945 },
7946 .fixup_map1 = { 3 },
Jann Horn2255f8d2017-12-18 20:12:01 -08007947 .errstr = "unbounded min value",
Daniel Borkmann86412502017-07-21 00:00:25 +02007948 .result = REJECT,
7949 .result_unpriv = REJECT,
7950 },
Edward Cree545722c2017-07-21 14:36:57 +01007951 {
Edward Creef65b1842017-08-07 15:27:12 +01007952 "subtraction bounds (map value) variant 1",
Edward Cree545722c2017-07-21 14:36:57 +01007953 .insns = {
7954 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7955 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7956 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7957 BPF_LD_MAP_FD(BPF_REG_1, 0),
7958 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7959 BPF_FUNC_map_lookup_elem),
7960 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7961 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7962 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
7963 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7964 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
7965 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7966 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
7967 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7968 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7969 BPF_EXIT_INSN(),
7970 BPF_MOV64_IMM(BPF_REG_0, 0),
7971 BPF_EXIT_INSN(),
7972 },
7973 .fixup_map1 = { 3 },
Edward Creef65b1842017-08-07 15:27:12 +01007974 .errstr = "R0 max value is outside of the array range",
7975 .result = REJECT,
7976 },
7977 {
7978 "subtraction bounds (map value) variant 2",
7979 .insns = {
7980 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7981 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7982 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7983 BPF_LD_MAP_FD(BPF_REG_1, 0),
7984 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7985 BPF_FUNC_map_lookup_elem),
7986 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7987 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7988 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
7989 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7990 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
7991 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7992 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7993 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7994 BPF_EXIT_INSN(),
7995 BPF_MOV64_IMM(BPF_REG_0, 0),
7996 BPF_EXIT_INSN(),
7997 },
7998 .fixup_map1 = { 3 },
Edward Cree545722c2017-07-21 14:36:57 +01007999 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
8000 .result = REJECT,
Edward Cree545722c2017-07-21 14:36:57 +01008001 },
Edward Cree69c4e8a2017-08-07 15:29:51 +01008002 {
Jann Horn2255f8d2017-12-18 20:12:01 -08008003 "bounds check based on zero-extended MOV",
8004 .insns = {
8005 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8006 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8008 BPF_LD_MAP_FD(BPF_REG_1, 0),
8009 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8010 BPF_FUNC_map_lookup_elem),
8011 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8012 /* r2 = 0x0000'0000'ffff'ffff */
8013 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
8014 /* r2 = 0 */
8015 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
8016 /* no-op */
8017 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8018 /* access at offset 0 */
8019 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8020 /* exit */
8021 BPF_MOV64_IMM(BPF_REG_0, 0),
8022 BPF_EXIT_INSN(),
8023 },
8024 .fixup_map1 = { 3 },
8025 .result = ACCEPT
8026 },
8027 {
8028 "bounds check based on sign-extended MOV. test1",
8029 .insns = {
8030 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8031 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8032 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8033 BPF_LD_MAP_FD(BPF_REG_1, 0),
8034 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8035 BPF_FUNC_map_lookup_elem),
8036 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8037 /* r2 = 0xffff'ffff'ffff'ffff */
8038 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
8039 /* r2 = 0xffff'ffff */
8040 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
8041 /* r0 = <oob pointer> */
8042 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8043 /* access to OOB pointer */
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 = "map_value pointer and 4294967295",
8051 .result = REJECT
8052 },
8053 {
8054 "bounds check based on sign-extended MOV. test2",
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, 4),
8063 /* r2 = 0xffff'ffff'ffff'ffff */
8064 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
8065 /* r2 = 0xfff'ffff */
8066 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
8067 /* r0 = <oob pointer> */
8068 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8069 /* access to OOB pointer */
8070 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8071 /* exit */
8072 BPF_MOV64_IMM(BPF_REG_0, 0),
8073 BPF_EXIT_INSN(),
8074 },
8075 .fixup_map1 = { 3 },
8076 .errstr = "R0 min value is outside of the array range",
8077 .result = REJECT
8078 },
8079 {
8080 "bounds check based on reg_off + var_off + insn_off. test1",
8081 .insns = {
8082 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8083 offsetof(struct __sk_buff, mark)),
8084 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8085 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8086 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8087 BPF_LD_MAP_FD(BPF_REG_1, 0),
8088 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8089 BPF_FUNC_map_lookup_elem),
8090 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8091 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
8092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
8093 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
8094 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
8095 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
8096 BPF_MOV64_IMM(BPF_REG_0, 0),
8097 BPF_EXIT_INSN(),
8098 },
8099 .fixup_map1 = { 4 },
8100 .errstr = "value_size=8 off=1073741825",
8101 .result = REJECT,
8102 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8103 },
8104 {
8105 "bounds check based on reg_off + var_off + insn_off. test2",
8106 .insns = {
8107 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8108 offsetof(struct __sk_buff, mark)),
8109 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8110 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8112 BPF_LD_MAP_FD(BPF_REG_1, 0),
8113 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8114 BPF_FUNC_map_lookup_elem),
8115 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
8116 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
8117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
8118 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
8119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
8120 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
8121 BPF_MOV64_IMM(BPF_REG_0, 0),
8122 BPF_EXIT_INSN(),
8123 },
8124 .fixup_map1 = { 4 },
8125 .errstr = "value 1073741823",
8126 .result = REJECT,
8127 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8128 },
8129 {
8130 "bounds check after truncation of non-boundary-crossing range",
8131 .insns = {
8132 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8133 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8134 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8135 BPF_LD_MAP_FD(BPF_REG_1, 0),
8136 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8137 BPF_FUNC_map_lookup_elem),
8138 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8139 /* r1 = [0x00, 0xff] */
8140 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8141 BPF_MOV64_IMM(BPF_REG_2, 1),
8142 /* r2 = 0x10'0000'0000 */
8143 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
8144 /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
8145 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
8146 /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
8147 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8148 /* r1 = [0x00, 0xff] */
8149 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
8150 /* r1 = 0 */
8151 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8152 /* no-op */
8153 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8154 /* access at offset 0 */
8155 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8156 /* exit */
8157 BPF_MOV64_IMM(BPF_REG_0, 0),
8158 BPF_EXIT_INSN(),
8159 },
8160 .fixup_map1 = { 3 },
8161 .result = ACCEPT
8162 },
8163 {
8164 "bounds check after truncation of boundary-crossing range (1)",
8165 .insns = {
8166 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8167 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8168 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8169 BPF_LD_MAP_FD(BPF_REG_1, 0),
8170 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8171 BPF_FUNC_map_lookup_elem),
8172 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8173 /* r1 = [0x00, 0xff] */
8174 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8175 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8176 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
8177 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8178 /* r1 = [0xffff'ff80, 0xffff'ffff] or
8179 * [0x0000'0000, 0x0000'007f]
8180 */
8181 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
8182 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8183 /* r1 = [0x00, 0xff] or
8184 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
8185 */
8186 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8187 /* r1 = 0 or
8188 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
8189 */
8190 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8191 /* no-op or OOB pointer computation */
8192 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8193 /* potentially OOB access */
8194 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8195 /* exit */
8196 BPF_MOV64_IMM(BPF_REG_0, 0),
8197 BPF_EXIT_INSN(),
8198 },
8199 .fixup_map1 = { 3 },
8200 /* not actually fully unbounded, but the bound is very high */
8201 .errstr = "R0 unbounded memory access",
8202 .result = REJECT
8203 },
8204 {
8205 "bounds check after truncation of boundary-crossing range (2)",
8206 .insns = {
8207 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8208 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8209 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8210 BPF_LD_MAP_FD(BPF_REG_1, 0),
8211 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8212 BPF_FUNC_map_lookup_elem),
8213 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
8214 /* r1 = [0x00, 0xff] */
8215 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8216 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8217 /* r1 = [0xffff'ff80, 0x1'0000'007f] */
8218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
8219 /* r1 = [0xffff'ff80, 0xffff'ffff] or
8220 * [0x0000'0000, 0x0000'007f]
8221 * difference to previous test: truncation via MOV32
8222 * instead of ALU32.
8223 */
8224 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
8225 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8226 /* r1 = [0x00, 0xff] or
8227 * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
8228 */
8229 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
8230 /* r1 = 0 or
8231 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
8232 */
8233 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8234 /* no-op or OOB pointer computation */
8235 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8236 /* potentially OOB access */
8237 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8238 /* exit */
8239 BPF_MOV64_IMM(BPF_REG_0, 0),
8240 BPF_EXIT_INSN(),
8241 },
8242 .fixup_map1 = { 3 },
8243 /* not actually fully unbounded, but the bound is very high */
8244 .errstr = "R0 unbounded memory access",
8245 .result = REJECT
8246 },
8247 {
8248 "bounds check after wrapping 32-bit addition",
8249 .insns = {
8250 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8251 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8253 BPF_LD_MAP_FD(BPF_REG_1, 0),
8254 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8255 BPF_FUNC_map_lookup_elem),
8256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
8257 /* r1 = 0x7fff'ffff */
8258 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
8259 /* r1 = 0xffff'fffe */
8260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8261 /* r1 = 0 */
8262 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
8263 /* no-op */
8264 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8265 /* access at offset 0 */
8266 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8267 /* exit */
8268 BPF_MOV64_IMM(BPF_REG_0, 0),
8269 BPF_EXIT_INSN(),
8270 },
8271 .fixup_map1 = { 3 },
8272 .result = ACCEPT
8273 },
8274 {
8275 "bounds check after shift with oversized count operand",
8276 .insns = {
8277 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8278 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8279 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8280 BPF_LD_MAP_FD(BPF_REG_1, 0),
8281 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8282 BPF_FUNC_map_lookup_elem),
8283 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8284 BPF_MOV64_IMM(BPF_REG_2, 32),
8285 BPF_MOV64_IMM(BPF_REG_1, 1),
8286 /* r1 = (u32)1 << (u32)32 = ? */
8287 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
8288 /* r1 = [0x0000, 0xffff] */
8289 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
8290 /* computes unknown pointer, potentially OOB */
8291 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8292 /* potentially OOB access */
8293 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8294 /* exit */
8295 BPF_MOV64_IMM(BPF_REG_0, 0),
8296 BPF_EXIT_INSN(),
8297 },
8298 .fixup_map1 = { 3 },
8299 .errstr = "R0 max value is outside of the array range",
8300 .result = REJECT
8301 },
8302 {
8303 "bounds check after right shift of maybe-negative number",
8304 .insns = {
8305 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8306 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8308 BPF_LD_MAP_FD(BPF_REG_1, 0),
8309 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8310 BPF_FUNC_map_lookup_elem),
8311 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
8312 /* r1 = [0x00, 0xff] */
8313 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8314 /* r1 = [-0x01, 0xfe] */
8315 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
8316 /* r1 = 0 or 0xff'ffff'ffff'ffff */
8317 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8318 /* r1 = 0 or 0xffff'ffff'ffff */
8319 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
8320 /* computes unknown pointer, potentially OOB */
8321 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8322 /* potentially OOB access */
8323 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8324 /* exit */
8325 BPF_MOV64_IMM(BPF_REG_0, 0),
8326 BPF_EXIT_INSN(),
8327 },
8328 .fixup_map1 = { 3 },
8329 .errstr = "R0 unbounded memory access",
8330 .result = REJECT
8331 },
8332 {
8333 "bounds check map access with off+size signed 32bit overflow. test1",
8334 .insns = {
8335 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8336 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8337 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8338 BPF_LD_MAP_FD(BPF_REG_1, 0),
8339 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8340 BPF_FUNC_map_lookup_elem),
8341 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8342 BPF_EXIT_INSN(),
8343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
8344 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8345 BPF_JMP_A(0),
8346 BPF_EXIT_INSN(),
8347 },
8348 .fixup_map1 = { 3 },
8349 .errstr = "map_value pointer and 2147483646",
8350 .result = REJECT
8351 },
8352 {
8353 "bounds check map access with off+size signed 32bit overflow. test2",
8354 .insns = {
8355 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8356 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8357 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8358 BPF_LD_MAP_FD(BPF_REG_1, 0),
8359 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8360 BPF_FUNC_map_lookup_elem),
8361 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8362 BPF_EXIT_INSN(),
8363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
8366 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8367 BPF_JMP_A(0),
8368 BPF_EXIT_INSN(),
8369 },
8370 .fixup_map1 = { 3 },
8371 .errstr = "pointer offset 1073741822",
8372 .result = REJECT
8373 },
8374 {
8375 "bounds check map access with off+size signed 32bit overflow. test3",
8376 .insns = {
8377 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8378 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8379 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8380 BPF_LD_MAP_FD(BPF_REG_1, 0),
8381 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8382 BPF_FUNC_map_lookup_elem),
8383 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8384 BPF_EXIT_INSN(),
8385 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8386 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
8387 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8388 BPF_JMP_A(0),
8389 BPF_EXIT_INSN(),
8390 },
8391 .fixup_map1 = { 3 },
8392 .errstr = "pointer offset -1073741822",
8393 .result = REJECT
8394 },
8395 {
8396 "bounds check map access with off+size signed 32bit overflow. test4",
8397 .insns = {
8398 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8399 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8400 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8401 BPF_LD_MAP_FD(BPF_REG_1, 0),
8402 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8403 BPF_FUNC_map_lookup_elem),
8404 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
8405 BPF_EXIT_INSN(),
8406 BPF_MOV64_IMM(BPF_REG_1, 1000000),
8407 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
8408 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8409 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
8410 BPF_JMP_A(0),
8411 BPF_EXIT_INSN(),
8412 },
8413 .fixup_map1 = { 3 },
8414 .errstr = "map_value pointer and 1000000000000",
8415 .result = REJECT
8416 },
8417 {
8418 "pointer/scalar confusion in state equality check (way 1)",
8419 .insns = {
8420 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8421 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8422 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8423 BPF_LD_MAP_FD(BPF_REG_1, 0),
8424 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8425 BPF_FUNC_map_lookup_elem),
8426 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
8427 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8428 BPF_JMP_A(1),
8429 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8430 BPF_JMP_A(0),
8431 BPF_EXIT_INSN(),
8432 },
8433 .fixup_map1 = { 3 },
8434 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008435 .retval = POINTER_VALUE,
Jann Horn2255f8d2017-12-18 20:12:01 -08008436 .result_unpriv = REJECT,
8437 .errstr_unpriv = "R0 leaks addr as return value"
8438 },
8439 {
8440 "pointer/scalar confusion in state equality check (way 2)",
8441 .insns = {
8442 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8443 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8445 BPF_LD_MAP_FD(BPF_REG_1, 0),
8446 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8447 BPF_FUNC_map_lookup_elem),
8448 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8449 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
8450 BPF_JMP_A(1),
8451 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
8452 BPF_EXIT_INSN(),
8453 },
8454 .fixup_map1 = { 3 },
8455 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008456 .retval = POINTER_VALUE,
Jann Horn2255f8d2017-12-18 20:12:01 -08008457 .result_unpriv = REJECT,
8458 .errstr_unpriv = "R0 leaks addr as return value"
8459 },
8460 {
Edward Cree69c4e8a2017-08-07 15:29:51 +01008461 "variable-offset ctx access",
8462 .insns = {
8463 /* Get an unknown value */
8464 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8465 /* Make it small and 4-byte aligned */
8466 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8467 /* add it to skb. We now have either &skb->len or
8468 * &skb->pkt_type, but we don't know which
8469 */
8470 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
8471 /* dereference it */
8472 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8473 BPF_EXIT_INSN(),
8474 },
8475 .errstr = "variable ctx access var_off=(0x0; 0x4)",
8476 .result = REJECT,
8477 .prog_type = BPF_PROG_TYPE_LWT_IN,
8478 },
8479 {
8480 "variable-offset stack access",
8481 .insns = {
8482 /* Fill the top 8 bytes of the stack */
8483 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8484 /* Get an unknown value */
8485 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8486 /* Make it small and 4-byte aligned */
8487 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8488 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8489 /* add it to fp. We now have either fp-4 or fp-8, but
8490 * we don't know which
8491 */
8492 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8493 /* dereference it */
8494 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
8495 BPF_EXIT_INSN(),
8496 },
8497 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
8498 .result = REJECT,
8499 .prog_type = BPF_PROG_TYPE_LWT_IN,
8500 },
Edward Creed893dc22017-08-23 15:09:46 +01008501 {
Jann Horn2255f8d2017-12-18 20:12:01 -08008502 "indirect variable-offset stack access",
8503 .insns = {
8504 /* Fill the top 8 bytes of the stack */
8505 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8506 /* Get an unknown value */
8507 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8508 /* Make it small and 4-byte aligned */
8509 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8510 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
8511 /* add it to fp. We now have either fp-4 or fp-8, but
8512 * we don't know which
8513 */
8514 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
8515 /* dereference it indirectly */
8516 BPF_LD_MAP_FD(BPF_REG_1, 0),
8517 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8518 BPF_FUNC_map_lookup_elem),
8519 BPF_MOV64_IMM(BPF_REG_0, 0),
8520 BPF_EXIT_INSN(),
8521 },
8522 .fixup_map1 = { 5 },
8523 .errstr = "variable stack read R2",
8524 .result = REJECT,
8525 .prog_type = BPF_PROG_TYPE_LWT_IN,
8526 },
8527 {
8528 "direct stack access with 32-bit wraparound. test1",
8529 .insns = {
8530 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8531 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
8533 BPF_MOV32_IMM(BPF_REG_0, 0),
8534 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8535 BPF_EXIT_INSN()
8536 },
8537 .errstr = "fp pointer and 2147483647",
8538 .result = REJECT
8539 },
8540 {
8541 "direct stack access with 32-bit wraparound. test2",
8542 .insns = {
8543 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8544 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
8546 BPF_MOV32_IMM(BPF_REG_0, 0),
8547 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8548 BPF_EXIT_INSN()
8549 },
8550 .errstr = "fp pointer and 1073741823",
8551 .result = REJECT
8552 },
8553 {
8554 "direct stack access with 32-bit wraparound. test3",
8555 .insns = {
8556 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8557 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
8559 BPF_MOV32_IMM(BPF_REG_0, 0),
8560 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
8561 BPF_EXIT_INSN()
8562 },
8563 .errstr = "fp pointer offset 1073741822",
8564 .result = REJECT
8565 },
8566 {
Edward Creed893dc22017-08-23 15:09:46 +01008567 "liveness pruning and write screening",
8568 .insns = {
8569 /* Get an unknown value */
8570 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8571 /* branch conditions teach us nothing about R2 */
8572 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8573 BPF_MOV64_IMM(BPF_REG_0, 0),
8574 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8575 BPF_MOV64_IMM(BPF_REG_0, 0),
8576 BPF_EXIT_INSN(),
8577 },
8578 .errstr = "R0 !read_ok",
8579 .result = REJECT,
8580 .prog_type = BPF_PROG_TYPE_LWT_IN,
8581 },
Alexei Starovoitovdf20cb72017-08-23 15:10:26 +01008582 {
8583 "varlen_map_value_access pruning",
8584 .insns = {
8585 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8586 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8588 BPF_LD_MAP_FD(BPF_REG_1, 0),
8589 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8590 BPF_FUNC_map_lookup_elem),
8591 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8592 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
8593 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
8594 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
8595 BPF_MOV32_IMM(BPF_REG_1, 0),
8596 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
8597 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8598 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
8599 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
8600 offsetof(struct test_val, foo)),
8601 BPF_EXIT_INSN(),
8602 },
8603 .fixup_map2 = { 3 },
8604 .errstr_unpriv = "R0 leaks addr",
8605 .errstr = "R0 unbounded memory access",
8606 .result_unpriv = REJECT,
8607 .result = REJECT,
8608 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8609 },
Edward Creee67b8a62017-09-15 14:37:38 +01008610 {
8611 "invalid 64-bit BPF_END",
8612 .insns = {
8613 BPF_MOV32_IMM(BPF_REG_0, 0),
8614 {
8615 .code = BPF_ALU64 | BPF_END | BPF_TO_LE,
8616 .dst_reg = BPF_REG_0,
8617 .src_reg = 0,
8618 .off = 0,
8619 .imm = 32,
8620 },
8621 BPF_EXIT_INSN(),
8622 },
Daniel Borkmann21ccaf22018-01-26 23:33:48 +01008623 .errstr = "unknown opcode d7",
Edward Creee67b8a62017-09-15 14:37:38 +01008624 .result = REJECT,
8625 },
Daniel Borkmann22c88522017-09-25 02:25:53 +02008626 {
Daniel Borkmann65073a62018-01-31 12:58:56 +01008627 "XDP, using ifindex from netdev",
8628 .insns = {
8629 BPF_MOV64_IMM(BPF_REG_0, 0),
8630 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8631 offsetof(struct xdp_md, ingress_ifindex)),
8632 BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
8633 BPF_MOV64_IMM(BPF_REG_0, 1),
8634 BPF_EXIT_INSN(),
8635 },
8636 .result = ACCEPT,
8637 .prog_type = BPF_PROG_TYPE_XDP,
8638 .retval = 1,
8639 },
8640 {
Daniel Borkmann22c88522017-09-25 02:25:53 +02008641 "meta access, test1",
8642 .insns = {
8643 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8644 offsetof(struct xdp_md, data_meta)),
8645 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8646 offsetof(struct xdp_md, data)),
8647 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8649 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8650 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8651 BPF_MOV64_IMM(BPF_REG_0, 0),
8652 BPF_EXIT_INSN(),
8653 },
8654 .result = ACCEPT,
8655 .prog_type = BPF_PROG_TYPE_XDP,
8656 },
8657 {
8658 "meta access, test2",
8659 .insns = {
8660 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8661 offsetof(struct xdp_md, data_meta)),
8662 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8663 offsetof(struct xdp_md, data)),
8664 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8665 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
8666 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8667 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8668 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8669 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
8670 BPF_MOV64_IMM(BPF_REG_0, 0),
8671 BPF_EXIT_INSN(),
8672 },
8673 .result = REJECT,
8674 .errstr = "invalid access to packet, off=-8",
8675 .prog_type = BPF_PROG_TYPE_XDP,
8676 },
8677 {
8678 "meta access, test3",
8679 .insns = {
8680 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8681 offsetof(struct xdp_md, data_meta)),
8682 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8683 offsetof(struct xdp_md, data_end)),
8684 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8685 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8686 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8687 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8688 BPF_MOV64_IMM(BPF_REG_0, 0),
8689 BPF_EXIT_INSN(),
8690 },
8691 .result = REJECT,
8692 .errstr = "invalid access to packet",
8693 .prog_type = BPF_PROG_TYPE_XDP,
8694 },
8695 {
8696 "meta access, test4",
8697 .insns = {
8698 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8699 offsetof(struct xdp_md, data_meta)),
8700 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8701 offsetof(struct xdp_md, data_end)),
8702 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8703 offsetof(struct xdp_md, data)),
8704 BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
8705 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8706 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
8707 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8708 BPF_MOV64_IMM(BPF_REG_0, 0),
8709 BPF_EXIT_INSN(),
8710 },
8711 .result = REJECT,
8712 .errstr = "invalid access to packet",
8713 .prog_type = BPF_PROG_TYPE_XDP,
8714 },
8715 {
8716 "meta access, test5",
8717 .insns = {
8718 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8719 offsetof(struct xdp_md, data_meta)),
8720 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8721 offsetof(struct xdp_md, data)),
8722 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8723 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8724 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
8725 BPF_MOV64_IMM(BPF_REG_2, -8),
8726 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8727 BPF_FUNC_xdp_adjust_meta),
8728 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8729 BPF_MOV64_IMM(BPF_REG_0, 0),
8730 BPF_EXIT_INSN(),
8731 },
8732 .result = REJECT,
8733 .errstr = "R3 !read_ok",
8734 .prog_type = BPF_PROG_TYPE_XDP,
8735 },
8736 {
8737 "meta access, test6",
8738 .insns = {
8739 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8740 offsetof(struct xdp_md, data_meta)),
8741 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8742 offsetof(struct xdp_md, data)),
8743 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8745 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8747 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
8748 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8749 BPF_MOV64_IMM(BPF_REG_0, 0),
8750 BPF_EXIT_INSN(),
8751 },
8752 .result = REJECT,
8753 .errstr = "invalid access to packet",
8754 .prog_type = BPF_PROG_TYPE_XDP,
8755 },
8756 {
8757 "meta access, test7",
8758 .insns = {
8759 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8760 offsetof(struct xdp_md, data_meta)),
8761 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8762 offsetof(struct xdp_md, data)),
8763 BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
8764 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
8765 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8766 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
8767 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8768 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8769 BPF_MOV64_IMM(BPF_REG_0, 0),
8770 BPF_EXIT_INSN(),
8771 },
8772 .result = ACCEPT,
8773 .prog_type = BPF_PROG_TYPE_XDP,
8774 },
8775 {
8776 "meta access, test8",
8777 .insns = {
8778 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8779 offsetof(struct xdp_md, data_meta)),
8780 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8781 offsetof(struct xdp_md, data)),
8782 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8784 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8785 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8786 BPF_MOV64_IMM(BPF_REG_0, 0),
8787 BPF_EXIT_INSN(),
8788 },
8789 .result = ACCEPT,
8790 .prog_type = BPF_PROG_TYPE_XDP,
8791 },
8792 {
8793 "meta access, test9",
8794 .insns = {
8795 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8796 offsetof(struct xdp_md, data_meta)),
8797 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8798 offsetof(struct xdp_md, data)),
8799 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
8800 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
8801 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
8802 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
8803 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8804 BPF_MOV64_IMM(BPF_REG_0, 0),
8805 BPF_EXIT_INSN(),
8806 },
8807 .result = REJECT,
8808 .errstr = "invalid access to packet",
8809 .prog_type = BPF_PROG_TYPE_XDP,
8810 },
8811 {
8812 "meta access, test10",
8813 .insns = {
8814 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8815 offsetof(struct xdp_md, data_meta)),
8816 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8817 offsetof(struct xdp_md, data)),
8818 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8819 offsetof(struct xdp_md, data_end)),
8820 BPF_MOV64_IMM(BPF_REG_5, 42),
8821 BPF_MOV64_IMM(BPF_REG_6, 24),
8822 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8823 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8824 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8825 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8826 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
8827 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8828 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8829 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8830 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
8831 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
8832 BPF_MOV64_IMM(BPF_REG_0, 0),
8833 BPF_EXIT_INSN(),
8834 },
8835 .result = REJECT,
8836 .errstr = "invalid access to packet",
8837 .prog_type = BPF_PROG_TYPE_XDP,
8838 },
8839 {
8840 "meta access, test11",
8841 .insns = {
8842 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8843 offsetof(struct xdp_md, data_meta)),
8844 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8845 offsetof(struct xdp_md, data)),
8846 BPF_MOV64_IMM(BPF_REG_5, 42),
8847 BPF_MOV64_IMM(BPF_REG_6, 24),
8848 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
8849 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
8850 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
8851 BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
8852 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
8853 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8854 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
8855 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
8856 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
8857 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
8858 BPF_MOV64_IMM(BPF_REG_0, 0),
8859 BPF_EXIT_INSN(),
8860 },
8861 .result = ACCEPT,
8862 .prog_type = BPF_PROG_TYPE_XDP,
8863 },
8864 {
8865 "meta access, test12",
8866 .insns = {
8867 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8868 offsetof(struct xdp_md, data_meta)),
8869 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8870 offsetof(struct xdp_md, data)),
8871 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
8872 offsetof(struct xdp_md, data_end)),
8873 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
8874 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8875 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
8876 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
8877 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
8878 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
8879 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
8880 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
8881 BPF_MOV64_IMM(BPF_REG_0, 0),
8882 BPF_EXIT_INSN(),
8883 },
8884 .result = ACCEPT,
8885 .prog_type = BPF_PROG_TYPE_XDP,
8886 },
Alexei Starovoitov390ee7e2017-10-02 22:50:23 -07008887 {
Jakub Kicinski28e33f92017-10-16 11:16:55 -07008888 "arithmetic ops make PTR_TO_CTX unusable",
8889 .insns = {
8890 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
8891 offsetof(struct __sk_buff, data) -
8892 offsetof(struct __sk_buff, mark)),
8893 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8894 offsetof(struct __sk_buff, mark)),
8895 BPF_EXIT_INSN(),
8896 },
Daniel Borkmann58990d12018-06-07 17:40:03 +02008897 .errstr = "dereference of modified ctx ptr",
Jakub Kicinski28e33f92017-10-16 11:16:55 -07008898 .result = REJECT,
8899 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8900 },
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008901 {
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008902 "pkt_end - pkt_start is allowed",
8903 .insns = {
8904 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8905 offsetof(struct __sk_buff, data_end)),
8906 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8907 offsetof(struct __sk_buff, data)),
8908 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
8909 BPF_EXIT_INSN(),
8910 },
8911 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -08008912 .retval = TEST_DATA_LEN,
Alexei Starovoitov82abbf82017-12-18 20:15:20 -08008913 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8914 },
8915 {
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008916 "XDP pkt read, pkt_end mangling, bad access 1",
8917 .insns = {
8918 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8919 offsetof(struct xdp_md, data)),
8920 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8921 offsetof(struct xdp_md, data_end)),
8922 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8923 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8924 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
8925 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8926 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8927 BPF_MOV64_IMM(BPF_REG_0, 0),
8928 BPF_EXIT_INSN(),
8929 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07008930 .errstr = "R3 pointer arithmetic on pkt_end",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008931 .result = REJECT,
8932 .prog_type = BPF_PROG_TYPE_XDP,
8933 },
8934 {
8935 "XDP pkt read, pkt_end mangling, bad access 2",
8936 .insns = {
8937 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8938 offsetof(struct xdp_md, data)),
8939 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8940 offsetof(struct xdp_md, data_end)),
8941 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8942 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8943 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
8944 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8945 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8946 BPF_MOV64_IMM(BPF_REG_0, 0),
8947 BPF_EXIT_INSN(),
8948 },
Joe Stringeraad2eea2018-10-02 13:35:30 -07008949 .errstr = "R3 pointer arithmetic on pkt_end",
Daniel Borkmannb37242c2017-10-21 02:34:23 +02008950 .result = REJECT,
8951 .prog_type = BPF_PROG_TYPE_XDP,
8952 },
8953 {
8954 "XDP pkt read, pkt_data' > pkt_end, good access",
8955 .insns = {
8956 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8957 offsetof(struct xdp_md, data)),
8958 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8959 offsetof(struct xdp_md, data_end)),
8960 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8961 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8962 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8963 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8964 BPF_MOV64_IMM(BPF_REG_0, 0),
8965 BPF_EXIT_INSN(),
8966 },
8967 .result = ACCEPT,
8968 .prog_type = BPF_PROG_TYPE_XDP,
8969 },
8970 {
8971 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
8972 .insns = {
8973 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8974 offsetof(struct xdp_md, data)),
8975 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8976 offsetof(struct xdp_md, data_end)),
8977 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8978 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8979 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8980 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8981 BPF_MOV64_IMM(BPF_REG_0, 0),
8982 BPF_EXIT_INSN(),
8983 },
8984 .errstr = "R1 offset is outside of the packet",
8985 .result = REJECT,
8986 .prog_type = BPF_PROG_TYPE_XDP,
8987 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8988 },
8989 {
8990 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
8991 .insns = {
8992 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8993 offsetof(struct xdp_md, data)),
8994 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8995 offsetof(struct xdp_md, data_end)),
8996 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8998 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8999 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9000 BPF_MOV64_IMM(BPF_REG_0, 0),
9001 BPF_EXIT_INSN(),
9002 },
9003 .errstr = "R1 offset is outside of the packet",
9004 .result = REJECT,
9005 .prog_type = BPF_PROG_TYPE_XDP,
9006 },
9007 {
9008 "XDP pkt read, pkt_end > pkt_data', good access",
9009 .insns = {
9010 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9011 offsetof(struct xdp_md, data)),
9012 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9013 offsetof(struct xdp_md, data_end)),
9014 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9015 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9016 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9017 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9018 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9019 BPF_MOV64_IMM(BPF_REG_0, 0),
9020 BPF_EXIT_INSN(),
9021 },
9022 .result = ACCEPT,
9023 .prog_type = BPF_PROG_TYPE_XDP,
9024 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9025 },
9026 {
9027 "XDP pkt read, pkt_end > pkt_data', bad access 1",
9028 .insns = {
9029 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9030 offsetof(struct xdp_md, data)),
9031 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9032 offsetof(struct xdp_md, data_end)),
9033 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9034 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9035 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9036 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9037 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9038 BPF_MOV64_IMM(BPF_REG_0, 0),
9039 BPF_EXIT_INSN(),
9040 },
9041 .errstr = "R1 offset is outside of the packet",
9042 .result = REJECT,
9043 .prog_type = BPF_PROG_TYPE_XDP,
9044 },
9045 {
9046 "XDP pkt read, pkt_end > pkt_data', bad access 2",
9047 .insns = {
9048 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9049 offsetof(struct xdp_md, data)),
9050 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9051 offsetof(struct xdp_md, data_end)),
9052 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9054 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9055 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9056 BPF_MOV64_IMM(BPF_REG_0, 0),
9057 BPF_EXIT_INSN(),
9058 },
9059 .errstr = "R1 offset is outside of the packet",
9060 .result = REJECT,
9061 .prog_type = BPF_PROG_TYPE_XDP,
9062 },
9063 {
9064 "XDP pkt read, pkt_data' < pkt_end, good access",
9065 .insns = {
9066 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9067 offsetof(struct xdp_md, data)),
9068 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9069 offsetof(struct xdp_md, data_end)),
9070 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9072 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9073 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9074 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9075 BPF_MOV64_IMM(BPF_REG_0, 0),
9076 BPF_EXIT_INSN(),
9077 },
9078 .result = ACCEPT,
9079 .prog_type = BPF_PROG_TYPE_XDP,
9080 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9081 },
9082 {
9083 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
9084 .insns = {
9085 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9086 offsetof(struct xdp_md, data)),
9087 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9088 offsetof(struct xdp_md, data_end)),
9089 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9090 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9091 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9092 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9093 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9094 BPF_MOV64_IMM(BPF_REG_0, 0),
9095 BPF_EXIT_INSN(),
9096 },
9097 .errstr = "R1 offset is outside of the packet",
9098 .result = REJECT,
9099 .prog_type = BPF_PROG_TYPE_XDP,
9100 },
9101 {
9102 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
9103 .insns = {
9104 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9105 offsetof(struct xdp_md, data)),
9106 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9107 offsetof(struct xdp_md, data_end)),
9108 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9109 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9110 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9111 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9112 BPF_MOV64_IMM(BPF_REG_0, 0),
9113 BPF_EXIT_INSN(),
9114 },
9115 .errstr = "R1 offset is outside of the packet",
9116 .result = REJECT,
9117 .prog_type = BPF_PROG_TYPE_XDP,
9118 },
9119 {
9120 "XDP pkt read, pkt_end < pkt_data', good access",
9121 .insns = {
9122 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9123 offsetof(struct xdp_md, data)),
9124 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9125 offsetof(struct xdp_md, data_end)),
9126 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9127 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9128 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9129 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9130 BPF_MOV64_IMM(BPF_REG_0, 0),
9131 BPF_EXIT_INSN(),
9132 },
9133 .result = ACCEPT,
9134 .prog_type = BPF_PROG_TYPE_XDP,
9135 },
9136 {
9137 "XDP pkt read, pkt_end < pkt_data', bad access 1",
9138 .insns = {
9139 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9140 offsetof(struct xdp_md, data)),
9141 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9142 offsetof(struct xdp_md, data_end)),
9143 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9144 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9145 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9146 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9147 BPF_MOV64_IMM(BPF_REG_0, 0),
9148 BPF_EXIT_INSN(),
9149 },
9150 .errstr = "R1 offset is outside of the packet",
9151 .result = REJECT,
9152 .prog_type = BPF_PROG_TYPE_XDP,
9153 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9154 },
9155 {
9156 "XDP pkt read, pkt_end < pkt_data', bad access 2",
9157 .insns = {
9158 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9159 offsetof(struct xdp_md, data)),
9160 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9161 offsetof(struct xdp_md, data_end)),
9162 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9163 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9164 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9165 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9166 BPF_MOV64_IMM(BPF_REG_0, 0),
9167 BPF_EXIT_INSN(),
9168 },
9169 .errstr = "R1 offset is outside of the packet",
9170 .result = REJECT,
9171 .prog_type = BPF_PROG_TYPE_XDP,
9172 },
9173 {
9174 "XDP pkt read, pkt_data' >= pkt_end, good access",
9175 .insns = {
9176 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9177 offsetof(struct xdp_md, data)),
9178 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9179 offsetof(struct xdp_md, data_end)),
9180 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9182 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9183 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9184 BPF_MOV64_IMM(BPF_REG_0, 0),
9185 BPF_EXIT_INSN(),
9186 },
9187 .result = ACCEPT,
9188 .prog_type = BPF_PROG_TYPE_XDP,
9189 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9190 },
9191 {
9192 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
9193 .insns = {
9194 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9195 offsetof(struct xdp_md, data)),
9196 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9197 offsetof(struct xdp_md, data_end)),
9198 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9199 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9200 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9201 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9202 BPF_MOV64_IMM(BPF_REG_0, 0),
9203 BPF_EXIT_INSN(),
9204 },
9205 .errstr = "R1 offset is outside of the packet",
9206 .result = REJECT,
9207 .prog_type = BPF_PROG_TYPE_XDP,
9208 },
9209 {
9210 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
9211 .insns = {
9212 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9213 offsetof(struct xdp_md, data)),
9214 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9215 offsetof(struct xdp_md, data_end)),
9216 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9218 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9219 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9220 BPF_MOV64_IMM(BPF_REG_0, 0),
9221 BPF_EXIT_INSN(),
9222 },
9223 .errstr = "R1 offset is outside of the packet",
9224 .result = REJECT,
9225 .prog_type = BPF_PROG_TYPE_XDP,
9226 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9227 },
9228 {
9229 "XDP pkt read, pkt_end >= pkt_data', good access",
9230 .insns = {
9231 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9232 offsetof(struct xdp_md, data)),
9233 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9234 offsetof(struct xdp_md, data_end)),
9235 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9236 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9237 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9238 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9239 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9240 BPF_MOV64_IMM(BPF_REG_0, 0),
9241 BPF_EXIT_INSN(),
9242 },
9243 .result = ACCEPT,
9244 .prog_type = BPF_PROG_TYPE_XDP,
9245 },
9246 {
9247 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
9248 .insns = {
9249 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9250 offsetof(struct xdp_md, data)),
9251 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9252 offsetof(struct xdp_md, data_end)),
9253 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9254 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9255 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9256 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9257 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9258 BPF_MOV64_IMM(BPF_REG_0, 0),
9259 BPF_EXIT_INSN(),
9260 },
9261 .errstr = "R1 offset is outside of the packet",
9262 .result = REJECT,
9263 .prog_type = BPF_PROG_TYPE_XDP,
9264 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9265 },
9266 {
9267 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
9268 .insns = {
9269 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9270 offsetof(struct xdp_md, data)),
9271 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9272 offsetof(struct xdp_md, data_end)),
9273 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9274 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9275 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9276 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9277 BPF_MOV64_IMM(BPF_REG_0, 0),
9278 BPF_EXIT_INSN(),
9279 },
9280 .errstr = "R1 offset is outside of the packet",
9281 .result = REJECT,
9282 .prog_type = BPF_PROG_TYPE_XDP,
9283 },
9284 {
9285 "XDP pkt read, pkt_data' <= pkt_end, good access",
9286 .insns = {
9287 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9288 offsetof(struct xdp_md, data)),
9289 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9290 offsetof(struct xdp_md, data_end)),
9291 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9292 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9293 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9294 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9295 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9296 BPF_MOV64_IMM(BPF_REG_0, 0),
9297 BPF_EXIT_INSN(),
9298 },
9299 .result = ACCEPT,
9300 .prog_type = BPF_PROG_TYPE_XDP,
9301 },
9302 {
9303 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
9304 .insns = {
9305 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9306 offsetof(struct xdp_md, data)),
9307 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9308 offsetof(struct xdp_md, data_end)),
9309 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9310 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9311 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9312 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9313 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9314 BPF_MOV64_IMM(BPF_REG_0, 0),
9315 BPF_EXIT_INSN(),
9316 },
9317 .errstr = "R1 offset is outside of the packet",
9318 .result = REJECT,
9319 .prog_type = BPF_PROG_TYPE_XDP,
9320 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9321 },
9322 {
9323 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
9324 .insns = {
9325 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9326 offsetof(struct xdp_md, data)),
9327 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9328 offsetof(struct xdp_md, data_end)),
9329 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9330 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9331 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9332 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9333 BPF_MOV64_IMM(BPF_REG_0, 0),
9334 BPF_EXIT_INSN(),
9335 },
9336 .errstr = "R1 offset is outside of the packet",
9337 .result = REJECT,
9338 .prog_type = BPF_PROG_TYPE_XDP,
9339 },
9340 {
9341 "XDP pkt read, pkt_end <= pkt_data', good access",
9342 .insns = {
9343 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9344 offsetof(struct xdp_md, data)),
9345 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9346 offsetof(struct xdp_md, data_end)),
9347 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9348 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9349 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9350 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9351 BPF_MOV64_IMM(BPF_REG_0, 0),
9352 BPF_EXIT_INSN(),
9353 },
9354 .result = ACCEPT,
9355 .prog_type = BPF_PROG_TYPE_XDP,
9356 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9357 },
9358 {
9359 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
9360 .insns = {
9361 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9362 offsetof(struct xdp_md, data)),
9363 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9364 offsetof(struct xdp_md, data_end)),
9365 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9367 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9368 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9369 BPF_MOV64_IMM(BPF_REG_0, 0),
9370 BPF_EXIT_INSN(),
9371 },
9372 .errstr = "R1 offset is outside of the packet",
9373 .result = REJECT,
9374 .prog_type = BPF_PROG_TYPE_XDP,
9375 },
9376 {
9377 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
9378 .insns = {
9379 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9380 offsetof(struct xdp_md, data)),
9381 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9382 offsetof(struct xdp_md, data_end)),
9383 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9384 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9385 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9386 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9387 BPF_MOV64_IMM(BPF_REG_0, 0),
9388 BPF_EXIT_INSN(),
9389 },
9390 .errstr = "R1 offset is outside of the packet",
9391 .result = REJECT,
9392 .prog_type = BPF_PROG_TYPE_XDP,
9393 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9394 },
Daniel Borkmannb06723d2017-11-01 23:58:09 +01009395 {
Daniel Borkmann634eab12017-11-01 23:58:11 +01009396 "XDP pkt read, pkt_meta' > pkt_data, good access",
9397 .insns = {
9398 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9399 offsetof(struct xdp_md, data_meta)),
9400 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9401 offsetof(struct xdp_md, data)),
9402 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9403 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9404 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9405 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9406 BPF_MOV64_IMM(BPF_REG_0, 0),
9407 BPF_EXIT_INSN(),
9408 },
9409 .result = ACCEPT,
9410 .prog_type = BPF_PROG_TYPE_XDP,
9411 },
9412 {
9413 "XDP pkt read, pkt_meta' > pkt_data, bad access 1",
9414 .insns = {
9415 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9416 offsetof(struct xdp_md, data_meta)),
9417 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9418 offsetof(struct xdp_md, data)),
9419 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9420 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9421 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9423 BPF_MOV64_IMM(BPF_REG_0, 0),
9424 BPF_EXIT_INSN(),
9425 },
9426 .errstr = "R1 offset is outside of the packet",
9427 .result = REJECT,
9428 .prog_type = BPF_PROG_TYPE_XDP,
9429 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9430 },
9431 {
9432 "XDP pkt read, pkt_meta' > pkt_data, bad access 2",
9433 .insns = {
9434 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9435 offsetof(struct xdp_md, data_meta)),
9436 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9437 offsetof(struct xdp_md, data)),
9438 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9439 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9440 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
9441 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9442 BPF_MOV64_IMM(BPF_REG_0, 0),
9443 BPF_EXIT_INSN(),
9444 },
9445 .errstr = "R1 offset is outside of the packet",
9446 .result = REJECT,
9447 .prog_type = BPF_PROG_TYPE_XDP,
9448 },
9449 {
9450 "XDP pkt read, pkt_data > pkt_meta', good access",
9451 .insns = {
9452 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9453 offsetof(struct xdp_md, data_meta)),
9454 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9455 offsetof(struct xdp_md, data)),
9456 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9458 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9459 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9460 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9461 BPF_MOV64_IMM(BPF_REG_0, 0),
9462 BPF_EXIT_INSN(),
9463 },
9464 .result = ACCEPT,
9465 .prog_type = BPF_PROG_TYPE_XDP,
9466 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9467 },
9468 {
9469 "XDP pkt read, pkt_data > pkt_meta', bad access 1",
9470 .insns = {
9471 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9472 offsetof(struct xdp_md, data_meta)),
9473 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9474 offsetof(struct xdp_md, data)),
9475 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9476 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9477 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9478 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9479 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9480 BPF_MOV64_IMM(BPF_REG_0, 0),
9481 BPF_EXIT_INSN(),
9482 },
9483 .errstr = "R1 offset is outside of the packet",
9484 .result = REJECT,
9485 .prog_type = BPF_PROG_TYPE_XDP,
9486 },
9487 {
9488 "XDP pkt read, pkt_data > pkt_meta', bad access 2",
9489 .insns = {
9490 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9491 offsetof(struct xdp_md, data_meta)),
9492 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9493 offsetof(struct xdp_md, data)),
9494 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9495 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9496 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9497 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9498 BPF_MOV64_IMM(BPF_REG_0, 0),
9499 BPF_EXIT_INSN(),
9500 },
9501 .errstr = "R1 offset is outside of the packet",
9502 .result = REJECT,
9503 .prog_type = BPF_PROG_TYPE_XDP,
9504 },
9505 {
9506 "XDP pkt read, pkt_meta' < pkt_data, good access",
9507 .insns = {
9508 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9509 offsetof(struct xdp_md, data_meta)),
9510 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9511 offsetof(struct xdp_md, data)),
9512 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9513 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9514 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9515 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9516 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9517 BPF_MOV64_IMM(BPF_REG_0, 0),
9518 BPF_EXIT_INSN(),
9519 },
9520 .result = ACCEPT,
9521 .prog_type = BPF_PROG_TYPE_XDP,
9522 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9523 },
9524 {
9525 "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
9526 .insns = {
9527 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9528 offsetof(struct xdp_md, data_meta)),
9529 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9530 offsetof(struct xdp_md, data)),
9531 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9533 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9534 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9535 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9536 BPF_MOV64_IMM(BPF_REG_0, 0),
9537 BPF_EXIT_INSN(),
9538 },
9539 .errstr = "R1 offset is outside of the packet",
9540 .result = REJECT,
9541 .prog_type = BPF_PROG_TYPE_XDP,
9542 },
9543 {
9544 "XDP pkt read, pkt_meta' < pkt_data, bad access 2",
9545 .insns = {
9546 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9547 offsetof(struct xdp_md, data_meta)),
9548 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9549 offsetof(struct xdp_md, data)),
9550 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9552 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9553 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9554 BPF_MOV64_IMM(BPF_REG_0, 0),
9555 BPF_EXIT_INSN(),
9556 },
9557 .errstr = "R1 offset is outside of the packet",
9558 .result = REJECT,
9559 .prog_type = BPF_PROG_TYPE_XDP,
9560 },
9561 {
9562 "XDP pkt read, pkt_data < pkt_meta', good access",
9563 .insns = {
9564 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9565 offsetof(struct xdp_md, data_meta)),
9566 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9567 offsetof(struct xdp_md, data)),
9568 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9569 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9570 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9571 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9572 BPF_MOV64_IMM(BPF_REG_0, 0),
9573 BPF_EXIT_INSN(),
9574 },
9575 .result = ACCEPT,
9576 .prog_type = BPF_PROG_TYPE_XDP,
9577 },
9578 {
9579 "XDP pkt read, pkt_data < pkt_meta', bad access 1",
9580 .insns = {
9581 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9582 offsetof(struct xdp_md, data_meta)),
9583 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9584 offsetof(struct xdp_md, data)),
9585 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9587 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9588 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9589 BPF_MOV64_IMM(BPF_REG_0, 0),
9590 BPF_EXIT_INSN(),
9591 },
9592 .errstr = "R1 offset is outside of the packet",
9593 .result = REJECT,
9594 .prog_type = BPF_PROG_TYPE_XDP,
9595 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9596 },
9597 {
9598 "XDP pkt read, pkt_data < pkt_meta', bad access 2",
9599 .insns = {
9600 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9601 offsetof(struct xdp_md, data_meta)),
9602 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9603 offsetof(struct xdp_md, data)),
9604 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9606 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9607 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9608 BPF_MOV64_IMM(BPF_REG_0, 0),
9609 BPF_EXIT_INSN(),
9610 },
9611 .errstr = "R1 offset is outside of the packet",
9612 .result = REJECT,
9613 .prog_type = BPF_PROG_TYPE_XDP,
9614 },
9615 {
9616 "XDP pkt read, pkt_meta' >= pkt_data, good access",
9617 .insns = {
9618 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9619 offsetof(struct xdp_md, data_meta)),
9620 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9621 offsetof(struct xdp_md, data)),
9622 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9624 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9625 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9626 BPF_MOV64_IMM(BPF_REG_0, 0),
9627 BPF_EXIT_INSN(),
9628 },
9629 .result = ACCEPT,
9630 .prog_type = BPF_PROG_TYPE_XDP,
9631 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9632 },
9633 {
9634 "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
9635 .insns = {
9636 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9637 offsetof(struct xdp_md, data_meta)),
9638 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9639 offsetof(struct xdp_md, data)),
9640 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9641 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9642 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9643 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9644 BPF_MOV64_IMM(BPF_REG_0, 0),
9645 BPF_EXIT_INSN(),
9646 },
9647 .errstr = "R1 offset is outside of the packet",
9648 .result = REJECT,
9649 .prog_type = BPF_PROG_TYPE_XDP,
9650 },
9651 {
9652 "XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
9653 .insns = {
9654 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9655 offsetof(struct xdp_md, data_meta)),
9656 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9657 offsetof(struct xdp_md, data)),
9658 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9659 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9660 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9661 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9662 BPF_MOV64_IMM(BPF_REG_0, 0),
9663 BPF_EXIT_INSN(),
9664 },
9665 .errstr = "R1 offset is outside of the packet",
9666 .result = REJECT,
9667 .prog_type = BPF_PROG_TYPE_XDP,
9668 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9669 },
9670 {
9671 "XDP pkt read, pkt_data >= pkt_meta', good access",
9672 .insns = {
9673 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9674 offsetof(struct xdp_md, data_meta)),
9675 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9676 offsetof(struct xdp_md, data)),
9677 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9678 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9679 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9680 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9681 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9682 BPF_MOV64_IMM(BPF_REG_0, 0),
9683 BPF_EXIT_INSN(),
9684 },
9685 .result = ACCEPT,
9686 .prog_type = BPF_PROG_TYPE_XDP,
9687 },
9688 {
9689 "XDP pkt read, pkt_data >= pkt_meta', bad access 1",
9690 .insns = {
9691 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9692 offsetof(struct xdp_md, data_meta)),
9693 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9694 offsetof(struct xdp_md, data)),
9695 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9696 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9697 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9698 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9699 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9700 BPF_MOV64_IMM(BPF_REG_0, 0),
9701 BPF_EXIT_INSN(),
9702 },
9703 .errstr = "R1 offset is outside of the packet",
9704 .result = REJECT,
9705 .prog_type = BPF_PROG_TYPE_XDP,
9706 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9707 },
9708 {
9709 "XDP pkt read, pkt_data >= pkt_meta', bad access 2",
9710 .insns = {
9711 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9712 offsetof(struct xdp_md, data_meta)),
9713 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9714 offsetof(struct xdp_md, data)),
9715 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9716 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9717 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9718 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9719 BPF_MOV64_IMM(BPF_REG_0, 0),
9720 BPF_EXIT_INSN(),
9721 },
9722 .errstr = "R1 offset is outside of the packet",
9723 .result = REJECT,
9724 .prog_type = BPF_PROG_TYPE_XDP,
9725 },
9726 {
9727 "XDP pkt read, pkt_meta' <= pkt_data, good access",
9728 .insns = {
9729 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9730 offsetof(struct xdp_md, data_meta)),
9731 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9732 offsetof(struct xdp_md, data)),
9733 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9735 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9736 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9737 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9738 BPF_MOV64_IMM(BPF_REG_0, 0),
9739 BPF_EXIT_INSN(),
9740 },
9741 .result = ACCEPT,
9742 .prog_type = BPF_PROG_TYPE_XDP,
9743 },
9744 {
9745 "XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
9746 .insns = {
9747 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9748 offsetof(struct xdp_md, data_meta)),
9749 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9750 offsetof(struct xdp_md, data)),
9751 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9752 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9753 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9754 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9755 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9756 BPF_MOV64_IMM(BPF_REG_0, 0),
9757 BPF_EXIT_INSN(),
9758 },
9759 .errstr = "R1 offset is outside of the packet",
9760 .result = REJECT,
9761 .prog_type = BPF_PROG_TYPE_XDP,
9762 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9763 },
9764 {
9765 "XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
9766 .insns = {
9767 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9768 offsetof(struct xdp_md, data_meta)),
9769 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9770 offsetof(struct xdp_md, data)),
9771 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9772 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9773 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9774 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9775 BPF_MOV64_IMM(BPF_REG_0, 0),
9776 BPF_EXIT_INSN(),
9777 },
9778 .errstr = "R1 offset is outside of the packet",
9779 .result = REJECT,
9780 .prog_type = BPF_PROG_TYPE_XDP,
9781 },
9782 {
9783 "XDP pkt read, pkt_data <= pkt_meta', good access",
9784 .insns = {
9785 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9786 offsetof(struct xdp_md, data_meta)),
9787 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9788 offsetof(struct xdp_md, data)),
9789 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9791 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9792 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9793 BPF_MOV64_IMM(BPF_REG_0, 0),
9794 BPF_EXIT_INSN(),
9795 },
9796 .result = ACCEPT,
9797 .prog_type = BPF_PROG_TYPE_XDP,
9798 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9799 },
9800 {
9801 "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
9802 .insns = {
9803 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9804 offsetof(struct xdp_md, data_meta)),
9805 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9806 offsetof(struct xdp_md, data)),
9807 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9808 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9809 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9810 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9811 BPF_MOV64_IMM(BPF_REG_0, 0),
9812 BPF_EXIT_INSN(),
9813 },
9814 .errstr = "R1 offset is outside of the packet",
9815 .result = REJECT,
9816 .prog_type = BPF_PROG_TYPE_XDP,
9817 },
9818 {
9819 "XDP pkt read, pkt_data <= pkt_meta', bad access 2",
9820 .insns = {
9821 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9822 offsetof(struct xdp_md, data_meta)),
9823 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9824 offsetof(struct xdp_md, data)),
9825 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9826 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9827 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9828 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9829 BPF_MOV64_IMM(BPF_REG_0, 0),
9830 BPF_EXIT_INSN(),
9831 },
9832 .errstr = "R1 offset is outside of the packet",
9833 .result = REJECT,
9834 .prog_type = BPF_PROG_TYPE_XDP,
9835 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9836 },
9837 {
Daniel Borkmann6f161012018-01-18 01:15:21 +01009838 "check deducing bounds from const, 1",
9839 .insns = {
9840 BPF_MOV64_IMM(BPF_REG_0, 1),
9841 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
9842 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9843 BPF_EXIT_INSN(),
9844 },
9845 .result = REJECT,
9846 .errstr = "R0 tried to subtract pointer from scalar",
9847 },
9848 {
9849 "check deducing bounds from const, 2",
9850 .insns = {
9851 BPF_MOV64_IMM(BPF_REG_0, 1),
9852 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
9853 BPF_EXIT_INSN(),
9854 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
9855 BPF_EXIT_INSN(),
9856 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9857 BPF_EXIT_INSN(),
9858 },
9859 .result = ACCEPT,
Yonghong Song35136922018-01-22 22:10:59 -08009860 .retval = 1,
Daniel Borkmann6f161012018-01-18 01:15:21 +01009861 },
9862 {
9863 "check deducing bounds from const, 3",
9864 .insns = {
9865 BPF_MOV64_IMM(BPF_REG_0, 0),
9866 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9867 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9868 BPF_EXIT_INSN(),
9869 },
9870 .result = REJECT,
9871 .errstr = "R0 tried to subtract pointer from scalar",
9872 },
9873 {
9874 "check deducing bounds from const, 4",
9875 .insns = {
9876 BPF_MOV64_IMM(BPF_REG_0, 0),
9877 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
9878 BPF_EXIT_INSN(),
9879 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9880 BPF_EXIT_INSN(),
9881 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9882 BPF_EXIT_INSN(),
9883 },
9884 .result = ACCEPT,
9885 },
9886 {
9887 "check deducing bounds from const, 5",
9888 .insns = {
9889 BPF_MOV64_IMM(BPF_REG_0, 0),
9890 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9891 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9892 BPF_EXIT_INSN(),
9893 },
9894 .result = REJECT,
9895 .errstr = "R0 tried to subtract pointer from scalar",
9896 },
9897 {
9898 "check deducing bounds from const, 6",
9899 .insns = {
9900 BPF_MOV64_IMM(BPF_REG_0, 0),
9901 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9902 BPF_EXIT_INSN(),
9903 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9904 BPF_EXIT_INSN(),
9905 },
9906 .result = REJECT,
9907 .errstr = "R0 tried to subtract pointer from scalar",
9908 },
9909 {
9910 "check deducing bounds from const, 7",
9911 .insns = {
9912 BPF_MOV64_IMM(BPF_REG_0, ~0),
9913 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9914 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
9915 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9916 offsetof(struct __sk_buff, mark)),
9917 BPF_EXIT_INSN(),
9918 },
9919 .result = REJECT,
9920 .errstr = "dereference of modified ctx ptr",
9921 },
9922 {
9923 "check deducing bounds from const, 8",
9924 .insns = {
9925 BPF_MOV64_IMM(BPF_REG_0, ~0),
9926 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
9927 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
9928 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9929 offsetof(struct __sk_buff, mark)),
9930 BPF_EXIT_INSN(),
9931 },
9932 .result = REJECT,
9933 .errstr = "dereference of modified ctx ptr",
9934 },
9935 {
9936 "check deducing bounds from const, 9",
9937 .insns = {
9938 BPF_MOV64_IMM(BPF_REG_0, 0),
9939 BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
9940 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9941 BPF_EXIT_INSN(),
9942 },
9943 .result = REJECT,
9944 .errstr = "R0 tried to subtract pointer from scalar",
9945 },
9946 {
9947 "check deducing bounds from const, 10",
9948 .insns = {
9949 BPF_MOV64_IMM(BPF_REG_0, 0),
9950 BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
9951 /* Marks reg as unknown. */
9952 BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
9953 BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
9954 BPF_EXIT_INSN(),
9955 },
9956 .result = REJECT,
9957 .errstr = "math between ctx pointer and register with unbounded min value is not allowed",
9958 },
9959 {
Daniel Borkmannb06723d2017-11-01 23:58:09 +01009960 "bpf_exit with invalid return code. test1",
9961 .insns = {
9962 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9963 BPF_EXIT_INSN(),
9964 },
9965 .errstr = "R0 has value (0x0; 0xffffffff)",
9966 .result = REJECT,
9967 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9968 },
9969 {
9970 "bpf_exit with invalid return code. test2",
9971 .insns = {
9972 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9973 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
9974 BPF_EXIT_INSN(),
9975 },
9976 .result = ACCEPT,
9977 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9978 },
9979 {
9980 "bpf_exit with invalid return code. test3",
9981 .insns = {
9982 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9983 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
9984 BPF_EXIT_INSN(),
9985 },
9986 .errstr = "R0 has value (0x0; 0x3)",
9987 .result = REJECT,
9988 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9989 },
9990 {
9991 "bpf_exit with invalid return code. test4",
9992 .insns = {
9993 BPF_MOV64_IMM(BPF_REG_0, 1),
9994 BPF_EXIT_INSN(),
9995 },
9996 .result = ACCEPT,
9997 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9998 },
9999 {
10000 "bpf_exit with invalid return code. test5",
10001 .insns = {
10002 BPF_MOV64_IMM(BPF_REG_0, 2),
10003 BPF_EXIT_INSN(),
10004 },
10005 .errstr = "R0 has value (0x2; 0x0)",
10006 .result = REJECT,
10007 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10008 },
10009 {
10010 "bpf_exit with invalid return code. test6",
10011 .insns = {
10012 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10013 BPF_EXIT_INSN(),
10014 },
10015 .errstr = "R0 is not a known value (ctx)",
10016 .result = REJECT,
10017 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10018 },
10019 {
10020 "bpf_exit with invalid return code. test7",
10021 .insns = {
10022 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10023 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
10024 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
10025 BPF_EXIT_INSN(),
10026 },
10027 .errstr = "R0 has unknown scalar value",
10028 .result = REJECT,
10029 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
10030 },
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010031 {
10032 "calls: basic sanity",
10033 .insns = {
10034 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10035 BPF_MOV64_IMM(BPF_REG_0, 1),
10036 BPF_EXIT_INSN(),
10037 BPF_MOV64_IMM(BPF_REG_0, 2),
10038 BPF_EXIT_INSN(),
10039 },
10040 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10041 .result = ACCEPT,
10042 },
10043 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010044 "calls: not on unpriviledged",
10045 .insns = {
10046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10047 BPF_MOV64_IMM(BPF_REG_0, 1),
10048 BPF_EXIT_INSN(),
10049 BPF_MOV64_IMM(BPF_REG_0, 2),
10050 BPF_EXIT_INSN(),
10051 },
10052 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
10053 .result_unpriv = REJECT,
10054 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010055 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010056 },
10057 {
Daniel Borkmann21ccaf22018-01-26 23:33:48 +010010058 "calls: div by 0 in subprog",
10059 .insns = {
10060 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10061 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10062 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10063 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10064 offsetof(struct __sk_buff, data_end)),
10065 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10067 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10068 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10069 BPF_MOV64_IMM(BPF_REG_0, 1),
10070 BPF_EXIT_INSN(),
10071 BPF_MOV32_IMM(BPF_REG_2, 0),
10072 BPF_MOV32_IMM(BPF_REG_3, 1),
10073 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
10074 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10075 offsetof(struct __sk_buff, data)),
10076 BPF_EXIT_INSN(),
10077 },
10078 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10079 .result = ACCEPT,
10080 .retval = 1,
10081 },
10082 {
10083 "calls: multiple ret types in subprog 1",
10084 .insns = {
10085 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10086 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10087 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10088 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10089 offsetof(struct __sk_buff, data_end)),
10090 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10091 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10092 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10093 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10094 BPF_MOV64_IMM(BPF_REG_0, 1),
10095 BPF_EXIT_INSN(),
10096 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10097 offsetof(struct __sk_buff, data)),
10098 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
10099 BPF_MOV32_IMM(BPF_REG_0, 42),
10100 BPF_EXIT_INSN(),
10101 },
10102 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10103 .result = REJECT,
10104 .errstr = "R0 invalid mem access 'inv'",
10105 },
10106 {
10107 "calls: multiple ret types in subprog 2",
10108 .insns = {
10109 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10110 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10111 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10112 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
10113 offsetof(struct __sk_buff, data_end)),
10114 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
10115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
10116 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
10117 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
10118 BPF_MOV64_IMM(BPF_REG_0, 1),
10119 BPF_EXIT_INSN(),
10120 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10121 offsetof(struct __sk_buff, data)),
10122 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10123 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
10124 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10125 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10126 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10127 BPF_LD_MAP_FD(BPF_REG_1, 0),
10128 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10129 BPF_FUNC_map_lookup_elem),
10130 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
10131 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
10132 offsetof(struct __sk_buff, data)),
10133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
10134 BPF_EXIT_INSN(),
10135 },
10136 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10137 .fixup_map1 = { 16 },
10138 .result = REJECT,
10139 .errstr = "R0 min value is outside of the array range",
10140 },
10141 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010142 "calls: overlapping caller/callee",
10143 .insns = {
10144 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
10145 BPF_MOV64_IMM(BPF_REG_0, 1),
10146 BPF_EXIT_INSN(),
10147 },
10148 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10149 .errstr = "last insn is not an exit or jmp",
10150 .result = REJECT,
10151 },
10152 {
10153 "calls: wrong recursive calls",
10154 .insns = {
10155 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10156 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10157 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10158 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10159 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
10160 BPF_MOV64_IMM(BPF_REG_0, 1),
10161 BPF_EXIT_INSN(),
10162 },
10163 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10164 .errstr = "jump out of range",
10165 .result = REJECT,
10166 },
10167 {
10168 "calls: wrong src reg",
10169 .insns = {
10170 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
10171 BPF_MOV64_IMM(BPF_REG_0, 1),
10172 BPF_EXIT_INSN(),
10173 },
10174 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10175 .errstr = "BPF_CALL uses reserved fields",
10176 .result = REJECT,
10177 },
10178 {
10179 "calls: wrong off value",
10180 .insns = {
10181 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
10182 BPF_MOV64_IMM(BPF_REG_0, 1),
10183 BPF_EXIT_INSN(),
10184 BPF_MOV64_IMM(BPF_REG_0, 2),
10185 BPF_EXIT_INSN(),
10186 },
10187 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10188 .errstr = "BPF_CALL uses reserved fields",
10189 .result = REJECT,
10190 },
10191 {
10192 "calls: jump back loop",
10193 .insns = {
10194 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10195 BPF_MOV64_IMM(BPF_REG_0, 1),
10196 BPF_EXIT_INSN(),
10197 },
10198 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10199 .errstr = "back-edge from insn 0 to 0",
10200 .result = REJECT,
10201 },
10202 {
10203 "calls: conditional call",
10204 .insns = {
10205 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10206 offsetof(struct __sk_buff, mark)),
10207 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10209 BPF_MOV64_IMM(BPF_REG_0, 1),
10210 BPF_EXIT_INSN(),
10211 BPF_MOV64_IMM(BPF_REG_0, 2),
10212 BPF_EXIT_INSN(),
10213 },
10214 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10215 .errstr = "jump out of range",
10216 .result = REJECT,
10217 },
10218 {
10219 "calls: conditional call 2",
10220 .insns = {
10221 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10222 offsetof(struct __sk_buff, mark)),
10223 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10224 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10225 BPF_MOV64_IMM(BPF_REG_0, 1),
10226 BPF_EXIT_INSN(),
10227 BPF_MOV64_IMM(BPF_REG_0, 2),
10228 BPF_EXIT_INSN(),
10229 BPF_MOV64_IMM(BPF_REG_0, 3),
10230 BPF_EXIT_INSN(),
10231 },
10232 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10233 .result = ACCEPT,
10234 },
10235 {
10236 "calls: conditional call 3",
10237 .insns = {
10238 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10239 offsetof(struct __sk_buff, mark)),
10240 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10241 BPF_JMP_IMM(BPF_JA, 0, 0, 4),
10242 BPF_MOV64_IMM(BPF_REG_0, 1),
10243 BPF_EXIT_INSN(),
10244 BPF_MOV64_IMM(BPF_REG_0, 1),
10245 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10246 BPF_MOV64_IMM(BPF_REG_0, 3),
10247 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10248 },
10249 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10250 .errstr = "back-edge from insn",
10251 .result = REJECT,
10252 },
10253 {
10254 "calls: conditional call 4",
10255 .insns = {
10256 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10257 offsetof(struct __sk_buff, mark)),
10258 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10259 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10260 BPF_MOV64_IMM(BPF_REG_0, 1),
10261 BPF_EXIT_INSN(),
10262 BPF_MOV64_IMM(BPF_REG_0, 1),
10263 BPF_JMP_IMM(BPF_JA, 0, 0, -5),
10264 BPF_MOV64_IMM(BPF_REG_0, 3),
10265 BPF_EXIT_INSN(),
10266 },
10267 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10268 .result = ACCEPT,
10269 },
10270 {
10271 "calls: conditional call 5",
10272 .insns = {
10273 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10274 offsetof(struct __sk_buff, mark)),
10275 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
10276 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10277 BPF_MOV64_IMM(BPF_REG_0, 1),
10278 BPF_EXIT_INSN(),
10279 BPF_MOV64_IMM(BPF_REG_0, 1),
10280 BPF_JMP_IMM(BPF_JA, 0, 0, -6),
10281 BPF_MOV64_IMM(BPF_REG_0, 3),
10282 BPF_EXIT_INSN(),
10283 },
10284 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10285 .errstr = "back-edge from insn",
10286 .result = REJECT,
10287 },
10288 {
10289 "calls: conditional call 6",
10290 .insns = {
10291 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10292 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
10293 BPF_EXIT_INSN(),
10294 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10295 offsetof(struct __sk_buff, mark)),
10296 BPF_EXIT_INSN(),
10297 },
10298 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10299 .errstr = "back-edge from insn",
10300 .result = REJECT,
10301 },
10302 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010303 "calls: using r0 returned by callee",
10304 .insns = {
10305 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10306 BPF_EXIT_INSN(),
10307 BPF_MOV64_IMM(BPF_REG_0, 2),
10308 BPF_EXIT_INSN(),
10309 },
10310 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10311 .result = ACCEPT,
10312 },
10313 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010314 "calls: using uninit r0 from callee",
10315 .insns = {
10316 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10317 BPF_EXIT_INSN(),
10318 BPF_EXIT_INSN(),
10319 },
10320 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10321 .errstr = "!read_ok",
10322 .result = REJECT,
10323 },
10324 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010325 "calls: callee is using r1",
10326 .insns = {
10327 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10328 BPF_EXIT_INSN(),
10329 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10330 offsetof(struct __sk_buff, len)),
10331 BPF_EXIT_INSN(),
10332 },
10333 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
10334 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010335 .retval = TEST_DATA_LEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010336 },
10337 {
10338 "calls: callee using args1",
10339 .insns = {
10340 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10341 BPF_EXIT_INSN(),
10342 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10343 BPF_EXIT_INSN(),
10344 },
10345 .errstr_unpriv = "allowed for root only",
10346 .result_unpriv = REJECT,
10347 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010348 .retval = POINTER_VALUE,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010349 },
10350 {
10351 "calls: callee using wrong args2",
10352 .insns = {
10353 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10354 BPF_EXIT_INSN(),
10355 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
10356 BPF_EXIT_INSN(),
10357 },
10358 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10359 .errstr = "R2 !read_ok",
10360 .result = REJECT,
10361 },
10362 {
10363 "calls: callee using two args",
10364 .insns = {
10365 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10366 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
10367 offsetof(struct __sk_buff, len)),
10368 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
10369 offsetof(struct __sk_buff, len)),
10370 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10371 BPF_EXIT_INSN(),
10372 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10373 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
10374 BPF_EXIT_INSN(),
10375 },
10376 .errstr_unpriv = "allowed for root only",
10377 .result_unpriv = REJECT,
10378 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010379 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010380 },
10381 {
10382 "calls: callee changing pkt pointers",
10383 .insns = {
10384 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
10385 offsetof(struct xdp_md, data)),
10386 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
10387 offsetof(struct xdp_md, data_end)),
10388 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
10389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
10390 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
10391 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10392 /* clear_all_pkt_pointers() has to walk all frames
10393 * to make sure that pkt pointers in the caller
10394 * are cleared when callee is calling a helper that
10395 * adjusts packet size
10396 */
10397 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10398 BPF_MOV32_IMM(BPF_REG_0, 0),
10399 BPF_EXIT_INSN(),
10400 BPF_MOV64_IMM(BPF_REG_2, 0),
10401 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10402 BPF_FUNC_xdp_adjust_head),
10403 BPF_EXIT_INSN(),
10404 },
10405 .result = REJECT,
10406 .errstr = "R6 invalid mem access 'inv'",
10407 .prog_type = BPF_PROG_TYPE_XDP,
10408 },
10409 {
10410 "calls: two calls with args",
10411 .insns = {
10412 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10413 BPF_EXIT_INSN(),
10414 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10415 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10416 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10417 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10418 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10419 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10420 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10421 BPF_EXIT_INSN(),
10422 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10423 offsetof(struct __sk_buff, len)),
10424 BPF_EXIT_INSN(),
10425 },
10426 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10427 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010428 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010429 },
10430 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010431 "calls: calls with stack arith",
10432 .insns = {
10433 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10434 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10435 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10436 BPF_EXIT_INSN(),
10437 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10439 BPF_EXIT_INSN(),
10440 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
10441 BPF_MOV64_IMM(BPF_REG_0, 42),
10442 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10443 BPF_EXIT_INSN(),
10444 },
10445 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10446 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010447 .retval = 42,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010448 },
10449 {
10450 "calls: calls with misaligned stack access",
10451 .insns = {
10452 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10453 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10454 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10455 BPF_EXIT_INSN(),
10456 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
10457 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10458 BPF_EXIT_INSN(),
10459 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
10460 BPF_MOV64_IMM(BPF_REG_0, 42),
10461 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
10462 BPF_EXIT_INSN(),
10463 },
10464 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10465 .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
10466 .errstr = "misaligned stack access",
10467 .result = REJECT,
10468 },
10469 {
10470 "calls: calls control flow, jump test",
10471 .insns = {
10472 BPF_MOV64_IMM(BPF_REG_0, 42),
10473 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10474 BPF_MOV64_IMM(BPF_REG_0, 43),
10475 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10476 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10477 BPF_EXIT_INSN(),
10478 },
10479 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10480 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010481 .retval = 43,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010482 },
10483 {
10484 "calls: calls control flow, jump test 2",
10485 .insns = {
10486 BPF_MOV64_IMM(BPF_REG_0, 42),
10487 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10488 BPF_MOV64_IMM(BPF_REG_0, 43),
10489 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
10490 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10491 BPF_EXIT_INSN(),
10492 },
10493 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10494 .errstr = "jump out of range from insn 1 to 4",
10495 .result = REJECT,
10496 },
10497 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010498 "calls: two calls with bad jump",
10499 .insns = {
10500 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10501 BPF_EXIT_INSN(),
10502 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10503 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10504 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10505 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10506 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10507 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10508 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10509 BPF_EXIT_INSN(),
10510 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10511 offsetof(struct __sk_buff, len)),
10512 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
10513 BPF_EXIT_INSN(),
10514 },
10515 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10516 .errstr = "jump out of range from insn 11 to 9",
10517 .result = REJECT,
10518 },
10519 {
10520 "calls: recursive call. test1",
10521 .insns = {
10522 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10523 BPF_EXIT_INSN(),
10524 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10525 BPF_EXIT_INSN(),
10526 },
10527 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10528 .errstr = "back-edge",
10529 .result = REJECT,
10530 },
10531 {
10532 "calls: recursive call. test2",
10533 .insns = {
10534 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10535 BPF_EXIT_INSN(),
10536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10537 BPF_EXIT_INSN(),
10538 },
10539 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10540 .errstr = "back-edge",
10541 .result = REJECT,
10542 },
10543 {
10544 "calls: unreachable code",
10545 .insns = {
10546 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10547 BPF_EXIT_INSN(),
10548 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10549 BPF_EXIT_INSN(),
10550 BPF_MOV64_IMM(BPF_REG_0, 0),
10551 BPF_EXIT_INSN(),
10552 BPF_MOV64_IMM(BPF_REG_0, 0),
10553 BPF_EXIT_INSN(),
10554 },
10555 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10556 .errstr = "unreachable insn 6",
10557 .result = REJECT,
10558 },
10559 {
10560 "calls: invalid call",
10561 .insns = {
10562 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10563 BPF_EXIT_INSN(),
10564 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
10565 BPF_EXIT_INSN(),
10566 },
10567 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10568 .errstr = "invalid destination",
10569 .result = REJECT,
10570 },
10571 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010572 "calls: invalid call 2",
10573 .insns = {
10574 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10575 BPF_EXIT_INSN(),
10576 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
10577 BPF_EXIT_INSN(),
10578 },
10579 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10580 .errstr = "invalid destination",
10581 .result = REJECT,
10582 },
10583 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010584 "calls: jumping across function bodies. test1",
10585 .insns = {
10586 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10587 BPF_MOV64_IMM(BPF_REG_0, 0),
10588 BPF_EXIT_INSN(),
10589 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
10590 BPF_EXIT_INSN(),
10591 },
10592 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10593 .errstr = "jump out of range",
10594 .result = REJECT,
10595 },
10596 {
10597 "calls: jumping across function bodies. test2",
10598 .insns = {
10599 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
10600 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10601 BPF_MOV64_IMM(BPF_REG_0, 0),
10602 BPF_EXIT_INSN(),
10603 BPF_EXIT_INSN(),
10604 },
10605 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10606 .errstr = "jump out of range",
10607 .result = REJECT,
10608 },
10609 {
10610 "calls: call without exit",
10611 .insns = {
10612 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10613 BPF_EXIT_INSN(),
10614 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10615 BPF_EXIT_INSN(),
10616 BPF_MOV64_IMM(BPF_REG_0, 0),
10617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
10618 },
10619 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10620 .errstr = "not an exit",
10621 .result = REJECT,
10622 },
10623 {
10624 "calls: call into middle of ld_imm64",
10625 .insns = {
10626 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10627 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10628 BPF_MOV64_IMM(BPF_REG_0, 0),
10629 BPF_EXIT_INSN(),
10630 BPF_LD_IMM64(BPF_REG_0, 0),
10631 BPF_EXIT_INSN(),
10632 },
10633 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10634 .errstr = "last insn",
10635 .result = REJECT,
10636 },
10637 {
10638 "calls: call into middle of other call",
10639 .insns = {
10640 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10641 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10642 BPF_MOV64_IMM(BPF_REG_0, 0),
10643 BPF_EXIT_INSN(),
10644 BPF_MOV64_IMM(BPF_REG_0, 0),
10645 BPF_MOV64_IMM(BPF_REG_0, 0),
10646 BPF_EXIT_INSN(),
10647 },
10648 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10649 .errstr = "last insn",
10650 .result = REJECT,
10651 },
10652 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010653 "calls: ld_abs with changing ctx data in callee",
10654 .insns = {
10655 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10656 BPF_LD_ABS(BPF_B, 0),
10657 BPF_LD_ABS(BPF_H, 0),
10658 BPF_LD_ABS(BPF_W, 0),
10659 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
10660 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10661 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
10662 BPF_LD_ABS(BPF_B, 0),
10663 BPF_LD_ABS(BPF_H, 0),
10664 BPF_LD_ABS(BPF_W, 0),
10665 BPF_EXIT_INSN(),
10666 BPF_MOV64_IMM(BPF_REG_2, 1),
10667 BPF_MOV64_IMM(BPF_REG_3, 2),
10668 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10669 BPF_FUNC_skb_vlan_push),
10670 BPF_EXIT_INSN(),
10671 },
10672 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10673 .errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
10674 .result = REJECT,
10675 },
10676 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010677 "calls: two calls with bad fallthrough",
10678 .insns = {
10679 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10680 BPF_EXIT_INSN(),
10681 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10682 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10683 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10684 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10685 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10686 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10687 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10688 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
10689 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10690 offsetof(struct __sk_buff, len)),
10691 BPF_EXIT_INSN(),
10692 },
10693 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
10694 .errstr = "not an exit",
10695 .result = REJECT,
10696 },
10697 {
10698 "calls: two calls with stack read",
10699 .insns = {
10700 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10701 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10702 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10704 BPF_EXIT_INSN(),
10705 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10706 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10707 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10708 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10709 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10710 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10711 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10712 BPF_EXIT_INSN(),
10713 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10714 BPF_EXIT_INSN(),
10715 },
10716 .prog_type = BPF_PROG_TYPE_XDP,
10717 .result = ACCEPT,
10718 },
10719 {
10720 "calls: two calls with stack write",
10721 .insns = {
10722 /* main prog */
10723 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10724 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10725 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10726 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10727 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10728 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10729 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10730 BPF_EXIT_INSN(),
10731
10732 /* subprog 1 */
10733 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10734 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10735 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
10736 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
10737 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10738 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10739 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
10740 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
10741 /* write into stack frame of main prog */
10742 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10743 BPF_EXIT_INSN(),
10744
10745 /* subprog 2 */
10746 /* read from stack frame of main prog */
10747 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10748 BPF_EXIT_INSN(),
10749 },
10750 .prog_type = BPF_PROG_TYPE_XDP,
10751 .result = ACCEPT,
10752 },
10753 {
Jann Horn6b80ad22017-12-22 19:12:35 +010010754 "calls: stack overflow using two frames (pre-call access)",
10755 .insns = {
10756 /* prog 1 */
10757 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10758 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
10759 BPF_EXIT_INSN(),
10760
10761 /* prog 2 */
10762 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10763 BPF_MOV64_IMM(BPF_REG_0, 0),
10764 BPF_EXIT_INSN(),
10765 },
10766 .prog_type = BPF_PROG_TYPE_XDP,
10767 .errstr = "combined stack size",
10768 .result = REJECT,
10769 },
10770 {
10771 "calls: stack overflow using two frames (post-call access)",
10772 .insns = {
10773 /* prog 1 */
10774 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
10775 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10776 BPF_EXIT_INSN(),
10777
10778 /* prog 2 */
10779 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10780 BPF_MOV64_IMM(BPF_REG_0, 0),
10781 BPF_EXIT_INSN(),
10782 },
10783 .prog_type = BPF_PROG_TYPE_XDP,
10784 .errstr = "combined stack size",
10785 .result = REJECT,
10786 },
10787 {
Alexei Starovoitov6b86c422017-12-25 13:15:41 -080010788 "calls: stack depth check using three frames. test1",
10789 .insns = {
10790 /* main */
10791 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10792 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10793 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10794 BPF_MOV64_IMM(BPF_REG_0, 0),
10795 BPF_EXIT_INSN(),
10796 /* A */
10797 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10798 BPF_EXIT_INSN(),
10799 /* B */
10800 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10801 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10802 BPF_EXIT_INSN(),
10803 },
10804 .prog_type = BPF_PROG_TYPE_XDP,
10805 /* stack_main=32, stack_A=256, stack_B=64
10806 * and max(main+A, main+A+B) < 512
10807 */
10808 .result = ACCEPT,
10809 },
10810 {
10811 "calls: stack depth check using three frames. test2",
10812 .insns = {
10813 /* main */
10814 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10815 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
10816 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
10817 BPF_MOV64_IMM(BPF_REG_0, 0),
10818 BPF_EXIT_INSN(),
10819 /* A */
10820 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10821 BPF_EXIT_INSN(),
10822 /* B */
10823 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
10824 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10825 BPF_EXIT_INSN(),
10826 },
10827 .prog_type = BPF_PROG_TYPE_XDP,
10828 /* stack_main=32, stack_A=64, stack_B=256
10829 * and max(main+A, main+A+B) < 512
10830 */
10831 .result = ACCEPT,
10832 },
10833 {
10834 "calls: stack depth check using three frames. test3",
10835 .insns = {
10836 /* main */
10837 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10838 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10839 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10840 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
10841 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
10842 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
10843 BPF_MOV64_IMM(BPF_REG_0, 0),
10844 BPF_EXIT_INSN(),
10845 /* A */
10846 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
10847 BPF_EXIT_INSN(),
10848 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
10849 BPF_JMP_IMM(BPF_JA, 0, 0, -3),
10850 /* B */
10851 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
10852 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
10853 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
10854 BPF_EXIT_INSN(),
10855 },
10856 .prog_type = BPF_PROG_TYPE_XDP,
10857 /* stack_main=64, stack_A=224, stack_B=256
10858 * and max(main+A, main+A+B) > 512
10859 */
10860 .errstr = "combined stack",
10861 .result = REJECT,
10862 },
10863 {
10864 "calls: stack depth check using three frames. test4",
10865 /* void main(void) {
10866 * func1(0);
10867 * func1(1);
10868 * func2(1);
10869 * }
10870 * void func1(int alloc_or_recurse) {
10871 * if (alloc_or_recurse) {
10872 * frame_pointer[-300] = 1;
10873 * } else {
10874 * func2(alloc_or_recurse);
10875 * }
10876 * }
10877 * void func2(int alloc_or_recurse) {
10878 * if (alloc_or_recurse) {
10879 * frame_pointer[-300] = 1;
10880 * }
10881 * }
10882 */
10883 .insns = {
10884 /* main */
10885 BPF_MOV64_IMM(BPF_REG_1, 0),
10886 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
10887 BPF_MOV64_IMM(BPF_REG_1, 1),
10888 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
10889 BPF_MOV64_IMM(BPF_REG_1, 1),
10890 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
10891 BPF_MOV64_IMM(BPF_REG_0, 0),
10892 BPF_EXIT_INSN(),
10893 /* A */
10894 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
10895 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10896 BPF_EXIT_INSN(),
10897 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10898 BPF_EXIT_INSN(),
10899 /* B */
10900 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10901 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
10902 BPF_EXIT_INSN(),
10903 },
10904 .prog_type = BPF_PROG_TYPE_XDP,
10905 .result = REJECT,
10906 .errstr = "combined stack",
10907 },
10908 {
Alexei Starovoitovaada9ce2017-12-25 13:15:42 -080010909 "calls: stack depth check using three frames. test5",
10910 .insns = {
10911 /* main */
10912 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
10913 BPF_EXIT_INSN(),
10914 /* A */
10915 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10916 BPF_EXIT_INSN(),
10917 /* B */
10918 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
10919 BPF_EXIT_INSN(),
10920 /* C */
10921 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
10922 BPF_EXIT_INSN(),
10923 /* D */
10924 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
10925 BPF_EXIT_INSN(),
10926 /* E */
10927 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
10928 BPF_EXIT_INSN(),
10929 /* F */
10930 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
10931 BPF_EXIT_INSN(),
10932 /* G */
10933 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
10934 BPF_EXIT_INSN(),
10935 /* H */
10936 BPF_MOV64_IMM(BPF_REG_0, 0),
10937 BPF_EXIT_INSN(),
10938 },
10939 .prog_type = BPF_PROG_TYPE_XDP,
10940 .errstr = "call stack",
10941 .result = REJECT,
10942 },
10943 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010944 "calls: spill into caller stack frame",
10945 .insns = {
10946 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10947 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10948 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10949 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10950 BPF_EXIT_INSN(),
10951 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
10952 BPF_MOV64_IMM(BPF_REG_0, 0),
10953 BPF_EXIT_INSN(),
10954 },
10955 .prog_type = BPF_PROG_TYPE_XDP,
10956 .errstr = "cannot spill",
10957 .result = REJECT,
10958 },
10959 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010960 "calls: write into caller stack frame",
10961 .insns = {
10962 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10963 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10964 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10966 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10967 BPF_EXIT_INSN(),
10968 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
10969 BPF_MOV64_IMM(BPF_REG_0, 0),
10970 BPF_EXIT_INSN(),
10971 },
10972 .prog_type = BPF_PROG_TYPE_XDP,
10973 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080010974 .retval = 42,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080010975 },
10976 {
10977 "calls: write into callee stack frame",
10978 .insns = {
10979 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10980 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
10981 BPF_EXIT_INSN(),
10982 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
10983 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
10984 BPF_EXIT_INSN(),
10985 },
10986 .prog_type = BPF_PROG_TYPE_XDP,
10987 .errstr = "cannot return stack pointer",
10988 .result = REJECT,
10989 },
10990 {
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080010991 "calls: two calls with stack write and void return",
10992 .insns = {
10993 /* main prog */
10994 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10995 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10996 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10997 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10998 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10999 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11000 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
11001 BPF_EXIT_INSN(),
11002
11003 /* subprog 1 */
11004 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11005 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11006 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11007 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11008 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11009 BPF_EXIT_INSN(),
11010
11011 /* subprog 2 */
11012 /* write into stack frame of main prog */
11013 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
11014 BPF_EXIT_INSN(), /* void return */
11015 },
11016 .prog_type = BPF_PROG_TYPE_XDP,
11017 .result = ACCEPT,
11018 },
11019 {
11020 "calls: ambiguous return value",
11021 .insns = {
11022 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11023 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
11024 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11025 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11026 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11027 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11028 BPF_EXIT_INSN(),
11029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
11030 BPF_MOV64_IMM(BPF_REG_0, 0),
11031 BPF_EXIT_INSN(),
11032 },
11033 .errstr_unpriv = "allowed for root only",
11034 .result_unpriv = REJECT,
11035 .errstr = "R0 !read_ok",
11036 .result = REJECT,
11037 },
11038 {
11039 "calls: two calls that return map_value",
11040 .insns = {
11041 /* main prog */
11042 /* pass fp-16, fp-8 into a function */
11043 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11045 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11046 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11047 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
11048
11049 /* fetch map_value_ptr from the stack of this function */
11050 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11051 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11052 /* write into map value */
11053 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11054 /* fetch secound map_value_ptr from the stack */
11055 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
11056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11057 /* write into map value */
11058 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11059 BPF_MOV64_IMM(BPF_REG_0, 0),
11060 BPF_EXIT_INSN(),
11061
11062 /* subprog 1 */
11063 /* call 3rd function twice */
11064 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11065 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11066 /* first time with fp-8 */
11067 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11068 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11069 /* second time with fp-16 */
11070 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11071 BPF_EXIT_INSN(),
11072
11073 /* subprog 2 */
11074 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11075 /* lookup from map */
11076 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11077 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11079 BPF_LD_MAP_FD(BPF_REG_1, 0),
11080 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11081 BPF_FUNC_map_lookup_elem),
11082 /* write map_value_ptr into stack frame of main prog */
11083 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11084 BPF_MOV64_IMM(BPF_REG_0, 0),
11085 BPF_EXIT_INSN(), /* return 0 */
11086 },
11087 .prog_type = BPF_PROG_TYPE_XDP,
11088 .fixup_map1 = { 23 },
11089 .result = ACCEPT,
11090 },
11091 {
11092 "calls: two calls that return map_value with bool condition",
11093 .insns = {
11094 /* main prog */
11095 /* pass fp-16, fp-8 into a function */
11096 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11097 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11098 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11099 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11100 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11101 BPF_MOV64_IMM(BPF_REG_0, 0),
11102 BPF_EXIT_INSN(),
11103
11104 /* subprog 1 */
11105 /* call 3rd function twice */
11106 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11107 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11108 /* first time with fp-8 */
11109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
11110 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11111 /* fetch map_value_ptr from the stack of this function */
11112 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11113 /* write into map value */
11114 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11115 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11116 /* second time with fp-16 */
11117 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11118 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11119 /* fetch secound map_value_ptr from the stack */
11120 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
11121 /* write into map value */
11122 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11123 BPF_EXIT_INSN(),
11124
11125 /* subprog 2 */
11126 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11127 /* lookup from map */
11128 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11129 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11130 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11131 BPF_LD_MAP_FD(BPF_REG_1, 0),
11132 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11133 BPF_FUNC_map_lookup_elem),
11134 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11135 BPF_MOV64_IMM(BPF_REG_0, 0),
11136 BPF_EXIT_INSN(), /* return 0 */
11137 /* write map_value_ptr into stack frame of main prog */
11138 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11139 BPF_MOV64_IMM(BPF_REG_0, 1),
11140 BPF_EXIT_INSN(), /* return 1 */
11141 },
11142 .prog_type = BPF_PROG_TYPE_XDP,
11143 .fixup_map1 = { 23 },
11144 .result = ACCEPT,
11145 },
11146 {
11147 "calls: two calls that return map_value with incorrect bool check",
11148 .insns = {
11149 /* main prog */
11150 /* pass fp-16, fp-8 into a function */
11151 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11154 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11155 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11156 BPF_MOV64_IMM(BPF_REG_0, 0),
11157 BPF_EXIT_INSN(),
11158
11159 /* subprog 1 */
11160 /* call 3rd function twice */
11161 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11162 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11163 /* first time with fp-8 */
11164 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
11165 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
11166 /* fetch map_value_ptr from the stack of this function */
11167 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
11168 /* write into map value */
11169 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11170 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11171 /* second time with fp-16 */
11172 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11173 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11174 /* fetch secound map_value_ptr from the stack */
11175 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
11176 /* write into map value */
11177 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11178 BPF_EXIT_INSN(),
11179
11180 /* subprog 2 */
11181 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11182 /* lookup from map */
11183 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11184 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11186 BPF_LD_MAP_FD(BPF_REG_1, 0),
11187 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11188 BPF_FUNC_map_lookup_elem),
11189 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11190 BPF_MOV64_IMM(BPF_REG_0, 0),
11191 BPF_EXIT_INSN(), /* return 0 */
11192 /* write map_value_ptr into stack frame of main prog */
11193 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11194 BPF_MOV64_IMM(BPF_REG_0, 1),
11195 BPF_EXIT_INSN(), /* return 1 */
11196 },
11197 .prog_type = BPF_PROG_TYPE_XDP,
11198 .fixup_map1 = { 23 },
11199 .result = REJECT,
11200 .errstr = "invalid read from stack off -16+0 size 8",
11201 },
11202 {
11203 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
11204 .insns = {
11205 /* main prog */
11206 /* pass fp-16, fp-8 into a function */
11207 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11209 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11211 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11212 BPF_MOV64_IMM(BPF_REG_0, 0),
11213 BPF_EXIT_INSN(),
11214
11215 /* subprog 1 */
11216 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11217 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11218 /* 1st lookup from map */
11219 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11220 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11221 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11222 BPF_LD_MAP_FD(BPF_REG_1, 0),
11223 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11224 BPF_FUNC_map_lookup_elem),
11225 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11226 BPF_MOV64_IMM(BPF_REG_8, 0),
11227 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11228 /* write map_value_ptr into stack frame of main prog at fp-8 */
11229 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11230 BPF_MOV64_IMM(BPF_REG_8, 1),
11231
11232 /* 2nd lookup from map */
11233 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11235 BPF_LD_MAP_FD(BPF_REG_1, 0),
11236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11237 BPF_FUNC_map_lookup_elem),
11238 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11239 BPF_MOV64_IMM(BPF_REG_9, 0),
11240 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11241 /* write map_value_ptr into stack frame of main prog at fp-16 */
11242 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11243 BPF_MOV64_IMM(BPF_REG_9, 1),
11244
11245 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11246 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11247 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11248 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11249 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11250 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11251 BPF_EXIT_INSN(),
11252
11253 /* subprog 2 */
11254 /* if arg2 == 1 do *arg1 = 0 */
11255 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11256 /* fetch map_value_ptr from the stack of this function */
11257 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11258 /* write into map value */
11259 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11260
11261 /* if arg4 == 1 do *arg3 = 0 */
11262 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11263 /* fetch map_value_ptr from the stack of this function */
11264 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11265 /* write into map value */
11266 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11267 BPF_EXIT_INSN(),
11268 },
11269 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11270 .fixup_map1 = { 12, 22 },
11271 .result = REJECT,
11272 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11273 },
11274 {
11275 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
11276 .insns = {
11277 /* main prog */
11278 /* pass fp-16, fp-8 into a function */
11279 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11280 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11281 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11283 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11284 BPF_MOV64_IMM(BPF_REG_0, 0),
11285 BPF_EXIT_INSN(),
11286
11287 /* subprog 1 */
11288 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11289 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11290 /* 1st lookup from map */
11291 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11292 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11293 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11294 BPF_LD_MAP_FD(BPF_REG_1, 0),
11295 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11296 BPF_FUNC_map_lookup_elem),
11297 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11298 BPF_MOV64_IMM(BPF_REG_8, 0),
11299 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11300 /* write map_value_ptr into stack frame of main prog at fp-8 */
11301 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11302 BPF_MOV64_IMM(BPF_REG_8, 1),
11303
11304 /* 2nd lookup from map */
11305 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
11306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11307 BPF_LD_MAP_FD(BPF_REG_1, 0),
11308 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
11309 BPF_FUNC_map_lookup_elem),
11310 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11311 BPF_MOV64_IMM(BPF_REG_9, 0),
11312 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11313 /* write map_value_ptr into stack frame of main prog at fp-16 */
11314 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11315 BPF_MOV64_IMM(BPF_REG_9, 1),
11316
11317 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11318 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
11319 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11320 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11321 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11322 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
11323 BPF_EXIT_INSN(),
11324
11325 /* subprog 2 */
11326 /* if arg2 == 1 do *arg1 = 0 */
11327 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11328 /* fetch map_value_ptr from the stack of this function */
11329 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11330 /* write into map value */
11331 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11332
11333 /* if arg4 == 1 do *arg3 = 0 */
11334 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11335 /* fetch map_value_ptr from the stack of this function */
11336 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11337 /* write into map value */
11338 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11339 BPF_EXIT_INSN(),
11340 },
11341 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11342 .fixup_map1 = { 12, 22 },
11343 .result = ACCEPT,
11344 },
11345 {
11346 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
11347 .insns = {
11348 /* main prog */
11349 /* pass fp-16, fp-8 into a function */
11350 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11351 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11352 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11353 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11354 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11355 BPF_MOV64_IMM(BPF_REG_0, 0),
11356 BPF_EXIT_INSN(),
11357
11358 /* subprog 1 */
11359 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11360 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11361 /* 1st lookup from map */
11362 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
11363 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11365 BPF_LD_MAP_FD(BPF_REG_1, 0),
11366 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11367 BPF_FUNC_map_lookup_elem),
11368 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11369 BPF_MOV64_IMM(BPF_REG_8, 0),
11370 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11371 /* write map_value_ptr into stack frame of main prog at fp-8 */
11372 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11373 BPF_MOV64_IMM(BPF_REG_8, 1),
11374
11375 /* 2nd lookup from map */
11376 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11378 BPF_LD_MAP_FD(BPF_REG_1, 0),
11379 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11380 BPF_FUNC_map_lookup_elem),
11381 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11382 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
11383 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11384 /* write map_value_ptr into stack frame of main prog at fp-16 */
11385 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11386 BPF_MOV64_IMM(BPF_REG_9, 1),
11387
11388 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11389 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
11390 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11391 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11392 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11393 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
11394 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
11395
11396 /* subprog 2 */
11397 /* if arg2 == 1 do *arg1 = 0 */
11398 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11399 /* fetch map_value_ptr from the stack of this function */
11400 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11401 /* write into map value */
11402 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11403
11404 /* if arg4 == 1 do *arg3 = 0 */
11405 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11406 /* fetch map_value_ptr from the stack of this function */
11407 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11408 /* write into map value */
11409 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11410 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
11411 },
11412 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11413 .fixup_map1 = { 12, 22 },
11414 .result = REJECT,
11415 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
11416 },
11417 {
11418 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
11419 .insns = {
11420 /* main prog */
11421 /* pass fp-16, fp-8 into a function */
11422 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11424 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11425 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11426 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11427 BPF_MOV64_IMM(BPF_REG_0, 0),
11428 BPF_EXIT_INSN(),
11429
11430 /* subprog 1 */
11431 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11432 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11433 /* 1st lookup from map */
11434 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11435 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11436 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11437 BPF_LD_MAP_FD(BPF_REG_1, 0),
11438 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11439 BPF_FUNC_map_lookup_elem),
11440 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11441 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11442 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11443 BPF_MOV64_IMM(BPF_REG_8, 0),
11444 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11445 BPF_MOV64_IMM(BPF_REG_8, 1),
11446
11447 /* 2nd lookup from map */
11448 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11449 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11450 BPF_LD_MAP_FD(BPF_REG_1, 0),
11451 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11452 BPF_FUNC_map_lookup_elem),
11453 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11454 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11455 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11456 BPF_MOV64_IMM(BPF_REG_9, 0),
11457 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11458 BPF_MOV64_IMM(BPF_REG_9, 1),
11459
11460 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11461 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11462 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11463 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11464 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11465 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11466 BPF_EXIT_INSN(),
11467
11468 /* subprog 2 */
11469 /* if arg2 == 1 do *arg1 = 0 */
11470 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11471 /* fetch map_value_ptr from the stack of this function */
11472 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11473 /* write into map value */
11474 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11475
11476 /* if arg4 == 1 do *arg3 = 0 */
11477 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11478 /* fetch map_value_ptr from the stack of this function */
11479 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11480 /* write into map value */
11481 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11482 BPF_EXIT_INSN(),
11483 },
11484 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11485 .fixup_map1 = { 12, 22 },
11486 .result = ACCEPT,
11487 },
11488 {
11489 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
11490 .insns = {
11491 /* main prog */
11492 /* pass fp-16, fp-8 into a function */
11493 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11495 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11496 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11497 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11498 BPF_MOV64_IMM(BPF_REG_0, 0),
11499 BPF_EXIT_INSN(),
11500
11501 /* subprog 1 */
11502 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11503 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11504 /* 1st lookup from map */
11505 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11506 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11507 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11508 BPF_LD_MAP_FD(BPF_REG_1, 0),
11509 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11510 BPF_FUNC_map_lookup_elem),
11511 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11512 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11513 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11514 BPF_MOV64_IMM(BPF_REG_8, 0),
11515 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11516 BPF_MOV64_IMM(BPF_REG_8, 1),
11517
11518 /* 2nd lookup from map */
11519 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11520 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11521 BPF_LD_MAP_FD(BPF_REG_1, 0),
11522 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11523 BPF_FUNC_map_lookup_elem),
11524 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11525 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11526 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11527 BPF_MOV64_IMM(BPF_REG_9, 0),
11528 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11529 BPF_MOV64_IMM(BPF_REG_9, 1),
11530
11531 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11532 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11534 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11535 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11536 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11537 BPF_EXIT_INSN(),
11538
11539 /* subprog 2 */
11540 /* if arg2 == 1 do *arg1 = 0 */
11541 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11542 /* fetch map_value_ptr from the stack of this function */
11543 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11544 /* write into map value */
11545 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11546
11547 /* if arg4 == 0 do *arg3 = 0 */
11548 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
11549 /* fetch map_value_ptr from the stack of this function */
11550 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11551 /* write into map value */
11552 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11553 BPF_EXIT_INSN(),
11554 },
11555 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11556 .fixup_map1 = { 12, 22 },
11557 .result = REJECT,
11558 .errstr = "R0 invalid mem access 'inv'",
11559 },
11560 {
11561 "calls: pkt_ptr spill into caller stack",
11562 .insns = {
11563 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11565 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11566 BPF_EXIT_INSN(),
11567
11568 /* subprog 1 */
11569 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11570 offsetof(struct __sk_buff, data)),
11571 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11572 offsetof(struct __sk_buff, data_end)),
11573 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11574 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11575 /* spill unchecked pkt_ptr into stack of caller */
11576 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11577 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11578 /* now the pkt range is verified, read pkt_ptr from stack */
11579 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11580 /* write 4 bytes into packet */
11581 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11582 BPF_EXIT_INSN(),
11583 },
11584 .result = ACCEPT,
11585 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011586 .retval = POINTER_VALUE,
Alexei Starovoitova7ff3ec2017-12-14 17:55:07 -080011587 },
Alexei Starovoitovd98588c2017-12-14 17:55:09 -080011588 {
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011589 "calls: pkt_ptr spill into caller stack 2",
11590 .insns = {
11591 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11593 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11594 /* Marking is still kept, but not in all cases safe. */
11595 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11596 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11597 BPF_EXIT_INSN(),
11598
11599 /* subprog 1 */
11600 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11601 offsetof(struct __sk_buff, data)),
11602 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11603 offsetof(struct __sk_buff, data_end)),
11604 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11606 /* spill unchecked pkt_ptr into stack of caller */
11607 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11608 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11609 /* now the pkt range is verified, read pkt_ptr from stack */
11610 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11611 /* write 4 bytes into packet */
11612 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11613 BPF_EXIT_INSN(),
11614 },
11615 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11616 .errstr = "invalid access to packet",
11617 .result = REJECT,
11618 },
11619 {
11620 "calls: pkt_ptr spill into caller stack 3",
11621 .insns = {
11622 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11624 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11625 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11626 /* Marking is still kept and safe here. */
11627 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11628 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11629 BPF_EXIT_INSN(),
11630
11631 /* subprog 1 */
11632 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11633 offsetof(struct __sk_buff, data)),
11634 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11635 offsetof(struct __sk_buff, data_end)),
11636 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11637 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11638 /* spill unchecked pkt_ptr into stack of caller */
11639 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11640 BPF_MOV64_IMM(BPF_REG_5, 0),
11641 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11642 BPF_MOV64_IMM(BPF_REG_5, 1),
11643 /* now the pkt range is verified, read pkt_ptr from stack */
11644 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11645 /* write 4 bytes into packet */
11646 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11647 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11648 BPF_EXIT_INSN(),
11649 },
11650 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11651 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011652 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011653 },
11654 {
11655 "calls: pkt_ptr spill into caller stack 4",
11656 .insns = {
11657 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11658 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11659 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11660 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11661 /* Check marking propagated. */
11662 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11663 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
11664 BPF_EXIT_INSN(),
11665
11666 /* subprog 1 */
11667 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11668 offsetof(struct __sk_buff, data)),
11669 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11670 offsetof(struct __sk_buff, data_end)),
11671 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11672 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11673 /* spill unchecked pkt_ptr into stack of caller */
11674 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11675 BPF_MOV64_IMM(BPF_REG_5, 0),
11676 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11677 BPF_MOV64_IMM(BPF_REG_5, 1),
11678 /* don't read back pkt_ptr from stack here */
11679 /* write 4 bytes into packet */
11680 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11681 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11682 BPF_EXIT_INSN(),
11683 },
11684 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11685 .result = ACCEPT,
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080011686 .retval = 1,
Daniel Borkmann28ab1732017-12-14 17:55:17 -080011687 },
11688 {
11689 "calls: pkt_ptr spill into caller stack 5",
11690 .insns = {
11691 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11692 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11693 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
11694 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11695 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11696 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11697 BPF_EXIT_INSN(),
11698
11699 /* subprog 1 */
11700 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11701 offsetof(struct __sk_buff, data)),
11702 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11703 offsetof(struct __sk_buff, data_end)),
11704 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11705 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11706 BPF_MOV64_IMM(BPF_REG_5, 0),
11707 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11708 /* spill checked pkt_ptr into stack of caller */
11709 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11710 BPF_MOV64_IMM(BPF_REG_5, 1),
11711 /* don't read back pkt_ptr from stack here */
11712 /* write 4 bytes into packet */
11713 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11714 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11715 BPF_EXIT_INSN(),
11716 },
11717 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11718 .errstr = "same insn cannot be used with different",
11719 .result = REJECT,
11720 },
11721 {
11722 "calls: pkt_ptr spill into caller stack 6",
11723 .insns = {
11724 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11725 offsetof(struct __sk_buff, data_end)),
11726 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11727 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11728 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11729 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11730 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11731 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11732 BPF_EXIT_INSN(),
11733
11734 /* subprog 1 */
11735 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11736 offsetof(struct __sk_buff, data)),
11737 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11738 offsetof(struct __sk_buff, data_end)),
11739 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11740 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11741 BPF_MOV64_IMM(BPF_REG_5, 0),
11742 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11743 /* spill checked pkt_ptr into stack of caller */
11744 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11745 BPF_MOV64_IMM(BPF_REG_5, 1),
11746 /* don't read back pkt_ptr from stack here */
11747 /* write 4 bytes into packet */
11748 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11749 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11750 BPF_EXIT_INSN(),
11751 },
11752 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11753 .errstr = "R4 invalid mem access",
11754 .result = REJECT,
11755 },
11756 {
11757 "calls: pkt_ptr spill into caller stack 7",
11758 .insns = {
11759 BPF_MOV64_IMM(BPF_REG_2, 0),
11760 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11762 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11763 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11764 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11765 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11766 BPF_EXIT_INSN(),
11767
11768 /* subprog 1 */
11769 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11770 offsetof(struct __sk_buff, data)),
11771 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11772 offsetof(struct __sk_buff, data_end)),
11773 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11775 BPF_MOV64_IMM(BPF_REG_5, 0),
11776 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11777 /* spill checked pkt_ptr into stack of caller */
11778 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11779 BPF_MOV64_IMM(BPF_REG_5, 1),
11780 /* don't read back pkt_ptr from stack here */
11781 /* write 4 bytes into packet */
11782 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11783 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11784 BPF_EXIT_INSN(),
11785 },
11786 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11787 .errstr = "R4 invalid mem access",
11788 .result = REJECT,
11789 },
11790 {
11791 "calls: pkt_ptr spill into caller stack 8",
11792 .insns = {
11793 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11794 offsetof(struct __sk_buff, data)),
11795 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11796 offsetof(struct __sk_buff, data_end)),
11797 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11798 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11799 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11800 BPF_EXIT_INSN(),
11801 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11802 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11803 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11804 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11805 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11806 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11807 BPF_EXIT_INSN(),
11808
11809 /* subprog 1 */
11810 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11811 offsetof(struct __sk_buff, data)),
11812 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11813 offsetof(struct __sk_buff, data_end)),
11814 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11815 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11816 BPF_MOV64_IMM(BPF_REG_5, 0),
11817 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
11818 /* spill checked pkt_ptr into stack of caller */
11819 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11820 BPF_MOV64_IMM(BPF_REG_5, 1),
11821 /* don't read back pkt_ptr from stack here */
11822 /* write 4 bytes into packet */
11823 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11824 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11825 BPF_EXIT_INSN(),
11826 },
11827 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11828 .result = ACCEPT,
11829 },
11830 {
11831 "calls: pkt_ptr spill into caller stack 9",
11832 .insns = {
11833 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11834 offsetof(struct __sk_buff, data)),
11835 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11836 offsetof(struct __sk_buff, data_end)),
11837 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11838 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11839 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
11840 BPF_EXIT_INSN(),
11841 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11842 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11843 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11844 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
11845 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
11846 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
11847 BPF_EXIT_INSN(),
11848
11849 /* subprog 1 */
11850 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11851 offsetof(struct __sk_buff, data)),
11852 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11853 offsetof(struct __sk_buff, data_end)),
11854 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11855 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11856 BPF_MOV64_IMM(BPF_REG_5, 0),
11857 /* spill unchecked pkt_ptr into stack of caller */
11858 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11859 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11860 BPF_MOV64_IMM(BPF_REG_5, 1),
11861 /* don't read back pkt_ptr from stack here */
11862 /* write 4 bytes into packet */
11863 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11864 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
11865 BPF_EXIT_INSN(),
11866 },
11867 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11868 .errstr = "invalid access to packet",
11869 .result = REJECT,
11870 },
11871 {
Alexei Starovoitovd98588c2017-12-14 17:55:09 -080011872 "calls: caller stack init to zero or map_value_or_null",
11873 .insns = {
11874 BPF_MOV64_IMM(BPF_REG_0, 0),
11875 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11876 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11877 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11878 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11879 /* fetch map_value_or_null or const_zero from stack */
11880 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11881 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11882 /* store into map_value */
11883 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
11884 BPF_EXIT_INSN(),
11885
11886 /* subprog 1 */
11887 /* if (ctx == 0) return; */
11888 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
11889 /* else bpf_map_lookup() and *(fp - 8) = r0 */
11890 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
11891 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11892 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11893 BPF_LD_MAP_FD(BPF_REG_1, 0),
11894 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11895 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11896 BPF_FUNC_map_lookup_elem),
11897 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11898 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11899 BPF_EXIT_INSN(),
11900 },
11901 .fixup_map1 = { 13 },
11902 .result = ACCEPT,
11903 .prog_type = BPF_PROG_TYPE_XDP,
11904 },
11905 {
11906 "calls: stack init to zero and pruning",
11907 .insns = {
11908 /* first make allocated_stack 16 byte */
11909 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
11910 /* now fork the execution such that the false branch
11911 * of JGT insn will be verified second and it skisp zero
11912 * init of fp-8 stack slot. If stack liveness marking
11913 * is missing live_read marks from call map_lookup
11914 * processing then pruning will incorrectly assume
11915 * that fp-8 stack slot was unused in the fall-through
11916 * branch and will accept the program incorrectly
11917 */
11918 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
11919 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11920 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
11921 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11923 BPF_LD_MAP_FD(BPF_REG_1, 0),
11924 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11925 BPF_FUNC_map_lookup_elem),
11926 BPF_EXIT_INSN(),
11927 },
11928 .fixup_map2 = { 6 },
11929 .errstr = "invalid indirect read from stack off -8+0 size 8",
11930 .result = REJECT,
11931 .prog_type = BPF_PROG_TYPE_XDP,
11932 },
Gianluca Borellofd05e572017-12-23 10:09:55 +000011933 {
Daniel Borkmann06be0862018-06-02 23:06:31 +020011934 "calls: two calls returning different map pointers for lookup (hash, array)",
11935 .insns = {
11936 /* main prog */
11937 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11938 BPF_CALL_REL(11),
11939 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11940 BPF_CALL_REL(12),
11941 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11942 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11943 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11944 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11945 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11946 BPF_FUNC_map_lookup_elem),
11947 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11948 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
11949 offsetof(struct test_val, foo)),
11950 BPF_MOV64_IMM(BPF_REG_0, 1),
11951 BPF_EXIT_INSN(),
11952 /* subprog 1 */
11953 BPF_LD_MAP_FD(BPF_REG_0, 0),
11954 BPF_EXIT_INSN(),
11955 /* subprog 2 */
11956 BPF_LD_MAP_FD(BPF_REG_0, 0),
11957 BPF_EXIT_INSN(),
11958 },
11959 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11960 .fixup_map2 = { 13 },
11961 .fixup_map4 = { 16 },
11962 .result = ACCEPT,
11963 .retval = 1,
11964 },
11965 {
11966 "calls: two calls returning different map pointers for lookup (hash, map in map)",
11967 .insns = {
11968 /* main prog */
11969 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
11970 BPF_CALL_REL(11),
11971 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11972 BPF_CALL_REL(12),
11973 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
11974 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11975 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11976 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11977 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11978 BPF_FUNC_map_lookup_elem),
11979 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11980 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
11981 offsetof(struct test_val, foo)),
11982 BPF_MOV64_IMM(BPF_REG_0, 1),
11983 BPF_EXIT_INSN(),
11984 /* subprog 1 */
11985 BPF_LD_MAP_FD(BPF_REG_0, 0),
11986 BPF_EXIT_INSN(),
11987 /* subprog 2 */
11988 BPF_LD_MAP_FD(BPF_REG_0, 0),
11989 BPF_EXIT_INSN(),
11990 },
11991 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
11992 .fixup_map_in_map = { 16 },
11993 .fixup_map4 = { 13 },
11994 .result = REJECT,
11995 .errstr = "R0 invalid mem access 'map_ptr'",
11996 },
11997 {
11998 "cond: two branches returning different map pointers for lookup (tail, tail)",
11999 .insns = {
12000 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
12001 offsetof(struct __sk_buff, mark)),
12002 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 3),
12003 BPF_LD_MAP_FD(BPF_REG_2, 0),
12004 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12005 BPF_LD_MAP_FD(BPF_REG_2, 0),
12006 BPF_MOV64_IMM(BPF_REG_3, 7),
12007 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12008 BPF_FUNC_tail_call),
12009 BPF_MOV64_IMM(BPF_REG_0, 1),
12010 BPF_EXIT_INSN(),
12011 },
12012 .fixup_prog1 = { 5 },
12013 .fixup_prog2 = { 2 },
12014 .result_unpriv = REJECT,
12015 .errstr_unpriv = "tail_call abusing map_ptr",
12016 .result = ACCEPT,
12017 .retval = 42,
12018 },
12019 {
12020 "cond: two branches returning same map pointers for lookup (tail, tail)",
12021 .insns = {
12022 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
12023 offsetof(struct __sk_buff, mark)),
12024 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 3),
12025 BPF_LD_MAP_FD(BPF_REG_2, 0),
12026 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12027 BPF_LD_MAP_FD(BPF_REG_2, 0),
12028 BPF_MOV64_IMM(BPF_REG_3, 7),
12029 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12030 BPF_FUNC_tail_call),
12031 BPF_MOV64_IMM(BPF_REG_0, 1),
12032 BPF_EXIT_INSN(),
12033 },
12034 .fixup_prog2 = { 2, 5 },
12035 .result_unpriv = ACCEPT,
12036 .result = ACCEPT,
12037 .retval = 42,
12038 },
12039 {
Gianluca Borellofd05e572017-12-23 10:09:55 +000012040 "search pruning: all branches should be verified (nop operation)",
12041 .insns = {
12042 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12044 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
12045 BPF_LD_MAP_FD(BPF_REG_1, 0),
12046 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
12047 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
12048 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
12049 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
12050 BPF_MOV64_IMM(BPF_REG_4, 0),
12051 BPF_JMP_A(1),
12052 BPF_MOV64_IMM(BPF_REG_4, 1),
12053 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
12054 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
12055 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
12056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
12057 BPF_MOV64_IMM(BPF_REG_6, 0),
12058 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
12059 BPF_EXIT_INSN(),
12060 },
12061 .fixup_map1 = { 3 },
12062 .errstr = "R6 invalid mem access 'inv'",
12063 .result = REJECT,
12064 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12065 },
12066 {
12067 "search pruning: all branches should be verified (invalid stack access)",
12068 .insns = {
12069 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12071 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
12072 BPF_LD_MAP_FD(BPF_REG_1, 0),
12073 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
12074 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
12075 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
12076 BPF_MOV64_IMM(BPF_REG_4, 0),
12077 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
12078 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
12079 BPF_JMP_A(1),
12080 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
12081 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
12082 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
12083 BPF_EXIT_INSN(),
12084 },
12085 .fixup_map1 = { 3 },
12086 .errstr = "invalid read from stack off -16+0 size 8",
12087 .result = REJECT,
12088 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12089 },
Daniel Borkmann23d191a2018-02-24 01:08:03 +010012090 {
12091 "jit: lsh, rsh, arsh by 1",
12092 .insns = {
12093 BPF_MOV64_IMM(BPF_REG_0, 1),
12094 BPF_MOV64_IMM(BPF_REG_1, 0xff),
12095 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
12096 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
12097 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
12098 BPF_EXIT_INSN(),
12099 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
12100 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
12101 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
12102 BPF_EXIT_INSN(),
12103 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
12104 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
12105 BPF_EXIT_INSN(),
12106 BPF_MOV64_IMM(BPF_REG_0, 2),
12107 BPF_EXIT_INSN(),
12108 },
12109 .result = ACCEPT,
12110 .retval = 2,
12111 },
12112 {
12113 "jit: mov32 for ldimm64, 1",
12114 .insns = {
12115 BPF_MOV64_IMM(BPF_REG_0, 2),
12116 BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
12117 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
12118 BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
12119 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
12120 BPF_MOV64_IMM(BPF_REG_0, 1),
12121 BPF_EXIT_INSN(),
12122 },
12123 .result = ACCEPT,
12124 .retval = 2,
12125 },
12126 {
12127 "jit: mov32 for ldimm64, 2",
12128 .insns = {
12129 BPF_MOV64_IMM(BPF_REG_0, 1),
12130 BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
12131 BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
12132 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
12133 BPF_MOV64_IMM(BPF_REG_0, 2),
12134 BPF_EXIT_INSN(),
12135 },
12136 .result = ACCEPT,
12137 .retval = 2,
12138 },
12139 {
12140 "jit: various mul tests",
12141 .insns = {
12142 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
12143 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
12144 BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
12145 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
12146 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
12147 BPF_MOV64_IMM(BPF_REG_0, 1),
12148 BPF_EXIT_INSN(),
12149 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
12150 BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
12151 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
12152 BPF_MOV64_IMM(BPF_REG_0, 1),
12153 BPF_EXIT_INSN(),
12154 BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
12155 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
12156 BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
12157 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
12158 BPF_MOV64_IMM(BPF_REG_0, 1),
12159 BPF_EXIT_INSN(),
12160 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
12161 BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
12162 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
12163 BPF_MOV64_IMM(BPF_REG_0, 1),
12164 BPF_EXIT_INSN(),
12165 BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
12166 BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
12167 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
12168 BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
12169 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
12170 BPF_MOV64_IMM(BPF_REG_0, 1),
12171 BPF_EXIT_INSN(),
12172 BPF_MOV64_IMM(BPF_REG_0, 2),
12173 BPF_EXIT_INSN(),
12174 },
12175 .result = ACCEPT,
12176 .retval = 2,
12177 },
David S. Miller0f3e9c92018-03-06 00:53:44 -050012178 {
Daniel Borkmannca369602018-02-23 22:29:05 +010012179 "xadd/w check unaligned stack",
12180 .insns = {
12181 BPF_MOV64_IMM(BPF_REG_0, 1),
12182 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12183 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
12184 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12185 BPF_EXIT_INSN(),
12186 },
12187 .result = REJECT,
12188 .errstr = "misaligned stack access off",
12189 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12190 },
12191 {
12192 "xadd/w check unaligned map",
12193 .insns = {
12194 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12195 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12196 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12197 BPF_LD_MAP_FD(BPF_REG_1, 0),
12198 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12199 BPF_FUNC_map_lookup_elem),
12200 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
12201 BPF_EXIT_INSN(),
12202 BPF_MOV64_IMM(BPF_REG_1, 1),
12203 BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
12204 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
12205 BPF_EXIT_INSN(),
12206 },
12207 .fixup_map1 = { 3 },
12208 .result = REJECT,
12209 .errstr = "misaligned value access off",
12210 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12211 },
12212 {
12213 "xadd/w check unaligned pkt",
12214 .insns = {
12215 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
12216 offsetof(struct xdp_md, data)),
12217 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
12218 offsetof(struct xdp_md, data_end)),
12219 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
12220 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
12221 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
12222 BPF_MOV64_IMM(BPF_REG_0, 99),
12223 BPF_JMP_IMM(BPF_JA, 0, 0, 6),
12224 BPF_MOV64_IMM(BPF_REG_0, 1),
12225 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
12226 BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
12227 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
12228 BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
12229 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
12230 BPF_EXIT_INSN(),
12231 },
12232 .result = REJECT,
Joe Stringer9d2be442018-10-02 13:35:31 -070012233 .errstr = "BPF_XADD stores into R2 ctx",
Daniel Borkmannca369602018-02-23 22:29:05 +010012234 .prog_type = BPF_PROG_TYPE_XDP,
12235 },
Yonghong Song2abe611c2018-04-28 22:28:14 -070012236 {
Daniel Borkmannfa47a162018-07-19 18:18:36 +020012237 "xadd/w check whether src/dst got mangled, 1",
12238 .insns = {
12239 BPF_MOV64_IMM(BPF_REG_0, 1),
12240 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12241 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12242 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12243 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12244 BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
12245 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12246 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12247 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
12248 BPF_EXIT_INSN(),
12249 BPF_MOV64_IMM(BPF_REG_0, 42),
12250 BPF_EXIT_INSN(),
12251 },
12252 .result = ACCEPT,
12253 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12254 .retval = 3,
12255 },
12256 {
12257 "xadd/w check whether src/dst got mangled, 2",
12258 .insns = {
12259 BPF_MOV64_IMM(BPF_REG_0, 1),
12260 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
12261 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12262 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12263 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12264 BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8),
12265 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3),
12266 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2),
12267 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
12268 BPF_EXIT_INSN(),
12269 BPF_MOV64_IMM(BPF_REG_0, 42),
12270 BPF_EXIT_INSN(),
12271 },
12272 .result = ACCEPT,
12273 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12274 .retval = 3,
12275 },
12276 {
Yonghong Song2abe611c2018-04-28 22:28:14 -070012277 "bpf_get_stack return R0 within range",
12278 .insns = {
12279 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12280 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
12281 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12282 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
12283 BPF_LD_MAP_FD(BPF_REG_1, 0),
12284 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12285 BPF_FUNC_map_lookup_elem),
12286 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
12287 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
12288 BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
12289 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12290 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12291 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
12292 BPF_MOV64_IMM(BPF_REG_4, 256),
12293 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12294 BPF_MOV64_IMM(BPF_REG_1, 0),
12295 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
12296 BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
12297 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
12298 BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
12299 BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
12300 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
12301 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
12302 BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
12303 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
12304 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 32),
12305 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
12306 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
12307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12308 BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
12309 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
12310 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
12311 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
12312 BPF_MOV64_REG(BPF_REG_3, BPF_REG_9),
12313 BPF_MOV64_IMM(BPF_REG_4, 0),
12314 BPF_EMIT_CALL(BPF_FUNC_get_stack),
12315 BPF_EXIT_INSN(),
12316 },
12317 .fixup_map2 = { 4 },
12318 .result = ACCEPT,
12319 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
12320 },
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012321 {
12322 "ld_abs: invalid op 1",
12323 .insns = {
12324 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12325 BPF_LD_ABS(BPF_DW, 0),
12326 BPF_EXIT_INSN(),
12327 },
12328 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12329 .result = REJECT,
12330 .errstr = "unknown opcode",
12331 },
12332 {
12333 "ld_abs: invalid op 2",
12334 .insns = {
12335 BPF_MOV32_IMM(BPF_REG_0, 256),
12336 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12337 BPF_LD_IND(BPF_DW, BPF_REG_0, 0),
12338 BPF_EXIT_INSN(),
12339 },
12340 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12341 .result = REJECT,
12342 .errstr = "unknown opcode",
12343 },
12344 {
12345 "ld_abs: nmap reduced",
12346 .insns = {
12347 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12348 BPF_LD_ABS(BPF_H, 12),
12349 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 28),
12350 BPF_LD_ABS(BPF_H, 12),
12351 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 26),
12352 BPF_MOV32_IMM(BPF_REG_0, 18),
12353 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -64),
12354 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -64),
12355 BPF_LD_IND(BPF_W, BPF_REG_7, 14),
12356 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -60),
12357 BPF_MOV32_IMM(BPF_REG_0, 280971478),
12358 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
12359 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
12360 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -60),
12361 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
12362 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 15),
12363 BPF_LD_ABS(BPF_H, 12),
12364 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 13),
12365 BPF_MOV32_IMM(BPF_REG_0, 22),
12366 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
12367 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
12368 BPF_LD_IND(BPF_H, BPF_REG_7, 14),
12369 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -52),
12370 BPF_MOV32_IMM(BPF_REG_0, 17366),
12371 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -48),
12372 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -48),
12373 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -52),
12374 BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
12375 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
12376 BPF_MOV32_IMM(BPF_REG_0, 256),
12377 BPF_EXIT_INSN(),
12378 BPF_MOV32_IMM(BPF_REG_0, 0),
12379 BPF_EXIT_INSN(),
12380 },
12381 .data = {
12382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0,
12383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12384 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
12385 },
12386 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12387 .result = ACCEPT,
12388 .retval = 256,
12389 },
12390 {
12391 "ld_abs: div + abs, test 1",
12392 .insns = {
12393 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12394 BPF_LD_ABS(BPF_B, 3),
12395 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12396 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12397 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12398 BPF_LD_ABS(BPF_B, 4),
12399 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12400 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12401 BPF_EXIT_INSN(),
12402 },
12403 .data = {
12404 10, 20, 30, 40, 50,
12405 },
12406 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12407 .result = ACCEPT,
12408 .retval = 10,
12409 },
12410 {
12411 "ld_abs: div + abs, test 2",
12412 .insns = {
12413 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12414 BPF_LD_ABS(BPF_B, 3),
12415 BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
12416 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
12417 BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
12418 BPF_LD_ABS(BPF_B, 128),
12419 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
12420 BPF_LD_IND(BPF_B, BPF_REG_8, -70),
12421 BPF_EXIT_INSN(),
12422 },
12423 .data = {
12424 10, 20, 30, 40, 50,
12425 },
12426 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12427 .result = ACCEPT,
12428 .retval = 0,
12429 },
12430 {
12431 "ld_abs: div + abs, test 3",
12432 .insns = {
12433 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12434 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12435 BPF_LD_ABS(BPF_B, 3),
12436 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12437 BPF_EXIT_INSN(),
12438 },
12439 .data = {
12440 10, 20, 30, 40, 50,
12441 },
12442 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12443 .result = ACCEPT,
12444 .retval = 0,
12445 },
12446 {
12447 "ld_abs: div + abs, test 4",
12448 .insns = {
12449 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
12450 BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
12451 BPF_LD_ABS(BPF_B, 256),
12452 BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
12453 BPF_EXIT_INSN(),
12454 },
12455 .data = {
12456 10, 20, 30, 40, 50,
12457 },
12458 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12459 .result = ACCEPT,
12460 .retval = 0,
12461 },
12462 {
12463 "ld_abs: vlan + abs, test 1",
12464 .insns = { },
12465 .data = {
12466 0x34,
12467 },
12468 .fill_helper = bpf_fill_ld_abs_vlan_push_pop,
12469 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12470 .result = ACCEPT,
12471 .retval = 0xbef,
12472 },
12473 {
12474 "ld_abs: vlan + abs, test 2",
12475 .insns = {
12476 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
12477 BPF_LD_ABS(BPF_B, 0),
12478 BPF_LD_ABS(BPF_H, 0),
12479 BPF_LD_ABS(BPF_W, 0),
12480 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
12481 BPF_MOV64_IMM(BPF_REG_6, 0),
12482 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12483 BPF_MOV64_IMM(BPF_REG_2, 1),
12484 BPF_MOV64_IMM(BPF_REG_3, 2),
12485 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12486 BPF_FUNC_skb_vlan_push),
12487 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
12488 BPF_LD_ABS(BPF_B, 0),
12489 BPF_LD_ABS(BPF_H, 0),
12490 BPF_LD_ABS(BPF_W, 0),
12491 BPF_MOV64_IMM(BPF_REG_0, 42),
12492 BPF_EXIT_INSN(),
12493 },
12494 .data = {
12495 0x34,
12496 },
12497 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12498 .result = ACCEPT,
12499 .retval = 42,
12500 },
12501 {
12502 "ld_abs: jump around ld_abs",
12503 .insns = { },
12504 .data = {
12505 10, 11,
12506 },
12507 .fill_helper = bpf_fill_jump_around_ld_abs,
12508 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12509 .result = ACCEPT,
12510 .retval = 10,
12511 },
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +020012512 {
12513 "ld_dw: xor semi-random 64 bit imms, test 1",
12514 .insns = { },
12515 .data = { },
12516 .fill_helper = bpf_fill_rand_ld_dw,
12517 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12518 .result = ACCEPT,
12519 .retval = 4090,
12520 },
12521 {
12522 "ld_dw: xor semi-random 64 bit imms, test 2",
12523 .insns = { },
12524 .data = { },
12525 .fill_helper = bpf_fill_rand_ld_dw,
12526 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12527 .result = ACCEPT,
12528 .retval = 2047,
12529 },
12530 {
12531 "ld_dw: xor semi-random 64 bit imms, test 3",
12532 .insns = { },
12533 .data = { },
12534 .fill_helper = bpf_fill_rand_ld_dw,
12535 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12536 .result = ACCEPT,
12537 .retval = 511,
12538 },
12539 {
12540 "ld_dw: xor semi-random 64 bit imms, test 4",
12541 .insns = { },
12542 .data = { },
12543 .fill_helper = bpf_fill_rand_ld_dw,
12544 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12545 .result = ACCEPT,
12546 .retval = 5,
12547 },
Daniel Borkmann58990d12018-06-07 17:40:03 +020012548 {
12549 "pass unmodified ctx pointer to helper",
12550 .insns = {
12551 BPF_MOV64_IMM(BPF_REG_2, 0),
12552 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12553 BPF_FUNC_csum_update),
12554 BPF_MOV64_IMM(BPF_REG_0, 0),
12555 BPF_EXIT_INSN(),
12556 },
12557 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12558 .result = ACCEPT,
12559 },
12560 {
12561 "pass modified ctx pointer to helper, 1",
12562 .insns = {
12563 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
12564 BPF_MOV64_IMM(BPF_REG_2, 0),
12565 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12566 BPF_FUNC_csum_update),
12567 BPF_MOV64_IMM(BPF_REG_0, 0),
12568 BPF_EXIT_INSN(),
12569 },
12570 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12571 .result = REJECT,
12572 .errstr = "dereference of modified ctx ptr",
12573 },
12574 {
12575 "pass modified ctx pointer to helper, 2",
12576 .insns = {
12577 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
12578 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12579 BPF_FUNC_get_socket_cookie),
12580 BPF_MOV64_IMM(BPF_REG_0, 0),
12581 BPF_EXIT_INSN(),
12582 },
12583 .result_unpriv = REJECT,
12584 .result = REJECT,
12585 .errstr_unpriv = "dereference of modified ctx ptr",
12586 .errstr = "dereference of modified ctx ptr",
12587 },
12588 {
12589 "pass modified ctx pointer to helper, 3",
12590 .insns = {
12591 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
12592 BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
12593 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
12594 BPF_MOV64_IMM(BPF_REG_2, 0),
12595 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12596 BPF_FUNC_csum_update),
12597 BPF_MOV64_IMM(BPF_REG_0, 0),
12598 BPF_EXIT_INSN(),
12599 },
12600 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12601 .result = REJECT,
12602 .errstr = "variable ctx access var_off=(0x0; 0x4)",
12603 },
Arthur Fabrefbeb1602018-07-31 18:17:22 +010012604 {
12605 "mov64 src == dst",
12606 .insns = {
12607 BPF_MOV64_IMM(BPF_REG_2, 0),
12608 BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
12609 // Check bounds are OK
12610 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
12611 BPF_MOV64_IMM(BPF_REG_0, 0),
12612 BPF_EXIT_INSN(),
12613 },
12614 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12615 .result = ACCEPT,
12616 },
12617 {
12618 "mov64 src != dst",
12619 .insns = {
12620 BPF_MOV64_IMM(BPF_REG_3, 0),
12621 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
12622 // Check bounds are OK
12623 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
12624 BPF_MOV64_IMM(BPF_REG_0, 0),
12625 BPF_EXIT_INSN(),
12626 },
12627 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12628 .result = ACCEPT,
12629 },
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012630};
12631
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012632static int probe_filter_length(const struct bpf_insn *fp)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012633{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012634 int len;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012635
12636 for (len = MAX_INSNS - 1; len > 0; --len)
12637 if (fp[len].code != 0 || fp[len].imm != 0)
12638 break;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012639 return len + 1;
12640}
12641
Daniel Borkmann06be0862018-06-02 23:06:31 +020012642static int create_map(uint32_t type, uint32_t size_key,
12643 uint32_t size_value, uint32_t max_elem)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012644{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012645 int fd;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012646
Daniel Borkmann06be0862018-06-02 23:06:31 +020012647 fd = bpf_create_map(type, size_key, size_value, max_elem,
12648 type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012649 if (fd < 0)
12650 printf("Failed to create hash map '%s'!\n", strerror(errno));
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012651
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012652 return fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012653}
12654
Joe Stringer0c586072018-10-02 13:35:37 -070012655static int create_prog_dummy1(enum bpf_map_type prog_type)
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012656{
12657 struct bpf_insn prog[] = {
12658 BPF_MOV64_IMM(BPF_REG_0, 42),
12659 BPF_EXIT_INSN(),
12660 };
12661
Joe Stringer0c586072018-10-02 13:35:37 -070012662 return bpf_load_program(prog_type, prog,
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012663 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12664}
12665
Joe Stringer0c586072018-10-02 13:35:37 -070012666static int create_prog_dummy2(enum bpf_map_type prog_type, int mfd, int idx)
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012667{
12668 struct bpf_insn prog[] = {
12669 BPF_MOV64_IMM(BPF_REG_3, idx),
12670 BPF_LD_MAP_FD(BPF_REG_2, mfd),
12671 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12672 BPF_FUNC_tail_call),
12673 BPF_MOV64_IMM(BPF_REG_0, 41),
12674 BPF_EXIT_INSN(),
12675 };
12676
Joe Stringer0c586072018-10-02 13:35:37 -070012677 return bpf_load_program(prog_type, prog,
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012678 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12679}
12680
Joe Stringer0c586072018-10-02 13:35:37 -070012681static int create_prog_array(enum bpf_map_type prog_type, uint32_t max_elem,
12682 int p1key)
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012683{
Daniel Borkmann06be0862018-06-02 23:06:31 +020012684 int p2key = 1;
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012685 int mfd, p1fd, p2fd;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070012686
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012687 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
Daniel Borkmann06be0862018-06-02 23:06:31 +020012688 sizeof(int), max_elem, 0);
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012689 if (mfd < 0) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012690 printf("Failed to create prog array '%s'!\n", strerror(errno));
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012691 return -1;
12692 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012693
Joe Stringer0c586072018-10-02 13:35:37 -070012694 p1fd = create_prog_dummy1(prog_type);
12695 p2fd = create_prog_dummy2(prog_type, mfd, p2key);
Daniel Borkmannb33eb732018-02-26 22:34:33 +010012696 if (p1fd < 0 || p2fd < 0)
12697 goto out;
12698 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
12699 goto out;
12700 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
12701 goto out;
12702 close(p2fd);
12703 close(p1fd);
12704
12705 return mfd;
12706out:
12707 close(p2fd);
12708 close(p1fd);
12709 close(mfd);
12710 return -1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012711}
12712
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012713static int create_map_in_map(void)
12714{
12715 int inner_map_fd, outer_map_fd;
12716
12717 inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12718 sizeof(int), 1, 0);
12719 if (inner_map_fd < 0) {
12720 printf("Failed to create array '%s'!\n", strerror(errno));
12721 return inner_map_fd;
12722 }
12723
Martin KaFai Lau88cda1c2017-09-27 14:37:54 -070012724 outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012725 sizeof(int), inner_map_fd, 1, 0);
12726 if (outer_map_fd < 0)
12727 printf("Failed to create array of maps '%s'!\n",
12728 strerror(errno));
12729
12730 close(inner_map_fd);
12731
12732 return outer_map_fd;
12733}
12734
Roman Gushchina3c60542018-09-28 14:45:53 +000012735static int create_cgroup_storage(bool percpu)
Roman Gushchind4c9f572018-08-02 14:27:28 -070012736{
Roman Gushchina3c60542018-09-28 14:45:53 +000012737 enum bpf_map_type type = percpu ? BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE :
12738 BPF_MAP_TYPE_CGROUP_STORAGE;
Roman Gushchind4c9f572018-08-02 14:27:28 -070012739 int fd;
12740
Roman Gushchina3c60542018-09-28 14:45:53 +000012741 fd = bpf_create_map(type, sizeof(struct bpf_cgroup_storage_key),
Roman Gushchind4c9f572018-08-02 14:27:28 -070012742 TEST_DATA_LEN, 0, 0);
12743 if (fd < 0)
Roman Gushchina3c60542018-09-28 14:45:53 +000012744 printf("Failed to create cgroup storage '%s'!\n",
12745 strerror(errno));
Roman Gushchind4c9f572018-08-02 14:27:28 -070012746
12747 return fd;
12748}
12749
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012750static char bpf_vlog[UINT_MAX >> 8];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012751
Joe Stringer0c586072018-10-02 13:35:37 -070012752static void do_test_fixup(struct bpf_test *test, enum bpf_map_type prog_type,
12753 struct bpf_insn *prog, int *map_fds)
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070012754{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012755 int *fixup_map1 = test->fixup_map1;
12756 int *fixup_map2 = test->fixup_map2;
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012757 int *fixup_map3 = test->fixup_map3;
Daniel Borkmann06be0862018-06-02 23:06:31 +020012758 int *fixup_map4 = test->fixup_map4;
12759 int *fixup_prog1 = test->fixup_prog1;
12760 int *fixup_prog2 = test->fixup_prog2;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012761 int *fixup_map_in_map = test->fixup_map_in_map;
Roman Gushchind4c9f572018-08-02 14:27:28 -070012762 int *fixup_cgroup_storage = test->fixup_cgroup_storage;
Roman Gushchina3c60542018-09-28 14:45:53 +000012763 int *fixup_percpu_cgroup_storage = test->fixup_percpu_cgroup_storage;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012764
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012765 if (test->fill_helper)
12766 test->fill_helper(test);
12767
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012768 /* Allocating HTs with 1 elem is fine here, since we only test
12769 * for verifier and not do a runtime lookup, so the only thing
12770 * that really matters is value size in this case.
12771 */
12772 if (*fixup_map1) {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012773 map_fds[0] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12774 sizeof(long long), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012775 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012776 prog[*fixup_map1].imm = map_fds[0];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012777 fixup_map1++;
12778 } while (*fixup_map1);
12779 }
12780
12781 if (*fixup_map2) {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012782 map_fds[1] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12783 sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012784 do {
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012785 prog[*fixup_map2].imm = map_fds[1];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012786 fixup_map2++;
12787 } while (*fixup_map2);
12788 }
12789
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012790 if (*fixup_map3) {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012791 map_fds[2] = create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
12792 sizeof(struct other_val), 1);
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012793 do {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012794 prog[*fixup_map3].imm = map_fds[2];
Paul Chaignon5f90dd62018-04-24 15:08:19 +020012795 fixup_map3++;
12796 } while (*fixup_map3);
12797 }
12798
Daniel Borkmann06be0862018-06-02 23:06:31 +020012799 if (*fixup_map4) {
12800 map_fds[3] = create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12801 sizeof(struct test_val), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012802 do {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012803 prog[*fixup_map4].imm = map_fds[3];
12804 fixup_map4++;
12805 } while (*fixup_map4);
12806 }
12807
12808 if (*fixup_prog1) {
Joe Stringer0c586072018-10-02 13:35:37 -070012809 map_fds[4] = create_prog_array(prog_type, 4, 0);
Daniel Borkmann06be0862018-06-02 23:06:31 +020012810 do {
12811 prog[*fixup_prog1].imm = map_fds[4];
12812 fixup_prog1++;
12813 } while (*fixup_prog1);
12814 }
12815
12816 if (*fixup_prog2) {
Joe Stringer0c586072018-10-02 13:35:37 -070012817 map_fds[5] = create_prog_array(prog_type, 8, 7);
Daniel Borkmann06be0862018-06-02 23:06:31 +020012818 do {
12819 prog[*fixup_prog2].imm = map_fds[5];
12820 fixup_prog2++;
12821 } while (*fixup_prog2);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012822 }
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012823
12824 if (*fixup_map_in_map) {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012825 map_fds[6] = create_map_in_map();
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012826 do {
Daniel Borkmann06be0862018-06-02 23:06:31 +020012827 prog[*fixup_map_in_map].imm = map_fds[6];
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012828 fixup_map_in_map++;
12829 } while (*fixup_map_in_map);
12830 }
Roman Gushchind4c9f572018-08-02 14:27:28 -070012831
12832 if (*fixup_cgroup_storage) {
Roman Gushchina3c60542018-09-28 14:45:53 +000012833 map_fds[7] = create_cgroup_storage(false);
Roman Gushchind4c9f572018-08-02 14:27:28 -070012834 do {
12835 prog[*fixup_cgroup_storage].imm = map_fds[7];
12836 fixup_cgroup_storage++;
12837 } while (*fixup_cgroup_storage);
12838 }
Roman Gushchina3c60542018-09-28 14:45:53 +000012839
12840 if (*fixup_percpu_cgroup_storage) {
12841 map_fds[8] = create_cgroup_storage(true);
12842 do {
12843 prog[*fixup_percpu_cgroup_storage].imm = map_fds[8];
12844 fixup_percpu_cgroup_storage++;
12845 } while (*fixup_percpu_cgroup_storage);
12846 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012847}
12848
12849static void do_test_single(struct bpf_test *test, bool unpriv,
12850 int *passes, int *errors)
12851{
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012852 int fd_prog, expected_ret, reject_from_alignment;
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012853 int prog_len, prog_type = test->prog_type;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012854 struct bpf_insn *prog = test->insns;
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012855 int map_fds[MAX_NR_MAPS];
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012856 const char *expected_err;
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012857 uint32_t retval;
12858 int i, err;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012859
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012860 for (i = 0; i < MAX_NR_MAPS; i++)
12861 map_fds[i] = -1;
12862
Joe Stringer0c586072018-10-02 13:35:37 -070012863 if (!prog_type)
12864 prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
12865 do_test_fixup(test, prog_type, prog, map_fds);
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012866 prog_len = probe_filter_length(prog);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012867
Joe Stringer0c586072018-10-02 13:35:37 -070012868 fd_prog = bpf_verify_program(prog_type, prog, prog_len,
12869 test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
Daniel Borkmannd6554902017-07-21 00:00:22 +020012870 "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012871
12872 expected_ret = unpriv && test->result_unpriv != UNDEF ?
12873 test->result_unpriv : test->result;
12874 expected_err = unpriv && test->errstr_unpriv ?
12875 test->errstr_unpriv : test->errstr;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012876
12877 reject_from_alignment = fd_prog < 0 &&
12878 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
12879 strstr(bpf_vlog, "Unknown alignment.");
12880#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
12881 if (reject_from_alignment) {
12882 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
12883 strerror(errno));
12884 goto fail_log;
12885 }
12886#endif
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012887 if (expected_ret == ACCEPT) {
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012888 if (fd_prog < 0 && !reject_from_alignment) {
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012889 printf("FAIL\nFailed to load prog '%s'!\n",
12890 strerror(errno));
12891 goto fail_log;
12892 }
12893 } else {
12894 if (fd_prog >= 0) {
12895 printf("FAIL\nUnexpected success to load!\n");
12896 goto fail_log;
12897 }
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012898 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
Joe Stringer95f87a92018-02-14 13:50:34 -080012899 printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
12900 expected_err, bpf_vlog);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012901 goto fail_log;
12902 }
12903 }
12904
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012905 if (fd_prog >= 0) {
Daniel Borkmann6e6fddc2018-07-11 15:30:14 +020012906 __u8 tmp[TEST_DATA_LEN << 2];
12907 __u32 size_tmp = sizeof(tmp);
12908
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012909 err = bpf_prog_test_run(fd_prog, 1, test->data,
Daniel Borkmann6e6fddc2018-07-11 15:30:14 +020012910 sizeof(test->data), tmp, &size_tmp,
Daniel Borkmann93731ef2018-05-04 01:08:13 +020012911 &retval, NULL);
Alexei Starovoitov111e6b42018-01-17 16:52:03 -080012912 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
12913 printf("Unexpected bpf_prog_test_run error\n");
12914 goto fail_log;
12915 }
12916 if (!err && retval != test->retval &&
12917 test->retval != POINTER_VALUE) {
12918 printf("FAIL retval %d != %d\n", retval, test->retval);
12919 goto fail_log;
12920 }
12921 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012922 (*passes)++;
Daniel Borkmann02ea80b2017-03-31 02:24:04 +020012923 printf("OK%s\n", reject_from_alignment ?
12924 " (NOTE: reject due to unknown alignment)" : "");
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012925close_fds:
12926 close(fd_prog);
Martin KaFai Laufb30d4b2017-03-22 10:00:35 -070012927 for (i = 0; i < MAX_NR_MAPS; i++)
12928 close(map_fds[i]);
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020012929 sched_yield();
12930 return;
12931fail_log:
12932 (*errors)++;
12933 printf("%s", bpf_vlog);
12934 goto close_fds;
12935}
12936
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012937static bool is_admin(void)
12938{
12939 cap_t caps;
12940 cap_flag_value_t sysadmin = CAP_CLEAR;
12941 const cap_value_t cap_val = CAP_SYS_ADMIN;
12942
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080012943#ifdef CAP_IS_SUPPORTED
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012944 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
12945 perror("cap_get_flag");
12946 return false;
12947 }
Alexei Starovoitov1da8ac72017-03-10 22:05:55 -080012948#endif
Mickaël Salaünd02d8982017-02-10 00:21:37 +010012949 caps = cap_get_proc();
12950 if (!caps) {
12951 perror("cap_get_proc");
12952 return false;
12953 }
12954 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
12955 perror("cap_get_flag");
12956 if (cap_free(caps))
12957 perror("cap_free");
12958 return (sysadmin == CAP_SET);
12959}
12960
12961static int set_admin(bool admin)
12962{
12963 cap_t caps;
12964 const cap_value_t cap_val = CAP_SYS_ADMIN;
12965 int ret = -1;
12966
12967 caps = cap_get_proc();
12968 if (!caps) {
12969 perror("cap_get_proc");
12970 return -1;
12971 }
12972 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
12973 admin ? CAP_SET : CAP_CLEAR)) {
12974 perror("cap_set_flag");
12975 goto out;
12976 }
12977 if (cap_set_proc(caps)) {
12978 perror("cap_set_proc");
12979 goto out;
12980 }
12981 ret = 0;
12982out:
12983 if (cap_free(caps))
12984 perror("cap_free");
12985 return ret;
12986}
12987
Joe Stringer0a6748742018-02-14 13:50:36 -080012988static void get_unpriv_disabled()
12989{
12990 char buf[2];
12991 FILE *fd;
12992
12993 fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
Jesper Dangaard Brouerdeea8122018-05-17 19:39:31 +020012994 if (!fd) {
12995 perror("fopen /proc/sys/"UNPRIV_SYSCTL);
12996 unpriv_disabled = true;
12997 return;
12998 }
Joe Stringer0a6748742018-02-14 13:50:36 -080012999 if (fgets(buf, 2, fd) == buf && atoi(buf))
13000 unpriv_disabled = true;
13001 fclose(fd);
13002}
13003
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013004static int do_test(bool unpriv, unsigned int from, unsigned int to)
13005{
Joe Stringerd0a0e492018-02-14 13:50:35 -080013006 int i, passes = 0, errors = 0, skips = 0;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013007
13008 for (i = from; i < to; i++) {
13009 struct bpf_test *test = &tests[i];
13010
13011 /* Program types that are not supported by non-root we
13012 * skip right away.
13013 */
Joe Stringer0a6748742018-02-14 13:50:36 -080013014 if (!test->prog_type && unpriv_disabled) {
13015 printf("#%d/u %s SKIP\n", i, test->descr);
13016 skips++;
13017 } else if (!test->prog_type) {
Mickaël Salaünd02d8982017-02-10 00:21:37 +010013018 if (!unpriv)
13019 set_admin(false);
13020 printf("#%d/u %s ", i, test->descr);
13021 do_test_single(test, true, &passes, &errors);
13022 if (!unpriv)
13023 set_admin(true);
13024 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013025
Joe Stringerd0a0e492018-02-14 13:50:35 -080013026 if (unpriv) {
13027 printf("#%d/p %s SKIP\n", i, test->descr);
13028 skips++;
13029 } else {
Mickaël Salaünd02d8982017-02-10 00:21:37 +010013030 printf("#%d/p %s ", i, test->descr);
13031 do_test_single(test, false, &passes, &errors);
13032 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013033 }
13034
Joe Stringerd0a0e492018-02-14 13:50:35 -080013035 printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
13036 skips, errors);
Jesper Dangaard Brouerefe5f9c2017-06-13 15:17:19 +020013037 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013038}
13039
13040int main(int argc, char **argv)
13041{
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013042 unsigned int from = 0, to = ARRAY_SIZE(tests);
Mickaël Salaünd02d8982017-02-10 00:21:37 +010013043 bool unpriv = !is_admin();
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013044
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013045 if (argc == 3) {
13046 unsigned int l = atoi(argv[argc - 2]);
13047 unsigned int u = atoi(argv[argc - 1]);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013048
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013049 if (l < to && u < to) {
13050 from = l;
13051 to = u + 1;
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013052 }
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013053 } else if (argc == 2) {
13054 unsigned int t = atoi(argv[argc - 1]);
Alexei Starovoitovbf508872015-10-07 22:23:23 -070013055
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013056 if (t < to) {
13057 from = t;
13058 to = t + 1;
Alexei Starovoitovbf508872015-10-07 22:23:23 -070013059 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013060 }
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013061
Joe Stringer0a6748742018-02-14 13:50:36 -080013062 get_unpriv_disabled();
13063 if (unpriv && unpriv_disabled) {
13064 printf("Cannot run as unprivileged user with sysctl %s.\n",
13065 UNPRIV_SYSCTL);
13066 return EXIT_FAILURE;
13067 }
13068
Daniel Borkmanna82d8cd2018-05-14 23:22:34 +020013069 bpf_semi_rand_init();
Daniel Borkmann5aa5bd12016-10-17 14:28:36 +020013070 return do_test(unpriv, from, to);
Alexei Starovoitov3c731eb2014-09-26 00:17:07 -070013071}