15aa5bd14SDaniel Borkmann /*
25aa5bd14SDaniel Borkmann  * Testsuite for eBPF verifier
35aa5bd14SDaniel Borkmann  *
45aa5bd14SDaniel Borkmann  * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5a7ff3ecaSAlexei Starovoitov  * Copyright (c) 2017 Facebook
65aa5bd14SDaniel Borkmann  *
75aa5bd14SDaniel Borkmann  * This program is free software; you can redistribute it and/or
85aa5bd14SDaniel Borkmann  * modify it under the terms of version 2 of the GNU General Public
95aa5bd14SDaniel Borkmann  * License as published by the Free Software Foundation.
105aa5bd14SDaniel Borkmann  */
115aa5bd14SDaniel Borkmann 
122c460621SDaniel Borkmann #include <endian.h>
131da8ac7cSAlexei Starovoitov #include <asm/types.h>
141da8ac7cSAlexei Starovoitov #include <linux/types.h>
15702498a1SMickaël Salaün #include <stdint.h>
165aa5bd14SDaniel Borkmann #include <stdio.h>
17702498a1SMickaël Salaün #include <stdlib.h>
185aa5bd14SDaniel Borkmann #include <unistd.h>
195aa5bd14SDaniel Borkmann #include <errno.h>
205aa5bd14SDaniel Borkmann #include <string.h>
215aa5bd14SDaniel Borkmann #include <stddef.h>
225aa5bd14SDaniel Borkmann #include <stdbool.h>
235aa5bd14SDaniel Borkmann #include <sched.h>
2421ccaf21SDaniel Borkmann #include <limits.h>
255aa5bd14SDaniel Borkmann 
26d02d8986SMickaël Salaün #include <sys/capability.h>
275aa5bd14SDaniel Borkmann 
285aa5bd14SDaniel Borkmann #include <linux/unistd.h>
295aa5bd14SDaniel Borkmann #include <linux/filter.h>
305aa5bd14SDaniel Borkmann #include <linux/bpf_perf_event.h>
315aa5bd14SDaniel Borkmann #include <linux/bpf.h>
32111e6b45SAlexei Starovoitov #include <linux/if_ether.h>
335aa5bd14SDaniel Borkmann 
342ee89fb9SMickaël Salaün #include <bpf/bpf.h>
352ee89fb9SMickaël Salaün 
3602ea80b1SDaniel Borkmann #ifdef HAVE_GENHDR
3702ea80b1SDaniel Borkmann # include "autoconf.h"
3802ea80b1SDaniel Borkmann #else
3902ea80b1SDaniel Borkmann # if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
4002ea80b1SDaniel Borkmann #  define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
4102ea80b1SDaniel Borkmann # endif
4202ea80b1SDaniel Borkmann #endif
43fe8d662aSDaniel Borkmann #include "bpf_rlimit.h"
44a82d8cd3SDaniel Borkmann #include "bpf_rand.h"
455aa5bd14SDaniel Borkmann #include "../../../include/linux/filter.h"
465aa5bd14SDaniel Borkmann 
475aa5bd14SDaniel Borkmann #ifndef ARRAY_SIZE
485aa5bd14SDaniel Borkmann # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
495aa5bd14SDaniel Borkmann #endif
505aa5bd14SDaniel Borkmann 
5193731ef0SDaniel Borkmann #define MAX_INSNS	BPF_MAXINSNS
525aa5bd14SDaniel Borkmann #define MAX_FIXUPS	8
53fb30d4b7SMartin KaFai Lau #define MAX_NR_MAPS	4
54111e6b45SAlexei Starovoitov #define POINTER_VALUE	0xcafe4all
55111e6b45SAlexei Starovoitov #define TEST_DATA_LEN	64
565aa5bd14SDaniel Borkmann 
5702ea80b1SDaniel Borkmann #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS	(1 << 0)
58614d0d77SDaniel Borkmann #define F_LOAD_WITH_STRICT_ALIGNMENT		(1 << 1)
5902ea80b1SDaniel Borkmann 
600a674874SJoe Stringer #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
610a674874SJoe Stringer static bool unpriv_disabled = false;
620a674874SJoe Stringer 
635aa5bd14SDaniel Borkmann struct bpf_test {
645aa5bd14SDaniel Borkmann 	const char *descr;
655aa5bd14SDaniel Borkmann 	struct bpf_insn	insns[MAX_INSNS];
665aa5bd14SDaniel Borkmann 	int fixup_map1[MAX_FIXUPS];
675aa5bd14SDaniel Borkmann 	int fixup_map2[MAX_FIXUPS];
685f90dd6aSPaul Chaignon 	int fixup_map3[MAX_FIXUPS];
695aa5bd14SDaniel Borkmann 	int fixup_prog[MAX_FIXUPS];
70fb30d4b7SMartin KaFai Lau 	int fixup_map_in_map[MAX_FIXUPS];
715aa5bd14SDaniel Borkmann 	const char *errstr;
725aa5bd14SDaniel Borkmann 	const char *errstr_unpriv;
73111e6b45SAlexei Starovoitov 	uint32_t retval;
745aa5bd14SDaniel Borkmann 	enum {
755aa5bd14SDaniel Borkmann 		UNDEF,
765aa5bd14SDaniel Borkmann 		ACCEPT,
775aa5bd14SDaniel Borkmann 		REJECT
785aa5bd14SDaniel Borkmann 	} result, result_unpriv;
795aa5bd14SDaniel Borkmann 	enum bpf_prog_type prog_type;
8002ea80b1SDaniel Borkmann 	uint8_t flags;
8193731ef0SDaniel Borkmann 	__u8 data[TEST_DATA_LEN];
8293731ef0SDaniel Borkmann 	void (*fill_helper)(struct bpf_test *self);
835aa5bd14SDaniel Borkmann };
845aa5bd14SDaniel Borkmann 
855aa5bd14SDaniel Borkmann /* Note we want this to be 64 bit aligned so that the end of our array is
865aa5bd14SDaniel Borkmann  * actually the end of the structure.
875aa5bd14SDaniel Borkmann  */
885aa5bd14SDaniel Borkmann #define MAX_ENTRIES 11
895aa5bd14SDaniel Borkmann 
905aa5bd14SDaniel Borkmann struct test_val {
915aa5bd14SDaniel Borkmann 	unsigned int index;
925aa5bd14SDaniel Borkmann 	int foo[MAX_ENTRIES];
935aa5bd14SDaniel Borkmann };
945aa5bd14SDaniel Borkmann 
955f90dd6aSPaul Chaignon struct other_val {
965f90dd6aSPaul Chaignon 	long long foo;
975f90dd6aSPaul Chaignon 	long long bar;
985f90dd6aSPaul Chaignon };
995f90dd6aSPaul Chaignon 
10093731ef0SDaniel Borkmann static void bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
10193731ef0SDaniel Borkmann {
10293731ef0SDaniel Borkmann 	/* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
10393731ef0SDaniel Borkmann #define PUSH_CNT 51
10493731ef0SDaniel Borkmann 	unsigned int len = BPF_MAXINSNS;
10593731ef0SDaniel Borkmann 	struct bpf_insn *insn = self->insns;
10693731ef0SDaniel Borkmann 	int i = 0, j, k = 0;
10793731ef0SDaniel Borkmann 
10893731ef0SDaniel Borkmann 	insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
10993731ef0SDaniel Borkmann loop:
11093731ef0SDaniel Borkmann 	for (j = 0; j < PUSH_CNT; j++) {
11193731ef0SDaniel Borkmann 		insn[i++] = BPF_LD_ABS(BPF_B, 0);
11293731ef0SDaniel Borkmann 		insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
11393731ef0SDaniel Borkmann 		i++;
11493731ef0SDaniel Borkmann 		insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
11593731ef0SDaniel Borkmann 		insn[i++] = BPF_MOV64_IMM(BPF_REG_2, 1);
11693731ef0SDaniel Borkmann 		insn[i++] = BPF_MOV64_IMM(BPF_REG_3, 2);
11793731ef0SDaniel Borkmann 		insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11893731ef0SDaniel Borkmann 					 BPF_FUNC_skb_vlan_push),
11993731ef0SDaniel Borkmann 		insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
12093731ef0SDaniel Borkmann 		i++;
12193731ef0SDaniel Borkmann 	}
12293731ef0SDaniel Borkmann 
12393731ef0SDaniel Borkmann 	for (j = 0; j < PUSH_CNT; j++) {
12493731ef0SDaniel Borkmann 		insn[i++] = BPF_LD_ABS(BPF_B, 0);
12593731ef0SDaniel Borkmann 		insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x34, len - i - 2);
12693731ef0SDaniel Borkmann 		i++;
12793731ef0SDaniel Borkmann 		insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
12893731ef0SDaniel Borkmann 		insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12993731ef0SDaniel Borkmann 					 BPF_FUNC_skb_vlan_pop),
13093731ef0SDaniel Borkmann 		insn[i] = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, len - i - 2);
13193731ef0SDaniel Borkmann 		i++;
13293731ef0SDaniel Borkmann 	}
13393731ef0SDaniel Borkmann 	if (++k < 5)
13493731ef0SDaniel Borkmann 		goto loop;
13593731ef0SDaniel Borkmann 
13693731ef0SDaniel Borkmann 	for (; i < len - 1; i++)
13793731ef0SDaniel Borkmann 		insn[i] = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, 0xbef);
13893731ef0SDaniel Borkmann 	insn[len - 1] = BPF_EXIT_INSN();
13993731ef0SDaniel Borkmann }
14093731ef0SDaniel Borkmann 
14193731ef0SDaniel Borkmann static void bpf_fill_jump_around_ld_abs(struct bpf_test *self)
14293731ef0SDaniel Borkmann {
14393731ef0SDaniel Borkmann 	struct bpf_insn *insn = self->insns;
14493731ef0SDaniel Borkmann 	unsigned int len = BPF_MAXINSNS;
14593731ef0SDaniel Borkmann 	int i = 0;
14693731ef0SDaniel Borkmann 
14793731ef0SDaniel Borkmann 	insn[i++] = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
14893731ef0SDaniel Borkmann 	insn[i++] = BPF_LD_ABS(BPF_B, 0);
14993731ef0SDaniel Borkmann 	insn[i] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 10, len - i - 2);
15093731ef0SDaniel Borkmann 	i++;
15193731ef0SDaniel Borkmann 	while (i < len - 1)
15293731ef0SDaniel Borkmann 		insn[i++] = BPF_LD_ABS(BPF_B, 1);
15393731ef0SDaniel Borkmann 	insn[i] = BPF_EXIT_INSN();
15493731ef0SDaniel Borkmann }
15593731ef0SDaniel Borkmann 
156a82d8cd3SDaniel Borkmann static void bpf_fill_rand_ld_dw(struct bpf_test *self)
157a82d8cd3SDaniel Borkmann {
158a82d8cd3SDaniel Borkmann 	struct bpf_insn *insn = self->insns;
159a82d8cd3SDaniel Borkmann 	uint64_t res = 0;
160a82d8cd3SDaniel Borkmann 	int i = 0;
161a82d8cd3SDaniel Borkmann 
162a82d8cd3SDaniel Borkmann 	insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0);
163a82d8cd3SDaniel Borkmann 	while (i < self->retval) {
164a82d8cd3SDaniel Borkmann 		uint64_t val = bpf_semi_rand_get();
165a82d8cd3SDaniel Borkmann 		struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) };
166a82d8cd3SDaniel Borkmann 
167a82d8cd3SDaniel Borkmann 		res ^= val;
168a82d8cd3SDaniel Borkmann 		insn[i++] = tmp[0];
169a82d8cd3SDaniel Borkmann 		insn[i++] = tmp[1];
170a82d8cd3SDaniel Borkmann 		insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
171a82d8cd3SDaniel Borkmann 	}
172a82d8cd3SDaniel Borkmann 	insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
173a82d8cd3SDaniel Borkmann 	insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32);
174a82d8cd3SDaniel Borkmann 	insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1);
175a82d8cd3SDaniel Borkmann 	insn[i] = BPF_EXIT_INSN();
176a82d8cd3SDaniel Borkmann 	res ^= (res >> 32);
177a82d8cd3SDaniel Borkmann 	self->retval = (uint32_t)res;
178a82d8cd3SDaniel Borkmann }
179a82d8cd3SDaniel Borkmann 
1805aa5bd14SDaniel Borkmann static struct bpf_test tests[] = {
1815aa5bd14SDaniel Borkmann 	{
1825aa5bd14SDaniel Borkmann 		"add+sub+mul",
1835aa5bd14SDaniel Borkmann 		.insns = {
1845aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 1),
1855aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2),
1865aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 3),
1875aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2),
1885aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
1895aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3),
1905aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
1915aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
1925aa5bd14SDaniel Borkmann 		},
1935aa5bd14SDaniel Borkmann 		.result = ACCEPT,
194111e6b45SAlexei Starovoitov 		.retval = -3,
1955aa5bd14SDaniel Borkmann 	},
1965aa5bd14SDaniel Borkmann 	{
19787c1793bSDaniel Borkmann 		"DIV32 by 0, zero check 1",
19887c1793bSDaniel Borkmann 		.insns = {
19987c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
20087c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
20187c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
20287c1793bSDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
20387c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
20487c1793bSDaniel Borkmann 		},
20587c1793bSDaniel Borkmann 		.result = ACCEPT,
20621ccaf21SDaniel Borkmann 		.retval = 42,
20787c1793bSDaniel Borkmann 	},
20887c1793bSDaniel Borkmann 	{
20987c1793bSDaniel Borkmann 		"DIV32 by 0, zero check 2",
21087c1793bSDaniel Borkmann 		.insns = {
21187c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
21287c1793bSDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
21387c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
21487c1793bSDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
21587c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
21687c1793bSDaniel Borkmann 		},
21787c1793bSDaniel Borkmann 		.result = ACCEPT,
21821ccaf21SDaniel Borkmann 		.retval = 42,
21987c1793bSDaniel Borkmann 	},
22087c1793bSDaniel Borkmann 	{
22187c1793bSDaniel Borkmann 		"DIV64 by 0, zero check",
22287c1793bSDaniel Borkmann 		.insns = {
22387c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
22487c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
22587c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
22687c1793bSDaniel Borkmann 			BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
22787c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
22887c1793bSDaniel Borkmann 		},
22987c1793bSDaniel Borkmann 		.result = ACCEPT,
23021ccaf21SDaniel Borkmann 		.retval = 42,
23187c1793bSDaniel Borkmann 	},
23287c1793bSDaniel Borkmann 	{
23387c1793bSDaniel Borkmann 		"MOD32 by 0, zero check 1",
23487c1793bSDaniel Borkmann 		.insns = {
23587c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
23687c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
23787c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
23887c1793bSDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
23987c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
24087c1793bSDaniel Borkmann 		},
24187c1793bSDaniel Borkmann 		.result = ACCEPT,
24221ccaf21SDaniel Borkmann 		.retval = 42,
24387c1793bSDaniel Borkmann 	},
24487c1793bSDaniel Borkmann 	{
24587c1793bSDaniel Borkmann 		"MOD32 by 0, zero check 2",
24687c1793bSDaniel Borkmann 		.insns = {
24787c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
24887c1793bSDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
24987c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
25087c1793bSDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
25187c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
25287c1793bSDaniel Borkmann 		},
25387c1793bSDaniel Borkmann 		.result = ACCEPT,
25421ccaf21SDaniel Borkmann 		.retval = 42,
25587c1793bSDaniel Borkmann 	},
25687c1793bSDaniel Borkmann 	{
25787c1793bSDaniel Borkmann 		"MOD64 by 0, zero check",
25887c1793bSDaniel Borkmann 		.insns = {
25987c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
26087c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
26187c1793bSDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 1),
26287c1793bSDaniel Borkmann 			BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
26387c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
26487c1793bSDaniel Borkmann 		},
26587c1793bSDaniel Borkmann 		.result = ACCEPT,
26621ccaf21SDaniel Borkmann 		.retval = 42,
26721ccaf21SDaniel Borkmann 	},
26821ccaf21SDaniel Borkmann 	{
26921ccaf21SDaniel Borkmann 		"DIV32 by 0, zero check ok, cls",
27021ccaf21SDaniel Borkmann 		.insns = {
27121ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
27221ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 2),
27321ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 16),
27421ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
27521ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
27621ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
27721ccaf21SDaniel Borkmann 		},
27821ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
27921ccaf21SDaniel Borkmann 		.result = ACCEPT,
28021ccaf21SDaniel Borkmann 		.retval = 8,
28121ccaf21SDaniel Borkmann 	},
28221ccaf21SDaniel Borkmann 	{
28321ccaf21SDaniel Borkmann 		"DIV32 by 0, zero check 1, cls",
28421ccaf21SDaniel Borkmann 		.insns = {
28521ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
28621ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
28721ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
28821ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
28921ccaf21SDaniel Borkmann 		},
29021ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29121ccaf21SDaniel Borkmann 		.result = ACCEPT,
29287c1793bSDaniel Borkmann 		.retval = 0,
29387c1793bSDaniel Borkmann 	},
29487c1793bSDaniel Borkmann 	{
29521ccaf21SDaniel Borkmann 		"DIV32 by 0, zero check 2, cls",
29621ccaf21SDaniel Borkmann 		.insns = {
29721ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
29821ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
29921ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
30021ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
30121ccaf21SDaniel Borkmann 		},
30221ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30321ccaf21SDaniel Borkmann 		.result = ACCEPT,
30421ccaf21SDaniel Borkmann 		.retval = 0,
30521ccaf21SDaniel Borkmann 	},
30621ccaf21SDaniel Borkmann 	{
30721ccaf21SDaniel Borkmann 		"DIV64 by 0, zero check, cls",
30821ccaf21SDaniel Borkmann 		.insns = {
30921ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
31021ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
31121ccaf21SDaniel Borkmann 			BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
31221ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
31321ccaf21SDaniel Borkmann 		},
31421ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31521ccaf21SDaniel Borkmann 		.result = ACCEPT,
31621ccaf21SDaniel Borkmann 		.retval = 0,
31721ccaf21SDaniel Borkmann 	},
31821ccaf21SDaniel Borkmann 	{
31921ccaf21SDaniel Borkmann 		"MOD32 by 0, zero check ok, cls",
32021ccaf21SDaniel Borkmann 		.insns = {
32121ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
32221ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 3),
32321ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 5),
32421ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
32521ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
32621ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
32721ccaf21SDaniel Borkmann 		},
32821ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
32921ccaf21SDaniel Borkmann 		.result = ACCEPT,
33021ccaf21SDaniel Borkmann 		.retval = 2,
33121ccaf21SDaniel Borkmann 	},
33221ccaf21SDaniel Borkmann 	{
33321ccaf21SDaniel Borkmann 		"MOD32 by 0, zero check 1, cls",
33421ccaf21SDaniel Borkmann 		.insns = {
33521ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
33621ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
33721ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
33821ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
33921ccaf21SDaniel Borkmann 		},
34021ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
34121ccaf21SDaniel Borkmann 		.result = ACCEPT,
34221ccaf21SDaniel Borkmann 		.retval = 1,
34321ccaf21SDaniel Borkmann 	},
34421ccaf21SDaniel Borkmann 	{
34521ccaf21SDaniel Borkmann 		"MOD32 by 0, zero check 2, cls",
34621ccaf21SDaniel Borkmann 		.insns = {
34721ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xffffffff00000000LL),
34821ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
34921ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
35021ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
35121ccaf21SDaniel Borkmann 		},
35221ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
35321ccaf21SDaniel Borkmann 		.result = ACCEPT,
35421ccaf21SDaniel Borkmann 		.retval = 1,
35521ccaf21SDaniel Borkmann 	},
35621ccaf21SDaniel Borkmann 	{
35721ccaf21SDaniel Borkmann 		"MOD64 by 0, zero check 1, cls",
35821ccaf21SDaniel Borkmann 		.insns = {
35921ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
36021ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 2),
36121ccaf21SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
36221ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
36321ccaf21SDaniel Borkmann 		},
36421ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36521ccaf21SDaniel Borkmann 		.result = ACCEPT,
36621ccaf21SDaniel Borkmann 		.retval = 2,
36721ccaf21SDaniel Borkmann 	},
36821ccaf21SDaniel Borkmann 	{
36921ccaf21SDaniel Borkmann 		"MOD64 by 0, zero check 2, cls",
37021ccaf21SDaniel Borkmann 		.insns = {
37121ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
37221ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, -1),
37321ccaf21SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
37421ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
37521ccaf21SDaniel Borkmann 		},
37621ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
37721ccaf21SDaniel Borkmann 		.result = ACCEPT,
37821ccaf21SDaniel Borkmann 		.retval = -1,
37921ccaf21SDaniel Borkmann 	},
38021ccaf21SDaniel Borkmann 	/* Just make sure that JITs used udiv/umod as otherwise we get
38121ccaf21SDaniel Borkmann 	 * an exception from INT_MIN/-1 overflow similarly as with div
38221ccaf21SDaniel Borkmann 	 * by zero.
38321ccaf21SDaniel Borkmann 	 */
38421ccaf21SDaniel Borkmann 	{
38521ccaf21SDaniel Borkmann 		"DIV32 overflow, check 1",
38621ccaf21SDaniel Borkmann 		.insns = {
38721ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, -1),
38821ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
38921ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
39021ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
39121ccaf21SDaniel Borkmann 		},
39221ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39321ccaf21SDaniel Borkmann 		.result = ACCEPT,
39421ccaf21SDaniel Borkmann 		.retval = 0,
39521ccaf21SDaniel Borkmann 	},
39621ccaf21SDaniel Borkmann 	{
39721ccaf21SDaniel Borkmann 		"DIV32 overflow, check 2",
39821ccaf21SDaniel Borkmann 		.insns = {
39921ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
40021ccaf21SDaniel Borkmann 			BPF_ALU32_IMM(BPF_DIV, BPF_REG_0, -1),
40121ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
40221ccaf21SDaniel Borkmann 		},
40321ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
40421ccaf21SDaniel Borkmann 		.result = ACCEPT,
40521ccaf21SDaniel Borkmann 		.retval = 0,
40621ccaf21SDaniel Borkmann 	},
40721ccaf21SDaniel Borkmann 	{
40821ccaf21SDaniel Borkmann 		"DIV64 overflow, check 1",
40921ccaf21SDaniel Borkmann 		.insns = {
41021ccaf21SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, -1),
41121ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
41221ccaf21SDaniel Borkmann 			BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
41321ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
41421ccaf21SDaniel Borkmann 		},
41521ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
41621ccaf21SDaniel Borkmann 		.result = ACCEPT,
41721ccaf21SDaniel Borkmann 		.retval = 0,
41821ccaf21SDaniel Borkmann 	},
41921ccaf21SDaniel Borkmann 	{
42021ccaf21SDaniel Borkmann 		"DIV64 overflow, check 2",
42121ccaf21SDaniel Borkmann 		.insns = {
42221ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
42321ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
42421ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
42521ccaf21SDaniel Borkmann 		},
42621ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
42721ccaf21SDaniel Borkmann 		.result = ACCEPT,
42821ccaf21SDaniel Borkmann 		.retval = 0,
42921ccaf21SDaniel Borkmann 	},
43021ccaf21SDaniel Borkmann 	{
43121ccaf21SDaniel Borkmann 		"MOD32 overflow, check 1",
43221ccaf21SDaniel Borkmann 		.insns = {
43321ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, -1),
43421ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
43521ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_MOD, BPF_REG_0, BPF_REG_1),
43621ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
43721ccaf21SDaniel Borkmann 		},
43821ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
43921ccaf21SDaniel Borkmann 		.result = ACCEPT,
44021ccaf21SDaniel Borkmann 		.retval = INT_MIN,
44121ccaf21SDaniel Borkmann 	},
44221ccaf21SDaniel Borkmann 	{
44321ccaf21SDaniel Borkmann 		"MOD32 overflow, check 2",
44421ccaf21SDaniel Borkmann 		.insns = {
44521ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, INT_MIN),
44621ccaf21SDaniel Borkmann 			BPF_ALU32_IMM(BPF_MOD, BPF_REG_0, -1),
44721ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
44821ccaf21SDaniel Borkmann 		},
44921ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
45021ccaf21SDaniel Borkmann 		.result = ACCEPT,
45121ccaf21SDaniel Borkmann 		.retval = INT_MIN,
45221ccaf21SDaniel Borkmann 	},
45321ccaf21SDaniel Borkmann 	{
45421ccaf21SDaniel Borkmann 		"MOD64 overflow, check 1",
45521ccaf21SDaniel Borkmann 		.insns = {
45621ccaf21SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, -1),
45721ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
45821ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
45921ccaf21SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOD, BPF_REG_2, BPF_REG_1),
46021ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 0),
46121ccaf21SDaniel Borkmann 			BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
46221ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
46321ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
46421ccaf21SDaniel Borkmann 		},
46521ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
46621ccaf21SDaniel Borkmann 		.result = ACCEPT,
46721ccaf21SDaniel Borkmann 		.retval = 1,
46821ccaf21SDaniel Borkmann 	},
46921ccaf21SDaniel Borkmann 	{
47021ccaf21SDaniel Borkmann 		"MOD64 overflow, check 2",
47121ccaf21SDaniel Borkmann 		.insns = {
47221ccaf21SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
47321ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
47421ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MOD, BPF_REG_2, -1),
47521ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 0),
47621ccaf21SDaniel Borkmann 			BPF_JMP_REG(BPF_JNE, BPF_REG_3, BPF_REG_2, 1),
47721ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
47821ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
47921ccaf21SDaniel Borkmann 		},
48021ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
48121ccaf21SDaniel Borkmann 		.result = ACCEPT,
48221ccaf21SDaniel Borkmann 		.retval = 1,
48321ccaf21SDaniel Borkmann 	},
48421ccaf21SDaniel Borkmann 	{
48521ccaf21SDaniel Borkmann 		"xor32 zero extend check",
48621ccaf21SDaniel Borkmann 		.insns = {
48721ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, -1),
48821ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
48921ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 0xffff),
49021ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_XOR, BPF_REG_2, BPF_REG_2),
49121ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 2),
49221ccaf21SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
49321ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 1),
49421ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
49521ccaf21SDaniel Borkmann 		},
49621ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
49721ccaf21SDaniel Borkmann 		.result = ACCEPT,
49821ccaf21SDaniel Borkmann 		.retval = 1,
49921ccaf21SDaniel Borkmann 	},
50021ccaf21SDaniel Borkmann 	{
50187c1793bSDaniel Borkmann 		"empty prog",
50287c1793bSDaniel Borkmann 		.insns = {
50387c1793bSDaniel Borkmann 		},
50421ccaf21SDaniel Borkmann 		.errstr = "unknown opcode 00",
50587c1793bSDaniel Borkmann 		.result = REJECT,
50687c1793bSDaniel Borkmann 	},
50787c1793bSDaniel Borkmann 	{
50887c1793bSDaniel Borkmann 		"only exit insn",
50987c1793bSDaniel Borkmann 		.insns = {
51087c1793bSDaniel Borkmann 			BPF_EXIT_INSN(),
51187c1793bSDaniel Borkmann 		},
51287c1793bSDaniel Borkmann 		.errstr = "R0 !read_ok",
51387c1793bSDaniel Borkmann 		.result = REJECT,
5145aa5bd14SDaniel Borkmann 	},
5155aa5bd14SDaniel Borkmann 	{
5165aa5bd14SDaniel Borkmann 		"unreachable",
5175aa5bd14SDaniel Borkmann 		.insns = {
5185aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5195aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5205aa5bd14SDaniel Borkmann 		},
5215aa5bd14SDaniel Borkmann 		.errstr = "unreachable",
5225aa5bd14SDaniel Borkmann 		.result = REJECT,
5235aa5bd14SDaniel Borkmann 	},
5245aa5bd14SDaniel Borkmann 	{
5255aa5bd14SDaniel Borkmann 		"unreachable2",
5265aa5bd14SDaniel Borkmann 		.insns = {
5275aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
5285aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5295aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5305aa5bd14SDaniel Borkmann 		},
5315aa5bd14SDaniel Borkmann 		.errstr = "unreachable",
5325aa5bd14SDaniel Borkmann 		.result = REJECT,
5335aa5bd14SDaniel Borkmann 	},
5345aa5bd14SDaniel Borkmann 	{
5355aa5bd14SDaniel Borkmann 		"out of range jump",
5365aa5bd14SDaniel Borkmann 		.insns = {
5375aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
5385aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5395aa5bd14SDaniel Borkmann 		},
5405aa5bd14SDaniel Borkmann 		.errstr = "jump out of range",
5415aa5bd14SDaniel Borkmann 		.result = REJECT,
5425aa5bd14SDaniel Borkmann 	},
5435aa5bd14SDaniel Borkmann 	{
5445aa5bd14SDaniel Borkmann 		"out of range jump2",
5455aa5bd14SDaniel Borkmann 		.insns = {
5465aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -2),
5475aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5485aa5bd14SDaniel Borkmann 		},
5495aa5bd14SDaniel Borkmann 		.errstr = "jump out of range",
5505aa5bd14SDaniel Borkmann 		.result = REJECT,
5515aa5bd14SDaniel Borkmann 	},
5525aa5bd14SDaniel Borkmann 	{
5535aa5bd14SDaniel Borkmann 		"test1 ld_imm64",
5545aa5bd14SDaniel Borkmann 		.insns = {
5555aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
5565aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5575aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5585aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5595aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5605aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
5615aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5625aa5bd14SDaniel Borkmann 		},
5635aa5bd14SDaniel Borkmann 		.errstr = "invalid BPF_LD_IMM insn",
5645aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
5655aa5bd14SDaniel Borkmann 		.result = REJECT,
5665aa5bd14SDaniel Borkmann 	},
5675aa5bd14SDaniel Borkmann 	{
5685aa5bd14SDaniel Borkmann 		"test2 ld_imm64",
5695aa5bd14SDaniel Borkmann 		.insns = {
5705aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
5715aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5725aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5735aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5745aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5755aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5765aa5bd14SDaniel Borkmann 		},
5775aa5bd14SDaniel Borkmann 		.errstr = "invalid BPF_LD_IMM insn",
5785aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
5795aa5bd14SDaniel Borkmann 		.result = REJECT,
5805aa5bd14SDaniel Borkmann 	},
5815aa5bd14SDaniel Borkmann 	{
5825aa5bd14SDaniel Borkmann 		"test3 ld_imm64",
5835aa5bd14SDaniel Borkmann 		.insns = {
5845aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
5855aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
5865aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5875aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0),
5885aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5895aa5bd14SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 1),
5905aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
5915aa5bd14SDaniel Borkmann 		},
5925aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
5935aa5bd14SDaniel Borkmann 		.result = REJECT,
5945aa5bd14SDaniel Borkmann 	},
5955aa5bd14SDaniel Borkmann 	{
5965aa5bd14SDaniel Borkmann 		"test4 ld_imm64",
5975aa5bd14SDaniel Borkmann 		.insns = {
5985aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
5995aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
6005aa5bd14SDaniel Borkmann 		},
6015aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
6025aa5bd14SDaniel Borkmann 		.result = REJECT,
6035aa5bd14SDaniel Borkmann 	},
6045aa5bd14SDaniel Borkmann 	{
6055aa5bd14SDaniel Borkmann 		"test5 ld_imm64",
6065aa5bd14SDaniel Borkmann 		.insns = {
6075aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
6085aa5bd14SDaniel Borkmann 		},
6095aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
6105aa5bd14SDaniel Borkmann 		.result = REJECT,
6115aa5bd14SDaniel Borkmann 	},
6125aa5bd14SDaniel Borkmann 	{
613728a853aSDaniel Borkmann 		"test6 ld_imm64",
614728a853aSDaniel Borkmann 		.insns = {
615728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0),
616728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 0, 0),
617728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
618728a853aSDaniel Borkmann 		},
619728a853aSDaniel Borkmann 		.result = ACCEPT,
620728a853aSDaniel Borkmann 	},
621728a853aSDaniel Borkmann 	{
622728a853aSDaniel Borkmann 		"test7 ld_imm64",
623728a853aSDaniel Borkmann 		.insns = {
624728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
625728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 0, 1),
626728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
627728a853aSDaniel Borkmann 		},
628728a853aSDaniel Borkmann 		.result = ACCEPT,
629111e6b45SAlexei Starovoitov 		.retval = 1,
630728a853aSDaniel Borkmann 	},
631728a853aSDaniel Borkmann 	{
632728a853aSDaniel Borkmann 		"test8 ld_imm64",
633728a853aSDaniel Borkmann 		.insns = {
634728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 1, 1),
635728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 0, 1),
636728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
637728a853aSDaniel Borkmann 		},
638728a853aSDaniel Borkmann 		.errstr = "uses reserved fields",
639728a853aSDaniel Borkmann 		.result = REJECT,
640728a853aSDaniel Borkmann 	},
641728a853aSDaniel Borkmann 	{
642728a853aSDaniel Borkmann 		"test9 ld_imm64",
643728a853aSDaniel Borkmann 		.insns = {
644728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
645728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 1, 1),
646728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
647728a853aSDaniel Borkmann 		},
648728a853aSDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
649728a853aSDaniel Borkmann 		.result = REJECT,
650728a853aSDaniel Borkmann 	},
651728a853aSDaniel Borkmann 	{
652728a853aSDaniel Borkmann 		"test10 ld_imm64",
653728a853aSDaniel Borkmann 		.insns = {
654728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
655728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, BPF_REG_1, 0, 0, 1),
656728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
657728a853aSDaniel Borkmann 		},
658728a853aSDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
659728a853aSDaniel Borkmann 		.result = REJECT,
660728a853aSDaniel Borkmann 	},
661728a853aSDaniel Borkmann 	{
662728a853aSDaniel Borkmann 		"test11 ld_imm64",
663728a853aSDaniel Borkmann 		.insns = {
664728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 1),
665728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
666728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
667728a853aSDaniel Borkmann 		},
668728a853aSDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
669728a853aSDaniel Borkmann 		.result = REJECT,
670728a853aSDaniel Borkmann 	},
671728a853aSDaniel Borkmann 	{
672728a853aSDaniel Borkmann 		"test12 ld_imm64",
673728a853aSDaniel Borkmann 		.insns = {
674728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0),
675728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
676728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 0, 1),
677728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
678728a853aSDaniel Borkmann 		},
679728a853aSDaniel Borkmann 		.errstr = "not pointing to valid bpf_map",
680728a853aSDaniel Borkmann 		.result = REJECT,
681728a853aSDaniel Borkmann 	},
682728a853aSDaniel Borkmann 	{
683728a853aSDaniel Borkmann 		"test13 ld_imm64",
684728a853aSDaniel Borkmann 		.insns = {
685728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0),
686728a853aSDaniel Borkmann 			BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
687728a853aSDaniel Borkmann 			BPF_RAW_INSN(0, 0, BPF_REG_1, 0, 1),
688728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
689728a853aSDaniel Borkmann 		},
690728a853aSDaniel Borkmann 		.errstr = "invalid bpf_ld_imm64 insn",
691728a853aSDaniel Borkmann 		.result = REJECT,
692728a853aSDaniel Borkmann 	},
693728a853aSDaniel Borkmann 	{
6947891a87eSDaniel Borkmann 		"arsh32 on imm",
6957891a87eSDaniel Borkmann 		.insns = {
6967891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
6977891a87eSDaniel Borkmann 			BPF_ALU32_IMM(BPF_ARSH, BPF_REG_0, 5),
6987891a87eSDaniel Borkmann 			BPF_EXIT_INSN(),
6997891a87eSDaniel Borkmann 		},
7007891a87eSDaniel Borkmann 		.result = REJECT,
70121ccaf21SDaniel Borkmann 		.errstr = "unknown opcode c4",
7027891a87eSDaniel Borkmann 	},
7037891a87eSDaniel Borkmann 	{
7047891a87eSDaniel Borkmann 		"arsh32 on reg",
7057891a87eSDaniel Borkmann 		.insns = {
7067891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
7077891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 5),
7087891a87eSDaniel Borkmann 			BPF_ALU32_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
7097891a87eSDaniel Borkmann 			BPF_EXIT_INSN(),
7107891a87eSDaniel Borkmann 		},
7117891a87eSDaniel Borkmann 		.result = REJECT,
71221ccaf21SDaniel Borkmann 		.errstr = "unknown opcode cc",
7137891a87eSDaniel Borkmann 	},
7147891a87eSDaniel Borkmann 	{
7157891a87eSDaniel Borkmann 		"arsh64 on imm",
7167891a87eSDaniel Borkmann 		.insns = {
7177891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
7187891a87eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ARSH, BPF_REG_0, 5),
7197891a87eSDaniel Borkmann 			BPF_EXIT_INSN(),
7207891a87eSDaniel Borkmann 		},
7217891a87eSDaniel Borkmann 		.result = ACCEPT,
7227891a87eSDaniel Borkmann 	},
7237891a87eSDaniel Borkmann 	{
7247891a87eSDaniel Borkmann 		"arsh64 on reg",
7257891a87eSDaniel Borkmann 		.insns = {
7267891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
7277891a87eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 5),
7287891a87eSDaniel Borkmann 			BPF_ALU64_REG(BPF_ARSH, BPF_REG_0, BPF_REG_1),
7297891a87eSDaniel Borkmann 			BPF_EXIT_INSN(),
7307891a87eSDaniel Borkmann 		},
7317891a87eSDaniel Borkmann 		.result = ACCEPT,
7327891a87eSDaniel Borkmann 	},
7337891a87eSDaniel Borkmann 	{
7345aa5bd14SDaniel Borkmann 		"no bpf_exit",
7355aa5bd14SDaniel Borkmann 		.insns = {
7365aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
7375aa5bd14SDaniel Borkmann 		},
738a7ff3ecaSAlexei Starovoitov 		.errstr = "not an exit",
7395aa5bd14SDaniel Borkmann 		.result = REJECT,
7405aa5bd14SDaniel Borkmann 	},
7415aa5bd14SDaniel Borkmann 	{
7425aa5bd14SDaniel Borkmann 		"loop (back-edge)",
7435aa5bd14SDaniel Borkmann 		.insns = {
7445aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -1),
7455aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7465aa5bd14SDaniel Borkmann 		},
7475aa5bd14SDaniel Borkmann 		.errstr = "back-edge",
7485aa5bd14SDaniel Borkmann 		.result = REJECT,
7495aa5bd14SDaniel Borkmann 	},
7505aa5bd14SDaniel Borkmann 	{
7515aa5bd14SDaniel Borkmann 		"loop2 (back-edge)",
7525aa5bd14SDaniel Borkmann 		.insns = {
7535aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7545aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
7555aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
7565aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -4),
7575aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7585aa5bd14SDaniel Borkmann 		},
7595aa5bd14SDaniel Borkmann 		.errstr = "back-edge",
7605aa5bd14SDaniel Borkmann 		.result = REJECT,
7615aa5bd14SDaniel Borkmann 	},
7625aa5bd14SDaniel Borkmann 	{
7635aa5bd14SDaniel Borkmann 		"conditional loop",
7645aa5bd14SDaniel Borkmann 		.insns = {
7655aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7665aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
7675aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
7685aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
7695aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7705aa5bd14SDaniel Borkmann 		},
7715aa5bd14SDaniel Borkmann 		.errstr = "back-edge",
7725aa5bd14SDaniel Borkmann 		.result = REJECT,
7735aa5bd14SDaniel Borkmann 	},
7745aa5bd14SDaniel Borkmann 	{
7755aa5bd14SDaniel Borkmann 		"read uninitialized register",
7765aa5bd14SDaniel Borkmann 		.insns = {
7775aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7785aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7795aa5bd14SDaniel Borkmann 		},
7805aa5bd14SDaniel Borkmann 		.errstr = "R2 !read_ok",
7815aa5bd14SDaniel Borkmann 		.result = REJECT,
7825aa5bd14SDaniel Borkmann 	},
7835aa5bd14SDaniel Borkmann 	{
7845aa5bd14SDaniel Borkmann 		"read invalid register",
7855aa5bd14SDaniel Borkmann 		.insns = {
7865aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, -1),
7875aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7885aa5bd14SDaniel Borkmann 		},
7895aa5bd14SDaniel Borkmann 		.errstr = "R15 is invalid",
7905aa5bd14SDaniel Borkmann 		.result = REJECT,
7915aa5bd14SDaniel Borkmann 	},
7925aa5bd14SDaniel Borkmann 	{
7935aa5bd14SDaniel Borkmann 		"program doesn't init R0 before exit",
7945aa5bd14SDaniel Borkmann 		.insns = {
7955aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1),
7965aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
7975aa5bd14SDaniel Borkmann 		},
7985aa5bd14SDaniel Borkmann 		.errstr = "R0 !read_ok",
7995aa5bd14SDaniel Borkmann 		.result = REJECT,
8005aa5bd14SDaniel Borkmann 	},
8015aa5bd14SDaniel Borkmann 	{
8025aa5bd14SDaniel Borkmann 		"program doesn't init R0 before exit in all branches",
8035aa5bd14SDaniel Borkmann 		.insns = {
8045aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
8055aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
8065aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
8075aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8085aa5bd14SDaniel Borkmann 		},
8095aa5bd14SDaniel Borkmann 		.errstr = "R0 !read_ok",
8105aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
8115aa5bd14SDaniel Borkmann 		.result = REJECT,
8125aa5bd14SDaniel Borkmann 	},
8135aa5bd14SDaniel Borkmann 	{
8145aa5bd14SDaniel Borkmann 		"stack out of bounds",
8155aa5bd14SDaniel Borkmann 		.insns = {
8165aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
8175aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8185aa5bd14SDaniel Borkmann 		},
8195aa5bd14SDaniel Borkmann 		.errstr = "invalid stack",
8205aa5bd14SDaniel Borkmann 		.result = REJECT,
8215aa5bd14SDaniel Borkmann 	},
8225aa5bd14SDaniel Borkmann 	{
8235aa5bd14SDaniel Borkmann 		"invalid call insn1",
8245aa5bd14SDaniel Borkmann 		.insns = {
8255aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0),
8265aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8275aa5bd14SDaniel Borkmann 		},
82821ccaf21SDaniel Borkmann 		.errstr = "unknown opcode 8d",
8295aa5bd14SDaniel Borkmann 		.result = REJECT,
8305aa5bd14SDaniel Borkmann 	},
8315aa5bd14SDaniel Borkmann 	{
8325aa5bd14SDaniel Borkmann 		"invalid call insn2",
8335aa5bd14SDaniel Borkmann 		.insns = {
8345aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0),
8355aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8365aa5bd14SDaniel Borkmann 		},
8375aa5bd14SDaniel Borkmann 		.errstr = "BPF_CALL uses reserved",
8385aa5bd14SDaniel Borkmann 		.result = REJECT,
8395aa5bd14SDaniel Borkmann 	},
8405aa5bd14SDaniel Borkmann 	{
8415aa5bd14SDaniel Borkmann 		"invalid function call",
8425aa5bd14SDaniel Borkmann 		.insns = {
8435aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567),
8445aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8455aa5bd14SDaniel Borkmann 		},
846e00c7b21SDaniel Borkmann 		.errstr = "invalid func unknown#1234567",
8475aa5bd14SDaniel Borkmann 		.result = REJECT,
8485aa5bd14SDaniel Borkmann 	},
8495aa5bd14SDaniel Borkmann 	{
8505aa5bd14SDaniel Borkmann 		"uninitialized stack1",
8515aa5bd14SDaniel Borkmann 		.insns = {
8525aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8535aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8545aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
8555aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8565aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
8575aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8585aa5bd14SDaniel Borkmann 		},
8595aa5bd14SDaniel Borkmann 		.fixup_map1 = { 2 },
8605aa5bd14SDaniel Borkmann 		.errstr = "invalid indirect read from stack",
8615aa5bd14SDaniel Borkmann 		.result = REJECT,
8625aa5bd14SDaniel Borkmann 	},
8635aa5bd14SDaniel Borkmann 	{
8645aa5bd14SDaniel Borkmann 		"uninitialized stack2",
8655aa5bd14SDaniel Borkmann 		.insns = {
8665aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8675aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
8685aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
8695aa5bd14SDaniel Borkmann 		},
8705aa5bd14SDaniel Borkmann 		.errstr = "invalid read from stack",
8715aa5bd14SDaniel Borkmann 		.result = REJECT,
8725aa5bd14SDaniel Borkmann 	},
8735aa5bd14SDaniel Borkmann 	{
874728a853aSDaniel Borkmann 		"invalid fp arithmetic",
875728a853aSDaniel Borkmann 		/* If this gets ever changed, make sure JITs can deal with it. */
876728a853aSDaniel Borkmann 		.insns = {
877728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
878728a853aSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
879728a853aSDaniel Borkmann 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 8),
880728a853aSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
881728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
882728a853aSDaniel Borkmann 		},
88382abbf8dSAlexei Starovoitov 		.errstr = "R1 subtraction from stack pointer",
884728a853aSDaniel Borkmann 		.result = REJECT,
885728a853aSDaniel Borkmann 	},
886728a853aSDaniel Borkmann 	{
887728a853aSDaniel Borkmann 		"non-invalid fp arithmetic",
888728a853aSDaniel Borkmann 		.insns = {
889728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
890728a853aSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
891728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
892728a853aSDaniel Borkmann 		},
893728a853aSDaniel Borkmann 		.result = ACCEPT,
894728a853aSDaniel Borkmann 	},
895728a853aSDaniel Borkmann 	{
8965aa5bd14SDaniel Borkmann 		"invalid argument register",
8975aa5bd14SDaniel Borkmann 		.insns = {
8985aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8995aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_cgroup_classid),
9005aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9015aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_cgroup_classid),
9025aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9035aa5bd14SDaniel Borkmann 		},
9045aa5bd14SDaniel Borkmann 		.errstr = "R1 !read_ok",
9055aa5bd14SDaniel Borkmann 		.result = REJECT,
9065aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
9075aa5bd14SDaniel Borkmann 	},
9085aa5bd14SDaniel Borkmann 	{
9095aa5bd14SDaniel Borkmann 		"non-invalid argument register",
9105aa5bd14SDaniel Borkmann 		.insns = {
9115aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
9125aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9135aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_cgroup_classid),
9145aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6),
9155aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
9165aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_cgroup_classid),
9175aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9185aa5bd14SDaniel Borkmann 		},
9195aa5bd14SDaniel Borkmann 		.result = ACCEPT,
9205aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
9215aa5bd14SDaniel Borkmann 	},
9225aa5bd14SDaniel Borkmann 	{
9235aa5bd14SDaniel Borkmann 		"check valid spill/fill",
9245aa5bd14SDaniel Borkmann 		.insns = {
9255aa5bd14SDaniel Borkmann 			/* spill R1(ctx) into stack */
9265aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
9275aa5bd14SDaniel Borkmann 			/* fill it back into R2 */
9285aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
9295aa5bd14SDaniel Borkmann 			/* should be able to access R0 = *(R2 + 8) */
9305aa5bd14SDaniel Borkmann 			/* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
9315aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9325aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9335aa5bd14SDaniel Borkmann 		},
9345aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
9355aa5bd14SDaniel Borkmann 		.result = ACCEPT,
9365aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
937111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
9385aa5bd14SDaniel Borkmann 	},
9395aa5bd14SDaniel Borkmann 	{
9405aa5bd14SDaniel Borkmann 		"check valid spill/fill, skb mark",
9415aa5bd14SDaniel Borkmann 		.insns = {
9425aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
9435aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
9445aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
9455aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
9465aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
9475aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9485aa5bd14SDaniel Borkmann 		},
9495aa5bd14SDaniel Borkmann 		.result = ACCEPT,
9505aa5bd14SDaniel Borkmann 		.result_unpriv = ACCEPT,
9515aa5bd14SDaniel Borkmann 	},
9525aa5bd14SDaniel Borkmann 	{
9535aa5bd14SDaniel Borkmann 		"check corrupted spill/fill",
9545aa5bd14SDaniel Borkmann 		.insns = {
9555aa5bd14SDaniel Borkmann 			/* spill R1(ctx) into stack */
9565aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
9575aa5bd14SDaniel Borkmann 			/* mess up with R1 pointer on stack */
9585aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
9595aa5bd14SDaniel Borkmann 			/* fill back into R0 should fail */
9605aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
9615aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9625aa5bd14SDaniel Borkmann 		},
9635aa5bd14SDaniel Borkmann 		.errstr_unpriv = "attempt to corrupt spilled",
9645aa5bd14SDaniel Borkmann 		.errstr = "corrupted spill",
9655aa5bd14SDaniel Borkmann 		.result = REJECT,
9665aa5bd14SDaniel Borkmann 	},
9675aa5bd14SDaniel Borkmann 	{
9685aa5bd14SDaniel Borkmann 		"invalid src register in STX",
9695aa5bd14SDaniel Borkmann 		.insns = {
9705aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
9715aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9725aa5bd14SDaniel Borkmann 		},
9735aa5bd14SDaniel Borkmann 		.errstr = "R15 is invalid",
9745aa5bd14SDaniel Borkmann 		.result = REJECT,
9755aa5bd14SDaniel Borkmann 	},
9765aa5bd14SDaniel Borkmann 	{
9775aa5bd14SDaniel Borkmann 		"invalid dst register in STX",
9785aa5bd14SDaniel Borkmann 		.insns = {
9795aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1),
9805aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9815aa5bd14SDaniel Borkmann 		},
9825aa5bd14SDaniel Borkmann 		.errstr = "R14 is invalid",
9835aa5bd14SDaniel Borkmann 		.result = REJECT,
9845aa5bd14SDaniel Borkmann 	},
9855aa5bd14SDaniel Borkmann 	{
9865aa5bd14SDaniel Borkmann 		"invalid dst register in ST",
9875aa5bd14SDaniel Borkmann 		.insns = {
9885aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_B, 14, -1, -1),
9895aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9905aa5bd14SDaniel Borkmann 		},
9915aa5bd14SDaniel Borkmann 		.errstr = "R14 is invalid",
9925aa5bd14SDaniel Borkmann 		.result = REJECT,
9935aa5bd14SDaniel Borkmann 	},
9945aa5bd14SDaniel Borkmann 	{
9955aa5bd14SDaniel Borkmann 		"invalid src register in LDX",
9965aa5bd14SDaniel Borkmann 		.insns = {
9975aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0),
9985aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
9995aa5bd14SDaniel Borkmann 		},
10005aa5bd14SDaniel Borkmann 		.errstr = "R12 is invalid",
10015aa5bd14SDaniel Borkmann 		.result = REJECT,
10025aa5bd14SDaniel Borkmann 	},
10035aa5bd14SDaniel Borkmann 	{
10045aa5bd14SDaniel Borkmann 		"invalid dst register in LDX",
10055aa5bd14SDaniel Borkmann 		.insns = {
10065aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0),
10075aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10085aa5bd14SDaniel Borkmann 		},
10095aa5bd14SDaniel Borkmann 		.errstr = "R11 is invalid",
10105aa5bd14SDaniel Borkmann 		.result = REJECT,
10115aa5bd14SDaniel Borkmann 	},
10125aa5bd14SDaniel Borkmann 	{
10135aa5bd14SDaniel Borkmann 		"junk insn",
10145aa5bd14SDaniel Borkmann 		.insns = {
10155aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(0, 0, 0, 0, 0),
10165aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10175aa5bd14SDaniel Borkmann 		},
101821ccaf21SDaniel Borkmann 		.errstr = "unknown opcode 00",
10195aa5bd14SDaniel Borkmann 		.result = REJECT,
10205aa5bd14SDaniel Borkmann 	},
10215aa5bd14SDaniel Borkmann 	{
10225aa5bd14SDaniel Borkmann 		"junk insn2",
10235aa5bd14SDaniel Borkmann 		.insns = {
10245aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(1, 0, 0, 0, 0),
10255aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10265aa5bd14SDaniel Borkmann 		},
10275aa5bd14SDaniel Borkmann 		.errstr = "BPF_LDX uses reserved fields",
10285aa5bd14SDaniel Borkmann 		.result = REJECT,
10295aa5bd14SDaniel Borkmann 	},
10305aa5bd14SDaniel Borkmann 	{
10315aa5bd14SDaniel Borkmann 		"junk insn3",
10325aa5bd14SDaniel Borkmann 		.insns = {
10335aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(-1, 0, 0, 0, 0),
10345aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10355aa5bd14SDaniel Borkmann 		},
103621ccaf21SDaniel Borkmann 		.errstr = "unknown opcode ff",
10375aa5bd14SDaniel Borkmann 		.result = REJECT,
10385aa5bd14SDaniel Borkmann 	},
10395aa5bd14SDaniel Borkmann 	{
10405aa5bd14SDaniel Borkmann 		"junk insn4",
10415aa5bd14SDaniel Borkmann 		.insns = {
10425aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(-1, -1, -1, -1, -1),
10435aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10445aa5bd14SDaniel Borkmann 		},
104521ccaf21SDaniel Borkmann 		.errstr = "unknown opcode ff",
10465aa5bd14SDaniel Borkmann 		.result = REJECT,
10475aa5bd14SDaniel Borkmann 	},
10485aa5bd14SDaniel Borkmann 	{
10495aa5bd14SDaniel Borkmann 		"junk insn5",
10505aa5bd14SDaniel Borkmann 		.insns = {
10515aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
10525aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10535aa5bd14SDaniel Borkmann 		},
10545aa5bd14SDaniel Borkmann 		.errstr = "BPF_ALU uses reserved fields",
10555aa5bd14SDaniel Borkmann 		.result = REJECT,
10565aa5bd14SDaniel Borkmann 	},
10575aa5bd14SDaniel Borkmann 	{
10585aa5bd14SDaniel Borkmann 		"misaligned read from stack",
10595aa5bd14SDaniel Borkmann 		.insns = {
10605aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10615aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4),
10625aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10635aa5bd14SDaniel Borkmann 		},
1064f65b1849SEdward Cree 		.errstr = "misaligned stack access",
10655aa5bd14SDaniel Borkmann 		.result = REJECT,
10665aa5bd14SDaniel Borkmann 	},
10675aa5bd14SDaniel Borkmann 	{
10685aa5bd14SDaniel Borkmann 		"invalid map_fd for function call",
10695aa5bd14SDaniel Borkmann 		.insns = {
10705aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10715aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
10725aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10735aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10745aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10755aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_delete_elem),
10765aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10775aa5bd14SDaniel Borkmann 		},
10785aa5bd14SDaniel Borkmann 		.errstr = "fd 0 is not pointing to valid bpf_map",
10795aa5bd14SDaniel Borkmann 		.result = REJECT,
10805aa5bd14SDaniel Borkmann 	},
10815aa5bd14SDaniel Borkmann 	{
10825aa5bd14SDaniel Borkmann 		"don't check return value before access",
10835aa5bd14SDaniel Borkmann 		.insns = {
10845aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10855aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10865aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10875aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10885aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10895aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
10905aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10915aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
10925aa5bd14SDaniel Borkmann 		},
10935aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
10945aa5bd14SDaniel Borkmann 		.errstr = "R0 invalid mem access 'map_value_or_null'",
10955aa5bd14SDaniel Borkmann 		.result = REJECT,
10965aa5bd14SDaniel Borkmann 	},
10975aa5bd14SDaniel Borkmann 	{
10985aa5bd14SDaniel Borkmann 		"access memory with incorrect alignment",
10995aa5bd14SDaniel Borkmann 		.insns = {
11005aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11015aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11025aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11035aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11045aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11055aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
11065aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11075aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
11085aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
11095aa5bd14SDaniel Borkmann 		},
11105aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
1111f65b1849SEdward Cree 		.errstr = "misaligned value access",
11125aa5bd14SDaniel Borkmann 		.result = REJECT,
1113f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
11145aa5bd14SDaniel Borkmann 	},
11155aa5bd14SDaniel Borkmann 	{
11165aa5bd14SDaniel Borkmann 		"sometimes access memory with incorrect alignment",
11175aa5bd14SDaniel Borkmann 		.insns = {
11185aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11195aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11205aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11215aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11225aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11235aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
11245aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
11255aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11265aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
11275aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
11285aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
11295aa5bd14SDaniel Borkmann 		},
11305aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
11315aa5bd14SDaniel Borkmann 		.errstr = "R0 invalid mem access",
11325aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
11335aa5bd14SDaniel Borkmann 		.result = REJECT,
1134f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
11355aa5bd14SDaniel Borkmann 	},
11365aa5bd14SDaniel Borkmann 	{
11375aa5bd14SDaniel Borkmann 		"jump test 1",
11385aa5bd14SDaniel Borkmann 		.insns = {
11395aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11405aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8),
11415aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
11425aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
11435aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1),
11445aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1),
11455aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1),
11465aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2),
11475aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1),
11485aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3),
11495aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1),
11505aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4),
11515aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
11525aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5),
11535aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
11545aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
11555aa5bd14SDaniel Borkmann 		},
11565aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
11575aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
11585aa5bd14SDaniel Borkmann 		.result = ACCEPT,
11595aa5bd14SDaniel Borkmann 	},
11605aa5bd14SDaniel Borkmann 	{
11615aa5bd14SDaniel Borkmann 		"jump test 2",
11625aa5bd14SDaniel Borkmann 		.insns = {
11635aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11645aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
11655aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
11665aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 14),
11675aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2),
11685aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
11695aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 11),
11705aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2),
11715aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
11725aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 8),
11735aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2),
11745aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
11755aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 5),
11765aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2),
11775aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
11785aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11795aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1),
11805aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
11815aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
11825aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
11835aa5bd14SDaniel Borkmann 		},
11845aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
11855aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
11865aa5bd14SDaniel Borkmann 		.result = ACCEPT,
11875aa5bd14SDaniel Borkmann 	},
11885aa5bd14SDaniel Borkmann 	{
11895aa5bd14SDaniel Borkmann 		"jump test 3",
11905aa5bd14SDaniel Borkmann 		.insns = {
11915aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11925aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
11935aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0),
11945aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11955aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 19),
11965aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3),
11975aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0),
11985aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11995aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 15),
12005aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3),
12015aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0),
12025aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
12035aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 11),
12045aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3),
12055aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0),
12065aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40),
12075aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 7),
12085aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3),
12095aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0),
12105aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48),
12115aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 3),
12125aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0),
12135aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0),
12145aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56),
12155aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
12165aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12175aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_delete_elem),
12185aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
12195aa5bd14SDaniel Borkmann 		},
12205aa5bd14SDaniel Borkmann 		.fixup_map1 = { 24 },
12215aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
12225aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
12235aa5bd14SDaniel Borkmann 		.result = ACCEPT,
1224111e6b45SAlexei Starovoitov 		.retval = -ENOENT,
12255aa5bd14SDaniel Borkmann 	},
12265aa5bd14SDaniel Borkmann 	{
12275aa5bd14SDaniel Borkmann 		"jump test 4",
12285aa5bd14SDaniel Borkmann 		.insns = {
12295aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12305aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12315aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12325aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12335aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12345aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12355aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12365aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12375aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12385aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12395aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12405aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12415aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12425aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12435aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12445aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12455aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12465aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12475aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12485aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12495aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12505aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12515aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12525aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12535aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12545aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12555aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12565aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12575aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12585aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12595aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12605aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12615aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1),
12625aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2),
12635aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3),
12645aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4),
12655aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
12665aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
12675aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
12685aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
12695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
12705aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
12715aa5bd14SDaniel Borkmann 		},
12725aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
12735aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
12745aa5bd14SDaniel Borkmann 		.result = ACCEPT,
12755aa5bd14SDaniel Borkmann 	},
12765aa5bd14SDaniel Borkmann 	{
12775aa5bd14SDaniel Borkmann 		"jump test 5",
12785aa5bd14SDaniel Borkmann 		.insns = {
12795aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
12805aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
12815aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
12825aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
12835aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12845aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
12855aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
12865aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
12875aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
12885aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
12895aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12905aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
12915aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
12925aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
12935aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
12945aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
12955aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
12965aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
12975aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
12985aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
12995aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
13005aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
13015aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
13025aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
13035aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
13045aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
13055aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
13065aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8),
13075aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
13085aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8),
13095aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
13105aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
13115aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13125aa5bd14SDaniel Borkmann 		},
13135aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
13145aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
13155aa5bd14SDaniel Borkmann 		.result = ACCEPT,
13165aa5bd14SDaniel Borkmann 	},
13175aa5bd14SDaniel Borkmann 	{
13185aa5bd14SDaniel Borkmann 		"access skb fields ok",
13195aa5bd14SDaniel Borkmann 		.insns = {
13205aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13215aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, len)),
13225aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
13235aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13245aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
13255aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
13265aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13275aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, pkt_type)),
13285aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
13295aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13305aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, queue_mapping)),
13315aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
13325aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13335aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, protocol)),
13345aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
13355aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13365aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, vlan_present)),
13375aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
13385aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13395aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, vlan_tci)),
13405aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
1341b1d9fc41SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1342b1d9fc41SDaniel Borkmann 				    offsetof(struct __sk_buff, napi_id)),
1343b1d9fc41SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
13445aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13455aa5bd14SDaniel Borkmann 		},
13465aa5bd14SDaniel Borkmann 		.result = ACCEPT,
13475aa5bd14SDaniel Borkmann 	},
13485aa5bd14SDaniel Borkmann 	{
13495aa5bd14SDaniel Borkmann 		"access skb fields bad1",
13505aa5bd14SDaniel Borkmann 		.insns = {
13515aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
13525aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13535aa5bd14SDaniel Borkmann 		},
13545aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
13555aa5bd14SDaniel Borkmann 		.result = REJECT,
13565aa5bd14SDaniel Borkmann 	},
13575aa5bd14SDaniel Borkmann 	{
13585aa5bd14SDaniel Borkmann 		"access skb fields bad2",
13595aa5bd14SDaniel Borkmann 		.insns = {
13605aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
13615aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
13625aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
13635aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
13645aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
13655aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13665aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
13675aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
13685aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13695aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13705aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13715aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, pkt_type)),
13725aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13735aa5bd14SDaniel Borkmann 		},
13745aa5bd14SDaniel Borkmann 		.fixup_map1 = { 4 },
13755aa5bd14SDaniel Borkmann 		.errstr = "different pointers",
13765aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
13775aa5bd14SDaniel Borkmann 		.result = REJECT,
13785aa5bd14SDaniel Borkmann 	},
13795aa5bd14SDaniel Borkmann 	{
13805aa5bd14SDaniel Borkmann 		"access skb fields bad3",
13815aa5bd14SDaniel Borkmann 		.insns = {
13825aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
13835aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
13845aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, pkt_type)),
13855aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13865aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
13875aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
13885aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
13895aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
13905aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
13915aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
13925aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
13935aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
13945aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
13955aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -12),
13965aa5bd14SDaniel Borkmann 		},
13975aa5bd14SDaniel Borkmann 		.fixup_map1 = { 6 },
13985aa5bd14SDaniel Borkmann 		.errstr = "different pointers",
13995aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
14005aa5bd14SDaniel Borkmann 		.result = REJECT,
14015aa5bd14SDaniel Borkmann 	},
14025aa5bd14SDaniel Borkmann 	{
14035aa5bd14SDaniel Borkmann 		"access skb fields bad4",
14045aa5bd14SDaniel Borkmann 		.insns = {
14055aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3),
14065aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
14075aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, len)),
14085aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
14095aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
14105aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
14115aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
14125aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
14135aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
14145aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14155aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
14165aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
14175aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
14185aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
14195aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -13),
14205aa5bd14SDaniel Borkmann 		},
14215aa5bd14SDaniel Borkmann 		.fixup_map1 = { 7 },
14225aa5bd14SDaniel Borkmann 		.errstr = "different pointers",
14235aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
14245aa5bd14SDaniel Borkmann 		.result = REJECT,
14255aa5bd14SDaniel Borkmann 	},
14265aa5bd14SDaniel Borkmann 	{
142741bc94f5SJohn Fastabend 		"invalid access __sk_buff family",
142841bc94f5SJohn Fastabend 		.insns = {
142941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
143041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, family)),
143141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
143241bc94f5SJohn Fastabend 		},
143341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
143441bc94f5SJohn Fastabend 		.result = REJECT,
143541bc94f5SJohn Fastabend 	},
143641bc94f5SJohn Fastabend 	{
143741bc94f5SJohn Fastabend 		"invalid access __sk_buff remote_ip4",
143841bc94f5SJohn Fastabend 		.insns = {
143941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
144041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip4)),
144141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
144241bc94f5SJohn Fastabend 		},
144341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
144441bc94f5SJohn Fastabend 		.result = REJECT,
144541bc94f5SJohn Fastabend 	},
144641bc94f5SJohn Fastabend 	{
144741bc94f5SJohn Fastabend 		"invalid access __sk_buff local_ip4",
144841bc94f5SJohn Fastabend 		.insns = {
144941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
145041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip4)),
145141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
145241bc94f5SJohn Fastabend 		},
145341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
145441bc94f5SJohn Fastabend 		.result = REJECT,
145541bc94f5SJohn Fastabend 	},
145641bc94f5SJohn Fastabend 	{
145741bc94f5SJohn Fastabend 		"invalid access __sk_buff remote_ip6",
145841bc94f5SJohn Fastabend 		.insns = {
145941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
146041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip6)),
146141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
146241bc94f5SJohn Fastabend 		},
146341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
146441bc94f5SJohn Fastabend 		.result = REJECT,
146541bc94f5SJohn Fastabend 	},
146641bc94f5SJohn Fastabend 	{
146741bc94f5SJohn Fastabend 		"invalid access __sk_buff local_ip6",
146841bc94f5SJohn Fastabend 		.insns = {
146941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
147041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip6)),
147141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
147241bc94f5SJohn Fastabend 		},
147341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
147441bc94f5SJohn Fastabend 		.result = REJECT,
147541bc94f5SJohn Fastabend 	},
147641bc94f5SJohn Fastabend 	{
147741bc94f5SJohn Fastabend 		"invalid access __sk_buff remote_port",
147841bc94f5SJohn Fastabend 		.insns = {
147941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
148041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_port)),
148141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
148241bc94f5SJohn Fastabend 		},
148341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
148441bc94f5SJohn Fastabend 		.result = REJECT,
148541bc94f5SJohn Fastabend 	},
148641bc94f5SJohn Fastabend 	{
148741bc94f5SJohn Fastabend 		"invalid access __sk_buff remote_port",
148841bc94f5SJohn Fastabend 		.insns = {
148941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
149041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_port)),
149141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
149241bc94f5SJohn Fastabend 		},
149341bc94f5SJohn Fastabend 		.errstr = "invalid bpf_context access",
149441bc94f5SJohn Fastabend 		.result = REJECT,
149541bc94f5SJohn Fastabend 	},
149641bc94f5SJohn Fastabend 	{
149741bc94f5SJohn Fastabend 		"valid access __sk_buff family",
149841bc94f5SJohn Fastabend 		.insns = {
149941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
150041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, family)),
150141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
150241bc94f5SJohn Fastabend 		},
150341bc94f5SJohn Fastabend 		.result = ACCEPT,
150441bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
150541bc94f5SJohn Fastabend 	},
150641bc94f5SJohn Fastabend 	{
150741bc94f5SJohn Fastabend 		"valid access __sk_buff remote_ip4",
150841bc94f5SJohn Fastabend 		.insns = {
150941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
151041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip4)),
151141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
151241bc94f5SJohn Fastabend 		},
151341bc94f5SJohn Fastabend 		.result = ACCEPT,
151441bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
151541bc94f5SJohn Fastabend 	},
151641bc94f5SJohn Fastabend 	{
151741bc94f5SJohn Fastabend 		"valid access __sk_buff local_ip4",
151841bc94f5SJohn Fastabend 		.insns = {
151941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
152041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip4)),
152141bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
152241bc94f5SJohn Fastabend 		},
152341bc94f5SJohn Fastabend 		.result = ACCEPT,
152441bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
152541bc94f5SJohn Fastabend 	},
152641bc94f5SJohn Fastabend 	{
152741bc94f5SJohn Fastabend 		"valid access __sk_buff remote_ip6",
152841bc94f5SJohn Fastabend 		.insns = {
152941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
153041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip6[0])),
153141bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
153241bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip6[1])),
153341bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
153441bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip6[2])),
153541bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
153641bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_ip6[3])),
153741bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
153841bc94f5SJohn Fastabend 		},
153941bc94f5SJohn Fastabend 		.result = ACCEPT,
154041bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
154141bc94f5SJohn Fastabend 	},
154241bc94f5SJohn Fastabend 	{
154341bc94f5SJohn Fastabend 		"valid access __sk_buff local_ip6",
154441bc94f5SJohn Fastabend 		.insns = {
154541bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
154641bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip6[0])),
154741bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
154841bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip6[1])),
154941bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
155041bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip6[2])),
155141bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
155241bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_ip6[3])),
155341bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
155441bc94f5SJohn Fastabend 		},
155541bc94f5SJohn Fastabend 		.result = ACCEPT,
155641bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
155741bc94f5SJohn Fastabend 	},
155841bc94f5SJohn Fastabend 	{
155941bc94f5SJohn Fastabend 		"valid access __sk_buff remote_port",
156041bc94f5SJohn Fastabend 		.insns = {
156141bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
156241bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, remote_port)),
156341bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
156441bc94f5SJohn Fastabend 		},
156541bc94f5SJohn Fastabend 		.result = ACCEPT,
156641bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
156741bc94f5SJohn Fastabend 	},
156841bc94f5SJohn Fastabend 	{
156941bc94f5SJohn Fastabend 		"valid access __sk_buff remote_port",
157041bc94f5SJohn Fastabend 		.insns = {
157141bc94f5SJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
157241bc94f5SJohn Fastabend 				    offsetof(struct __sk_buff, local_port)),
157341bc94f5SJohn Fastabend 			BPF_EXIT_INSN(),
157441bc94f5SJohn Fastabend 		},
157541bc94f5SJohn Fastabend 		.result = ACCEPT,
157641bc94f5SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
157741bc94f5SJohn Fastabend 	},
157841bc94f5SJohn Fastabend 	{
1579ed85054dSJohn Fastabend 		"invalid access of tc_classid for SK_SKB",
1580ed85054dSJohn Fastabend 		.insns = {
1581ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1582ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, tc_classid)),
1583ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1584ed85054dSJohn Fastabend 		},
1585ed85054dSJohn Fastabend 		.result = REJECT,
1586ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1587ed85054dSJohn Fastabend 		.errstr = "invalid bpf_context access",
1588ed85054dSJohn Fastabend 	},
1589ed85054dSJohn Fastabend 	{
1590f7e9cb1eSJohn Fastabend 		"invalid access of skb->mark for SK_SKB",
1591f7e9cb1eSJohn Fastabend 		.insns = {
1592f7e9cb1eSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1593f7e9cb1eSJohn Fastabend 				    offsetof(struct __sk_buff, mark)),
1594f7e9cb1eSJohn Fastabend 			BPF_EXIT_INSN(),
1595f7e9cb1eSJohn Fastabend 		},
1596f7e9cb1eSJohn Fastabend 		.result =  REJECT,
1597f7e9cb1eSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1598f7e9cb1eSJohn Fastabend 		.errstr = "invalid bpf_context access",
1599f7e9cb1eSJohn Fastabend 	},
1600f7e9cb1eSJohn Fastabend 	{
1601f7e9cb1eSJohn Fastabend 		"check skb->mark is not writeable by SK_SKB",
1602ed85054dSJohn Fastabend 		.insns = {
1603ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1604ed85054dSJohn Fastabend 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1605ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, mark)),
1606ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1607ed85054dSJohn Fastabend 		},
1608f7e9cb1eSJohn Fastabend 		.result =  REJECT,
1609ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1610f7e9cb1eSJohn Fastabend 		.errstr = "invalid bpf_context access",
1611ed85054dSJohn Fastabend 	},
1612ed85054dSJohn Fastabend 	{
1613ed85054dSJohn Fastabend 		"check skb->tc_index is writeable by SK_SKB",
1614ed85054dSJohn Fastabend 		.insns = {
1615ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1616ed85054dSJohn Fastabend 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1617ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, tc_index)),
1618ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1619ed85054dSJohn Fastabend 		},
1620ed85054dSJohn Fastabend 		.result = ACCEPT,
1621ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1622ed85054dSJohn Fastabend 	},
1623ed85054dSJohn Fastabend 	{
1624ed85054dSJohn Fastabend 		"check skb->priority is writeable by SK_SKB",
1625ed85054dSJohn Fastabend 		.insns = {
1626ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1627ed85054dSJohn Fastabend 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1628ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, priority)),
1629ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1630ed85054dSJohn Fastabend 		},
1631ed85054dSJohn Fastabend 		.result = ACCEPT,
1632ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1633ed85054dSJohn Fastabend 	},
1634ed85054dSJohn Fastabend 	{
1635ed85054dSJohn Fastabend 		"direct packet read for SK_SKB",
1636ed85054dSJohn Fastabend 		.insns = {
1637ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1638ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data)),
1639ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1640ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data_end)),
1641ed85054dSJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1642ed85054dSJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1643ed85054dSJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1644ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1645ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1646ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1647ed85054dSJohn Fastabend 		},
1648ed85054dSJohn Fastabend 		.result = ACCEPT,
1649ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1650ed85054dSJohn Fastabend 	},
1651ed85054dSJohn Fastabend 	{
1652ed85054dSJohn Fastabend 		"direct packet write for SK_SKB",
1653ed85054dSJohn Fastabend 		.insns = {
1654ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1655ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data)),
1656ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1657ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data_end)),
1658ed85054dSJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1659ed85054dSJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1660ed85054dSJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1661ed85054dSJohn Fastabend 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1662ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1663ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1664ed85054dSJohn Fastabend 		},
1665ed85054dSJohn Fastabend 		.result = ACCEPT,
1666ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1667ed85054dSJohn Fastabend 	},
1668ed85054dSJohn Fastabend 	{
1669ed85054dSJohn Fastabend 		"overlapping checks for direct packet access SK_SKB",
1670ed85054dSJohn Fastabend 		.insns = {
1671ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1672ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data)),
1673ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1674ed85054dSJohn Fastabend 				    offsetof(struct __sk_buff, data_end)),
1675ed85054dSJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1676ed85054dSJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1677ed85054dSJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1678ed85054dSJohn Fastabend 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1679ed85054dSJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1680ed85054dSJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1681ed85054dSJohn Fastabend 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1682ed85054dSJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
1683ed85054dSJohn Fastabend 			BPF_EXIT_INSN(),
1684ed85054dSJohn Fastabend 		},
1685ed85054dSJohn Fastabend 		.result = ACCEPT,
1686ed85054dSJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_SKB,
1687ed85054dSJohn Fastabend 	},
1688ed85054dSJohn Fastabend 	{
16891acc60b6SJohn Fastabend 		"direct packet read for SK_MSG",
16901acc60b6SJohn Fastabend 		.insns = {
16911acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
16921acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data)),
16931acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
16941acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data_end)),
16951acc60b6SJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
16961acc60b6SJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
16971acc60b6SJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
16981acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
16991acc60b6SJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
17001acc60b6SJohn Fastabend 			BPF_EXIT_INSN(),
17011acc60b6SJohn Fastabend 		},
17021acc60b6SJohn Fastabend 		.result = ACCEPT,
17031acc60b6SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_MSG,
17041acc60b6SJohn Fastabend 	},
17051acc60b6SJohn Fastabend 	{
17061acc60b6SJohn Fastabend 		"direct packet write for SK_MSG",
17071acc60b6SJohn Fastabend 		.insns = {
17081acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
17091acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data)),
17101acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
17111acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data_end)),
17121acc60b6SJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
17131acc60b6SJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
17141acc60b6SJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
17151acc60b6SJohn Fastabend 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
17161acc60b6SJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
17171acc60b6SJohn Fastabend 			BPF_EXIT_INSN(),
17181acc60b6SJohn Fastabend 		},
17191acc60b6SJohn Fastabend 		.result = ACCEPT,
17201acc60b6SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_MSG,
17211acc60b6SJohn Fastabend 	},
17221acc60b6SJohn Fastabend 	{
17231acc60b6SJohn Fastabend 		"overlapping checks for direct packet access SK_MSG",
17241acc60b6SJohn Fastabend 		.insns = {
17251acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
17261acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data)),
17271acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
17281acc60b6SJohn Fastabend 				    offsetof(struct sk_msg_md, data_end)),
17291acc60b6SJohn Fastabend 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
17301acc60b6SJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
17311acc60b6SJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
17321acc60b6SJohn Fastabend 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
17331acc60b6SJohn Fastabend 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
17341acc60b6SJohn Fastabend 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
17351acc60b6SJohn Fastabend 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
17361acc60b6SJohn Fastabend 			BPF_MOV64_IMM(BPF_REG_0, 0),
17371acc60b6SJohn Fastabend 			BPF_EXIT_INSN(),
17381acc60b6SJohn Fastabend 		},
17391acc60b6SJohn Fastabend 		.result = ACCEPT,
17401acc60b6SJohn Fastabend 		.prog_type = BPF_PROG_TYPE_SK_MSG,
17411acc60b6SJohn Fastabend 	},
17421acc60b6SJohn Fastabend 	{
17435aa5bd14SDaniel Borkmann 		"check skb->mark is not writeable by sockets",
17445aa5bd14SDaniel Borkmann 		.insns = {
17455aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
17465aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
17475aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
17485aa5bd14SDaniel Borkmann 		},
17495aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
17505aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 leaks addr",
17515aa5bd14SDaniel Borkmann 		.result = REJECT,
17525aa5bd14SDaniel Borkmann 	},
17535aa5bd14SDaniel Borkmann 	{
17545aa5bd14SDaniel Borkmann 		"check skb->tc_index is not writeable by sockets",
17555aa5bd14SDaniel Borkmann 		.insns = {
17565aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
17575aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, tc_index)),
17585aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
17595aa5bd14SDaniel Borkmann 		},
17605aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
17615aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 leaks addr",
17625aa5bd14SDaniel Borkmann 		.result = REJECT,
17635aa5bd14SDaniel Borkmann 	},
17645aa5bd14SDaniel Borkmann 	{
176562c7989bSDaniel Borkmann 		"check cb access: byte",
17665aa5bd14SDaniel Borkmann 		.insns = {
176762c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
176862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
176962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
177062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
177162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 1),
177262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
177362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 2),
177462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
177562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 3),
177662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
177762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
177862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
177962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 1),
178062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
178162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 2),
178262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
178362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 3),
178462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
178562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
178662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
178762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 1),
178862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
178962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 2),
179062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
179162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 3),
179262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
179362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
179462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
179562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 1),
179662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
179762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 2),
179862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
179962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 3),
180062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
180162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
180262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
180362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 1),
180462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
180562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 2),
180662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
180762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 3),
180862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
180962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
181062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
181162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 1),
181262c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
181362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 2),
181462c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
181562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 3),
181662c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
181762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
181862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
181962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 1),
182062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
182162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 2),
182262c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
182362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 3),
182462c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
182562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
182662c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
182762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 1),
182862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
182962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 2),
183062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
183162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 3),
183262c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
183362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
183462c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
183562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 1),
183662c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
183762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 2),
183862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
183962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 3),
184062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
184162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
184262c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
184362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 1),
184462c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
184562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 2),
184662c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
184762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 3),
184862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
184962c7989bSDaniel Borkmann 		},
185062c7989bSDaniel Borkmann 		.result = ACCEPT,
185162c7989bSDaniel Borkmann 	},
185262c7989bSDaniel Borkmann 	{
185331fd8581SYonghong Song 		"__sk_buff->hash, offset 0, byte store not permitted",
185462c7989bSDaniel Borkmann 		.insns = {
185562c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
185662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
185731fd8581SYonghong Song 				    offsetof(struct __sk_buff, hash)),
185862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
185962c7989bSDaniel Borkmann 		},
186062c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
186162c7989bSDaniel Borkmann 		.result = REJECT,
186262c7989bSDaniel Borkmann 	},
186362c7989bSDaniel Borkmann 	{
186431fd8581SYonghong Song 		"__sk_buff->tc_index, offset 3, byte store not permitted",
186562c7989bSDaniel Borkmann 		.insns = {
186662c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
186762c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
186831fd8581SYonghong Song 				    offsetof(struct __sk_buff, tc_index) + 3),
186962c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
187062c7989bSDaniel Borkmann 		},
187162c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
187262c7989bSDaniel Borkmann 		.result = REJECT,
187362c7989bSDaniel Borkmann 	},
187462c7989bSDaniel Borkmann 	{
187518f3d6beSYonghong Song 		"check skb->hash byte load permitted",
187618f3d6beSYonghong Song 		.insns = {
187718f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
18782c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
187918f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
188018f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash)),
188118f3d6beSYonghong Song #else
188218f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
188318f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 3),
188418f3d6beSYonghong Song #endif
188518f3d6beSYonghong Song 			BPF_EXIT_INSN(),
188618f3d6beSYonghong Song 		},
188718f3d6beSYonghong Song 		.result = ACCEPT,
188818f3d6beSYonghong Song 	},
188918f3d6beSYonghong Song 	{
189018f3d6beSYonghong Song 		"check skb->hash byte load not permitted 1",
189118f3d6beSYonghong Song 		.insns = {
189218f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
189318f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
189418f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 1),
189518f3d6beSYonghong Song 			BPF_EXIT_INSN(),
189618f3d6beSYonghong Song 		},
189718f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
189818f3d6beSYonghong Song 		.result = REJECT,
189918f3d6beSYonghong Song 	},
190018f3d6beSYonghong Song 	{
190118f3d6beSYonghong Song 		"check skb->hash byte load not permitted 2",
190218f3d6beSYonghong Song 		.insns = {
190318f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
190418f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
190518f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 2),
190618f3d6beSYonghong Song 			BPF_EXIT_INSN(),
190718f3d6beSYonghong Song 		},
190818f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
190918f3d6beSYonghong Song 		.result = REJECT,
191018f3d6beSYonghong Song 	},
191118f3d6beSYonghong Song 	{
191218f3d6beSYonghong Song 		"check skb->hash byte load not permitted 3",
191318f3d6beSYonghong Song 		.insns = {
191418f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
19152c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
191618f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
191718f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 3),
191818f3d6beSYonghong Song #else
191918f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
192018f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash)),
192118f3d6beSYonghong Song #endif
192218f3d6beSYonghong Song 			BPF_EXIT_INSN(),
192318f3d6beSYonghong Song 		},
192418f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
192518f3d6beSYonghong Song 		.result = REJECT,
192618f3d6beSYonghong Song 	},
192718f3d6beSYonghong Song 	{
192862c7989bSDaniel Borkmann 		"check cb access: byte, wrong type",
192962c7989bSDaniel Borkmann 		.insns = {
193062c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
193162c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
19325aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
19335aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
19345aa5bd14SDaniel Borkmann 		},
19355aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
19365aa5bd14SDaniel Borkmann 		.result = REJECT,
193762c7989bSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
193862c7989bSDaniel Borkmann 	},
193962c7989bSDaniel Borkmann 	{
194062c7989bSDaniel Borkmann 		"check cb access: half",
194162c7989bSDaniel Borkmann 		.insns = {
194262c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
194362c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
194462c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
194562c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
194662c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 2),
194762c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
194862c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
194962c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
195062c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 2),
195162c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
195262c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
195362c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
195462c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 2),
195562c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
195662c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
195762c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
195862c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 2),
195962c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
196062c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
196162c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
196262c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 2),
196362c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
196462c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
196562c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
196662c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 2),
196762c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
196862c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
196962c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
197062c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1]) + 2),
197162c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
197262c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
197362c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
197462c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2]) + 2),
197562c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
197662c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
197762c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
197862c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3]) + 2),
197962c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
198062c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
198162c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
198262c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 2),
198362c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
198462c7989bSDaniel Borkmann 		},
198562c7989bSDaniel Borkmann 		.result = ACCEPT,
198662c7989bSDaniel Borkmann 	},
198762c7989bSDaniel Borkmann 	{
198862c7989bSDaniel Borkmann 		"check cb access: half, unaligned",
198962c7989bSDaniel Borkmann 		.insns = {
199062c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
199162c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
199262c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 1),
199362c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
199462c7989bSDaniel Borkmann 		},
1995f65b1849SEdward Cree 		.errstr = "misaligned context access",
199662c7989bSDaniel Borkmann 		.result = REJECT,
1997f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
199862c7989bSDaniel Borkmann 	},
199962c7989bSDaniel Borkmann 	{
200031fd8581SYonghong Song 		"check __sk_buff->hash, offset 0, half store not permitted",
200162c7989bSDaniel Borkmann 		.insns = {
200262c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
200362c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
200431fd8581SYonghong Song 				    offsetof(struct __sk_buff, hash)),
200562c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
200662c7989bSDaniel Borkmann 		},
200762c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
200862c7989bSDaniel Borkmann 		.result = REJECT,
200962c7989bSDaniel Borkmann 	},
201062c7989bSDaniel Borkmann 	{
201131fd8581SYonghong Song 		"check __sk_buff->tc_index, offset 2, half store not permitted",
201262c7989bSDaniel Borkmann 		.insns = {
201362c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
201462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
201531fd8581SYonghong Song 				    offsetof(struct __sk_buff, tc_index) + 2),
201662c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
201762c7989bSDaniel Borkmann 		},
201862c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
201962c7989bSDaniel Borkmann 		.result = REJECT,
202062c7989bSDaniel Borkmann 	},
202162c7989bSDaniel Borkmann 	{
202218f3d6beSYonghong Song 		"check skb->hash half load permitted",
202318f3d6beSYonghong Song 		.insns = {
202418f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
20252c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
202618f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
202718f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash)),
202818f3d6beSYonghong Song #else
202918f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
203018f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 2),
203118f3d6beSYonghong Song #endif
203218f3d6beSYonghong Song 			BPF_EXIT_INSN(),
203318f3d6beSYonghong Song 		},
203418f3d6beSYonghong Song 		.result = ACCEPT,
203518f3d6beSYonghong Song 	},
203618f3d6beSYonghong Song 	{
203718f3d6beSYonghong Song 		"check skb->hash half load not permitted",
203818f3d6beSYonghong Song 		.insns = {
203918f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
20402c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
204118f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
204218f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash) + 2),
204318f3d6beSYonghong Song #else
204418f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
204518f3d6beSYonghong Song 				    offsetof(struct __sk_buff, hash)),
204618f3d6beSYonghong Song #endif
204718f3d6beSYonghong Song 			BPF_EXIT_INSN(),
204818f3d6beSYonghong Song 		},
204918f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
205018f3d6beSYonghong Song 		.result = REJECT,
205118f3d6beSYonghong Song 	},
205218f3d6beSYonghong Song 	{
205362c7989bSDaniel Borkmann 		"check cb access: half, wrong type",
205462c7989bSDaniel Borkmann 		.insns = {
205562c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
205662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
205762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
205862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
205962c7989bSDaniel Borkmann 		},
206062c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
206162c7989bSDaniel Borkmann 		.result = REJECT,
206262c7989bSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
206362c7989bSDaniel Borkmann 	},
206462c7989bSDaniel Borkmann 	{
206562c7989bSDaniel Borkmann 		"check cb access: word",
206662c7989bSDaniel Borkmann 		.insns = {
206762c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
206862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
206962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
207062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
207162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
207262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
207362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
207462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
207562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
207662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
207762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
207862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
207962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
208062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
208162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
208262c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
208362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
208462c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
208562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
208662c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
208762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
208862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
208962c7989bSDaniel Borkmann 		},
209062c7989bSDaniel Borkmann 		.result = ACCEPT,
209162c7989bSDaniel Borkmann 	},
209262c7989bSDaniel Borkmann 	{
209362c7989bSDaniel Borkmann 		"check cb access: word, unaligned 1",
209462c7989bSDaniel Borkmann 		.insns = {
209562c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
209662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
209762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 2),
209862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
209962c7989bSDaniel Borkmann 		},
2100f65b1849SEdward Cree 		.errstr = "misaligned context access",
210162c7989bSDaniel Borkmann 		.result = REJECT,
2102f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
210362c7989bSDaniel Borkmann 	},
210462c7989bSDaniel Borkmann 	{
210562c7989bSDaniel Borkmann 		"check cb access: word, unaligned 2",
210662c7989bSDaniel Borkmann 		.insns = {
210762c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
210862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
210962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 1),
211062c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
211162c7989bSDaniel Borkmann 		},
2112f65b1849SEdward Cree 		.errstr = "misaligned context access",
211362c7989bSDaniel Borkmann 		.result = REJECT,
2114f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
211562c7989bSDaniel Borkmann 	},
211662c7989bSDaniel Borkmann 	{
211762c7989bSDaniel Borkmann 		"check cb access: word, unaligned 3",
211862c7989bSDaniel Borkmann 		.insns = {
211962c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
212062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
212162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 2),
212262c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
212362c7989bSDaniel Borkmann 		},
2124f65b1849SEdward Cree 		.errstr = "misaligned context access",
212562c7989bSDaniel Borkmann 		.result = REJECT,
2126f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
212762c7989bSDaniel Borkmann 	},
212862c7989bSDaniel Borkmann 	{
212962c7989bSDaniel Borkmann 		"check cb access: word, unaligned 4",
213062c7989bSDaniel Borkmann 		.insns = {
213162c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
213262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
213362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4]) + 3),
213462c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
213562c7989bSDaniel Borkmann 		},
2136f65b1849SEdward Cree 		.errstr = "misaligned context access",
213762c7989bSDaniel Borkmann 		.result = REJECT,
2138f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
213962c7989bSDaniel Borkmann 	},
214062c7989bSDaniel Borkmann 	{
214162c7989bSDaniel Borkmann 		"check cb access: double",
214262c7989bSDaniel Borkmann 		.insns = {
214362c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
214462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
214562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
214662c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
214762c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
214862c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
214962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
215062c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
215162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
215262c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
215362c7989bSDaniel Borkmann 		},
215462c7989bSDaniel Borkmann 		.result = ACCEPT,
215562c7989bSDaniel Borkmann 	},
215662c7989bSDaniel Borkmann 	{
215762c7989bSDaniel Borkmann 		"check cb access: double, unaligned 1",
215862c7989bSDaniel Borkmann 		.insns = {
215962c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
216062c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
216162c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[1])),
216262c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
216362c7989bSDaniel Borkmann 		},
2164f65b1849SEdward Cree 		.errstr = "misaligned context access",
216562c7989bSDaniel Borkmann 		.result = REJECT,
2166f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
216762c7989bSDaniel Borkmann 	},
216862c7989bSDaniel Borkmann 	{
216962c7989bSDaniel Borkmann 		"check cb access: double, unaligned 2",
217062c7989bSDaniel Borkmann 		.insns = {
217162c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
217262c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
217362c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
217462c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
217562c7989bSDaniel Borkmann 		},
2176f65b1849SEdward Cree 		.errstr = "misaligned context access",
217762c7989bSDaniel Borkmann 		.result = REJECT,
2178f65b1849SEdward Cree 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
217962c7989bSDaniel Borkmann 	},
218062c7989bSDaniel Borkmann 	{
218162c7989bSDaniel Borkmann 		"check cb access: double, oob 1",
218262c7989bSDaniel Borkmann 		.insns = {
218362c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
218462c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
218562c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
218662c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
218762c7989bSDaniel Borkmann 		},
218862c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
218962c7989bSDaniel Borkmann 		.result = REJECT,
219062c7989bSDaniel Borkmann 	},
219162c7989bSDaniel Borkmann 	{
219262c7989bSDaniel Borkmann 		"check cb access: double, oob 2",
219362c7989bSDaniel Borkmann 		.insns = {
219462c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
219562c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
219662c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
219762c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
219862c7989bSDaniel Borkmann 		},
219962c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
220062c7989bSDaniel Borkmann 		.result = REJECT,
220162c7989bSDaniel Borkmann 	},
220262c7989bSDaniel Borkmann 	{
220331fd8581SYonghong Song 		"check __sk_buff->ifindex dw store not permitted",
220462c7989bSDaniel Borkmann 		.insns = {
220562c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
220631fd8581SYonghong Song 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
220731fd8581SYonghong Song 				    offsetof(struct __sk_buff, ifindex)),
220862c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
220962c7989bSDaniel Borkmann 		},
221062c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
221162c7989bSDaniel Borkmann 		.result = REJECT,
221262c7989bSDaniel Borkmann 	},
221362c7989bSDaniel Borkmann 	{
221431fd8581SYonghong Song 		"check __sk_buff->ifindex dw load not permitted",
221562c7989bSDaniel Borkmann 		.insns = {
221662c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
221762c7989bSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
221831fd8581SYonghong Song 				    offsetof(struct __sk_buff, ifindex)),
221962c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
222062c7989bSDaniel Borkmann 		},
222162c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
222262c7989bSDaniel Borkmann 		.result = REJECT,
222362c7989bSDaniel Borkmann 	},
222462c7989bSDaniel Borkmann 	{
222562c7989bSDaniel Borkmann 		"check cb access: double, wrong type",
222662c7989bSDaniel Borkmann 		.insns = {
222762c7989bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
222862c7989bSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
222962c7989bSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
223062c7989bSDaniel Borkmann 			BPF_EXIT_INSN(),
223162c7989bSDaniel Borkmann 		},
223262c7989bSDaniel Borkmann 		.errstr = "invalid bpf_context access",
223362c7989bSDaniel Borkmann 		.result = REJECT,
223462c7989bSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
22355aa5bd14SDaniel Borkmann 	},
22365aa5bd14SDaniel Borkmann 	{
22375aa5bd14SDaniel Borkmann 		"check out of range skb->cb access",
22385aa5bd14SDaniel Borkmann 		.insns = {
22395aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22405aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0]) + 256),
22415aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
22425aa5bd14SDaniel Borkmann 		},
22435aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
22445aa5bd14SDaniel Borkmann 		.errstr_unpriv = "",
22455aa5bd14SDaniel Borkmann 		.result = REJECT,
22465aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_ACT,
22475aa5bd14SDaniel Borkmann 	},
22485aa5bd14SDaniel Borkmann 	{
22495aa5bd14SDaniel Borkmann 		"write skb fields from socket prog",
22505aa5bd14SDaniel Borkmann 		.insns = {
22515aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22525aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[4])),
22535aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
22545aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22555aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
22565aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22575aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, tc_index)),
22585aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
22595aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
22605aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
22615aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
22625aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[2])),
22635aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
22645aa5bd14SDaniel Borkmann 		},
22655aa5bd14SDaniel Borkmann 		.result = ACCEPT,
22665aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 leaks addr",
22675aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
22685aa5bd14SDaniel Borkmann 	},
22695aa5bd14SDaniel Borkmann 	{
22705aa5bd14SDaniel Borkmann 		"write skb fields from tc_cls_act prog",
22715aa5bd14SDaniel Borkmann 		.insns = {
22725aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22735aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
22745aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
22755aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
22765aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
22775aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, tc_index)),
22785aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
22795aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, tc_index)),
22805aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
22815aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, cb[3])),
22825aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
22835aa5bd14SDaniel Borkmann 		},
22845aa5bd14SDaniel Borkmann 		.errstr_unpriv = "",
22855aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
22865aa5bd14SDaniel Borkmann 		.result = ACCEPT,
22875aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
22885aa5bd14SDaniel Borkmann 	},
22895aa5bd14SDaniel Borkmann 	{
22905aa5bd14SDaniel Borkmann 		"PTR_TO_STACK store/load",
22915aa5bd14SDaniel Borkmann 		.insns = {
22925aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
22935aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
22945aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
22955aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
22965aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
22975aa5bd14SDaniel Borkmann 		},
22985aa5bd14SDaniel Borkmann 		.result = ACCEPT,
2299111e6b45SAlexei Starovoitov 		.retval = 0xfaceb00c,
23005aa5bd14SDaniel Borkmann 	},
23015aa5bd14SDaniel Borkmann 	{
23025aa5bd14SDaniel Borkmann 		"PTR_TO_STACK store/load - bad alignment on off",
23035aa5bd14SDaniel Borkmann 		.insns = {
23045aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
23055aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
23065aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
23075aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
23085aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23095aa5bd14SDaniel Borkmann 		},
23105aa5bd14SDaniel Borkmann 		.result = REJECT,
2311f65b1849SEdward Cree 		.errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
23125aa5bd14SDaniel Borkmann 	},
23135aa5bd14SDaniel Borkmann 	{
23145aa5bd14SDaniel Borkmann 		"PTR_TO_STACK store/load - bad alignment on reg",
23155aa5bd14SDaniel Borkmann 		.insns = {
23165aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
23175aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
23185aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
23195aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
23205aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23215aa5bd14SDaniel Borkmann 		},
23225aa5bd14SDaniel Borkmann 		.result = REJECT,
2323f65b1849SEdward Cree 		.errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
23245aa5bd14SDaniel Borkmann 	},
23255aa5bd14SDaniel Borkmann 	{
23265aa5bd14SDaniel Borkmann 		"PTR_TO_STACK store/load - out of bounds low",
23275aa5bd14SDaniel Borkmann 		.insns = {
23285aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
23295aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
23305aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
23315aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
23325aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23335aa5bd14SDaniel Borkmann 		},
23345aa5bd14SDaniel Borkmann 		.result = REJECT,
23355aa5bd14SDaniel Borkmann 		.errstr = "invalid stack off=-79992 size=8",
23365aa5bd14SDaniel Borkmann 	},
23375aa5bd14SDaniel Borkmann 	{
23385aa5bd14SDaniel Borkmann 		"PTR_TO_STACK store/load - out of bounds high",
23395aa5bd14SDaniel Borkmann 		.insns = {
23405aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
23415aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
23425aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
23435aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
23445aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23455aa5bd14SDaniel Borkmann 		},
23465aa5bd14SDaniel Borkmann 		.result = REJECT,
23475aa5bd14SDaniel Borkmann 		.errstr = "invalid stack off=0 size=8",
23485aa5bd14SDaniel Borkmann 	},
23495aa5bd14SDaniel Borkmann 	{
23505aa5bd14SDaniel Borkmann 		"unpriv: return pointer",
23515aa5bd14SDaniel Borkmann 		.insns = {
23525aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
23535aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23545aa5bd14SDaniel Borkmann 		},
23555aa5bd14SDaniel Borkmann 		.result = ACCEPT,
23565aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
23575aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
2358111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
23595aa5bd14SDaniel Borkmann 	},
23605aa5bd14SDaniel Borkmann 	{
23615aa5bd14SDaniel Borkmann 		"unpriv: add const to pointer",
23625aa5bd14SDaniel Borkmann 		.insns = {
23635aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
23645aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
23655aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23665aa5bd14SDaniel Borkmann 		},
23675aa5bd14SDaniel Borkmann 		.result = ACCEPT,
23685aa5bd14SDaniel Borkmann 	},
23695aa5bd14SDaniel Borkmann 	{
23705aa5bd14SDaniel Borkmann 		"unpriv: add pointer to pointer",
23715aa5bd14SDaniel Borkmann 		.insns = {
23725aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
23735aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
23745aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23755aa5bd14SDaniel Borkmann 		},
237682abbf8dSAlexei Starovoitov 		.result = REJECT,
237782abbf8dSAlexei Starovoitov 		.errstr = "R1 pointer += pointer",
23785aa5bd14SDaniel Borkmann 	},
23795aa5bd14SDaniel Borkmann 	{
23805aa5bd14SDaniel Borkmann 		"unpriv: neg pointer",
23815aa5bd14SDaniel Borkmann 		.insns = {
23825aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0),
23835aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
23845aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23855aa5bd14SDaniel Borkmann 		},
23865aa5bd14SDaniel Borkmann 		.result = ACCEPT,
23875aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
23885aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer arithmetic",
23895aa5bd14SDaniel Borkmann 	},
23905aa5bd14SDaniel Borkmann 	{
23915aa5bd14SDaniel Borkmann 		"unpriv: cmp pointer with const",
23925aa5bd14SDaniel Borkmann 		.insns = {
23935aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
23945aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
23955aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
23965aa5bd14SDaniel Borkmann 		},
23975aa5bd14SDaniel Borkmann 		.result = ACCEPT,
23985aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
23995aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
24005aa5bd14SDaniel Borkmann 	},
24015aa5bd14SDaniel Borkmann 	{
24025aa5bd14SDaniel Borkmann 		"unpriv: cmp pointer with pointer",
24035aa5bd14SDaniel Borkmann 		.insns = {
24045aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0),
24055aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24065aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24075aa5bd14SDaniel Borkmann 		},
24085aa5bd14SDaniel Borkmann 		.result = ACCEPT,
24095aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
24105aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R10 pointer comparison",
24115aa5bd14SDaniel Borkmann 	},
24125aa5bd14SDaniel Borkmann 	{
24135aa5bd14SDaniel Borkmann 		"unpriv: check that printk is disallowed",
24145aa5bd14SDaniel Borkmann 		.insns = {
24155aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
24165aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
24175aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
24185aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 8),
24195aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
24205aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
24215aa5bd14SDaniel Borkmann 				     BPF_FUNC_trace_printk),
24225aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24235aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24245aa5bd14SDaniel Borkmann 		},
24250eb6984fSDaniel Borkmann 		.errstr_unpriv = "unknown func bpf_trace_printk#6",
24265aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
24275aa5bd14SDaniel Borkmann 		.result = ACCEPT,
24285aa5bd14SDaniel Borkmann 	},
24295aa5bd14SDaniel Borkmann 	{
24305aa5bd14SDaniel Borkmann 		"unpriv: pass pointer to helper function",
24315aa5bd14SDaniel Borkmann 		.insns = {
24325aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
24335aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
24345aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
24355aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
24365aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
24375aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
24385aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
24395aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_update_elem),
24405aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24415aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24425aa5bd14SDaniel Borkmann 		},
24435aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
24445aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R4 leaks addr",
24455aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
24465aa5bd14SDaniel Borkmann 		.result = ACCEPT,
24475aa5bd14SDaniel Borkmann 	},
24485aa5bd14SDaniel Borkmann 	{
24495aa5bd14SDaniel Borkmann 		"unpriv: indirectly pass pointer on stack to helper function",
24505aa5bd14SDaniel Borkmann 		.insns = {
24515aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
24525aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
24535aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
24545aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
24555aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
24565aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
24575aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24585aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24595aa5bd14SDaniel Borkmann 		},
24605aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
24615aa5bd14SDaniel Borkmann 		.errstr = "invalid indirect read from stack off -8+0 size 8",
24625aa5bd14SDaniel Borkmann 		.result = REJECT,
24635aa5bd14SDaniel Borkmann 	},
24645aa5bd14SDaniel Borkmann 	{
24655aa5bd14SDaniel Borkmann 		"unpriv: mangle pointer on stack 1",
24665aa5bd14SDaniel Borkmann 		.insns = {
24675aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
24685aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
24695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24705aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24715aa5bd14SDaniel Borkmann 		},
24725aa5bd14SDaniel Borkmann 		.errstr_unpriv = "attempt to corrupt spilled",
24735aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
24745aa5bd14SDaniel Borkmann 		.result = ACCEPT,
24755aa5bd14SDaniel Borkmann 	},
24765aa5bd14SDaniel Borkmann 	{
24775aa5bd14SDaniel Borkmann 		"unpriv: mangle pointer on stack 2",
24785aa5bd14SDaniel Borkmann 		.insns = {
24795aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
24805aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0),
24815aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24825aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24835aa5bd14SDaniel Borkmann 		},
24845aa5bd14SDaniel Borkmann 		.errstr_unpriv = "attempt to corrupt spilled",
24855aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
24865aa5bd14SDaniel Borkmann 		.result = ACCEPT,
24875aa5bd14SDaniel Borkmann 	},
24885aa5bd14SDaniel Borkmann 	{
24895aa5bd14SDaniel Borkmann 		"unpriv: read pointer from stack in small chunks",
24905aa5bd14SDaniel Borkmann 		.insns = {
24915aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8),
24925aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8),
24935aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
24945aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
24955aa5bd14SDaniel Borkmann 		},
24965aa5bd14SDaniel Borkmann 		.errstr = "invalid size",
24975aa5bd14SDaniel Borkmann 		.result = REJECT,
24985aa5bd14SDaniel Borkmann 	},
24995aa5bd14SDaniel Borkmann 	{
25005aa5bd14SDaniel Borkmann 		"unpriv: write pointer into ctx",
25015aa5bd14SDaniel Borkmann 		.insns = {
25025aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
25035aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
25045aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25055aa5bd14SDaniel Borkmann 		},
25065aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 leaks addr",
25075aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
25085aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access",
25095aa5bd14SDaniel Borkmann 		.result = REJECT,
25105aa5bd14SDaniel Borkmann 	},
25115aa5bd14SDaniel Borkmann 	{
25125aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of ctx",
25135aa5bd14SDaniel Borkmann 		.insns = {
25145aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25155aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25165aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
25175aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
25185aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
25195aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25205aa5bd14SDaniel Borkmann 		},
25215aa5bd14SDaniel Borkmann 		.result = ACCEPT,
25225aa5bd14SDaniel Borkmann 	},
25235aa5bd14SDaniel Borkmann 	{
25245aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of ctx 2",
25255aa5bd14SDaniel Borkmann 		.insns = {
25265aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25275aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25285aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
25295aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
25305aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
25315aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_hash_recalc),
2532111e6b45SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
25335aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25345aa5bd14SDaniel Borkmann 		},
25355aa5bd14SDaniel Borkmann 		.result = ACCEPT,
25365aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
25375aa5bd14SDaniel Borkmann 	},
25385aa5bd14SDaniel Borkmann 	{
25395aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of ctx 3",
25405aa5bd14SDaniel Borkmann 		.insns = {
25415aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25425aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25435aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
25445aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
25455aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
25465aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
25475aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_hash_recalc),
25485aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25495aa5bd14SDaniel Borkmann 		},
25505aa5bd14SDaniel Borkmann 		.result = REJECT,
25515aa5bd14SDaniel Borkmann 		.errstr = "R1 type=fp expected=ctx",
25525aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
25535aa5bd14SDaniel Borkmann 	},
25545aa5bd14SDaniel Borkmann 	{
25555aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of ctx 4",
25565aa5bd14SDaniel Borkmann 		.insns = {
25575aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25585aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25595aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
25605aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
25615aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10,
25625aa5bd14SDaniel Borkmann 				     BPF_REG_0, -8, 0),
25635aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
25645aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
25655aa5bd14SDaniel Borkmann 				     BPF_FUNC_get_hash_recalc),
25665aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25675aa5bd14SDaniel Borkmann 		},
25685aa5bd14SDaniel Borkmann 		.result = REJECT,
25695aa5bd14SDaniel Borkmann 		.errstr = "R1 type=inv expected=ctx",
25705aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
25715aa5bd14SDaniel Borkmann 	},
25725aa5bd14SDaniel Borkmann 	{
25735aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of different pointers stx",
25745aa5bd14SDaniel Borkmann 		.insns = {
25755aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 42),
25765aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25775aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25785aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
25795aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
25805aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
25815aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
25825aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
25835aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
25845aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
25855aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3,
25865aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
25875aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
25885aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
25895aa5bd14SDaniel Borkmann 		},
25905aa5bd14SDaniel Borkmann 		.result = REJECT,
25915aa5bd14SDaniel Borkmann 		.errstr = "same insn cannot be used with different pointers",
25925aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
25935aa5bd14SDaniel Borkmann 	},
25945aa5bd14SDaniel Borkmann 	{
25955aa5bd14SDaniel Borkmann 		"unpriv: spill/fill of different pointers ldx",
25965aa5bd14SDaniel Borkmann 		.insns = {
25975aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
25985aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
25995aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
26005aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
26015aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
26025aa5bd14SDaniel Borkmann 				      -(__s32)offsetof(struct bpf_perf_event_data,
26035aa5bd14SDaniel Borkmann 						       sample_period) - 8),
26045aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0),
26055aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
26065aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
26075aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
26085aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1,
26095aa5bd14SDaniel Borkmann 				    offsetof(struct bpf_perf_event_data,
26105aa5bd14SDaniel Borkmann 					     sample_period)),
26115aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26125aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26135aa5bd14SDaniel Borkmann 		},
26145aa5bd14SDaniel Borkmann 		.result = REJECT,
26155aa5bd14SDaniel Borkmann 		.errstr = "same insn cannot be used with different pointers",
26165aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
26175aa5bd14SDaniel Borkmann 	},
26185aa5bd14SDaniel Borkmann 	{
26195aa5bd14SDaniel Borkmann 		"unpriv: write pointer into map elem value",
26205aa5bd14SDaniel Borkmann 		.insns = {
26215aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
26225aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
26235aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
26245aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
26255aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
26265aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
26275aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
26285aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
26295aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26305aa5bd14SDaniel Borkmann 		},
26315aa5bd14SDaniel Borkmann 		.fixup_map1 = { 3 },
26325aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
26335aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
26345aa5bd14SDaniel Borkmann 		.result = ACCEPT,
26355aa5bd14SDaniel Borkmann 	},
26365aa5bd14SDaniel Borkmann 	{
26375aa5bd14SDaniel Borkmann 		"unpriv: partial copy of pointer",
26385aa5bd14SDaniel Borkmann 		.insns = {
26395aa5bd14SDaniel Borkmann 			BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
26405aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26415aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26425aa5bd14SDaniel Borkmann 		},
26435aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R10 partial copy",
26445aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
26455aa5bd14SDaniel Borkmann 		.result = ACCEPT,
26465aa5bd14SDaniel Borkmann 	},
26475aa5bd14SDaniel Borkmann 	{
26485aa5bd14SDaniel Borkmann 		"unpriv: pass pointer to tail_call",
26495aa5bd14SDaniel Borkmann 		.insns = {
26505aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_1),
26515aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
26525aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
26535aa5bd14SDaniel Borkmann 				     BPF_FUNC_tail_call),
26545aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26555aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26565aa5bd14SDaniel Borkmann 		},
26575aa5bd14SDaniel Borkmann 		.fixup_prog = { 1 },
26585aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R3 leaks addr into helper",
26595aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
26605aa5bd14SDaniel Borkmann 		.result = ACCEPT,
26615aa5bd14SDaniel Borkmann 	},
26625aa5bd14SDaniel Borkmann 	{
26635aa5bd14SDaniel Borkmann 		"unpriv: cmp map pointer with zero",
26645aa5bd14SDaniel Borkmann 		.insns = {
26655aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0),
26665aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
26675aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
26685aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26695aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26705aa5bd14SDaniel Borkmann 		},
26715aa5bd14SDaniel Borkmann 		.fixup_map1 = { 1 },
26725aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R1 pointer comparison",
26735aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
26745aa5bd14SDaniel Borkmann 		.result = ACCEPT,
26755aa5bd14SDaniel Borkmann 	},
26765aa5bd14SDaniel Borkmann 	{
26775aa5bd14SDaniel Borkmann 		"unpriv: write into frame pointer",
26785aa5bd14SDaniel Borkmann 		.insns = {
26795aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_10, BPF_REG_1),
26805aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26815aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26825aa5bd14SDaniel Borkmann 		},
26835aa5bd14SDaniel Borkmann 		.errstr = "frame pointer is read only",
26845aa5bd14SDaniel Borkmann 		.result = REJECT,
26855aa5bd14SDaniel Borkmann 	},
26865aa5bd14SDaniel Borkmann 	{
26875aa5bd14SDaniel Borkmann 		"unpriv: spill/fill frame pointer",
26885aa5bd14SDaniel Borkmann 		.insns = {
26895aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
26905aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
26915aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0),
26925aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0),
26935aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
26945aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
26955aa5bd14SDaniel Borkmann 		},
26965aa5bd14SDaniel Borkmann 		.errstr = "frame pointer is read only",
26975aa5bd14SDaniel Borkmann 		.result = REJECT,
26985aa5bd14SDaniel Borkmann 	},
26995aa5bd14SDaniel Borkmann 	{
27005aa5bd14SDaniel Borkmann 		"unpriv: cmp of frame pointer",
27015aa5bd14SDaniel Borkmann 		.insns = {
27025aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0),
27035aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
27045aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
27055aa5bd14SDaniel Borkmann 		},
27065aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R10 pointer comparison",
27075aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
27085aa5bd14SDaniel Borkmann 		.result = ACCEPT,
27095aa5bd14SDaniel Borkmann 	},
27105aa5bd14SDaniel Borkmann 	{
2711728a853aSDaniel Borkmann 		"unpriv: adding of fp",
2712728a853aSDaniel Borkmann 		.insns = {
2713728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
2714728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0),
2715728a853aSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10),
2716728a853aSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
2717728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
2718728a853aSDaniel Borkmann 		},
2719f65b1849SEdward Cree 		.result = ACCEPT,
2720728a853aSDaniel Borkmann 	},
2721728a853aSDaniel Borkmann 	{
27225aa5bd14SDaniel Borkmann 		"unpriv: cmp of stack pointer",
27235aa5bd14SDaniel Borkmann 		.insns = {
27245aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
27255aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
27265aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0),
27275aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
27285aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
27295aa5bd14SDaniel Borkmann 		},
27305aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R2 pointer comparison",
27315aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
27325aa5bd14SDaniel Borkmann 		.result = ACCEPT,
27335aa5bd14SDaniel Borkmann 	},
27345aa5bd14SDaniel Borkmann 	{
2735b33eb735SDaniel Borkmann 		"runtime/jit: tail_call within bounds, prog once",
2736b33eb735SDaniel Borkmann 		.insns = {
2737b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
2738b33eb735SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
2739b33eb735SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2740b33eb735SDaniel Borkmann 				     BPF_FUNC_tail_call),
2741b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
2742b33eb735SDaniel Borkmann 			BPF_EXIT_INSN(),
2743b33eb735SDaniel Borkmann 		},
2744b33eb735SDaniel Borkmann 		.fixup_prog = { 1 },
2745b33eb735SDaniel Borkmann 		.result = ACCEPT,
2746b33eb735SDaniel Borkmann 		.retval = 42,
2747b33eb735SDaniel Borkmann 	},
2748b33eb735SDaniel Borkmann 	{
2749b33eb735SDaniel Borkmann 		"runtime/jit: tail_call within bounds, prog loop",
2750b33eb735SDaniel Borkmann 		.insns = {
2751b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 1),
2752b33eb735SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
2753b33eb735SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2754b33eb735SDaniel Borkmann 				     BPF_FUNC_tail_call),
2755b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
2756b33eb735SDaniel Borkmann 			BPF_EXIT_INSN(),
2757b33eb735SDaniel Borkmann 		},
2758b33eb735SDaniel Borkmann 		.fixup_prog = { 1 },
2759b33eb735SDaniel Borkmann 		.result = ACCEPT,
2760b33eb735SDaniel Borkmann 		.retval = 41,
2761b33eb735SDaniel Borkmann 	},
2762b33eb735SDaniel Borkmann 	{
2763b33eb735SDaniel Borkmann 		"runtime/jit: tail_call within bounds, no prog",
2764b33eb735SDaniel Borkmann 		.insns = {
2765b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 2),
2766b33eb735SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
2767b33eb735SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2768b33eb735SDaniel Borkmann 				     BPF_FUNC_tail_call),
2769b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
2770b33eb735SDaniel Borkmann 			BPF_EXIT_INSN(),
2771b33eb735SDaniel Borkmann 		},
2772b33eb735SDaniel Borkmann 		.fixup_prog = { 1 },
2773b33eb735SDaniel Borkmann 		.result = ACCEPT,
2774b33eb735SDaniel Borkmann 		.retval = 1,
2775b33eb735SDaniel Borkmann 	},
2776b33eb735SDaniel Borkmann 	{
2777b33eb735SDaniel Borkmann 		"runtime/jit: tail_call out of bounds",
2778b33eb735SDaniel Borkmann 		.insns = {
2779b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 256),
2780b33eb735SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
2781b33eb735SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2782b33eb735SDaniel Borkmann 				     BPF_FUNC_tail_call),
2783b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
2784b33eb735SDaniel Borkmann 			BPF_EXIT_INSN(),
2785b33eb735SDaniel Borkmann 		},
2786b33eb735SDaniel Borkmann 		.fixup_prog = { 1 },
2787b33eb735SDaniel Borkmann 		.result = ACCEPT,
2788b33eb735SDaniel Borkmann 		.retval = 2,
2789b33eb735SDaniel Borkmann 	},
2790b33eb735SDaniel Borkmann 	{
279116338a9bSDaniel Borkmann 		"runtime/jit: pass negative index to tail_call",
279216338a9bSDaniel Borkmann 		.insns = {
279316338a9bSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, -1),
279416338a9bSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
279516338a9bSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
279616338a9bSDaniel Borkmann 				     BPF_FUNC_tail_call),
2797b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
279816338a9bSDaniel Borkmann 			BPF_EXIT_INSN(),
279916338a9bSDaniel Borkmann 		},
280016338a9bSDaniel Borkmann 		.fixup_prog = { 1 },
280116338a9bSDaniel Borkmann 		.result = ACCEPT,
2802b33eb735SDaniel Borkmann 		.retval = 2,
280316338a9bSDaniel Borkmann 	},
280416338a9bSDaniel Borkmann 	{
280516338a9bSDaniel Borkmann 		"runtime/jit: pass > 32bit index to tail_call",
280616338a9bSDaniel Borkmann 		.insns = {
280716338a9bSDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
280816338a9bSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
280916338a9bSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
281016338a9bSDaniel Borkmann 				     BPF_FUNC_tail_call),
2811b33eb735SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
281216338a9bSDaniel Borkmann 			BPF_EXIT_INSN(),
281316338a9bSDaniel Borkmann 		},
281416338a9bSDaniel Borkmann 		.fixup_prog = { 2 },
281516338a9bSDaniel Borkmann 		.result = ACCEPT,
2816b33eb735SDaniel Borkmann 		.retval = 42,
281716338a9bSDaniel Borkmann 	},
281816338a9bSDaniel Borkmann 	{
2819332270fdSYonghong Song 		"stack pointer arithmetic",
28205aa5bd14SDaniel Borkmann 		.insns = {
2821332270fdSYonghong Song 			BPF_MOV64_IMM(BPF_REG_1, 4),
2822332270fdSYonghong Song 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2823332270fdSYonghong Song 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2824332270fdSYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2825332270fdSYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
2826332270fdSYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2827332270fdSYonghong Song 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
2828332270fdSYonghong Song 			BPF_ST_MEM(0, BPF_REG_2, 4, 0),
2829332270fdSYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2830332270fdSYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
2831332270fdSYonghong Song 			BPF_ST_MEM(0, BPF_REG_2, 4, 0),
28325aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
28335aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
28345aa5bd14SDaniel Borkmann 		},
28355aa5bd14SDaniel Borkmann 		.result = ACCEPT,
28365aa5bd14SDaniel Borkmann 	},
28375aa5bd14SDaniel Borkmann 	{
28385aa5bd14SDaniel Borkmann 		"raw_stack: no skb_load_bytes",
28395aa5bd14SDaniel Borkmann 		.insns = {
28405aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
28415aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
28425aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
28435aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
28445aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
28455aa5bd14SDaniel Borkmann 			/* Call to skb_load_bytes() omitted. */
28465aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
28475aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
28485aa5bd14SDaniel Borkmann 		},
28495aa5bd14SDaniel Borkmann 		.result = REJECT,
28505aa5bd14SDaniel Borkmann 		.errstr = "invalid read from stack off -8+0 size 8",
28515aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
28525aa5bd14SDaniel Borkmann 	},
28535aa5bd14SDaniel Borkmann 	{
28545aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, negative len",
28555aa5bd14SDaniel Borkmann 		.insns = {
28565aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
28575aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
28585aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
28595aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
28605aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, -8),
28615aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
28625aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
28635aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
28645aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
28655aa5bd14SDaniel Borkmann 		},
28665aa5bd14SDaniel Borkmann 		.result = REJECT,
2867f65b1849SEdward Cree 		.errstr = "R4 min value is negative",
28685aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
28695aa5bd14SDaniel Borkmann 	},
28705aa5bd14SDaniel Borkmann 	{
28715aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, negative len 2",
28725aa5bd14SDaniel Borkmann 		.insns = {
28735aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
28745aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
28755aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
28765aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
28775aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, ~0),
28785aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
28795aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
28805aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
28815aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
28825aa5bd14SDaniel Borkmann 		},
28835aa5bd14SDaniel Borkmann 		.result = REJECT,
2884f65b1849SEdward Cree 		.errstr = "R4 min value is negative",
28855aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
28865aa5bd14SDaniel Borkmann 	},
28875aa5bd14SDaniel Borkmann 	{
28885aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, zero len",
28895aa5bd14SDaniel Borkmann 		.insns = {
28905aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
28915aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
28925aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
28935aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
28945aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
28955aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
28965aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
28975aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
28985aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
28995aa5bd14SDaniel Borkmann 		},
29005aa5bd14SDaniel Borkmann 		.result = REJECT,
29015aa5bd14SDaniel Borkmann 		.errstr = "invalid stack type R3",
29025aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29035aa5bd14SDaniel Borkmann 	},
29045aa5bd14SDaniel Borkmann 	{
29055aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, no init",
29065aa5bd14SDaniel Borkmann 		.insns = {
29075aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
29085aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
29095aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
29105aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
29115aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
29125aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
29135aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
29145aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
29155aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
29165aa5bd14SDaniel Borkmann 		},
29175aa5bd14SDaniel Borkmann 		.result = ACCEPT,
29185aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29195aa5bd14SDaniel Borkmann 	},
29205aa5bd14SDaniel Borkmann 	{
29215aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, init",
29225aa5bd14SDaniel Borkmann 		.insns = {
29235aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
29245aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
29255aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
29265aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe),
29275aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
29285aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
29295aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
29305aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
29315aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
29325aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
29335aa5bd14SDaniel Borkmann 		},
29345aa5bd14SDaniel Borkmann 		.result = ACCEPT,
29355aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29365aa5bd14SDaniel Borkmann 	},
29375aa5bd14SDaniel Borkmann 	{
29385aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, spilled regs around bounds",
29395aa5bd14SDaniel Borkmann 		.insns = {
29405aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
29415aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
29425aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
29435aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
29445aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
29455aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
29465aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
29475aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
29485aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
29495aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
29505aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
29515aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
29525aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
29535aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
29545aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, priority)),
29555aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
29565aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
29575aa5bd14SDaniel Borkmann 		},
29585aa5bd14SDaniel Borkmann 		.result = ACCEPT,
29595aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29605aa5bd14SDaniel Borkmann 	},
29615aa5bd14SDaniel Borkmann 	{
29625aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, spilled regs corruption",
29635aa5bd14SDaniel Borkmann 		.insns = {
29645aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
29655aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
29665aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
29675aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
29685aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
29695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
29705aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
29715aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
29725aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
29735aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
29745aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
29755aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
29765aa5bd14SDaniel Borkmann 		},
29775aa5bd14SDaniel Borkmann 		.result = REJECT,
29785aa5bd14SDaniel Borkmann 		.errstr = "R0 invalid mem access 'inv'",
29795aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
29805aa5bd14SDaniel Borkmann 	},
29815aa5bd14SDaniel Borkmann 	{
29825aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, spilled regs corruption 2",
29835aa5bd14SDaniel Borkmann 		.insns = {
29845aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
29855aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
29865aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
29875aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
29885aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
29895aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
29905aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
29915aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
29925aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
29935aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
29945aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
29955aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
29965aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
29975aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
29985aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
29995aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
30005aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, priority)),
30015aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
30025aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3,
30035aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, pkt_type)),
30045aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
30055aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
30065aa5bd14SDaniel Borkmann 		},
30075aa5bd14SDaniel Borkmann 		.result = REJECT,
30085aa5bd14SDaniel Borkmann 		.errstr = "R3 invalid mem access 'inv'",
30095aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30105aa5bd14SDaniel Borkmann 	},
30115aa5bd14SDaniel Borkmann 	{
30125aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, spilled regs + data",
30135aa5bd14SDaniel Borkmann 		.insns = {
30145aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
30155aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
30165aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16),
30175aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8),
30185aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  0),
30195aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1,  8),
30205aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
30215aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
30225aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
30235aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
30245aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8),
30255aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6,  8),
30265aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,  0),
30275aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
30285aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
30295aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2,
30305aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, priority)),
30315aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
30325aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
30335aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
30345aa5bd14SDaniel Borkmann 		},
30355aa5bd14SDaniel Borkmann 		.result = ACCEPT,
30365aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30375aa5bd14SDaniel Borkmann 	},
30385aa5bd14SDaniel Borkmann 	{
30395aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 1",
30405aa5bd14SDaniel Borkmann 		.insns = {
30415aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
30425aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
30435aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513),
30445aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
30455aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
30465aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
30475aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
30485aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
30495aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
30505aa5bd14SDaniel Borkmann 		},
30515aa5bd14SDaniel Borkmann 		.result = REJECT,
30525aa5bd14SDaniel Borkmann 		.errstr = "invalid stack type R3 off=-513 access_size=8",
30535aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30545aa5bd14SDaniel Borkmann 	},
30555aa5bd14SDaniel Borkmann 	{
30565aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 2",
30575aa5bd14SDaniel Borkmann 		.insns = {
30585aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
30595aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
30605aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
30615aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
30625aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 8),
30635aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
30645aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
30655aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
30665aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
30675aa5bd14SDaniel Borkmann 		},
30685aa5bd14SDaniel Borkmann 		.result = REJECT,
30695aa5bd14SDaniel Borkmann 		.errstr = "invalid stack type R3 off=-1 access_size=8",
30705aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30715aa5bd14SDaniel Borkmann 	},
30725aa5bd14SDaniel Borkmann 	{
30735aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 3",
30745aa5bd14SDaniel Borkmann 		.insns = {
30755aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
30765aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
30775aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff),
30785aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
30795aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
30805aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
30815aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
30825aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
30835aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
30845aa5bd14SDaniel Borkmann 		},
30855aa5bd14SDaniel Borkmann 		.result = REJECT,
3086f65b1849SEdward Cree 		.errstr = "R4 min value is negative",
30875aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
30885aa5bd14SDaniel Borkmann 	},
30895aa5bd14SDaniel Borkmann 	{
30905aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 4",
30915aa5bd14SDaniel Borkmann 		.insns = {
30925aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
30935aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
30945aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1),
30955aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
30965aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
30975aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
30985aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
30995aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
31005aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
31015aa5bd14SDaniel Borkmann 		},
31025aa5bd14SDaniel Borkmann 		.result = REJECT,
3103f65b1849SEdward Cree 		.errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
31045aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31055aa5bd14SDaniel Borkmann 	},
31065aa5bd14SDaniel Borkmann 	{
31075aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 5",
31085aa5bd14SDaniel Borkmann 		.insns = {
31095aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
31105aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
31115aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
31125aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
31135aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff),
31145aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
31155aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
31165aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
31175aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
31185aa5bd14SDaniel Borkmann 		},
31195aa5bd14SDaniel Borkmann 		.result = REJECT,
3120f65b1849SEdward Cree 		.errstr = "R4 unbounded memory access, use 'var &= const' or 'if (var < const)'",
31215aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31225aa5bd14SDaniel Borkmann 	},
31235aa5bd14SDaniel Borkmann 	{
31245aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, invalid access 6",
31255aa5bd14SDaniel Borkmann 		.insns = {
31265aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
31275aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
31285aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
31295aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
31305aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
31315aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
31325aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
31335aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
31345aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
31355aa5bd14SDaniel Borkmann 		},
31365aa5bd14SDaniel Borkmann 		.result = REJECT,
31375aa5bd14SDaniel Borkmann 		.errstr = "invalid stack type R3 off=-512 access_size=0",
31385aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31395aa5bd14SDaniel Borkmann 	},
31405aa5bd14SDaniel Borkmann 	{
31415aa5bd14SDaniel Borkmann 		"raw_stack: skb_load_bytes, large access",
31425aa5bd14SDaniel Borkmann 		.insns = {
31435aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
31445aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10),
31455aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512),
31465aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
31475aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 512),
31485aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
31495aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
31505aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
31515aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
31525aa5bd14SDaniel Borkmann 		},
31535aa5bd14SDaniel Borkmann 		.result = ACCEPT,
31545aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31555aa5bd14SDaniel Borkmann 	},
31565aa5bd14SDaniel Borkmann 	{
3157f37a8cb8SDaniel Borkmann 		"context stores via ST",
3158f37a8cb8SDaniel Borkmann 		.insns = {
3159f37a8cb8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
3160f37a8cb8SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
3161f37a8cb8SDaniel Borkmann 			BPF_EXIT_INSN(),
3162f37a8cb8SDaniel Borkmann 		},
3163f37a8cb8SDaniel Borkmann 		.errstr = "BPF_ST stores into R1 context is not allowed",
3164f37a8cb8SDaniel Borkmann 		.result = REJECT,
3165f37a8cb8SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3166f37a8cb8SDaniel Borkmann 	},
3167f37a8cb8SDaniel Borkmann 	{
3168f37a8cb8SDaniel Borkmann 		"context stores via XADD",
3169f37a8cb8SDaniel Borkmann 		.insns = {
3170f37a8cb8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
3171f37a8cb8SDaniel Borkmann 			BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1,
3172f37a8cb8SDaniel Borkmann 				     BPF_REG_0, offsetof(struct __sk_buff, mark), 0),
3173f37a8cb8SDaniel Borkmann 			BPF_EXIT_INSN(),
3174f37a8cb8SDaniel Borkmann 		},
3175f37a8cb8SDaniel Borkmann 		.errstr = "BPF_XADD stores into R1 context is not allowed",
3176f37a8cb8SDaniel Borkmann 		.result = REJECT,
3177f37a8cb8SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3178f37a8cb8SDaniel Borkmann 	},
3179f37a8cb8SDaniel Borkmann 	{
31805aa5bd14SDaniel Borkmann 		"direct packet access: test1",
31815aa5bd14SDaniel Borkmann 		.insns = {
31825aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
31835aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
31845aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
31855aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
31865aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
31875aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
31885aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
31895aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
31905aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
31915aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
31925aa5bd14SDaniel Borkmann 		},
31935aa5bd14SDaniel Borkmann 		.result = ACCEPT,
31945aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
31955aa5bd14SDaniel Borkmann 	},
31965aa5bd14SDaniel Borkmann 	{
31975aa5bd14SDaniel Borkmann 		"direct packet access: test2",
31985aa5bd14SDaniel Borkmann 		.insns = {
31995aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
32005aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
32015aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
32025aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
32035aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32045aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
32055aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
32065aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15),
32075aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7),
32085aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12),
32095aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14),
32105aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
32115aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32125aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4),
321382abbf8dSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
321482abbf8dSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
32151f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49),
32161f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49),
32175aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
32185aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
32195aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
32205aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
32215aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
32225aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
32235aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4),
32245aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
32255aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32265aa5bd14SDaniel Borkmann 		},
32275aa5bd14SDaniel Borkmann 		.result = ACCEPT,
32285aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
32295aa5bd14SDaniel Borkmann 	},
32305aa5bd14SDaniel Borkmann 	{
32315aa5bd14SDaniel Borkmann 		"direct packet access: test3",
32325aa5bd14SDaniel Borkmann 		.insns = {
32335aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
32345aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32355aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
32365aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32375aa5bd14SDaniel Borkmann 		},
32385aa5bd14SDaniel Borkmann 		.errstr = "invalid bpf_context access off=76",
32395aa5bd14SDaniel Borkmann 		.result = REJECT,
32405aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
32415aa5bd14SDaniel Borkmann 	},
32425aa5bd14SDaniel Borkmann 	{
32435aa5bd14SDaniel Borkmann 		"direct packet access: test4 (write)",
32445aa5bd14SDaniel Borkmann 		.insns = {
32455aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
32465aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32475aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
32485aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
32495aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
32505aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
32515aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
32525aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
32535aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
32545aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32555aa5bd14SDaniel Borkmann 		},
32565aa5bd14SDaniel Borkmann 		.result = ACCEPT,
32575aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
32585aa5bd14SDaniel Borkmann 	},
32595aa5bd14SDaniel Borkmann 	{
32605aa5bd14SDaniel Borkmann 		"direct packet access: test5 (pkt_end >= reg, good access)",
32615aa5bd14SDaniel Borkmann 		.insns = {
32625aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
32635aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32645aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
32655aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
32665aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
32675aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
32685aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
32695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
32705aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32715aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
32725aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
32735aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32745aa5bd14SDaniel Borkmann 		},
32755aa5bd14SDaniel Borkmann 		.result = ACCEPT,
32765aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
32775aa5bd14SDaniel Borkmann 	},
32785aa5bd14SDaniel Borkmann 	{
32795aa5bd14SDaniel Borkmann 		"direct packet access: test6 (pkt_end >= reg, bad access)",
32805aa5bd14SDaniel Borkmann 		.insns = {
32815aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
32825aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
32835aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
32845aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
32855aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
32865aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
32875aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
32885aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
32895aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
32905aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32915aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
32925aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
32935aa5bd14SDaniel Borkmann 		},
32945aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
32955aa5bd14SDaniel Borkmann 		.result = REJECT,
32965aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
32975aa5bd14SDaniel Borkmann 	},
32985aa5bd14SDaniel Borkmann 	{
32995aa5bd14SDaniel Borkmann 		"direct packet access: test7 (pkt_end >= reg, both accesses)",
33005aa5bd14SDaniel Borkmann 		.insns = {
33015aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
33025aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
33035aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
33045aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
33055aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
33065aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
33075aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3),
33085aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33095aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
33105aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33115aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33125aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
33135aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33145aa5bd14SDaniel Borkmann 		},
33155aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
33165aa5bd14SDaniel Borkmann 		.result = REJECT,
33175aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33185aa5bd14SDaniel Borkmann 	},
33195aa5bd14SDaniel Borkmann 	{
33205aa5bd14SDaniel Borkmann 		"direct packet access: test8 (double test, variant 1)",
33215aa5bd14SDaniel Borkmann 		.insns = {
33225aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
33235aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
33245aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
33255aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
33265aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
33275aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
33285aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4),
33295aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
33305aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33315aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
33325aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33335aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33345aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
33355aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33365aa5bd14SDaniel Borkmann 		},
33375aa5bd14SDaniel Borkmann 		.result = ACCEPT,
33385aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33395aa5bd14SDaniel Borkmann 	},
33405aa5bd14SDaniel Borkmann 	{
33415aa5bd14SDaniel Borkmann 		"direct packet access: test9 (double test, variant 2)",
33425aa5bd14SDaniel Borkmann 		.insns = {
33435aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
33445aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
33455aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
33465aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
33475aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
33485aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
33495aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2),
33505aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
33515aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33525aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
33535aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33545aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
33555aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
33565aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33575aa5bd14SDaniel Borkmann 		},
33585aa5bd14SDaniel Borkmann 		.result = ACCEPT,
33595aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33605aa5bd14SDaniel Borkmann 	},
33615aa5bd14SDaniel Borkmann 	{
33625aa5bd14SDaniel Borkmann 		"direct packet access: test10 (write invalid)",
33635aa5bd14SDaniel Borkmann 		.insns = {
33645aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
33655aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
33665aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
33675aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
33685aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
33695aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
33705aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
33715aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
33725aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33735aa5bd14SDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
33745aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
33755aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
33765aa5bd14SDaniel Borkmann 		},
33775aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
33785aa5bd14SDaniel Borkmann 		.result = REJECT,
33795aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33805aa5bd14SDaniel Borkmann 	},
33815aa5bd14SDaniel Borkmann 	{
33823fadc801SDaniel Borkmann 		"direct packet access: test11 (shift, good access)",
33833fadc801SDaniel Borkmann 		.insns = {
33843fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
33853fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
33863fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
33873fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
33883fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
33893fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
33903fadc801SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
33913fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 144),
33923fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
33933fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
33943fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
33953fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
33963fadc801SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
33973fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
33983fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
33993fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
34003fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
34013fadc801SDaniel Borkmann 		},
34023fadc801SDaniel Borkmann 		.result = ACCEPT,
34033fadc801SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3404111e6b45SAlexei Starovoitov 		.retval = 1,
34053fadc801SDaniel Borkmann 	},
34063fadc801SDaniel Borkmann 	{
34073fadc801SDaniel Borkmann 		"direct packet access: test12 (and, good access)",
34083fadc801SDaniel Borkmann 		.insns = {
34093fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
34103fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
34113fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
34123fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
34133fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
34143fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
34153fadc801SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
34163fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 144),
34173fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
34183fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
34193fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
34203fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
34213fadc801SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
34223fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
34233fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
34243fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
34253fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
34263fadc801SDaniel Borkmann 		},
34273fadc801SDaniel Borkmann 		.result = ACCEPT,
34283fadc801SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3429111e6b45SAlexei Starovoitov 		.retval = 1,
34303fadc801SDaniel Borkmann 	},
34313fadc801SDaniel Borkmann 	{
34323fadc801SDaniel Borkmann 		"direct packet access: test13 (branches, good access)",
34333fadc801SDaniel Borkmann 		.insns = {
34343fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
34353fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
34363fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
34373fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
34383fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
34393fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
34403fadc801SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
34413fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
34423fadc801SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
34433fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 1),
34443fadc801SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
34453fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 14),
34463fadc801SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
34473fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 24),
34483fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
34493fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
34503fadc801SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
34513fadc801SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
34523fadc801SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
34533fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
34543fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
34553fadc801SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
34563fadc801SDaniel Borkmann 			BPF_EXIT_INSN(),
34573fadc801SDaniel Borkmann 		},
34583fadc801SDaniel Borkmann 		.result = ACCEPT,
34593fadc801SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3460111e6b45SAlexei Starovoitov 		.retval = 1,
34613fadc801SDaniel Borkmann 	},
34623fadc801SDaniel Borkmann 	{
346363dfef75SWilliam Tu 		"direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
346463dfef75SWilliam Tu 		.insns = {
346563dfef75SWilliam Tu 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
346663dfef75SWilliam Tu 				    offsetof(struct __sk_buff, data)),
346763dfef75SWilliam Tu 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
346863dfef75SWilliam Tu 				    offsetof(struct __sk_buff, data_end)),
346963dfef75SWilliam Tu 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
347063dfef75SWilliam Tu 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
347163dfef75SWilliam Tu 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
347263dfef75SWilliam Tu 			BPF_MOV64_IMM(BPF_REG_5, 12),
347363dfef75SWilliam Tu 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
347463dfef75SWilliam Tu 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
347563dfef75SWilliam Tu 			BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
347663dfef75SWilliam Tu 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
347763dfef75SWilliam Tu 			BPF_MOV64_IMM(BPF_REG_0, 1),
347863dfef75SWilliam Tu 			BPF_EXIT_INSN(),
347963dfef75SWilliam Tu 			BPF_MOV64_IMM(BPF_REG_0, 0),
348063dfef75SWilliam Tu 			BPF_EXIT_INSN(),
348163dfef75SWilliam Tu 		},
348263dfef75SWilliam Tu 		.result = ACCEPT,
348363dfef75SWilliam Tu 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3484111e6b45SAlexei Starovoitov 		.retval = 1,
348563dfef75SWilliam Tu 	},
348663dfef75SWilliam Tu 	{
348702ea80b1SDaniel Borkmann 		"direct packet access: test15 (spill with xadd)",
348802ea80b1SDaniel Borkmann 		.insns = {
348902ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
349002ea80b1SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
349102ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
349202ea80b1SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
349302ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
349402ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
349502ea80b1SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
349602ea80b1SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 4096),
349702ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
349802ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
349902ea80b1SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
350002ea80b1SDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
350102ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
350202ea80b1SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
350302ea80b1SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
350402ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
350502ea80b1SDaniel Borkmann 		},
350602ea80b1SDaniel Borkmann 		.errstr = "R2 invalid mem access 'inv'",
350702ea80b1SDaniel Borkmann 		.result = REJECT,
350802ea80b1SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
350902ea80b1SDaniel Borkmann 	},
351002ea80b1SDaniel Borkmann 	{
3511728a853aSDaniel Borkmann 		"direct packet access: test16 (arith on data_end)",
3512728a853aSDaniel Borkmann 		.insns = {
3513728a853aSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3514728a853aSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
3515728a853aSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3516728a853aSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
3517728a853aSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3518728a853aSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3519728a853aSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16),
3520728a853aSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3521728a853aSDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
3522728a853aSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
3523728a853aSDaniel Borkmann 			BPF_EXIT_INSN(),
3524728a853aSDaniel Borkmann 		},
352582abbf8dSAlexei Starovoitov 		.errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
3526728a853aSDaniel Borkmann 		.result = REJECT,
3527728a853aSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3528728a853aSDaniel Borkmann 	},
3529728a853aSDaniel Borkmann 	{
3530614d0d77SDaniel Borkmann 		"direct packet access: test17 (pruning, alignment)",
3531614d0d77SDaniel Borkmann 		.insns = {
3532614d0d77SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3533614d0d77SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
3534614d0d77SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3535614d0d77SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
3536614d0d77SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
3537614d0d77SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
3538614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3539614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
3540614d0d77SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
3541614d0d77SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
3542614d0d77SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
3543614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
3544614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
3545614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3546614d0d77SDaniel Borkmann 			BPF_JMP_A(-6),
3547614d0d77SDaniel Borkmann 		},
3548f65b1849SEdward Cree 		.errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4",
3549614d0d77SDaniel Borkmann 		.result = REJECT,
3550614d0d77SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3551614d0d77SDaniel Borkmann 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
3552614d0d77SDaniel Borkmann 	},
3553614d0d77SDaniel Borkmann 	{
35546d191ed4SDaniel Borkmann 		"direct packet access: test18 (imm += pkt_ptr, 1)",
35556d191ed4SDaniel Borkmann 		.insns = {
35566d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
35576d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
35586d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
35596d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
35606d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 8),
35616d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
35626d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
35636d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
35646d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
35656d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
35666d191ed4SDaniel Borkmann 		},
35676d191ed4SDaniel Borkmann 		.result = ACCEPT,
35686d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
35696d191ed4SDaniel Borkmann 	},
35706d191ed4SDaniel Borkmann 	{
35716d191ed4SDaniel Borkmann 		"direct packet access: test19 (imm += pkt_ptr, 2)",
35726d191ed4SDaniel Borkmann 		.insns = {
35736d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
35746d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
35756d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
35766d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
35776d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
35786d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
35796d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
35806d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 4),
35816d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
35826d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0),
35836d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
35846d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
35856d191ed4SDaniel Borkmann 		},
35866d191ed4SDaniel Borkmann 		.result = ACCEPT,
35876d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
35886d191ed4SDaniel Borkmann 	},
35896d191ed4SDaniel Borkmann 	{
35906d191ed4SDaniel Borkmann 		"direct packet access: test20 (x += pkt_ptr, 1)",
35916d191ed4SDaniel Borkmann 		.insns = {
35926d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
35936d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
35946d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
35956d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
35966d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
35976d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
35986d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
35991f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff),
36006d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
36016d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
36026d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
36031f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
36046d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
36056d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
36066d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
36076d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
36086d191ed4SDaniel Borkmann 		},
36096d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36106d191ed4SDaniel Borkmann 		.result = ACCEPT,
36116d191ed4SDaniel Borkmann 	},
36126d191ed4SDaniel Borkmann 	{
36136d191ed4SDaniel Borkmann 		"direct packet access: test21 (x += pkt_ptr, 2)",
36146d191ed4SDaniel Borkmann 		.insns = {
36156d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
36166d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
36176d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
36186d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
36196d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
36206d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
36216d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
36226d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
36236d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
36246d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
36251f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff),
36266d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
36276d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
36281f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1),
36296d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
36306d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
36316d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
36326d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
36336d191ed4SDaniel Borkmann 		},
36346d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36356d191ed4SDaniel Borkmann 		.result = ACCEPT,
36366d191ed4SDaniel Borkmann 	},
36376d191ed4SDaniel Borkmann 	{
36386d191ed4SDaniel Borkmann 		"direct packet access: test22 (x += pkt_ptr, 3)",
36396d191ed4SDaniel Borkmann 		.insns = {
36406d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
36416d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
36426d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
36436d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
36446d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
36456d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
36466d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8),
36476d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16),
36486d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
36496d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11),
36506d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
36516d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0xffffffff),
36526d191ed4SDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8),
36536d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
36541f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49),
36556d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2),
36566d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
36576d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
36586d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
36596d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
36606d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
36616d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
36626d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
36636d191ed4SDaniel Borkmann 		},
36646d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36656d191ed4SDaniel Borkmann 		.result = ACCEPT,
36666d191ed4SDaniel Borkmann 	},
36676d191ed4SDaniel Borkmann 	{
36686d191ed4SDaniel Borkmann 		"direct packet access: test23 (x += pkt_ptr, 4)",
36696d191ed4SDaniel Borkmann 		.insns = {
36706d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
36716d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
36726d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
36736d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
36746d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
36756d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
36766d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
36776d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
36786d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
36796d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 31),
36806d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
36816d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
36826d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
36836d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1),
36846d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
36856d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
36866d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
36876d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
36886d191ed4SDaniel Borkmann 		},
36896d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36906d191ed4SDaniel Borkmann 		.result = REJECT,
3691f65b1849SEdward Cree 		.errstr = "invalid access to packet, off=0 size=8, R5(id=1,off=0,r=0)",
36926d191ed4SDaniel Borkmann 	},
36936d191ed4SDaniel Borkmann 	{
36946d191ed4SDaniel Borkmann 		"direct packet access: test24 (x += pkt_ptr, 5)",
36956d191ed4SDaniel Borkmann 		.insns = {
36966d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
36976d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
36986d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
36996d191ed4SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
37006d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0xffffffff),
37016d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
37026d191ed4SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
37036d191ed4SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
37046d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
37056d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 64),
37066d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
37076d191ed4SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
37086d191ed4SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
37091f9ab38fSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1),
37106d191ed4SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
37116d191ed4SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0),
37126d191ed4SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
37136d191ed4SDaniel Borkmann 			BPF_EXIT_INSN(),
37146d191ed4SDaniel Borkmann 		},
37156d191ed4SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
37166d191ed4SDaniel Borkmann 		.result = ACCEPT,
37176d191ed4SDaniel Borkmann 	},
37186d191ed4SDaniel Borkmann 	{
371931e482bfSDaniel Borkmann 		"direct packet access: test25 (marking on <, good access)",
372031e482bfSDaniel Borkmann 		.insns = {
372131e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
372231e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
372331e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
372431e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
372531e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
372631e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
372731e482bfSDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2),
372831e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
372931e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
373031e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
373131e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -4),
373231e482bfSDaniel Borkmann 		},
373331e482bfSDaniel Borkmann 		.result = ACCEPT,
373431e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
373531e482bfSDaniel Borkmann 	},
373631e482bfSDaniel Borkmann 	{
373731e482bfSDaniel Borkmann 		"direct packet access: test26 (marking on <, bad access)",
373831e482bfSDaniel Borkmann 		.insns = {
373931e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
374031e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
374131e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
374231e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
374331e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
374431e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
374531e482bfSDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3),
374631e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
374731e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
374831e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
374931e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -3),
375031e482bfSDaniel Borkmann 		},
375131e482bfSDaniel Borkmann 		.result = REJECT,
375231e482bfSDaniel Borkmann 		.errstr = "invalid access to packet",
375331e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
375431e482bfSDaniel Borkmann 	},
375531e482bfSDaniel Borkmann 	{
375631e482bfSDaniel Borkmann 		"direct packet access: test27 (marking on <=, good access)",
375731e482bfSDaniel Borkmann 		.insns = {
375831e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
375931e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
376031e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
376131e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
376231e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
376331e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
376431e482bfSDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1),
376531e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
376631e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
376731e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
376831e482bfSDaniel Borkmann 		},
376931e482bfSDaniel Borkmann 		.result = ACCEPT,
377031e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
3771111e6b45SAlexei Starovoitov 		.retval = 1,
377231e482bfSDaniel Borkmann 	},
377331e482bfSDaniel Borkmann 	{
377431e482bfSDaniel Borkmann 		"direct packet access: test28 (marking on <=, bad access)",
377531e482bfSDaniel Borkmann 		.insns = {
377631e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
377731e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
377831e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
377931e482bfSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
378031e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
378131e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
378231e482bfSDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2),
378331e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
378431e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
378531e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
378631e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -4),
378731e482bfSDaniel Borkmann 		},
378831e482bfSDaniel Borkmann 		.result = REJECT,
378931e482bfSDaniel Borkmann 		.errstr = "invalid access to packet",
379031e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
379131e482bfSDaniel Borkmann 	},
379231e482bfSDaniel Borkmann 	{
37935aa5bd14SDaniel Borkmann 		"helper access to packet: test1, valid packet_ptr range",
37945aa5bd14SDaniel Borkmann 		.insns = {
37955aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
37965aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
37975aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
37985aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
37995aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
38005aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
38015aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
38025aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
38035aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
38045aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
38055aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
38065aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_update_elem),
38075aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38085aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38095aa5bd14SDaniel Borkmann 		},
38105aa5bd14SDaniel Borkmann 		.fixup_map1 = { 5 },
38115aa5bd14SDaniel Borkmann 		.result_unpriv = ACCEPT,
38125aa5bd14SDaniel Borkmann 		.result = ACCEPT,
38135aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
38145aa5bd14SDaniel Borkmann 	},
38155aa5bd14SDaniel Borkmann 	{
38165aa5bd14SDaniel Borkmann 		"helper access to packet: test2, unchecked packet_ptr",
38175aa5bd14SDaniel Borkmann 		.insns = {
38185aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
38195aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
38205aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
38215aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
38225aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
38235aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38245aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38255aa5bd14SDaniel Borkmann 		},
38265aa5bd14SDaniel Borkmann 		.fixup_map1 = { 1 },
38275aa5bd14SDaniel Borkmann 		.result = REJECT,
38285aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
38295aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
38305aa5bd14SDaniel Borkmann 	},
38315aa5bd14SDaniel Borkmann 	{
38325aa5bd14SDaniel Borkmann 		"helper access to packet: test3, variable add",
38335aa5bd14SDaniel Borkmann 		.insns = {
38345aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
38355aa5bd14SDaniel Borkmann 					offsetof(struct xdp_md, data)),
38365aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
38375aa5bd14SDaniel Borkmann 					offsetof(struct xdp_md, data_end)),
38385aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
38395aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
38405aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
38415aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
38425aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
38435aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
38445aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
38455aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
38465aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
38475aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
38485aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
38495aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
38505aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
38515aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38525aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38535aa5bd14SDaniel Borkmann 		},
38545aa5bd14SDaniel Borkmann 		.fixup_map1 = { 11 },
38555aa5bd14SDaniel Borkmann 		.result = ACCEPT,
38565aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
38575aa5bd14SDaniel Borkmann 	},
38585aa5bd14SDaniel Borkmann 	{
38595aa5bd14SDaniel Borkmann 		"helper access to packet: test4, packet_ptr with bad range",
38605aa5bd14SDaniel Borkmann 		.insns = {
38615aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
38625aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
38635aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
38645aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
38655aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
38665aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
38675aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
38685aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38695aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38705aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
38715aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
38725aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
38735aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38745aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38755aa5bd14SDaniel Borkmann 		},
38765aa5bd14SDaniel Borkmann 		.fixup_map1 = { 7 },
38775aa5bd14SDaniel Borkmann 		.result = REJECT,
38785aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
38795aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
38805aa5bd14SDaniel Borkmann 	},
38815aa5bd14SDaniel Borkmann 	{
38825aa5bd14SDaniel Borkmann 		"helper access to packet: test5, packet_ptr with too short range",
38835aa5bd14SDaniel Borkmann 		.insns = {
38845aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
38855aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
38865aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
38875aa5bd14SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
38885aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
38895aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
38905aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
38915aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
38925aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
38935aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
38945aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
38955aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
38965aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
38975aa5bd14SDaniel Borkmann 		},
38985aa5bd14SDaniel Borkmann 		.fixup_map1 = { 6 },
38995aa5bd14SDaniel Borkmann 		.result = REJECT,
39005aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
39015aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
39025aa5bd14SDaniel Borkmann 	},
39035aa5bd14SDaniel Borkmann 	{
39045aa5bd14SDaniel Borkmann 		"helper access to packet: test6, cls valid packet_ptr range",
39055aa5bd14SDaniel Borkmann 		.insns = {
39065aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39075aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
39085aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
39095aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
39105aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
39115aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
39125aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5),
39135aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
39145aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
39155aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
39165aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
39175aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_update_elem),
39185aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
39195aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
39205aa5bd14SDaniel Borkmann 		},
39215aa5bd14SDaniel Borkmann 		.fixup_map1 = { 5 },
39225aa5bd14SDaniel Borkmann 		.result = ACCEPT,
39235aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39245aa5bd14SDaniel Borkmann 	},
39255aa5bd14SDaniel Borkmann 	{
39265aa5bd14SDaniel Borkmann 		"helper access to packet: test7, cls unchecked packet_ptr",
39275aa5bd14SDaniel Borkmann 		.insns = {
39285aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39295aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
39305aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
39315aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
39325aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
39335aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
39345aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
39355aa5bd14SDaniel Borkmann 		},
39365aa5bd14SDaniel Borkmann 		.fixup_map1 = { 1 },
39375aa5bd14SDaniel Borkmann 		.result = REJECT,
39385aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
39395aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39405aa5bd14SDaniel Borkmann 	},
39415aa5bd14SDaniel Borkmann 	{
39425aa5bd14SDaniel Borkmann 		"helper access to packet: test8, cls variable add",
39435aa5bd14SDaniel Borkmann 		.insns = {
39445aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39455aa5bd14SDaniel Borkmann 					offsetof(struct __sk_buff, data)),
39465aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
39475aa5bd14SDaniel Borkmann 					offsetof(struct __sk_buff, data_end)),
39485aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
39495aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
39505aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10),
39515aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0),
39525aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
39535aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5),
39545aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_4),
39555aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8),
39565aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4),
39575aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
39585aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_4),
39595aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
39605aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
39615aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
39625aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
39635aa5bd14SDaniel Borkmann 		},
39645aa5bd14SDaniel Borkmann 		.fixup_map1 = { 11 },
39655aa5bd14SDaniel Borkmann 		.result = ACCEPT,
39665aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39675aa5bd14SDaniel Borkmann 	},
39685aa5bd14SDaniel Borkmann 	{
39695aa5bd14SDaniel Borkmann 		"helper access to packet: test9, cls packet_ptr with bad range",
39705aa5bd14SDaniel Borkmann 		.insns = {
39715aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39725aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
39735aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
39745aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
39755aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
39765aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
39775aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2),
39785aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
39795aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
39805aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
39815aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
39825aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
39835aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
39845aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
39855aa5bd14SDaniel Borkmann 		},
39865aa5bd14SDaniel Borkmann 		.fixup_map1 = { 7 },
39875aa5bd14SDaniel Borkmann 		.result = REJECT,
39885aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
39895aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39905aa5bd14SDaniel Borkmann 	},
39915aa5bd14SDaniel Borkmann 	{
39925aa5bd14SDaniel Borkmann 		"helper access to packet: test10, cls packet_ptr with too short range",
39935aa5bd14SDaniel Borkmann 		.insns = {
39945aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39955aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
39965aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
39975aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
39985aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
39995aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
40005aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7),
40015aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3),
40025aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
40035aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
40045aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
40055aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
40065aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
40075aa5bd14SDaniel Borkmann 		},
40085aa5bd14SDaniel Borkmann 		.fixup_map1 = { 6 },
40095aa5bd14SDaniel Borkmann 		.result = REJECT,
40105aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
40115aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
40125aa5bd14SDaniel Borkmann 	},
40135aa5bd14SDaniel Borkmann 	{
40145aa5bd14SDaniel Borkmann 		"helper access to packet: test11, cls unsuitable helper 1",
40155aa5bd14SDaniel Borkmann 		.insns = {
40165aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
40175aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
40185aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
40195aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
40205aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
40215aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
40225aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7),
40235aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4),
40245aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
40255aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 42),
40265aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
40275aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
40285aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_store_bytes),
40295aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
40305aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
40315aa5bd14SDaniel Borkmann 		},
40325aa5bd14SDaniel Borkmann 		.result = REJECT,
40335aa5bd14SDaniel Borkmann 		.errstr = "helper access to the packet",
40345aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
40355aa5bd14SDaniel Borkmann 	},
40365aa5bd14SDaniel Borkmann 	{
40375aa5bd14SDaniel Borkmann 		"helper access to packet: test12, cls unsuitable helper 2",
40385aa5bd14SDaniel Borkmann 		.insns = {
40395aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
40405aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
40415aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
40425aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
40435aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
40445aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
40455aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3),
40465aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
40475aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 4),
40485aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
40495aa5bd14SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
40505aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
40515aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
40525aa5bd14SDaniel Borkmann 		},
40535aa5bd14SDaniel Borkmann 		.result = REJECT,
40545aa5bd14SDaniel Borkmann 		.errstr = "helper access to the packet",
40555aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
40565aa5bd14SDaniel Borkmann 	},
40575aa5bd14SDaniel Borkmann 	{
40585aa5bd14SDaniel Borkmann 		"helper access to packet: test13, cls helper ok",
40595aa5bd14SDaniel Borkmann 		.insns = {
40605aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
40615aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
40625aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
40635aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
40645aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
40655aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
40665aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
40675aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
40685aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
40695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
40705aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
40715aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
40725aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
40735aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
40745aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
40755aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
40765aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
40775aa5bd14SDaniel Borkmann 		},
40785aa5bd14SDaniel Borkmann 		.result = ACCEPT,
40795aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
40805aa5bd14SDaniel Borkmann 	},
40815aa5bd14SDaniel Borkmann 	{
4082f65b1849SEdward Cree 		"helper access to packet: test14, cls helper ok sub",
40835aa5bd14SDaniel Borkmann 		.insns = {
40845aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
40855aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
40865aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
40875aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
40885aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
40895aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
40905aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
40915aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
40925aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4),
40935aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
40945aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
40955aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
40965aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
40975aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
40985aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
40995aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
41005aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
41015aa5bd14SDaniel Borkmann 		},
4102f65b1849SEdward Cree 		.result = ACCEPT,
41035aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
41045aa5bd14SDaniel Borkmann 	},
41055aa5bd14SDaniel Borkmann 	{
4106f65b1849SEdward Cree 		"helper access to packet: test15, cls helper fail sub",
4107f65b1849SEdward Cree 		.insns = {
4108f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
4109f65b1849SEdward Cree 				    offsetof(struct __sk_buff, data)),
4110f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
4111f65b1849SEdward Cree 				    offsetof(struct __sk_buff, data_end)),
4112f65b1849SEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
4113f65b1849SEdward Cree 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4114f65b1849SEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
4115f65b1849SEdward Cree 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
4116f65b1849SEdward Cree 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 12),
4117f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_2, 4),
4118f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_3, 0),
4119f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_4, 0),
4120f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_5, 0),
4121f65b1849SEdward Cree 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4122f65b1849SEdward Cree 				     BPF_FUNC_csum_diff),
4123f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
4124f65b1849SEdward Cree 			BPF_EXIT_INSN(),
4125f65b1849SEdward Cree 		},
4126f65b1849SEdward Cree 		.result = REJECT,
4127f65b1849SEdward Cree 		.errstr = "invalid access to packet",
4128f65b1849SEdward Cree 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
4129f65b1849SEdward Cree 	},
4130f65b1849SEdward Cree 	{
4131f65b1849SEdward Cree 		"helper access to packet: test16, cls helper fail range 1",
41325aa5bd14SDaniel Borkmann 		.insns = {
41335aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
41345aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
41355aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
41365aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
41375aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
41385aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41395aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
41405aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
41415aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41425aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 8),
41435aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
41445aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
41455aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
41465aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
41475aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
41485aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
41495aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
41505aa5bd14SDaniel Borkmann 		},
41515aa5bd14SDaniel Borkmann 		.result = REJECT,
41525aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
41535aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
41545aa5bd14SDaniel Borkmann 	},
41555aa5bd14SDaniel Borkmann 	{
4156f65b1849SEdward Cree 		"helper access to packet: test17, cls helper fail range 2",
41575aa5bd14SDaniel Borkmann 		.insns = {
41585aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
41595aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
41605aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
41615aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
41625aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
41635aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41645aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
41655aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
41665aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41675aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -9),
41685aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
41695aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
41705aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
41715aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
41725aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
41735aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
41745aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
41755aa5bd14SDaniel Borkmann 		},
41765aa5bd14SDaniel Borkmann 		.result = REJECT,
4177f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
41785aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
41795aa5bd14SDaniel Borkmann 	},
41805aa5bd14SDaniel Borkmann 	{
4181f65b1849SEdward Cree 		"helper access to packet: test18, cls helper fail range 3",
41825aa5bd14SDaniel Borkmann 		.insns = {
41835aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
41845aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
41855aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
41865aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
41875aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
41885aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41895aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
41905aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
41915aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
41925aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, ~0),
41935aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
41945aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
41955aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
41965aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
41975aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
41985aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
41995aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
42005aa5bd14SDaniel Borkmann 		},
42015aa5bd14SDaniel Borkmann 		.result = REJECT,
4202f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
42035aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
42045aa5bd14SDaniel Borkmann 	},
42055aa5bd14SDaniel Borkmann 	{
4206b6ff6391SYonghong Song 		"helper access to packet: test19, cls helper range zero",
42075aa5bd14SDaniel Borkmann 		.insns = {
42085aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
42095aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
42105aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
42115aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
42125aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
42135aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
42145aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
42155aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
42165aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
42175aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
42185aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
42195aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
42205aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
42215aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
42225aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
42235aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
42245aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
42255aa5bd14SDaniel Borkmann 		},
4226b6ff6391SYonghong Song 		.result = ACCEPT,
42275aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
42285aa5bd14SDaniel Borkmann 	},
42295aa5bd14SDaniel Borkmann 	{
4230f65b1849SEdward Cree 		"helper access to packet: test20, pkt end as input",
42315aa5bd14SDaniel Borkmann 		.insns = {
42325aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
42335aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
42345aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
42355aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
42365aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
42375aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
42385aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
42395aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
42405aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
42415aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
42425aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
42435aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
42445aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
42455aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
42465aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
42475aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
42485aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
42495aa5bd14SDaniel Borkmann 		},
42505aa5bd14SDaniel Borkmann 		.result = REJECT,
42515aa5bd14SDaniel Borkmann 		.errstr = "R1 type=pkt_end expected=fp",
42525aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
42535aa5bd14SDaniel Borkmann 	},
42545aa5bd14SDaniel Borkmann 	{
4255f65b1849SEdward Cree 		"helper access to packet: test21, wrong reg",
42565aa5bd14SDaniel Borkmann 		.insns = {
42575aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
42585aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
42595aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
42605aa5bd14SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
42615aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1),
42625aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
42635aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
42645aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6),
42655aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 4),
42665aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
42675aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
42685aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
42695aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
42705aa5bd14SDaniel Borkmann 				     BPF_FUNC_csum_diff),
42715aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
42725aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
42735aa5bd14SDaniel Borkmann 		},
42745aa5bd14SDaniel Borkmann 		.result = REJECT,
42755aa5bd14SDaniel Borkmann 		.errstr = "invalid access to packet",
42765aa5bd14SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
42775aa5bd14SDaniel Borkmann 	},
42785aa5bd14SDaniel Borkmann 	{
42795aa5bd14SDaniel Borkmann 		"valid map access into an array with a constant",
42805aa5bd14SDaniel Borkmann 		.insns = {
42815aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
42825aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
42835aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
42845aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
42855aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
42865aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
42875aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
42885aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
42895aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
42905aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
42915aa5bd14SDaniel Borkmann 		},
42925aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
42935aa5bd14SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
42945aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
42955aa5bd14SDaniel Borkmann 		.result = ACCEPT,
42965aa5bd14SDaniel Borkmann 	},
42975aa5bd14SDaniel Borkmann 	{
42985aa5bd14SDaniel Borkmann 		"valid map access into an array with a register",
42995aa5bd14SDaniel Borkmann 		.insns = {
43005aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43015aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
43025aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
43035aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
43045aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
43055aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
43065aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
43075aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 4),
43085aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
43095aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
43105aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
43115aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
43125aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
43135aa5bd14SDaniel Borkmann 		},
43145aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4315f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
43165aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
43175aa5bd14SDaniel Borkmann 		.result = ACCEPT,
431802ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
43195aa5bd14SDaniel Borkmann 	},
43205aa5bd14SDaniel Borkmann 	{
43215aa5bd14SDaniel Borkmann 		"valid map access into an array with a variable",
43225aa5bd14SDaniel Borkmann 		.insns = {
43235aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43245aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
43255aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
43265aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
43275aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
43285aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
43295aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
43305aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
43315aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
43325aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
43335aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
43345aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
43355aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
43365aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
43375aa5bd14SDaniel Borkmann 		},
43385aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4339f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
43405aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
43415aa5bd14SDaniel Borkmann 		.result = ACCEPT,
434202ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
43435aa5bd14SDaniel Borkmann 	},
43445aa5bd14SDaniel Borkmann 	{
43455aa5bd14SDaniel Borkmann 		"valid map access into an array with a signed variable",
43465aa5bd14SDaniel Borkmann 		.insns = {
43475aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43485aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
43495aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
43505aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
43515aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
43525aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
43535aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
43545aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
43555aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
43565aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
43575aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
43585aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
43595aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
43605aa5bd14SDaniel Borkmann 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
43615aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
43625aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
43635aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
43645aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
43655aa5bd14SDaniel Borkmann 		},
43665aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4367f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
43685aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
43695aa5bd14SDaniel Borkmann 		.result = ACCEPT,
437002ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
43715aa5bd14SDaniel Borkmann 	},
43725aa5bd14SDaniel Borkmann 	{
43735aa5bd14SDaniel Borkmann 		"invalid map access into an array with a constant",
43745aa5bd14SDaniel Borkmann 		.insns = {
43755aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43765aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
43775aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
43785aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
43795aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
43805aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
43815aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
43825aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
43835aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
43845aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
43855aa5bd14SDaniel Borkmann 		},
43865aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
43875aa5bd14SDaniel Borkmann 		.errstr = "invalid access to map value, value_size=48 off=48 size=8",
43885aa5bd14SDaniel Borkmann 		.result = REJECT,
43895aa5bd14SDaniel Borkmann 	},
43905aa5bd14SDaniel Borkmann 	{
43915aa5bd14SDaniel Borkmann 		"invalid map access into an array with a register",
43925aa5bd14SDaniel Borkmann 		.insns = {
43935aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43945aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
43955aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
43965aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
43975aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
43985aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
43995aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
44005aa5bd14SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
44015aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
44025aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
44035aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
44045aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
44055aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
44065aa5bd14SDaniel Borkmann 		},
44075aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
44085aa5bd14SDaniel Borkmann 		.errstr = "R0 min value is outside of the array range",
44095aa5bd14SDaniel Borkmann 		.result = REJECT,
441002ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
44115aa5bd14SDaniel Borkmann 	},
44125aa5bd14SDaniel Borkmann 	{
44135aa5bd14SDaniel Borkmann 		"invalid map access into an array with a variable",
44145aa5bd14SDaniel Borkmann 		.insns = {
44155aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
44165aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
44175aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
44185aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
44195aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
44205aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
44215aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
44225aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
44235aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
44245aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
44255aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
44265aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
44275aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
44285aa5bd14SDaniel Borkmann 		},
44295aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4430f65b1849SEdward Cree 		.errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
44315aa5bd14SDaniel Borkmann 		.result = REJECT,
443202ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
44335aa5bd14SDaniel Borkmann 	},
44345aa5bd14SDaniel Borkmann 	{
44355aa5bd14SDaniel Borkmann 		"invalid map access into an array with no floor check",
44365aa5bd14SDaniel Borkmann 		.insns = {
44375aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
44385aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
44395aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
44405aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
44415aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
44425aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
44435aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4444f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
44455aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
44465aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
44475aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
44485aa5bd14SDaniel Borkmann 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
44495aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
44505aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
44515aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
44525aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
44535aa5bd14SDaniel Borkmann 		},
44545aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4455f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
4456f65b1849SEdward Cree 		.errstr = "R0 unbounded memory access",
44575aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
44585aa5bd14SDaniel Borkmann 		.result = REJECT,
445902ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
44605aa5bd14SDaniel Borkmann 	},
44615aa5bd14SDaniel Borkmann 	{
44625aa5bd14SDaniel Borkmann 		"invalid map access into an array with a invalid max check",
44635aa5bd14SDaniel Borkmann 		.insns = {
44645aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
44655aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
44665aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
44675aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
44685aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
44695aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
44705aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
44715aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
44725aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
44735aa5bd14SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
44745aa5bd14SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_1, 0),
44755aa5bd14SDaniel Borkmann 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
44765aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
44775aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
44785aa5bd14SDaniel Borkmann 				   offsetof(struct test_val, foo)),
44795aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
44805aa5bd14SDaniel Borkmann 		},
44815aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3 },
4482f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
44835aa5bd14SDaniel Borkmann 		.errstr = "invalid access to map value, value_size=48 off=44 size=8",
44845aa5bd14SDaniel Borkmann 		.result_unpriv = REJECT,
44855aa5bd14SDaniel Borkmann 		.result = REJECT,
448602ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
44875aa5bd14SDaniel Borkmann 	},
44885aa5bd14SDaniel Borkmann 	{
44895aa5bd14SDaniel Borkmann 		"invalid map access into an array with a invalid max check",
44905aa5bd14SDaniel Borkmann 		.insns = {
44915aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
44925aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
44935aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
44945aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
44955aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
44965aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
44975aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
44985aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
44995aa5bd14SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
45005aa5bd14SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
45015aa5bd14SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
45025aa5bd14SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
45035aa5bd14SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
45045aa5bd14SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
45055aa5bd14SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
45065aa5bd14SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
45075aa5bd14SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
45085aa5bd14SDaniel Borkmann 				    offsetof(struct test_val, foo)),
45095aa5bd14SDaniel Borkmann 			BPF_EXIT_INSN(),
45105aa5bd14SDaniel Borkmann 		},
45115aa5bd14SDaniel Borkmann 		.fixup_map2 = { 3, 11 },
451282abbf8dSAlexei Starovoitov 		.errstr = "R0 pointer += pointer",
45135aa5bd14SDaniel Borkmann 		.result = REJECT,
451402ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
45155aa5bd14SDaniel Borkmann 	},
451657a09bf0SThomas Graf 	{
451757a09bf0SThomas Graf 		"multiple registers share map_lookup_elem result",
451857a09bf0SThomas Graf 		.insns = {
451957a09bf0SThomas Graf 			BPF_MOV64_IMM(BPF_REG_1, 10),
452057a09bf0SThomas Graf 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
452157a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
452257a09bf0SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
452357a09bf0SThomas Graf 			BPF_LD_MAP_FD(BPF_REG_1, 0),
452457a09bf0SThomas Graf 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
452557a09bf0SThomas Graf 				     BPF_FUNC_map_lookup_elem),
452657a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
452757a09bf0SThomas Graf 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
452857a09bf0SThomas Graf 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
452957a09bf0SThomas Graf 			BPF_EXIT_INSN(),
453057a09bf0SThomas Graf 		},
453157a09bf0SThomas Graf 		.fixup_map1 = { 4 },
453257a09bf0SThomas Graf 		.result = ACCEPT,
453357a09bf0SThomas Graf 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
453457a09bf0SThomas Graf 	},
453557a09bf0SThomas Graf 	{
4536614d0d77SDaniel Borkmann 		"alu ops on ptr_to_map_value_or_null, 1",
4537614d0d77SDaniel Borkmann 		.insns = {
4538614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 10),
4539614d0d77SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4540614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4541614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4542614d0d77SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4543614d0d77SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4544614d0d77SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
4545614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4546614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
4547614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
4548614d0d77SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4549614d0d77SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4550614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
4551614d0d77SDaniel Borkmann 		},
4552614d0d77SDaniel Borkmann 		.fixup_map1 = { 4 },
455382abbf8dSAlexei Starovoitov 		.errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4554614d0d77SDaniel Borkmann 		.result = REJECT,
4555614d0d77SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
4556614d0d77SDaniel Borkmann 	},
4557614d0d77SDaniel Borkmann 	{
4558614d0d77SDaniel Borkmann 		"alu ops on ptr_to_map_value_or_null, 2",
4559614d0d77SDaniel Borkmann 		.insns = {
4560614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 10),
4561614d0d77SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4562614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4563614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4564614d0d77SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4565614d0d77SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4566614d0d77SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
4567614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4568614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
4569614d0d77SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4570614d0d77SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4571614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
4572614d0d77SDaniel Borkmann 		},
4573614d0d77SDaniel Borkmann 		.fixup_map1 = { 4 },
457482abbf8dSAlexei Starovoitov 		.errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4575614d0d77SDaniel Borkmann 		.result = REJECT,
4576614d0d77SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
4577614d0d77SDaniel Borkmann 	},
4578614d0d77SDaniel Borkmann 	{
4579614d0d77SDaniel Borkmann 		"alu ops on ptr_to_map_value_or_null, 3",
4580614d0d77SDaniel Borkmann 		.insns = {
4581614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 10),
4582614d0d77SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
4583614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4584614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4585614d0d77SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4586614d0d77SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4587614d0d77SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
4588614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
4589614d0d77SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
4590614d0d77SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4591614d0d77SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
4592614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
4593614d0d77SDaniel Borkmann 		},
4594614d0d77SDaniel Borkmann 		.fixup_map1 = { 4 },
459582abbf8dSAlexei Starovoitov 		.errstr = "R4 pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL",
4596614d0d77SDaniel Borkmann 		.result = REJECT,
4597614d0d77SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
4598614d0d77SDaniel Borkmann 	},
4599614d0d77SDaniel Borkmann 	{
460057a09bf0SThomas Graf 		"invalid memory access with multiple map_lookup_elem calls",
460157a09bf0SThomas Graf 		.insns = {
460257a09bf0SThomas Graf 			BPF_MOV64_IMM(BPF_REG_1, 10),
460357a09bf0SThomas Graf 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
460457a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
460557a09bf0SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
460657a09bf0SThomas Graf 			BPF_LD_MAP_FD(BPF_REG_1, 0),
460757a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
460857a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
460957a09bf0SThomas Graf 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
461057a09bf0SThomas Graf 				     BPF_FUNC_map_lookup_elem),
461157a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
461257a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
461357a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
461457a09bf0SThomas Graf 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
461557a09bf0SThomas Graf 				     BPF_FUNC_map_lookup_elem),
461657a09bf0SThomas Graf 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
461757a09bf0SThomas Graf 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
461857a09bf0SThomas Graf 			BPF_EXIT_INSN(),
461957a09bf0SThomas Graf 		},
462057a09bf0SThomas Graf 		.fixup_map1 = { 4 },
462157a09bf0SThomas Graf 		.result = REJECT,
462257a09bf0SThomas Graf 		.errstr = "R4 !read_ok",
462357a09bf0SThomas Graf 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
462457a09bf0SThomas Graf 	},
462557a09bf0SThomas Graf 	{
462657a09bf0SThomas Graf 		"valid indirect map_lookup_elem access with 2nd lookup in branch",
462757a09bf0SThomas Graf 		.insns = {
462857a09bf0SThomas Graf 			BPF_MOV64_IMM(BPF_REG_1, 10),
462957a09bf0SThomas Graf 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
463057a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
463157a09bf0SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
463257a09bf0SThomas Graf 			BPF_LD_MAP_FD(BPF_REG_1, 0),
463357a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
463457a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
463557a09bf0SThomas Graf 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
463657a09bf0SThomas Graf 				     BPF_FUNC_map_lookup_elem),
463757a09bf0SThomas Graf 			BPF_MOV64_IMM(BPF_REG_2, 10),
463857a09bf0SThomas Graf 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
463957a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
464057a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
464157a09bf0SThomas Graf 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
464257a09bf0SThomas Graf 				     BPF_FUNC_map_lookup_elem),
464357a09bf0SThomas Graf 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
464457a09bf0SThomas Graf 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
464557a09bf0SThomas Graf 			BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
464657a09bf0SThomas Graf 			BPF_EXIT_INSN(),
464757a09bf0SThomas Graf 		},
464857a09bf0SThomas Graf 		.fixup_map1 = { 4 },
464957a09bf0SThomas Graf 		.result = ACCEPT,
465057a09bf0SThomas Graf 		.prog_type = BPF_PROG_TYPE_SCHED_CLS
465157a09bf0SThomas Graf 	},
4652e9548901SJosef Bacik 	{
4653e9548901SJosef Bacik 		"invalid map access from else condition",
4654e9548901SJosef Bacik 		.insns = {
4655e9548901SJosef Bacik 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4656e9548901SJosef Bacik 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4657e9548901SJosef Bacik 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4658e9548901SJosef Bacik 			BPF_LD_MAP_FD(BPF_REG_1, 0),
4659e9548901SJosef Bacik 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
4660e9548901SJosef Bacik 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
4661e9548901SJosef Bacik 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4662e9548901SJosef Bacik 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1),
4663e9548901SJosef Bacik 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4664e9548901SJosef Bacik 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4665e9548901SJosef Bacik 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4666e9548901SJosef Bacik 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
4667e9548901SJosef Bacik 			BPF_EXIT_INSN(),
4668e9548901SJosef Bacik 		},
4669e9548901SJosef Bacik 		.fixup_map2 = { 3 },
4670f65b1849SEdward Cree 		.errstr = "R0 unbounded memory access",
4671e9548901SJosef Bacik 		.result = REJECT,
4672f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
4673e9548901SJosef Bacik 		.result_unpriv = REJECT,
467402ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4675e9548901SJosef Bacik 	},
46763c839744SGianluca Borello 	{
46773c839744SGianluca Borello 		"constant register |= constant should keep constant type",
46783c839744SGianluca Borello 		.insns = {
46793c839744SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
46803c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
46813c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 34),
46823c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 13),
46833c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
46843c839744SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
46853c839744SGianluca Borello 			BPF_EXIT_INSN(),
46863c839744SGianluca Borello 		},
46873c839744SGianluca Borello 		.result = ACCEPT,
46883c839744SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
46893c839744SGianluca Borello 	},
46903c839744SGianluca Borello 	{
46913c839744SGianluca Borello 		"constant register |= constant should not bypass stack boundary checks",
46923c839744SGianluca Borello 		.insns = {
46933c839744SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
46943c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
46953c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 34),
46963c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_OR, BPF_REG_2, 24),
46973c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
46983c839744SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
46993c839744SGianluca Borello 			BPF_EXIT_INSN(),
47003c839744SGianluca Borello 		},
47013c839744SGianluca Borello 		.errstr = "invalid stack type R1 off=-48 access_size=58",
47023c839744SGianluca Borello 		.result = REJECT,
47033c839744SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
47043c839744SGianluca Borello 	},
47053c839744SGianluca Borello 	{
47063c839744SGianluca Borello 		"constant register |= constant register should keep constant type",
47073c839744SGianluca Borello 		.insns = {
47083c839744SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
47093c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
47103c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 34),
47113c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 13),
47123c839744SGianluca Borello 			BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
47133c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
47143c839744SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
47153c839744SGianluca Borello 			BPF_EXIT_INSN(),
47163c839744SGianluca Borello 		},
47173c839744SGianluca Borello 		.result = ACCEPT,
47183c839744SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
47193c839744SGianluca Borello 	},
47203c839744SGianluca Borello 	{
47213c839744SGianluca Borello 		"constant register |= constant register should not bypass stack boundary checks",
47223c839744SGianluca Borello 		.insns = {
47233c839744SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
47243c839744SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -48),
47253c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 34),
47263c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 24),
47273c839744SGianluca Borello 			BPF_ALU64_REG(BPF_OR, BPF_REG_2, BPF_REG_4),
47283c839744SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
47293c839744SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
47303c839744SGianluca Borello 			BPF_EXIT_INSN(),
47313c839744SGianluca Borello 		},
47323c839744SGianluca Borello 		.errstr = "invalid stack type R1 off=-48 access_size=58",
47333c839744SGianluca Borello 		.result = REJECT,
47343c839744SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
47353c839744SGianluca Borello 	},
47363f731d89SThomas Graf 	{
47373f731d89SThomas Graf 		"invalid direct packet write for LWT_IN",
47383f731d89SThomas Graf 		.insns = {
47393f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
47403f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
47413f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
47423f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
47433f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
47443f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
47453f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
47463f731d89SThomas Graf 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
47473f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
47483f731d89SThomas Graf 			BPF_EXIT_INSN(),
47493f731d89SThomas Graf 		},
47503f731d89SThomas Graf 		.errstr = "cannot write into packet",
47513f731d89SThomas Graf 		.result = REJECT,
47523f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_IN,
47533f731d89SThomas Graf 	},
47543f731d89SThomas Graf 	{
47553f731d89SThomas Graf 		"invalid direct packet write for LWT_OUT",
47563f731d89SThomas Graf 		.insns = {
47573f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
47583f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
47593f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
47603f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
47613f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
47623f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
47633f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
47643f731d89SThomas Graf 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
47653f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
47663f731d89SThomas Graf 			BPF_EXIT_INSN(),
47673f731d89SThomas Graf 		},
47683f731d89SThomas Graf 		.errstr = "cannot write into packet",
47693f731d89SThomas Graf 		.result = REJECT,
47703f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_OUT,
47713f731d89SThomas Graf 	},
47723f731d89SThomas Graf 	{
47733f731d89SThomas Graf 		"direct packet write for LWT_XMIT",
47743f731d89SThomas Graf 		.insns = {
47753f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
47763f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
47773f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
47783f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
47793f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
47803f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
47813f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
47823f731d89SThomas Graf 			BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
47833f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
47843f731d89SThomas Graf 			BPF_EXIT_INSN(),
47853f731d89SThomas Graf 		},
47863f731d89SThomas Graf 		.result = ACCEPT,
47873f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_XMIT,
47883f731d89SThomas Graf 	},
47893f731d89SThomas Graf 	{
47903f731d89SThomas Graf 		"direct packet read for LWT_IN",
47913f731d89SThomas Graf 		.insns = {
47923f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
47933f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
47943f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
47953f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
47963f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
47973f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
47983f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
47993f731d89SThomas Graf 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
48003f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
48013f731d89SThomas Graf 			BPF_EXIT_INSN(),
48023f731d89SThomas Graf 		},
48033f731d89SThomas Graf 		.result = ACCEPT,
48043f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_IN,
48053f731d89SThomas Graf 	},
48063f731d89SThomas Graf 	{
48073f731d89SThomas Graf 		"direct packet read for LWT_OUT",
48083f731d89SThomas Graf 		.insns = {
48093f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
48103f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
48113f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
48123f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
48133f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
48143f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
48153f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
48163f731d89SThomas Graf 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
48173f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
48183f731d89SThomas Graf 			BPF_EXIT_INSN(),
48193f731d89SThomas Graf 		},
48203f731d89SThomas Graf 		.result = ACCEPT,
48213f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_OUT,
48223f731d89SThomas Graf 	},
48233f731d89SThomas Graf 	{
48243f731d89SThomas Graf 		"direct packet read for LWT_XMIT",
48253f731d89SThomas Graf 		.insns = {
48263f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
48273f731d89SThomas Graf 				    offsetof(struct __sk_buff, data)),
48283f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
48293f731d89SThomas Graf 				    offsetof(struct __sk_buff, data_end)),
48303f731d89SThomas Graf 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
48313f731d89SThomas Graf 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
48323f731d89SThomas Graf 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
48333f731d89SThomas Graf 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
48343f731d89SThomas Graf 			BPF_MOV64_IMM(BPF_REG_0, 0),
48353f731d89SThomas Graf 			BPF_EXIT_INSN(),
48363f731d89SThomas Graf 		},
48373f731d89SThomas Graf 		.result = ACCEPT,
48383f731d89SThomas Graf 		.prog_type = BPF_PROG_TYPE_LWT_XMIT,
48393f731d89SThomas Graf 	},
48403f731d89SThomas Graf 	{
4841b1977682SAlexei Starovoitov 		"overlapping checks for direct packet access",
4842b1977682SAlexei Starovoitov 		.insns = {
4843b1977682SAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
4844b1977682SAlexei Starovoitov 				    offsetof(struct __sk_buff, data)),
4845b1977682SAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
4846b1977682SAlexei Starovoitov 				    offsetof(struct __sk_buff, data_end)),
4847b1977682SAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
4848b1977682SAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
4849b1977682SAlexei Starovoitov 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
4850b1977682SAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4851b1977682SAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
4852b1977682SAlexei Starovoitov 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
4853b1977682SAlexei Starovoitov 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
4854b1977682SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
4855b1977682SAlexei Starovoitov 			BPF_EXIT_INSN(),
4856b1977682SAlexei Starovoitov 		},
4857b1977682SAlexei Starovoitov 		.result = ACCEPT,
4858b1977682SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_LWT_XMIT,
4859b1977682SAlexei Starovoitov 	},
4860b1977682SAlexei Starovoitov 	{
48613f731d89SThomas Graf 		"invalid access of tc_classid for LWT_IN",
48623f731d89SThomas Graf 		.insns = {
48633f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
48643f731d89SThomas Graf 				    offsetof(struct __sk_buff, tc_classid)),
48653f731d89SThomas Graf 			BPF_EXIT_INSN(),
48663f731d89SThomas Graf 		},
48673f731d89SThomas Graf 		.result = REJECT,
48683f731d89SThomas Graf 		.errstr = "invalid bpf_context access",
48693f731d89SThomas Graf 	},
48703f731d89SThomas Graf 	{
48713f731d89SThomas Graf 		"invalid access of tc_classid for LWT_OUT",
48723f731d89SThomas Graf 		.insns = {
48733f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
48743f731d89SThomas Graf 				    offsetof(struct __sk_buff, tc_classid)),
48753f731d89SThomas Graf 			BPF_EXIT_INSN(),
48763f731d89SThomas Graf 		},
48773f731d89SThomas Graf 		.result = REJECT,
48783f731d89SThomas Graf 		.errstr = "invalid bpf_context access",
48793f731d89SThomas Graf 	},
48803f731d89SThomas Graf 	{
48813f731d89SThomas Graf 		"invalid access of tc_classid for LWT_XMIT",
48823f731d89SThomas Graf 		.insns = {
48833f731d89SThomas Graf 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
48843f731d89SThomas Graf 				    offsetof(struct __sk_buff, tc_classid)),
48853f731d89SThomas Graf 			BPF_EXIT_INSN(),
48863f731d89SThomas Graf 		},
48873f731d89SThomas Graf 		.result = REJECT,
48883f731d89SThomas Graf 		.errstr = "invalid bpf_context access",
48893f731d89SThomas Graf 	},
48905722569bSGianluca Borello 	{
48916bdf6abcSDaniel Borkmann 		"leak pointer into ctx 1",
48926bdf6abcSDaniel Borkmann 		.insns = {
48936bdf6abcSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
48946bdf6abcSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
48956bdf6abcSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
48966bdf6abcSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
48976bdf6abcSDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2,
48986bdf6abcSDaniel Borkmann 				      offsetof(struct __sk_buff, cb[0])),
48996bdf6abcSDaniel Borkmann 			BPF_EXIT_INSN(),
49006bdf6abcSDaniel Borkmann 		},
49016bdf6abcSDaniel Borkmann 		.fixup_map1 = { 2 },
49026bdf6abcSDaniel Borkmann 		.errstr_unpriv = "R2 leaks addr into mem",
49036bdf6abcSDaniel Borkmann 		.result_unpriv = REJECT,
4904f37a8cb8SDaniel Borkmann 		.result = REJECT,
4905f37a8cb8SDaniel Borkmann 		.errstr = "BPF_XADD stores into R1 context is not allowed",
49066bdf6abcSDaniel Borkmann 	},
49076bdf6abcSDaniel Borkmann 	{
49086bdf6abcSDaniel Borkmann 		"leak pointer into ctx 2",
49096bdf6abcSDaniel Borkmann 		.insns = {
49106bdf6abcSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
49116bdf6abcSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
49126bdf6abcSDaniel Borkmann 				    offsetof(struct __sk_buff, cb[0])),
49136bdf6abcSDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10,
49146bdf6abcSDaniel Borkmann 				      offsetof(struct __sk_buff, cb[0])),
49156bdf6abcSDaniel Borkmann 			BPF_EXIT_INSN(),
49166bdf6abcSDaniel Borkmann 		},
49176bdf6abcSDaniel Borkmann 		.errstr_unpriv = "R10 leaks addr into mem",
49186bdf6abcSDaniel Borkmann 		.result_unpriv = REJECT,
4919f37a8cb8SDaniel Borkmann 		.result = REJECT,
4920f37a8cb8SDaniel Borkmann 		.errstr = "BPF_XADD stores into R1 context is not allowed",
49216bdf6abcSDaniel Borkmann 	},
49226bdf6abcSDaniel Borkmann 	{
49236bdf6abcSDaniel Borkmann 		"leak pointer into ctx 3",
49246bdf6abcSDaniel Borkmann 		.insns = {
49256bdf6abcSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
49266bdf6abcSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_2, 0),
49276bdf6abcSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2,
49286bdf6abcSDaniel Borkmann 				      offsetof(struct __sk_buff, cb[0])),
49296bdf6abcSDaniel Borkmann 			BPF_EXIT_INSN(),
49306bdf6abcSDaniel Borkmann 		},
49316bdf6abcSDaniel Borkmann 		.fixup_map1 = { 1 },
49326bdf6abcSDaniel Borkmann 		.errstr_unpriv = "R2 leaks addr into ctx",
49336bdf6abcSDaniel Borkmann 		.result_unpriv = REJECT,
49346bdf6abcSDaniel Borkmann 		.result = ACCEPT,
49356bdf6abcSDaniel Borkmann 	},
49366bdf6abcSDaniel Borkmann 	{
49376bdf6abcSDaniel Borkmann 		"leak pointer into map val",
49386bdf6abcSDaniel Borkmann 		.insns = {
49396bdf6abcSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
49406bdf6abcSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
49416bdf6abcSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
49426bdf6abcSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
49436bdf6abcSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
49446bdf6abcSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
49456bdf6abcSDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
49466bdf6abcSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
49476bdf6abcSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
49486bdf6abcSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
49496bdf6abcSDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
49506bdf6abcSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
49516bdf6abcSDaniel Borkmann 			BPF_EXIT_INSN(),
49526bdf6abcSDaniel Borkmann 		},
49536bdf6abcSDaniel Borkmann 		.fixup_map1 = { 4 },
49546bdf6abcSDaniel Borkmann 		.errstr_unpriv = "R6 leaks addr into mem",
49556bdf6abcSDaniel Borkmann 		.result_unpriv = REJECT,
49566bdf6abcSDaniel Borkmann 		.result = ACCEPT,
49576bdf6abcSDaniel Borkmann 	},
49586bdf6abcSDaniel Borkmann 	{
49595722569bSGianluca Borello 		"helper access to map: full range",
49605722569bSGianluca Borello 		.insns = {
49615722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
49625722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
49635722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
49645722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
49655722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
49665722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
49675722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
49685722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
49695722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
49705722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
49715722569bSGianluca Borello 			BPF_EXIT_INSN(),
49725722569bSGianluca Borello 		},
49735722569bSGianluca Borello 		.fixup_map2 = { 3 },
49745722569bSGianluca Borello 		.result = ACCEPT,
49755722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
49765722569bSGianluca Borello 	},
49775722569bSGianluca Borello 	{
49785722569bSGianluca Borello 		"helper access to map: partial range",
49795722569bSGianluca Borello 		.insns = {
49805722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
49815722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
49825722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
49835722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
49845722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
49855722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
49865722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
49875722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 8),
49885722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
49895722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
49905722569bSGianluca Borello 			BPF_EXIT_INSN(),
49915722569bSGianluca Borello 		},
49925722569bSGianluca Borello 		.fixup_map2 = { 3 },
49935722569bSGianluca Borello 		.result = ACCEPT,
49945722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
49955722569bSGianluca Borello 	},
49965722569bSGianluca Borello 	{
49975722569bSGianluca Borello 		"helper access to map: empty range",
49985722569bSGianluca Borello 		.insns = {
49995722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
50005722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
50015722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
50025722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
50035722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5004f1a8b8e3SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
5005f1a8b8e3SYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
5006f1a8b8e3SYonghong Song 			BPF_MOV64_IMM(BPF_REG_2, 0),
5007f1a8b8e3SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_trace_printk),
50085722569bSGianluca Borello 			BPF_EXIT_INSN(),
50095722569bSGianluca Borello 		},
50105722569bSGianluca Borello 		.fixup_map2 = { 3 },
50115722569bSGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=0 size=0",
50125722569bSGianluca Borello 		.result = REJECT,
50135722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
50145722569bSGianluca Borello 	},
50155722569bSGianluca Borello 	{
50165722569bSGianluca Borello 		"helper access to map: out-of-bound range",
50175722569bSGianluca Borello 		.insns = {
50185722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
50195722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
50205722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
50215722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
50225722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
50235722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
50245722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
50255722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
50265722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
50275722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
50285722569bSGianluca Borello 			BPF_EXIT_INSN(),
50295722569bSGianluca Borello 		},
50305722569bSGianluca Borello 		.fixup_map2 = { 3 },
50315722569bSGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=0 size=56",
50325722569bSGianluca Borello 		.result = REJECT,
50335722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
50345722569bSGianluca Borello 	},
50355722569bSGianluca Borello 	{
50365722569bSGianluca Borello 		"helper access to map: negative range",
50375722569bSGianluca Borello 		.insns = {
50385722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
50395722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
50405722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
50415722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
50425722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
50435722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
50445722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
50455722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, -8),
50465722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
50475722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
50485722569bSGianluca Borello 			BPF_EXIT_INSN(),
50495722569bSGianluca Borello 		},
50505722569bSGianluca Borello 		.fixup_map2 = { 3 },
5051f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
50525722569bSGianluca Borello 		.result = REJECT,
50535722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
50545722569bSGianluca Borello 	},
50555722569bSGianluca Borello 	{
50565722569bSGianluca Borello 		"helper access to adjusted map (via const imm): full range",
50575722569bSGianluca Borello 		.insns = {
50585722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
50595722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
50605722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
50615722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
50625722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
50635722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
50645722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
50655722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
50665722569bSGianluca Borello 				offsetof(struct test_val, foo)),
50675722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
50685722569bSGianluca Borello 				sizeof(struct test_val) -
50695722569bSGianluca Borello 				offsetof(struct test_val, foo)),
50705722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
50715722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
50725722569bSGianluca Borello 			BPF_EXIT_INSN(),
50735722569bSGianluca Borello 		},
50745722569bSGianluca Borello 		.fixup_map2 = { 3 },
50755722569bSGianluca Borello 		.result = ACCEPT,
50765722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
50775722569bSGianluca Borello 	},
50785722569bSGianluca Borello 	{
50795722569bSGianluca Borello 		"helper access to adjusted map (via const imm): partial range",
50805722569bSGianluca Borello 		.insns = {
50815722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
50825722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
50835722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
50845722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
50855722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
50865722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
50875722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
50885722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
50895722569bSGianluca Borello 				offsetof(struct test_val, foo)),
50905722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 8),
50915722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
50925722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
50935722569bSGianluca Borello 			BPF_EXIT_INSN(),
50945722569bSGianluca Borello 		},
50955722569bSGianluca Borello 		.fixup_map2 = { 3 },
50965722569bSGianluca Borello 		.result = ACCEPT,
50975722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
50985722569bSGianluca Borello 	},
50995722569bSGianluca Borello 	{
51005722569bSGianluca Borello 		"helper access to adjusted map (via const imm): empty range",
51015722569bSGianluca Borello 		.insns = {
51025722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
51035722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
51045722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
51055722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
51065722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5107f1a8b8e3SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
51085722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
51095722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
51105722569bSGianluca Borello 				offsetof(struct test_val, foo)),
5111f1a8b8e3SYonghong Song 			BPF_MOV64_IMM(BPF_REG_2, 0),
5112f1a8b8e3SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_trace_printk),
51135722569bSGianluca Borello 			BPF_EXIT_INSN(),
51145722569bSGianluca Borello 		},
51155722569bSGianluca Borello 		.fixup_map2 = { 3 },
5116f65b1849SEdward Cree 		.errstr = "invalid access to map value, value_size=48 off=4 size=0",
51175722569bSGianluca Borello 		.result = REJECT,
51185722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
51195722569bSGianluca Borello 	},
51205722569bSGianluca Borello 	{
51215722569bSGianluca Borello 		"helper access to adjusted map (via const imm): out-of-bound range",
51225722569bSGianluca Borello 		.insns = {
51235722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
51245722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
51255722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
51265722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
51275722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
51285722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
51295722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
51305722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
51315722569bSGianluca Borello 				offsetof(struct test_val, foo)),
51325722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
51335722569bSGianluca Borello 				sizeof(struct test_val) -
51345722569bSGianluca Borello 				offsetof(struct test_val, foo) + 8),
51355722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
51365722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
51375722569bSGianluca Borello 			BPF_EXIT_INSN(),
51385722569bSGianluca Borello 		},
51395722569bSGianluca Borello 		.fixup_map2 = { 3 },
51405722569bSGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=4 size=52",
51415722569bSGianluca Borello 		.result = REJECT,
51425722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
51435722569bSGianluca Borello 	},
51445722569bSGianluca Borello 	{
51455722569bSGianluca Borello 		"helper access to adjusted map (via const imm): negative range (> adjustment)",
51465722569bSGianluca Borello 		.insns = {
51475722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
51485722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
51495722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
51505722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
51515722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
51525722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
51535722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
51545722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
51555722569bSGianluca Borello 				offsetof(struct test_val, foo)),
51565722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, -8),
51575722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
51585722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
51595722569bSGianluca Borello 			BPF_EXIT_INSN(),
51605722569bSGianluca Borello 		},
51615722569bSGianluca Borello 		.fixup_map2 = { 3 },
5162f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
51635722569bSGianluca Borello 		.result = REJECT,
51645722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
51655722569bSGianluca Borello 	},
51665722569bSGianluca Borello 	{
51675722569bSGianluca Borello 		"helper access to adjusted map (via const imm): negative range (< adjustment)",
51685722569bSGianluca Borello 		.insns = {
51695722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
51705722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
51715722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
51725722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
51735722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
51745722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
51755722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
51765722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
51775722569bSGianluca Borello 				offsetof(struct test_val, foo)),
51785722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, -1),
51795722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
51805722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
51815722569bSGianluca Borello 			BPF_EXIT_INSN(),
51825722569bSGianluca Borello 		},
51835722569bSGianluca Borello 		.fixup_map2 = { 3 },
5184f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
51855722569bSGianluca Borello 		.result = REJECT,
51865722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
51875722569bSGianluca Borello 	},
51885722569bSGianluca Borello 	{
51895722569bSGianluca Borello 		"helper access to adjusted map (via const reg): full range",
51905722569bSGianluca Borello 		.insns = {
51915722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
51925722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
51935722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
51945722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
51955722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
51965722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
51975722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
51985722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3,
51995722569bSGianluca Borello 				offsetof(struct test_val, foo)),
52005722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
52015722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
52025722569bSGianluca Borello 				sizeof(struct test_val) -
52035722569bSGianluca Borello 				offsetof(struct test_val, foo)),
52045722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
52055722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
52065722569bSGianluca Borello 			BPF_EXIT_INSN(),
52075722569bSGianluca Borello 		},
52085722569bSGianluca Borello 		.fixup_map2 = { 3 },
52095722569bSGianluca Borello 		.result = ACCEPT,
52105722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
52115722569bSGianluca Borello 	},
52125722569bSGianluca Borello 	{
52135722569bSGianluca Borello 		"helper access to adjusted map (via const reg): partial range",
52145722569bSGianluca Borello 		.insns = {
52155722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
52165722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
52175722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
52185722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
52195722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
52205722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
52215722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
52225722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3,
52235722569bSGianluca Borello 				offsetof(struct test_val, foo)),
52245722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
52255722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 8),
52265722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
52275722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
52285722569bSGianluca Borello 			BPF_EXIT_INSN(),
52295722569bSGianluca Borello 		},
52305722569bSGianluca Borello 		.fixup_map2 = { 3 },
52315722569bSGianluca Borello 		.result = ACCEPT,
52325722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
52335722569bSGianluca Borello 	},
52345722569bSGianluca Borello 	{
52355722569bSGianluca Borello 		"helper access to adjusted map (via const reg): empty range",
52365722569bSGianluca Borello 		.insns = {
52375722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
52385722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
52395722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
52405722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
52415722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5242f1a8b8e3SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
52435722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
52445722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
52455722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5246f1a8b8e3SYonghong Song 			BPF_MOV64_IMM(BPF_REG_2, 0),
5247f1a8b8e3SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_trace_printk),
52485722569bSGianluca Borello 			BPF_EXIT_INSN(),
52495722569bSGianluca Borello 		},
52505722569bSGianluca Borello 		.fixup_map2 = { 3 },
5251f1a8b8e3SYonghong Song 		.errstr = "R1 min value is outside of the array range",
52525722569bSGianluca Borello 		.result = REJECT,
52535722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
52545722569bSGianluca Borello 	},
52555722569bSGianluca Borello 	{
52565722569bSGianluca Borello 		"helper access to adjusted map (via const reg): out-of-bound range",
52575722569bSGianluca Borello 		.insns = {
52585722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
52595722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
52605722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
52615722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
52625722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
52635722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
52645722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
52655722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3,
52665722569bSGianluca Borello 				offsetof(struct test_val, foo)),
52675722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
52685722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
52695722569bSGianluca Borello 				sizeof(struct test_val) -
52705722569bSGianluca Borello 				offsetof(struct test_val, foo) + 8),
52715722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
52725722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
52735722569bSGianluca Borello 			BPF_EXIT_INSN(),
52745722569bSGianluca Borello 		},
52755722569bSGianluca Borello 		.fixup_map2 = { 3 },
52765722569bSGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=4 size=52",
52775722569bSGianluca Borello 		.result = REJECT,
52785722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
52795722569bSGianluca Borello 	},
52805722569bSGianluca Borello 	{
52815722569bSGianluca Borello 		"helper access to adjusted map (via const reg): negative range (> adjustment)",
52825722569bSGianluca Borello 		.insns = {
52835722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
52845722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
52855722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
52865722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
52875722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
52885722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
52895722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
52905722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3,
52915722569bSGianluca Borello 				offsetof(struct test_val, foo)),
52925722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
52935722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, -8),
52945722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
52955722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
52965722569bSGianluca Borello 			BPF_EXIT_INSN(),
52975722569bSGianluca Borello 		},
52985722569bSGianluca Borello 		.fixup_map2 = { 3 },
5299f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
53005722569bSGianluca Borello 		.result = REJECT,
53015722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
53025722569bSGianluca Borello 	},
53035722569bSGianluca Borello 	{
53045722569bSGianluca Borello 		"helper access to adjusted map (via const reg): negative range (< adjustment)",
53055722569bSGianluca Borello 		.insns = {
53065722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
53075722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
53085722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
53095722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
53105722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
53115722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
53125722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
53135722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3,
53145722569bSGianluca Borello 				offsetof(struct test_val, foo)),
53155722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
53165722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, -1),
53175722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
53185722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
53195722569bSGianluca Borello 			BPF_EXIT_INSN(),
53205722569bSGianluca Borello 		},
53215722569bSGianluca Borello 		.fixup_map2 = { 3 },
5322f65b1849SEdward Cree 		.errstr = "R2 min value is negative",
53235722569bSGianluca Borello 		.result = REJECT,
53245722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
53255722569bSGianluca Borello 	},
53265722569bSGianluca Borello 	{
53275722569bSGianluca Borello 		"helper access to adjusted map (via variable): full range",
53285722569bSGianluca Borello 		.insns = {
53295722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
53305722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
53315722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
53325722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
53335722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
53345722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
53355722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
53365722569bSGianluca Borello 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
53375722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
53385722569bSGianluca Borello 				offsetof(struct test_val, foo), 4),
53395722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
53405722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
53415722569bSGianluca Borello 				sizeof(struct test_val) -
53425722569bSGianluca Borello 				offsetof(struct test_val, foo)),
53435722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
53445722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
53455722569bSGianluca Borello 			BPF_EXIT_INSN(),
53465722569bSGianluca Borello 		},
53475722569bSGianluca Borello 		.fixup_map2 = { 3 },
53485722569bSGianluca Borello 		.result = ACCEPT,
53495722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
53505722569bSGianluca Borello 	},
53515722569bSGianluca Borello 	{
53525722569bSGianluca Borello 		"helper access to adjusted map (via variable): partial range",
53535722569bSGianluca Borello 		.insns = {
53545722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
53555722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
53565722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
53575722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
53585722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
53595722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
53605722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
53615722569bSGianluca Borello 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
53625722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
53635722569bSGianluca Borello 				offsetof(struct test_val, foo), 4),
53645722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
53655722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 8),
53665722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
53675722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
53685722569bSGianluca Borello 			BPF_EXIT_INSN(),
53695722569bSGianluca Borello 		},
53705722569bSGianluca Borello 		.fixup_map2 = { 3 },
53715722569bSGianluca Borello 		.result = ACCEPT,
53725722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
53735722569bSGianluca Borello 	},
53745722569bSGianluca Borello 	{
53755722569bSGianluca Borello 		"helper access to adjusted map (via variable): empty range",
53765722569bSGianluca Borello 		.insns = {
53775722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
53785722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
53795722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
53805722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
53815722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5382f1a8b8e3SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
53835722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
53845722569bSGianluca Borello 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
53855722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
5386f1a8b8e3SYonghong Song 				offsetof(struct test_val, foo), 3),
53875722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5388f1a8b8e3SYonghong Song 			BPF_MOV64_IMM(BPF_REG_2, 0),
5389f1a8b8e3SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_trace_printk),
53905722569bSGianluca Borello 			BPF_EXIT_INSN(),
53915722569bSGianluca Borello 		},
53925722569bSGianluca Borello 		.fixup_map2 = { 3 },
5393f1a8b8e3SYonghong Song 		.errstr = "R1 min value is outside of the array range",
53945722569bSGianluca Borello 		.result = REJECT,
53955722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
53965722569bSGianluca Borello 	},
53975722569bSGianluca Borello 	{
53985722569bSGianluca Borello 		"helper access to adjusted map (via variable): no max check",
53995722569bSGianluca Borello 		.insns = {
54005722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
54015722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
54025722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
54035722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
54045722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
54055722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
54065722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
54075722569bSGianluca Borello 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
54085722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
5409f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_2, 1),
54105722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
54115722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
54125722569bSGianluca Borello 			BPF_EXIT_INSN(),
54135722569bSGianluca Borello 		},
54145722569bSGianluca Borello 		.fixup_map2 = { 3 },
5415f65b1849SEdward Cree 		.errstr = "R1 unbounded memory access",
54165722569bSGianluca Borello 		.result = REJECT,
54175722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
54185722569bSGianluca Borello 	},
54195722569bSGianluca Borello 	{
54205722569bSGianluca Borello 		"helper access to adjusted map (via variable): wrong max check",
54215722569bSGianluca Borello 		.insns = {
54225722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
54235722569bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
54245722569bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
54255722569bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
54265722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
54275722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
54285722569bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
54295722569bSGianluca Borello 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
54305722569bSGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
54315722569bSGianluca Borello 				offsetof(struct test_val, foo), 4),
54325722569bSGianluca Borello 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
54335722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2,
54345722569bSGianluca Borello 				sizeof(struct test_val) -
54355722569bSGianluca Borello 				offsetof(struct test_val, foo) + 1),
54365722569bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
54375722569bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
54385722569bSGianluca Borello 			BPF_EXIT_INSN(),
54395722569bSGianluca Borello 		},
54405722569bSGianluca Borello 		.fixup_map2 = { 3 },
54415722569bSGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=4 size=45",
54425722569bSGianluca Borello 		.result = REJECT,
54435722569bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
54445722569bSGianluca Borello 	},
5445f0318d01SGianluca Borello 	{
544631e482bfSDaniel Borkmann 		"helper access to map: bounds check using <, good access",
544731e482bfSDaniel Borkmann 		.insns = {
544831e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
544931e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
545031e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
545131e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
545231e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
545331e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
545431e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
545531e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
545631e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 2),
545731e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
545831e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
545931e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
546031e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
546131e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
546231e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
546331e482bfSDaniel Borkmann 		},
546431e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
546531e482bfSDaniel Borkmann 		.result = ACCEPT,
546631e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
546731e482bfSDaniel Borkmann 	},
546831e482bfSDaniel Borkmann 	{
546931e482bfSDaniel Borkmann 		"helper access to map: bounds check using <, bad access",
547031e482bfSDaniel Borkmann 		.insns = {
547131e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
547231e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
547331e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
547431e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
547531e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
547631e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
547731e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
547831e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
547931e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JLT, BPF_REG_3, 32, 4),
548031e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
548131e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
548231e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
548331e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
548431e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
548531e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
548631e482bfSDaniel Borkmann 		},
548731e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
548831e482bfSDaniel Borkmann 		.result = REJECT,
548931e482bfSDaniel Borkmann 		.errstr = "R1 unbounded memory access",
549031e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
549131e482bfSDaniel Borkmann 	},
549231e482bfSDaniel Borkmann 	{
549331e482bfSDaniel Borkmann 		"helper access to map: bounds check using <=, good access",
549431e482bfSDaniel Borkmann 		.insns = {
549531e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
549631e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
549731e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
549831e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
549931e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
550031e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
550131e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
550231e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
550331e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 2),
550431e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
550531e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
550631e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
550731e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
550831e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
550931e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
551031e482bfSDaniel Borkmann 		},
551131e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
551231e482bfSDaniel Borkmann 		.result = ACCEPT,
551331e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
551431e482bfSDaniel Borkmann 	},
551531e482bfSDaniel Borkmann 	{
551631e482bfSDaniel Borkmann 		"helper access to map: bounds check using <=, bad access",
551731e482bfSDaniel Borkmann 		.insns = {
551831e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
551931e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
552031e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
552131e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
552231e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
552331e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
552431e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
552531e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
552631e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 32, 4),
552731e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
552831e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
552931e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
553031e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
553131e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
553231e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
553331e482bfSDaniel Borkmann 		},
553431e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
553531e482bfSDaniel Borkmann 		.result = REJECT,
553631e482bfSDaniel Borkmann 		.errstr = "R1 unbounded memory access",
553731e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
553831e482bfSDaniel Borkmann 	},
553931e482bfSDaniel Borkmann 	{
554031e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<, good access",
554131e482bfSDaniel Borkmann 		.insns = {
554231e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
554331e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
554431e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
554531e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
554631e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
554731e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
554831e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
554931e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
555031e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
555131e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
555231e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
555331e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 0, -3),
555431e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
555531e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
555631e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
555731e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
555831e482bfSDaniel Borkmann 		},
555931e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
556031e482bfSDaniel Borkmann 		.result = ACCEPT,
556131e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
556231e482bfSDaniel Borkmann 	},
556331e482bfSDaniel Borkmann 	{
556431e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<, good access 2",
556531e482bfSDaniel Borkmann 		.insns = {
556631e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
556731e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
556831e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
556931e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
557031e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
557131e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
557231e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
557331e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
557431e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
557531e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
557631e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
557731e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
557831e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
557931e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
558031e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
558131e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
558231e482bfSDaniel Borkmann 		},
558331e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
558431e482bfSDaniel Borkmann 		.result = ACCEPT,
558531e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
558631e482bfSDaniel Borkmann 	},
558731e482bfSDaniel Borkmann 	{
558831e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<, bad access",
558931e482bfSDaniel Borkmann 		.insns = {
559031e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
559131e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
559231e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
559331e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
559431e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
559531e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
559631e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
559731e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
559831e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, 32, 2),
559931e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
560031e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
560131e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLT, BPF_REG_3, -3, -3),
560231e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
560331e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
560431e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
560531e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
560631e482bfSDaniel Borkmann 		},
560731e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
560831e482bfSDaniel Borkmann 		.result = REJECT,
560931e482bfSDaniel Borkmann 		.errstr = "R1 min value is negative",
561031e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
561131e482bfSDaniel Borkmann 	},
561231e482bfSDaniel Borkmann 	{
561331e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<=, good access",
561431e482bfSDaniel Borkmann 		.insns = {
561531e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
561631e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
561731e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
561831e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
561931e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
562031e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
562131e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
562231e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
562331e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
562431e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
562531e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
562631e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0, -3),
562731e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
562831e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
562931e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
563031e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
563131e482bfSDaniel Borkmann 		},
563231e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
563331e482bfSDaniel Borkmann 		.result = ACCEPT,
563431e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
563531e482bfSDaniel Borkmann 	},
563631e482bfSDaniel Borkmann 	{
563731e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<=, good access 2",
563831e482bfSDaniel Borkmann 		.insns = {
563931e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
564031e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
564131e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
564231e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
564331e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
564431e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
564531e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
564631e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
564731e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
564831e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
564931e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
565031e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
565131e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
565231e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
565331e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
565431e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
565531e482bfSDaniel Borkmann 		},
565631e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
565731e482bfSDaniel Borkmann 		.result = ACCEPT,
565831e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
565931e482bfSDaniel Borkmann 	},
566031e482bfSDaniel Borkmann 	{
566131e482bfSDaniel Borkmann 		"helper access to map: bounds check using s<=, bad access",
566231e482bfSDaniel Borkmann 		.insns = {
566331e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
566431e482bfSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
566531e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
566631e482bfSDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
566731e482bfSDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
566831e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
566931e482bfSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
567031e482bfSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
567131e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 32, 2),
567231e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
567331e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
567431e482bfSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, -3, -3),
567531e482bfSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
567631e482bfSDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 0),
567731e482bfSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
567831e482bfSDaniel Borkmann 			BPF_EXIT_INSN(),
567931e482bfSDaniel Borkmann 		},
568031e482bfSDaniel Borkmann 		.fixup_map2 = { 3 },
568131e482bfSDaniel Borkmann 		.result = REJECT,
568231e482bfSDaniel Borkmann 		.errstr = "R1 min value is negative",
568331e482bfSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
568431e482bfSDaniel Borkmann 	},
568531e482bfSDaniel Borkmann 	{
56865f90dd6aSPaul Chaignon 		"map lookup helper access to map",
56875f90dd6aSPaul Chaignon 		.insns = {
56885f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
56895f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
56905f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
56915f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
56925f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
56935f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
56945f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
56955f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
56965f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
56975f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
56985f90dd6aSPaul Chaignon 		},
56995f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 8 },
57005f90dd6aSPaul Chaignon 		.result = ACCEPT,
57015f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57025f90dd6aSPaul Chaignon 	},
57035f90dd6aSPaul Chaignon 	{
57045f90dd6aSPaul Chaignon 		"map update helper access to map",
57055f90dd6aSPaul Chaignon 		.insns = {
57065f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
57075f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57085f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
57095f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57105f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57115f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
57125f90dd6aSPaul Chaignon 			BPF_MOV64_IMM(BPF_REG_4, 0),
57135f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
57145f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
57155f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57165f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
57175f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
57185f90dd6aSPaul Chaignon 		},
57195f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 10 },
57205f90dd6aSPaul Chaignon 		.result = ACCEPT,
57215f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57225f90dd6aSPaul Chaignon 	},
57235f90dd6aSPaul Chaignon 	{
57245f90dd6aSPaul Chaignon 		"map update helper access to map: wrong size",
57255f90dd6aSPaul Chaignon 		.insns = {
57265f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
57275f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57285f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
57295f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57305f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57315f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
57325f90dd6aSPaul Chaignon 			BPF_MOV64_IMM(BPF_REG_4, 0),
57335f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
57345f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
57355f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57365f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_update_elem),
57375f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
57385f90dd6aSPaul Chaignon 		},
57395f90dd6aSPaul Chaignon 		.fixup_map1 = { 3 },
57405f90dd6aSPaul Chaignon 		.fixup_map3 = { 10 },
57415f90dd6aSPaul Chaignon 		.result = REJECT,
57425f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=8 off=0 size=16",
57435f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57445f90dd6aSPaul Chaignon 	},
57455f90dd6aSPaul Chaignon 	{
57465f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const imm)",
57475f90dd6aSPaul Chaignon 		.insns = {
57485f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
57495f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57505f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
57515f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57525f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57535f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
57545f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
57555f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
57565f90dd6aSPaul Chaignon 				      offsetof(struct other_val, bar)),
57575f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57585f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57595f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
57605f90dd6aSPaul Chaignon 		},
57615f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 9 },
57625f90dd6aSPaul Chaignon 		.result = ACCEPT,
57635f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57645f90dd6aSPaul Chaignon 	},
57655f90dd6aSPaul Chaignon 	{
57665f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const imm): out-of-bound 1",
57675f90dd6aSPaul Chaignon 		.insns = {
57685f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
57695f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57705f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
57715f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57725f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57735f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
57745f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
57755f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2,
57765f90dd6aSPaul Chaignon 				      sizeof(struct other_val) - 4),
57775f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57785f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57795f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
57805f90dd6aSPaul Chaignon 		},
57815f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 9 },
57825f90dd6aSPaul Chaignon 		.result = REJECT,
57835f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=16 off=12 size=8",
57845f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57855f90dd6aSPaul Chaignon 	},
57865f90dd6aSPaul Chaignon 	{
57875f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const imm): out-of-bound 2",
57885f90dd6aSPaul Chaignon 		.insns = {
57895f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
57905f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57915f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
57925f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57935f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57945f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
57955f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
57965f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
57975f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
57985f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
57995f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
58005f90dd6aSPaul Chaignon 		},
58015f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 9 },
58025f90dd6aSPaul Chaignon 		.result = REJECT,
58035f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=16 off=-4 size=8",
58045f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58055f90dd6aSPaul Chaignon 	},
58065f90dd6aSPaul Chaignon 	{
58075f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const reg)",
58085f90dd6aSPaul Chaignon 		.insns = {
58095f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
58105f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
58115f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
58125f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58135f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58145f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
58155f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
58165f90dd6aSPaul Chaignon 			BPF_MOV64_IMM(BPF_REG_3,
58175f90dd6aSPaul Chaignon 				      offsetof(struct other_val, bar)),
58185f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
58195f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58205f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58215f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
58225f90dd6aSPaul Chaignon 		},
58235f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 10 },
58245f90dd6aSPaul Chaignon 		.result = ACCEPT,
58255f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58265f90dd6aSPaul Chaignon 	},
58275f90dd6aSPaul Chaignon 	{
58285f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const reg): out-of-bound 1",
58295f90dd6aSPaul Chaignon 		.insns = {
58305f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
58315f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
58325f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
58335f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58345f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58355f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
58365f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
58375f90dd6aSPaul Chaignon 			BPF_MOV64_IMM(BPF_REG_3,
58385f90dd6aSPaul Chaignon 				      sizeof(struct other_val) - 4),
58395f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
58405f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58415f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58425f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
58435f90dd6aSPaul Chaignon 		},
58445f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 10 },
58455f90dd6aSPaul Chaignon 		.result = REJECT,
58465f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=16 off=12 size=8",
58475f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58485f90dd6aSPaul Chaignon 	},
58495f90dd6aSPaul Chaignon 	{
58505f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via const reg): out-of-bound 2",
58515f90dd6aSPaul Chaignon 		.insns = {
58525f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
58535f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
58545f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
58555f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58565f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58575f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
58585f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
58595f90dd6aSPaul Chaignon 			BPF_MOV64_IMM(BPF_REG_3, -4),
58605f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
58615f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58625f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58635f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
58645f90dd6aSPaul Chaignon 		},
58655f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 10 },
58665f90dd6aSPaul Chaignon 		.result = REJECT,
58675f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=16 off=-4 size=8",
58685f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58695f90dd6aSPaul Chaignon 	},
58705f90dd6aSPaul Chaignon 	{
58715f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via variable)",
58725f90dd6aSPaul Chaignon 		.insns = {
58735f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
58745f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
58755f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
58765f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58775f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58785f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
58795f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
58805f90dd6aSPaul Chaignon 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
58815f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
58825f90dd6aSPaul Chaignon 				    offsetof(struct other_val, bar), 4),
58835f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
58845f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58855f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
58865f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
58875f90dd6aSPaul Chaignon 		},
58885f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 11 },
58895f90dd6aSPaul Chaignon 		.result = ACCEPT,
58905f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58915f90dd6aSPaul Chaignon 	},
58925f90dd6aSPaul Chaignon 	{
58935f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via variable): no max check",
58945f90dd6aSPaul Chaignon 		.insns = {
58955f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
58965f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
58975f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
58985f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
58995f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
59005f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
59015f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
59025f90dd6aSPaul Chaignon 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
59035f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
59045f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
59055f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
59065f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
59075f90dd6aSPaul Chaignon 		},
59085f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 10 },
59095f90dd6aSPaul Chaignon 		.result = REJECT,
59105f90dd6aSPaul Chaignon 		.errstr = "R2 unbounded memory access, make sure to bounds check any array access into a map",
59115f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
59125f90dd6aSPaul Chaignon 	},
59135f90dd6aSPaul Chaignon 	{
59145f90dd6aSPaul Chaignon 		"map helper access to adjusted map (via variable): wrong max check",
59155f90dd6aSPaul Chaignon 		.insns = {
59165f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
59175f90dd6aSPaul Chaignon 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
59185f90dd6aSPaul Chaignon 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
59195f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
59205f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
59215f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
59225f90dd6aSPaul Chaignon 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
59235f90dd6aSPaul Chaignon 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
59245f90dd6aSPaul Chaignon 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
59255f90dd6aSPaul Chaignon 				    offsetof(struct other_val, bar) + 1, 4),
59265f90dd6aSPaul Chaignon 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
59275f90dd6aSPaul Chaignon 			BPF_LD_MAP_FD(BPF_REG_1, 0),
59285f90dd6aSPaul Chaignon 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
59295f90dd6aSPaul Chaignon 			BPF_EXIT_INSN(),
59305f90dd6aSPaul Chaignon 		},
59315f90dd6aSPaul Chaignon 		.fixup_map3 = { 3, 11 },
59325f90dd6aSPaul Chaignon 		.result = REJECT,
59335f90dd6aSPaul Chaignon 		.errstr = "invalid access to map value, value_size=16 off=9 size=8",
59345f90dd6aSPaul Chaignon 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
59355f90dd6aSPaul Chaignon 	},
59365f90dd6aSPaul Chaignon 	{
5937f0318d01SGianluca Borello 		"map element value is preserved across register spilling",
5938f0318d01SGianluca Borello 		.insns = {
5939f0318d01SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
5940f0318d01SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
5941f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
5942f0318d01SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
5943f0318d01SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
5944f0318d01SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
5945f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
5946f0318d01SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5947f0318d01SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
5948f0318d01SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
5949f0318d01SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
5950f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
5951f0318d01SGianluca Borello 			BPF_EXIT_INSN(),
5952f0318d01SGianluca Borello 		},
5953f0318d01SGianluca Borello 		.fixup_map2 = { 3 },
5954f0318d01SGianluca Borello 		.errstr_unpriv = "R0 leaks addr",
5955f0318d01SGianluca Borello 		.result = ACCEPT,
5956f0318d01SGianluca Borello 		.result_unpriv = REJECT,
5957f0318d01SGianluca Borello 	},
5958f0318d01SGianluca Borello 	{
595902ea80b1SDaniel Borkmann 		"map element value or null is marked on register spilling",
596002ea80b1SDaniel Borkmann 		.insns = {
596102ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
596202ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
596302ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
596402ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
596502ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
596602ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
596702ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
596802ea80b1SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
596902ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
597002ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
597102ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
597202ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
597302ea80b1SDaniel Borkmann 		},
597402ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
597502ea80b1SDaniel Borkmann 		.errstr_unpriv = "R0 leaks addr",
597602ea80b1SDaniel Borkmann 		.result = ACCEPT,
597702ea80b1SDaniel Borkmann 		.result_unpriv = REJECT,
597802ea80b1SDaniel Borkmann 	},
597902ea80b1SDaniel Borkmann 	{
598002ea80b1SDaniel Borkmann 		"map element value store of cleared call register",
598102ea80b1SDaniel Borkmann 		.insns = {
598202ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
598302ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
598402ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
598502ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
598602ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
598702ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
598802ea80b1SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
598902ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
599002ea80b1SDaniel Borkmann 		},
599102ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
599202ea80b1SDaniel Borkmann 		.errstr_unpriv = "R1 !read_ok",
599302ea80b1SDaniel Borkmann 		.errstr = "R1 !read_ok",
599402ea80b1SDaniel Borkmann 		.result = REJECT,
599502ea80b1SDaniel Borkmann 		.result_unpriv = REJECT,
599602ea80b1SDaniel Borkmann 	},
599702ea80b1SDaniel Borkmann 	{
599802ea80b1SDaniel Borkmann 		"map element value with unaligned store",
599902ea80b1SDaniel Borkmann 		.insns = {
600002ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
600102ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
600202ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
600302ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
600402ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
600502ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
600602ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
600702ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
600802ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
600902ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
601002ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
601102ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
601202ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
601302ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
601402ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
601502ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
601602ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
601702ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
601802ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
601902ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
602002ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
602102ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
602202ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
602302ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
602402ea80b1SDaniel Borkmann 		},
602502ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
6026f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
602702ea80b1SDaniel Borkmann 		.result = ACCEPT,
602802ea80b1SDaniel Borkmann 		.result_unpriv = REJECT,
602902ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
603002ea80b1SDaniel Borkmann 	},
603102ea80b1SDaniel Borkmann 	{
603202ea80b1SDaniel Borkmann 		"map element value with unaligned load",
603302ea80b1SDaniel Borkmann 		.insns = {
603402ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
603502ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
603602ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
603702ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
603802ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
603902ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
604002ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
604102ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
604202ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
604302ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
604402ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
604502ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
604602ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
604702ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
604802ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
604902ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
605002ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
605102ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
605202ea80b1SDaniel Borkmann 		},
605302ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
6054f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
605502ea80b1SDaniel Borkmann 		.result = ACCEPT,
605602ea80b1SDaniel Borkmann 		.result_unpriv = REJECT,
605702ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
605802ea80b1SDaniel Borkmann 	},
605902ea80b1SDaniel Borkmann 	{
606002ea80b1SDaniel Borkmann 		"map element value illegal alu op, 1",
606102ea80b1SDaniel Borkmann 		.insns = {
606202ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
606302ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
606402ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
606502ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
606602ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
606702ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
606802ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
606902ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
607002ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
607102ea80b1SDaniel Borkmann 		},
607202ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
607382abbf8dSAlexei Starovoitov 		.errstr = "R0 bitwise operator &= on pointer",
607402ea80b1SDaniel Borkmann 		.result = REJECT,
607502ea80b1SDaniel Borkmann 	},
607602ea80b1SDaniel Borkmann 	{
607702ea80b1SDaniel Borkmann 		"map element value illegal alu op, 2",
607802ea80b1SDaniel Borkmann 		.insns = {
607902ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
608002ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
608102ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
608202ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
608302ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
608402ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
608502ea80b1SDaniel Borkmann 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
608602ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
608702ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
608802ea80b1SDaniel Borkmann 		},
608902ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
609082abbf8dSAlexei Starovoitov 		.errstr = "R0 32-bit pointer arithmetic prohibited",
609102ea80b1SDaniel Borkmann 		.result = REJECT,
609202ea80b1SDaniel Borkmann 	},
609302ea80b1SDaniel Borkmann 	{
609402ea80b1SDaniel Borkmann 		"map element value illegal alu op, 3",
609502ea80b1SDaniel Borkmann 		.insns = {
609602ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
609702ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
609802ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
609902ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
610002ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
610102ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
610202ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
610302ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
610402ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
610502ea80b1SDaniel Borkmann 		},
610602ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
610782abbf8dSAlexei Starovoitov 		.errstr = "R0 pointer arithmetic with /= operator",
610802ea80b1SDaniel Borkmann 		.result = REJECT,
610902ea80b1SDaniel Borkmann 	},
611002ea80b1SDaniel Borkmann 	{
611102ea80b1SDaniel Borkmann 		"map element value illegal alu op, 4",
611202ea80b1SDaniel Borkmann 		.insns = {
611302ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
611402ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
611502ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
611602ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
611702ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
611802ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
611902ea80b1SDaniel Borkmann 			BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
612002ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
612102ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
612202ea80b1SDaniel Borkmann 		},
612302ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
612402ea80b1SDaniel Borkmann 		.errstr_unpriv = "R0 pointer arithmetic prohibited",
612502ea80b1SDaniel Borkmann 		.errstr = "invalid mem access 'inv'",
612602ea80b1SDaniel Borkmann 		.result = REJECT,
612702ea80b1SDaniel Borkmann 		.result_unpriv = REJECT,
612802ea80b1SDaniel Borkmann 	},
612902ea80b1SDaniel Borkmann 	{
613002ea80b1SDaniel Borkmann 		"map element value illegal alu op, 5",
613102ea80b1SDaniel Borkmann 		.insns = {
613202ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
613302ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
613402ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
613502ea80b1SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
613602ea80b1SDaniel Borkmann 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
613702ea80b1SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
613802ea80b1SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 4096),
613902ea80b1SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
614002ea80b1SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
614102ea80b1SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
614202ea80b1SDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
614302ea80b1SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
614402ea80b1SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
614502ea80b1SDaniel Borkmann 			BPF_EXIT_INSN(),
614602ea80b1SDaniel Borkmann 		},
614702ea80b1SDaniel Borkmann 		.fixup_map2 = { 3 },
614802ea80b1SDaniel Borkmann 		.errstr = "R0 invalid mem access 'inv'",
614902ea80b1SDaniel Borkmann 		.result = REJECT,
615002ea80b1SDaniel Borkmann 	},
615102ea80b1SDaniel Borkmann 	{
615202ea80b1SDaniel Borkmann 		"map element value is preserved across register spilling",
6153f0318d01SGianluca Borello 		.insns = {
6154f0318d01SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6155f0318d01SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6156f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
6157f0318d01SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6158f0318d01SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6159f0318d01SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6160f0318d01SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
6161f0318d01SGianluca Borello 				offsetof(struct test_val, foo)),
6162f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
6163f0318d01SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6164f0318d01SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
6165f0318d01SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
6166f0318d01SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
6167f0318d01SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
6168f0318d01SGianluca Borello 			BPF_EXIT_INSN(),
6169f0318d01SGianluca Borello 		},
6170f0318d01SGianluca Borello 		.fixup_map2 = { 3 },
6171f65b1849SEdward Cree 		.errstr_unpriv = "R0 leaks addr",
6172f0318d01SGianluca Borello 		.result = ACCEPT,
6173f0318d01SGianluca Borello 		.result_unpriv = REJECT,
617402ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6175f0318d01SGianluca Borello 	},
617606c1c049SGianluca Borello 	{
617706c1c049SGianluca Borello 		"helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
617806c1c049SGianluca Borello 		.insns = {
617906c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
618006c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
618106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
618206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
618306c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
618406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
618506c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
618606c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
618706c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
618806c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
618906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
619006c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
619106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
619206c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
619306c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
619406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
619506c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
619606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
619706c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
619806c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
619906c1c049SGianluca Borello 			BPF_EXIT_INSN(),
620006c1c049SGianluca Borello 		},
620106c1c049SGianluca Borello 		.result = ACCEPT,
620206c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
620306c1c049SGianluca Borello 	},
620406c1c049SGianluca Borello 	{
620506c1c049SGianluca Borello 		"helper access to variable memory: stack, bitwise AND, zero included",
620606c1c049SGianluca Borello 		.insns = {
620706c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
620806c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
620906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
621006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
621106c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
621206c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
621306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
621406c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
621506c1c049SGianluca Borello 			BPF_EXIT_INSN(),
621606c1c049SGianluca Borello 		},
6217b6ff6391SYonghong Song 		.errstr = "invalid indirect read from stack off -64+0 size 64",
621806c1c049SGianluca Borello 		.result = REJECT,
621906c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
622006c1c049SGianluca Borello 	},
622106c1c049SGianluca Borello 	{
622206c1c049SGianluca Borello 		"helper access to variable memory: stack, bitwise AND + JMP, wrong max",
622306c1c049SGianluca Borello 		.insns = {
622406c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
622506c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
622606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
622706c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
622806c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
622906c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
623006c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
623106c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
623206c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
623306c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
623406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
623506c1c049SGianluca Borello 			BPF_EXIT_INSN(),
623606c1c049SGianluca Borello 		},
623706c1c049SGianluca Borello 		.errstr = "invalid stack type R1 off=-64 access_size=65",
623806c1c049SGianluca Borello 		.result = REJECT,
623906c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
624006c1c049SGianluca Borello 	},
624106c1c049SGianluca Borello 	{
624206c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP, correct bounds",
624306c1c049SGianluca Borello 		.insns = {
624406c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
624506c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
624606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
624706c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
624806c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
624906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
625006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
625106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
625206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
625306c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
625406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
625506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
625606c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
625706c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
625806c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
625906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
626006c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
626106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
626206c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
626306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
626406c1c049SGianluca Borello 			BPF_EXIT_INSN(),
626506c1c049SGianluca Borello 		},
626606c1c049SGianluca Borello 		.result = ACCEPT,
626706c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
626806c1c049SGianluca Borello 	},
626906c1c049SGianluca Borello 	{
627006c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP (signed), correct bounds",
627106c1c049SGianluca Borello 		.insns = {
627206c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
627306c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
627406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
627506c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
627606c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
627706c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
627806c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
627906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
628006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
628106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
628206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
628306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
628406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
628506c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
628606c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
628706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
628806c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
628906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
629006c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
629106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
629206c1c049SGianluca Borello 			BPF_EXIT_INSN(),
629306c1c049SGianluca Borello 		},
629406c1c049SGianluca Borello 		.result = ACCEPT,
629506c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
629606c1c049SGianluca Borello 	},
629706c1c049SGianluca Borello 	{
629806c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP, bounds + offset",
629906c1c049SGianluca Borello 		.insns = {
630006c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
630106c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
630206c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
630306c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
630406c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
630506c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
630606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
630706c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
630806c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
630906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
631006c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
631106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
631206c1c049SGianluca Borello 			BPF_EXIT_INSN(),
631306c1c049SGianluca Borello 		},
631406c1c049SGianluca Borello 		.errstr = "invalid stack type R1 off=-64 access_size=65",
631506c1c049SGianluca Borello 		.result = REJECT,
631606c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
631706c1c049SGianluca Borello 	},
631806c1c049SGianluca Borello 	{
631906c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP, wrong max",
632006c1c049SGianluca Borello 		.insns = {
632106c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
632206c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
632306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
632406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
632506c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
632606c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
632706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
632806c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
632906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
633006c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
633106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
633206c1c049SGianluca Borello 			BPF_EXIT_INSN(),
633306c1c049SGianluca Borello 		},
633406c1c049SGianluca Borello 		.errstr = "invalid stack type R1 off=-64 access_size=65",
633506c1c049SGianluca Borello 		.result = REJECT,
633606c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
633706c1c049SGianluca Borello 	},
633806c1c049SGianluca Borello 	{
633906c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP, no max check",
634006c1c049SGianluca Borello 		.insns = {
634106c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
634206c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
634306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
634406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
634506c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
634606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
634706c1c049SGianluca Borello 			BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
634806c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
634906c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
635006c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
635106c1c049SGianluca Borello 			BPF_EXIT_INSN(),
635206c1c049SGianluca Borello 		},
6353f65b1849SEdward Cree 		/* because max wasn't checked, signed min is negative */
6354f65b1849SEdward Cree 		.errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
635506c1c049SGianluca Borello 		.result = REJECT,
635606c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
635706c1c049SGianluca Borello 	},
635806c1c049SGianluca Borello 	{
635906c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP, no min check",
636006c1c049SGianluca Borello 		.insns = {
636106c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
636206c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
636306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
636406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
636506c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
636606c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
636706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
636806c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
636906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
637006c1c049SGianluca Borello 			BPF_EXIT_INSN(),
637106c1c049SGianluca Borello 		},
6372b6ff6391SYonghong Song 		.errstr = "invalid indirect read from stack off -64+0 size 64",
637306c1c049SGianluca Borello 		.result = REJECT,
637406c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
637506c1c049SGianluca Borello 	},
637606c1c049SGianluca Borello 	{
637706c1c049SGianluca Borello 		"helper access to variable memory: stack, JMP (signed), no min check",
637806c1c049SGianluca Borello 		.insns = {
637906c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
638006c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
638106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 16),
638206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
638306c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
638406c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
638506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
638606c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
638706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
638806c1c049SGianluca Borello 			BPF_EXIT_INSN(),
638906c1c049SGianluca Borello 		},
639006c1c049SGianluca Borello 		.errstr = "R2 min value is negative",
639106c1c049SGianluca Borello 		.result = REJECT,
639206c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
639306c1c049SGianluca Borello 	},
639406c1c049SGianluca Borello 	{
639506c1c049SGianluca Borello 		"helper access to variable memory: map, JMP, correct bounds",
639606c1c049SGianluca Borello 		.insns = {
639706c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
639806c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
639906c1c049SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
640006c1c049SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
640106c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
640206c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
640306c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
640406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
640506c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
640606c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
640706c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
640806c1c049SGianluca Borello 				sizeof(struct test_val), 4),
640906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
6410a1502132SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
641106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
641206c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
641306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
641406c1c049SGianluca Borello 			BPF_EXIT_INSN(),
641506c1c049SGianluca Borello 		},
641606c1c049SGianluca Borello 		.fixup_map2 = { 3 },
641706c1c049SGianluca Borello 		.result = ACCEPT,
641806c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
641906c1c049SGianluca Borello 	},
642006c1c049SGianluca Borello 	{
642106c1c049SGianluca Borello 		"helper access to variable memory: map, JMP, wrong max",
642206c1c049SGianluca Borello 		.insns = {
642306c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
642406c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
642506c1c049SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
642606c1c049SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
642706c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
642806c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
642906c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
643006c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
643106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
643206c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
643306c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
643406c1c049SGianluca Borello 				sizeof(struct test_val) + 1, 4),
643506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
6436a1502132SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
643706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
643806c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
643906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
644006c1c049SGianluca Borello 			BPF_EXIT_INSN(),
644106c1c049SGianluca Borello 		},
644206c1c049SGianluca Borello 		.fixup_map2 = { 3 },
644306c1c049SGianluca Borello 		.errstr = "invalid access to map value, value_size=48 off=0 size=49",
644406c1c049SGianluca Borello 		.result = REJECT,
644506c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
644606c1c049SGianluca Borello 	},
644706c1c049SGianluca Borello 	{
644806c1c049SGianluca Borello 		"helper access to variable memory: map adjusted, JMP, correct bounds",
644906c1c049SGianluca Borello 		.insns = {
645006c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
645106c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
645206c1c049SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
645306c1c049SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
645406c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
645506c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
645606c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
645706c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
645806c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
645906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
646006c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
646106c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
646206c1c049SGianluca Borello 				sizeof(struct test_val) - 20, 4),
646306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
6464a1502132SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
646506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
646606c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
646706c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
646806c1c049SGianluca Borello 			BPF_EXIT_INSN(),
646906c1c049SGianluca Borello 		},
647006c1c049SGianluca Borello 		.fixup_map2 = { 3 },
647106c1c049SGianluca Borello 		.result = ACCEPT,
647206c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
647306c1c049SGianluca Borello 	},
647406c1c049SGianluca Borello 	{
647506c1c049SGianluca Borello 		"helper access to variable memory: map adjusted, JMP, wrong max",
647606c1c049SGianluca Borello 		.insns = {
647706c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
647806c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
647906c1c049SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
648006c1c049SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
648106c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
648206c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
648306c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
648406c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
648506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
648606c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
648706c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
648806c1c049SGianluca Borello 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
648906c1c049SGianluca Borello 				sizeof(struct test_val) - 19, 4),
649006c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
6491a1502132SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
649206c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
649306c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
649406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
649506c1c049SGianluca Borello 			BPF_EXIT_INSN(),
649606c1c049SGianluca Borello 		},
649706c1c049SGianluca Borello 		.fixup_map2 = { 3 },
649806c1c049SGianluca Borello 		.errstr = "R1 min value is outside of the array range",
649906c1c049SGianluca Borello 		.result = REJECT,
650006c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
650106c1c049SGianluca Borello 	},
650206c1c049SGianluca Borello 	{
6503db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
6504f65b1849SEdward Cree 		.insns = {
6505f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_1, 0),
6506f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_2, 0),
6507f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_3, 0),
6508f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_4, 0),
6509f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_5, 0),
6510f65b1849SEdward Cree 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6511f65b1849SEdward Cree 			BPF_EXIT_INSN(),
6512f65b1849SEdward Cree 		},
6513f65b1849SEdward Cree 		.result = ACCEPT,
6514f65b1849SEdward Cree 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6515f65b1849SEdward Cree 	},
6516f65b1849SEdward Cree 	{
6517db1ac496SGianluca Borello 		"helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
651806c1c049SGianluca Borello 		.insns = {
651906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_1, 0),
6520d98588ceSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_2, 1),
65213fadc801SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
65223fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
652306c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
652406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
652506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
652606c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_5, 0),
652706c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
652806c1c049SGianluca Borello 			BPF_EXIT_INSN(),
652906c1c049SGianluca Borello 		},
6530f65b1849SEdward Cree 		.errstr = "R1 type=inv expected=fp",
653106c1c049SGianluca Borello 		.result = REJECT,
653206c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
653306c1c049SGianluca Borello 	},
653406c1c049SGianluca Borello 	{
6535db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
653606c1c049SGianluca Borello 		.insns = {
653706c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
653806c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
653906c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 0),
654006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
654106c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
654206c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
654306c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
654406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_5, 0),
654506c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
654606c1c049SGianluca Borello 			BPF_EXIT_INSN(),
654706c1c049SGianluca Borello 		},
6548b6ff6391SYonghong Song 		.result = ACCEPT,
6549b6ff6391SYonghong Song 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6550b6ff6391SYonghong Song 	},
6551b6ff6391SYonghong Song 	{
6552db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
6553b6ff6391SYonghong Song 		.insns = {
6554b6ff6391SYonghong Song 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6555b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6556b6ff6391SYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6557b6ff6391SYonghong Song 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6558b6ff6391SYonghong Song 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6559b6ff6391SYonghong Song 				     BPF_FUNC_map_lookup_elem),
6560b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6561b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6562b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_2, 0),
6563b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_3, 0),
6564b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 0),
6565b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_5, 0),
6566b6ff6391SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6567b6ff6391SYonghong Song 			BPF_EXIT_INSN(),
6568b6ff6391SYonghong Song 		},
6569b6ff6391SYonghong Song 		.fixup_map1 = { 3 },
6570b6ff6391SYonghong Song 		.result = ACCEPT,
6571b6ff6391SYonghong Song 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6572b6ff6391SYonghong Song 	},
6573b6ff6391SYonghong Song 	{
6574db1ac496SGianluca Borello 		"helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
6575b6ff6391SYonghong Song 		.insns = {
6576b6ff6391SYonghong Song 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6577b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6578b6ff6391SYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6579b6ff6391SYonghong Song 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6580b6ff6391SYonghong Song 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6581b6ff6391SYonghong Song 				     BPF_FUNC_map_lookup_elem),
6582b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
6583b6ff6391SYonghong Song 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6584b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
6585b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6586b6ff6391SYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6587b6ff6391SYonghong Song 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
6588b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_3, 0),
6589b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 0),
6590b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_5, 0),
6591b6ff6391SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6592b6ff6391SYonghong Song 			BPF_EXIT_INSN(),
6593b6ff6391SYonghong Song 		},
6594b6ff6391SYonghong Song 		.fixup_map1 = { 3 },
6595b6ff6391SYonghong Song 		.result = ACCEPT,
6596b6ff6391SYonghong Song 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6597b6ff6391SYonghong Song 	},
6598b6ff6391SYonghong Song 	{
6599db1ac496SGianluca Borello 		"helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
6600b6ff6391SYonghong Song 		.insns = {
6601b6ff6391SYonghong Song 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6602b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6603b6ff6391SYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6604b6ff6391SYonghong Song 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6605b6ff6391SYonghong Song 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6606b6ff6391SYonghong Song 				     BPF_FUNC_map_lookup_elem),
6607b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
6608b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6609b6ff6391SYonghong Song 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6610b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6611b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_3, 0),
6612b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 0),
6613b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_5, 0),
6614b6ff6391SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6615b6ff6391SYonghong Song 			BPF_EXIT_INSN(),
6616b6ff6391SYonghong Song 		},
6617b6ff6391SYonghong Song 		.fixup_map1 = { 3 },
6618b6ff6391SYonghong Song 		.result = ACCEPT,
6619b6ff6391SYonghong Song 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6620b6ff6391SYonghong Song 	},
6621b6ff6391SYonghong Song 	{
6622db1ac496SGianluca Borello 		"helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
6623b6ff6391SYonghong Song 		.insns = {
6624b6ff6391SYonghong Song 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
6625b6ff6391SYonghong Song 				    offsetof(struct __sk_buff, data)),
6626b6ff6391SYonghong Song 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6627b6ff6391SYonghong Song 				    offsetof(struct __sk_buff, data_end)),
6628b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
6629b6ff6391SYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
6630b6ff6391SYonghong Song 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
6631b6ff6391SYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
6632b6ff6391SYonghong Song 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
6633b6ff6391SYonghong Song 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6634b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_3, 0),
6635b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 0),
6636b6ff6391SYonghong Song 			BPF_MOV64_IMM(BPF_REG_5, 0),
6637b6ff6391SYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_csum_diff),
6638b6ff6391SYonghong Song 			BPF_EXIT_INSN(),
6639b6ff6391SYonghong Song 		},
6640b6ff6391SYonghong Song 		.result = ACCEPT,
664106c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
6642111e6b45SAlexei Starovoitov 		.retval = 0 /* csum_diff of 64-byte packet */,
664306c1c049SGianluca Borello 	},
664406c1c049SGianluca Borello 	{
6645db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6646db1ac496SGianluca Borello 		.insns = {
6647db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_1, 0),
6648db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 0),
6649db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6650db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6651db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6652db1ac496SGianluca Borello 		},
6653db1ac496SGianluca Borello 		.errstr = "R1 type=inv expected=fp",
6654db1ac496SGianluca Borello 		.result = REJECT,
6655db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6656db1ac496SGianluca Borello 	},
6657db1ac496SGianluca Borello 	{
6658db1ac496SGianluca Borello 		"helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
6659db1ac496SGianluca Borello 		.insns = {
6660db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_1, 0),
6661db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 1),
6662db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6663db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6664db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6665db1ac496SGianluca Borello 		},
6666db1ac496SGianluca Borello 		.errstr = "R1 type=inv expected=fp",
6667db1ac496SGianluca Borello 		.result = REJECT,
6668db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6669db1ac496SGianluca Borello 	},
6670db1ac496SGianluca Borello 	{
6671db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6672db1ac496SGianluca Borello 		.insns = {
6673db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6674db1ac496SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6675db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 0),
6676db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6677db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6678db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6679db1ac496SGianluca Borello 		},
6680db1ac496SGianluca Borello 		.result = ACCEPT,
6681db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6682db1ac496SGianluca Borello 	},
6683db1ac496SGianluca Borello 	{
6684db1ac496SGianluca Borello 		"helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6685db1ac496SGianluca Borello 		.insns = {
6686db1ac496SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6687db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6688db1ac496SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6689db1ac496SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6690db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6691db1ac496SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6692db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6693db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 0),
6694db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6695db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6696db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6697db1ac496SGianluca Borello 		},
6698db1ac496SGianluca Borello 		.fixup_map1 = { 3 },
6699db1ac496SGianluca Borello 		.result = ACCEPT,
6700db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6701db1ac496SGianluca Borello 	},
6702db1ac496SGianluca Borello 	{
6703db1ac496SGianluca Borello 		"helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6704db1ac496SGianluca Borello 		.insns = {
6705db1ac496SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6706db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6707db1ac496SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6708db1ac496SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6709db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6710db1ac496SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6711db1ac496SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6712db1ac496SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
6713db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
6714db1ac496SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
6715db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6716db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6717db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6718db1ac496SGianluca Borello 		},
6719db1ac496SGianluca Borello 		.fixup_map1 = { 3 },
6720db1ac496SGianluca Borello 		.result = ACCEPT,
6721db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6722db1ac496SGianluca Borello 	},
6723db1ac496SGianluca Borello 	{
6724db1ac496SGianluca Borello 		"helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
6725db1ac496SGianluca Borello 		.insns = {
6726db1ac496SGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6727db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6728db1ac496SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6729db1ac496SGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6730db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6731db1ac496SGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6732db1ac496SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6733db1ac496SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
6734db1ac496SGianluca Borello 			BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
6735db1ac496SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
6736db1ac496SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
6737db1ac496SGianluca Borello 			BPF_EXIT_INSN(),
6738db1ac496SGianluca Borello 		},
6739db1ac496SGianluca Borello 		.fixup_map1 = { 3 },
6740db1ac496SGianluca Borello 		.result = ACCEPT,
6741db1ac496SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6742db1ac496SGianluca Borello 	},
6743db1ac496SGianluca Borello 	{
674406c1c049SGianluca Borello 		"helper access to variable memory: 8 bytes leak",
674506c1c049SGianluca Borello 		.insns = {
674606c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
674706c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
674806c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
674906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
675006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
675106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
675206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
675306c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
675406c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
675506c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
6756d98588ceSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_2, 1),
67573fadc801SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
67583fadc801SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
675906c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
676006c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
676106c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
676206c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
676306c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
676406c1c049SGianluca Borello 			BPF_EXIT_INSN(),
676506c1c049SGianluca Borello 		},
676606c1c049SGianluca Borello 		.errstr = "invalid indirect read from stack off -64+32 size 64",
676706c1c049SGianluca Borello 		.result = REJECT,
676806c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
676906c1c049SGianluca Borello 	},
677006c1c049SGianluca Borello 	{
677106c1c049SGianluca Borello 		"helper access to variable memory: 8 bytes no leak (init memory)",
677206c1c049SGianluca Borello 		.insns = {
677306c1c049SGianluca Borello 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
677406c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
677506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_0, 0),
677606c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
677706c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
677806c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
677906c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
678006c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
678106c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
678206c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
678306c1c049SGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
678406c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
678506c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_2, 0),
678606c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
678706c1c049SGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
678806c1c049SGianluca Borello 			BPF_MOV64_IMM(BPF_REG_3, 0),
678906c1c049SGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_probe_read),
679006c1c049SGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
679106c1c049SGianluca Borello 			BPF_EXIT_INSN(),
679206c1c049SGianluca Borello 		},
679306c1c049SGianluca Borello 		.result = ACCEPT,
679406c1c049SGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
679506c1c049SGianluca Borello 	},
679629200c19SJosef Bacik 	{
679729200c19SJosef Bacik 		"invalid and of negative number",
679829200c19SJosef Bacik 		.insns = {
679929200c19SJosef Bacik 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
680029200c19SJosef Bacik 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
680129200c19SJosef Bacik 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
680229200c19SJosef Bacik 			BPF_LD_MAP_FD(BPF_REG_1, 0),
680329200c19SJosef Bacik 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
680429200c19SJosef Bacik 				     BPF_FUNC_map_lookup_elem),
680529200c19SJosef Bacik 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
6806f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
680729200c19SJosef Bacik 			BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
680829200c19SJosef Bacik 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
680929200c19SJosef Bacik 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
681029200c19SJosef Bacik 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
681129200c19SJosef Bacik 				   offsetof(struct test_val, foo)),
681229200c19SJosef Bacik 			BPF_EXIT_INSN(),
681329200c19SJosef Bacik 		},
681429200c19SJosef Bacik 		.fixup_map2 = { 3 },
6815f65b1849SEdward Cree 		.errstr = "R0 max value is outside of the array range",
681629200c19SJosef Bacik 		.result = REJECT,
681702ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
681829200c19SJosef Bacik 	},
681929200c19SJosef Bacik 	{
682029200c19SJosef Bacik 		"invalid range check",
682129200c19SJosef Bacik 		.insns = {
682229200c19SJosef Bacik 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
682329200c19SJosef Bacik 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
682429200c19SJosef Bacik 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
682529200c19SJosef Bacik 			BPF_LD_MAP_FD(BPF_REG_1, 0),
682629200c19SJosef Bacik 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
682729200c19SJosef Bacik 				     BPF_FUNC_map_lookup_elem),
682829200c19SJosef Bacik 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
682929200c19SJosef Bacik 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
683029200c19SJosef Bacik 			BPF_MOV64_IMM(BPF_REG_9, 1),
683129200c19SJosef Bacik 			BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
683229200c19SJosef Bacik 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
683329200c19SJosef Bacik 			BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
683429200c19SJosef Bacik 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
683529200c19SJosef Bacik 			BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
683629200c19SJosef Bacik 			BPF_MOV32_IMM(BPF_REG_3, 1),
683729200c19SJosef Bacik 			BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
683829200c19SJosef Bacik 			BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
683929200c19SJosef Bacik 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
684029200c19SJosef Bacik 			BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
684129200c19SJosef Bacik 			BPF_MOV64_REG(BPF_REG_0, 0),
684229200c19SJosef Bacik 			BPF_EXIT_INSN(),
684329200c19SJosef Bacik 		},
684429200c19SJosef Bacik 		.fixup_map2 = { 3 },
6845f65b1849SEdward Cree 		.errstr = "R0 max value is outside of the array range",
684629200c19SJosef Bacik 		.result = REJECT,
684702ea80b1SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6848fb30d4b7SMartin KaFai Lau 	},
6849fb30d4b7SMartin KaFai Lau 	{
6850fb30d4b7SMartin KaFai Lau 		"map in map access",
6851fb30d4b7SMartin KaFai Lau 		.insns = {
6852fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6853fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6854fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6855fb30d4b7SMartin KaFai Lau 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6856fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6857fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6858fb30d4b7SMartin KaFai Lau 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
6859fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6860fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6861fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6862fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6863fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6864fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6865fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_0, 0),
6866fb30d4b7SMartin KaFai Lau 			BPF_EXIT_INSN(),
6867fb30d4b7SMartin KaFai Lau 		},
6868fb30d4b7SMartin KaFai Lau 		.fixup_map_in_map = { 3 },
6869fb30d4b7SMartin KaFai Lau 		.result = ACCEPT,
6870fb30d4b7SMartin KaFai Lau 	},
6871fb30d4b7SMartin KaFai Lau 	{
6872fb30d4b7SMartin KaFai Lau 		"invalid inner map pointer",
6873fb30d4b7SMartin KaFai Lau 		.insns = {
6874fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6875fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6876fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6877fb30d4b7SMartin KaFai Lau 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6878fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6879fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6880fb30d4b7SMartin KaFai Lau 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
6881fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6882fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6883fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6884fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6885fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6886fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6887fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6888fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_0, 0),
6889fb30d4b7SMartin KaFai Lau 			BPF_EXIT_INSN(),
6890fb30d4b7SMartin KaFai Lau 		},
6891fb30d4b7SMartin KaFai Lau 		.fixup_map_in_map = { 3 },
689282abbf8dSAlexei Starovoitov 		.errstr = "R1 pointer arithmetic on CONST_PTR_TO_MAP prohibited",
6893fb30d4b7SMartin KaFai Lau 		.result = REJECT,
6894fb30d4b7SMartin KaFai Lau 	},
6895fb30d4b7SMartin KaFai Lau 	{
6896fb30d4b7SMartin KaFai Lau 		"forgot null checking on the inner map pointer",
6897fb30d4b7SMartin KaFai Lau 		.insns = {
6898fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6899fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6900fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6901fb30d4b7SMartin KaFai Lau 			BPF_LD_MAP_FD(BPF_REG_1, 0),
6902fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6903fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6904fb30d4b7SMartin KaFai Lau 			BPF_ST_MEM(0, BPF_REG_10, -4, 0),
6905fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6906fb30d4b7SMartin KaFai Lau 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
6907fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6908fb30d4b7SMartin KaFai Lau 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6909fb30d4b7SMartin KaFai Lau 				     BPF_FUNC_map_lookup_elem),
6910fb30d4b7SMartin KaFai Lau 			BPF_MOV64_REG(BPF_REG_0, 0),
6911fb30d4b7SMartin KaFai Lau 			BPF_EXIT_INSN(),
6912fb30d4b7SMartin KaFai Lau 		},
6913fb30d4b7SMartin KaFai Lau 		.fixup_map_in_map = { 3 },
6914fb30d4b7SMartin KaFai Lau 		.errstr = "R1 type=map_value_or_null expected=map_ptr",
6915fb30d4b7SMartin KaFai Lau 		.result = REJECT,
6916614d0d77SDaniel Borkmann 	},
6917614d0d77SDaniel Borkmann 	{
6918614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r1",
6919614d0d77SDaniel Borkmann 		.insns = {
6920614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6921614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0),
6922614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6923614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6924614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6925614d0d77SDaniel Borkmann 		},
6926614d0d77SDaniel Borkmann 		.errstr = "R1 !read_ok",
6927614d0d77SDaniel Borkmann 		.result = REJECT,
6928614d0d77SDaniel Borkmann 	},
6929614d0d77SDaniel Borkmann 	{
6930614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r2",
6931614d0d77SDaniel Borkmann 		.insns = {
6932614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6933614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
6934614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6935614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
6936614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6937614d0d77SDaniel Borkmann 		},
6938614d0d77SDaniel Borkmann 		.errstr = "R2 !read_ok",
6939614d0d77SDaniel Borkmann 		.result = REJECT,
6940614d0d77SDaniel Borkmann 	},
6941614d0d77SDaniel Borkmann 	{
6942614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r3",
6943614d0d77SDaniel Borkmann 		.insns = {
6944614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6945614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 0),
6946614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6947614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
6948614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6949614d0d77SDaniel Borkmann 		},
6950614d0d77SDaniel Borkmann 		.errstr = "R3 !read_ok",
6951614d0d77SDaniel Borkmann 		.result = REJECT,
6952614d0d77SDaniel Borkmann 	},
6953614d0d77SDaniel Borkmann 	{
6954614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r4",
6955614d0d77SDaniel Borkmann 		.insns = {
6956614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6957614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 0),
6958614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6959614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
6960614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6961614d0d77SDaniel Borkmann 		},
6962614d0d77SDaniel Borkmann 		.errstr = "R4 !read_ok",
6963614d0d77SDaniel Borkmann 		.result = REJECT,
6964614d0d77SDaniel Borkmann 	},
6965614d0d77SDaniel Borkmann 	{
6966614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r5",
6967614d0d77SDaniel Borkmann 		.insns = {
6968614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6969614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
6970614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6971614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
6972614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6973614d0d77SDaniel Borkmann 		},
6974614d0d77SDaniel Borkmann 		.errstr = "R5 !read_ok",
6975614d0d77SDaniel Borkmann 		.result = REJECT,
6976614d0d77SDaniel Borkmann 	},
6977614d0d77SDaniel Borkmann 	{
6978614d0d77SDaniel Borkmann 		"ld_abs: check calling conv, r7",
6979614d0d77SDaniel Borkmann 		.insns = {
6980614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
6981614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_7, 0),
6982614d0d77SDaniel Borkmann 			BPF_LD_ABS(BPF_W, -0x200000),
6983614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
6984614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
6985614d0d77SDaniel Borkmann 		},
6986614d0d77SDaniel Borkmann 		.result = ACCEPT,
6987614d0d77SDaniel Borkmann 	},
6988614d0d77SDaniel Borkmann 	{
698987ab8194SDaniel Borkmann 		"ld_abs: tests on r6 and skb data reload helper",
699087ab8194SDaniel Borkmann 		.insns = {
699187ab8194SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
699287ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
699387ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
699487ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
699587ab8194SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
699687ab8194SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_6, 0),
699787ab8194SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
699887ab8194SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
699987ab8194SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 2),
700087ab8194SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
700187ab8194SDaniel Borkmann 				     BPF_FUNC_skb_vlan_push),
700287ab8194SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
700387ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
700487ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
700587ab8194SDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
700687ab8194SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
700787ab8194SDaniel Borkmann 			BPF_EXIT_INSN(),
700887ab8194SDaniel Borkmann 		},
700987ab8194SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
701087ab8194SDaniel Borkmann 		.result = ACCEPT,
7011111e6b45SAlexei Starovoitov 		.retval = 42 /* ultimate return value */,
701287ab8194SDaniel Borkmann 	},
701387ab8194SDaniel Borkmann 	{
7014614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r1",
7015614d0d77SDaniel Borkmann 		.insns = {
7016614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7017614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 1),
7018614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
7019614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
7020614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7021614d0d77SDaniel Borkmann 		},
7022614d0d77SDaniel Borkmann 		.errstr = "R1 !read_ok",
7023614d0d77SDaniel Borkmann 		.result = REJECT,
7024614d0d77SDaniel Borkmann 	},
7025614d0d77SDaniel Borkmann 	{
7026614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r2",
7027614d0d77SDaniel Borkmann 		.insns = {
7028614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7029614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
7030614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
7031614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
7032614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7033614d0d77SDaniel Borkmann 		},
7034614d0d77SDaniel Borkmann 		.errstr = "R2 !read_ok",
7035614d0d77SDaniel Borkmann 		.result = REJECT,
7036614d0d77SDaniel Borkmann 	},
7037614d0d77SDaniel Borkmann 	{
7038614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r3",
7039614d0d77SDaniel Borkmann 		.insns = {
7040614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7041614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 1),
7042614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
7043614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
7044614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7045614d0d77SDaniel Borkmann 		},
7046614d0d77SDaniel Borkmann 		.errstr = "R3 !read_ok",
7047614d0d77SDaniel Borkmann 		.result = REJECT,
7048614d0d77SDaniel Borkmann 	},
7049614d0d77SDaniel Borkmann 	{
7050614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r4",
7051614d0d77SDaniel Borkmann 		.insns = {
7052614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7053614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_4, 1),
7054614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
7055614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
7056614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7057614d0d77SDaniel Borkmann 		},
7058614d0d77SDaniel Borkmann 		.errstr = "R4 !read_ok",
7059614d0d77SDaniel Borkmann 		.result = REJECT,
7060614d0d77SDaniel Borkmann 	},
7061614d0d77SDaniel Borkmann 	{
7062614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r5",
7063614d0d77SDaniel Borkmann 		.insns = {
7064614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7065614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
7066614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
7067614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
7068614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7069614d0d77SDaniel Borkmann 		},
7070614d0d77SDaniel Borkmann 		.errstr = "R5 !read_ok",
7071614d0d77SDaniel Borkmann 		.result = REJECT,
7072614d0d77SDaniel Borkmann 	},
7073614d0d77SDaniel Borkmann 	{
7074614d0d77SDaniel Borkmann 		"ld_ind: check calling conv, r7",
7075614d0d77SDaniel Borkmann 		.insns = {
7076614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
7077614d0d77SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_7, 1),
7078614d0d77SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
7079614d0d77SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
7080614d0d77SDaniel Borkmann 			BPF_EXIT_INSN(),
7081614d0d77SDaniel Borkmann 		},
7082614d0d77SDaniel Borkmann 		.result = ACCEPT,
7083111e6b45SAlexei Starovoitov 		.retval = 1,
7084614d0d77SDaniel Borkmann 	},
708518f3d6beSYonghong Song 	{
708618f3d6beSYonghong Song 		"check bpf_perf_event_data->sample_period byte load permitted",
708718f3d6beSYonghong Song 		.insns = {
708818f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
70892c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
709018f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
709118f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period)),
709218f3d6beSYonghong Song #else
709318f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
709418f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period) + 7),
709518f3d6beSYonghong Song #endif
709618f3d6beSYonghong Song 			BPF_EXIT_INSN(),
709718f3d6beSYonghong Song 		},
709818f3d6beSYonghong Song 		.result = ACCEPT,
709918f3d6beSYonghong Song 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
710018f3d6beSYonghong Song 	},
710118f3d6beSYonghong Song 	{
710218f3d6beSYonghong Song 		"check bpf_perf_event_data->sample_period half load permitted",
710318f3d6beSYonghong Song 		.insns = {
710418f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
71052c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
710618f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
710718f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period)),
710818f3d6beSYonghong Song #else
710918f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
711018f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period) + 6),
711118f3d6beSYonghong Song #endif
711218f3d6beSYonghong Song 			BPF_EXIT_INSN(),
711318f3d6beSYonghong Song 		},
711418f3d6beSYonghong Song 		.result = ACCEPT,
711518f3d6beSYonghong Song 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
711618f3d6beSYonghong Song 	},
711718f3d6beSYonghong Song 	{
711818f3d6beSYonghong Song 		"check bpf_perf_event_data->sample_period word load permitted",
711918f3d6beSYonghong Song 		.insns = {
712018f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
71212c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
712218f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
712318f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period)),
712418f3d6beSYonghong Song #else
712518f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
712618f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period) + 4),
712718f3d6beSYonghong Song #endif
712818f3d6beSYonghong Song 			BPF_EXIT_INSN(),
712918f3d6beSYonghong Song 		},
713018f3d6beSYonghong Song 		.result = ACCEPT,
713118f3d6beSYonghong Song 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
713218f3d6beSYonghong Song 	},
713318f3d6beSYonghong Song 	{
713418f3d6beSYonghong Song 		"check bpf_perf_event_data->sample_period dword load permitted",
713518f3d6beSYonghong Song 		.insns = {
713618f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
713718f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
713818f3d6beSYonghong Song 				    offsetof(struct bpf_perf_event_data, sample_period)),
713918f3d6beSYonghong Song 			BPF_EXIT_INSN(),
714018f3d6beSYonghong Song 		},
714118f3d6beSYonghong Song 		.result = ACCEPT,
714218f3d6beSYonghong Song 		.prog_type = BPF_PROG_TYPE_PERF_EVENT,
714318f3d6beSYonghong Song 	},
714418f3d6beSYonghong Song 	{
714518f3d6beSYonghong Song 		"check skb->data half load not permitted",
714618f3d6beSYonghong Song 		.insns = {
714718f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
71482c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
714918f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
715018f3d6beSYonghong Song 				    offsetof(struct __sk_buff, data)),
715118f3d6beSYonghong Song #else
715218f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
715318f3d6beSYonghong Song 				    offsetof(struct __sk_buff, data) + 2),
715418f3d6beSYonghong Song #endif
715518f3d6beSYonghong Song 			BPF_EXIT_INSN(),
715618f3d6beSYonghong Song 		},
715718f3d6beSYonghong Song 		.result = REJECT,
715818f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
715918f3d6beSYonghong Song 	},
716018f3d6beSYonghong Song 	{
716118f3d6beSYonghong Song 		"check skb->tc_classid half load not permitted for lwt prog",
716218f3d6beSYonghong Song 		.insns = {
716318f3d6beSYonghong Song 			BPF_MOV64_IMM(BPF_REG_0, 0),
71642c460621SDaniel Borkmann #if __BYTE_ORDER == __LITTLE_ENDIAN
716518f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
716618f3d6beSYonghong Song 				    offsetof(struct __sk_buff, tc_classid)),
716718f3d6beSYonghong Song #else
716818f3d6beSYonghong Song 			BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
716918f3d6beSYonghong Song 				    offsetof(struct __sk_buff, tc_classid) + 2),
717018f3d6beSYonghong Song #endif
717118f3d6beSYonghong Song 			BPF_EXIT_INSN(),
717218f3d6beSYonghong Song 		},
717318f3d6beSYonghong Song 		.result = REJECT,
717418f3d6beSYonghong Song 		.errstr = "invalid bpf_context access",
717518f3d6beSYonghong Song 		.prog_type = BPF_PROG_TYPE_LWT_IN,
717618f3d6beSYonghong Song 	},
7177b712296aSEdward Cree 	{
7178b712296aSEdward Cree 		"bounds checks mixing signed and unsigned, positive bounds",
7179b712296aSEdward Cree 		.insns = {
7180b712296aSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7181b712296aSEdward Cree 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7182b712296aSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7183b712296aSEdward Cree 			BPF_LD_MAP_FD(BPF_REG_1, 0),
7184b712296aSEdward Cree 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7185b712296aSEdward Cree 				     BPF_FUNC_map_lookup_elem),
7186b712296aSEdward Cree 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7187b712296aSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7188b712296aSEdward Cree 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7189b712296aSEdward Cree 			BPF_MOV64_IMM(BPF_REG_2, 2),
7190b712296aSEdward Cree 			BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
7191b712296aSEdward Cree 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
7192b712296aSEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7193b712296aSEdward Cree 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7194b712296aSEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
7195b712296aSEdward Cree 			BPF_EXIT_INSN(),
7196b712296aSEdward Cree 		},
7197b712296aSEdward Cree 		.fixup_map1 = { 3 },
71982255f8d5SJann Horn 		.errstr = "unbounded min value",
7199b712296aSEdward Cree 		.result = REJECT,
7200b712296aSEdward Cree 	},
7201b712296aSEdward Cree 	{
7202b712296aSEdward Cree 		"bounds checks mixing signed and unsigned",
7203b712296aSEdward Cree 		.insns = {
7204b712296aSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7205b712296aSEdward Cree 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7206b712296aSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7207b712296aSEdward Cree 			BPF_LD_MAP_FD(BPF_REG_1, 0),
7208b712296aSEdward Cree 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7209b712296aSEdward Cree 				     BPF_FUNC_map_lookup_elem),
7210b712296aSEdward Cree 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
7211b712296aSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
7212b712296aSEdward Cree 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
7213b712296aSEdward Cree 			BPF_MOV64_IMM(BPF_REG_2, -1),
7214b712296aSEdward Cree 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
7215b712296aSEdward Cree 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
7216b712296aSEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7217b712296aSEdward Cree 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
7218b712296aSEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
7219b712296aSEdward Cree 			BPF_EXIT_INSN(),
7220b712296aSEdward Cree 		},
7221b712296aSEdward Cree 		.fixup_map1 = { 3 },
72222255f8d5SJann Horn 		.errstr = "unbounded min value",
7223b712296aSEdward Cree 		.result = REJECT,
7224b712296aSEdward Cree 	},
722586412502SDaniel Borkmann 	{
722686412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 2",
722786412502SDaniel Borkmann 		.insns = {
722886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
722986412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
723086412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
723186412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
723286412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
723386412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
723486412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
723586412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
723686412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
723786412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
723886412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
723986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_8, 0),
724086412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
724186412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
724286412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
724386412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
724486412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
724586412502SDaniel Borkmann 			BPF_EXIT_INSN(),
724686412502SDaniel Borkmann 		},
724786412502SDaniel Borkmann 		.fixup_map1 = { 3 },
72482255f8d5SJann Horn 		.errstr = "unbounded min value",
724986412502SDaniel Borkmann 		.result = REJECT,
725086412502SDaniel Borkmann 	},
725186412502SDaniel Borkmann 	{
725286412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 3",
725386412502SDaniel Borkmann 		.insns = {
725486412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
725586412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
725686412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
725786412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
725886412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
725986412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
726086412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
726186412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
726286412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
726386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
726486412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
726586412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
726686412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
726786412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
726886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
726986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
727086412502SDaniel Borkmann 			BPF_EXIT_INSN(),
727186412502SDaniel Borkmann 		},
727286412502SDaniel Borkmann 		.fixup_map1 = { 3 },
72732255f8d5SJann Horn 		.errstr = "unbounded min value",
727486412502SDaniel Borkmann 		.result = REJECT,
727586412502SDaniel Borkmann 	},
727686412502SDaniel Borkmann 	{
727786412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 4",
727886412502SDaniel Borkmann 		.insns = {
727986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
728086412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
728186412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
728286412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
728386412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
728486412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
728586412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
728686412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
728786412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
728886412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
728986412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
729086412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
729186412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
729286412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
729386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
729486412502SDaniel Borkmann 			BPF_EXIT_INSN(),
729586412502SDaniel Borkmann 		},
729686412502SDaniel Borkmann 		.fixup_map1 = { 3 },
7297f65b1849SEdward Cree 		.result = ACCEPT,
729886412502SDaniel Borkmann 	},
729986412502SDaniel Borkmann 	{
730086412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 5",
730186412502SDaniel Borkmann 		.insns = {
730286412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
730386412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
730486412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
730586412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
730686412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
730786412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
730886412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
730986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
731086412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
731186412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
731286412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
731386412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
731486412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
731586412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
731686412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
731786412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
731886412502SDaniel Borkmann 			BPF_EXIT_INSN(),
731986412502SDaniel Borkmann 		},
732086412502SDaniel Borkmann 		.fixup_map1 = { 3 },
73212255f8d5SJann Horn 		.errstr = "unbounded min value",
732286412502SDaniel Borkmann 		.result = REJECT,
732386412502SDaniel Borkmann 	},
732486412502SDaniel Borkmann 	{
732586412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 6",
732686412502SDaniel Borkmann 		.insns = {
732786412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
732886412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
732986412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
733086412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
733186412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
733286412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_6, -1),
733386412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
733486412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
733586412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
733686412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
733786412502SDaniel Borkmann 			BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
733886412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
733986412502SDaniel Borkmann 				     BPF_FUNC_skb_load_bytes),
734086412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
734186412502SDaniel Borkmann 			BPF_EXIT_INSN(),
734286412502SDaniel Borkmann 		},
734386412502SDaniel Borkmann 		.errstr = "R4 min value is negative, either use unsigned",
734486412502SDaniel Borkmann 		.result = REJECT,
734586412502SDaniel Borkmann 	},
734686412502SDaniel Borkmann 	{
734786412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 7",
734886412502SDaniel Borkmann 		.insns = {
734986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
735086412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
735186412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
735286412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
735386412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
735486412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
735586412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
735686412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
735786412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
735886412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
735986412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
736086412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
736186412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
736286412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
736386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
736486412502SDaniel Borkmann 			BPF_EXIT_INSN(),
736586412502SDaniel Borkmann 		},
736686412502SDaniel Borkmann 		.fixup_map1 = { 3 },
7367f65b1849SEdward Cree 		.result = ACCEPT,
736886412502SDaniel Borkmann 	},
736986412502SDaniel Borkmann 	{
737086412502SDaniel Borkmann 		"bounds checks mixing signed and unsigned, variant 8",
737186412502SDaniel Borkmann 		.insns = {
737286412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
737386412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
737486412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
737586412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
737686412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
737786412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
737886412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
737986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
738086412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
738186412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
738286412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
738386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
738486412502SDaniel Borkmann 			BPF_EXIT_INSN(),
738586412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
738686412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
738786412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
738886412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
738986412502SDaniel Borkmann 			BPF_EXIT_INSN(),
739086412502SDaniel Borkmann 		},
739186412502SDaniel Borkmann 		.fixup_map1 = { 3 },
73922255f8d5SJann Horn 		.errstr = "unbounded min value",
739386412502SDaniel Borkmann 		.result = REJECT,
739486412502SDaniel Borkmann 	},
739586412502SDaniel Borkmann 	{
7396f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 9",
739786412502SDaniel Borkmann 		.insns = {
739886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
739986412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
740086412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
740186412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
740286412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
740386412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
740486412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
740586412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
740686412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
740786412502SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
740886412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
740986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
741086412502SDaniel Borkmann 			BPF_EXIT_INSN(),
741186412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
741286412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
741386412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
741486412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
741586412502SDaniel Borkmann 			BPF_EXIT_INSN(),
741686412502SDaniel Borkmann 		},
741786412502SDaniel Borkmann 		.fixup_map1 = { 3 },
7418f65b1849SEdward Cree 		.result = ACCEPT,
741986412502SDaniel Borkmann 	},
742086412502SDaniel Borkmann 	{
7421f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 10",
742286412502SDaniel Borkmann 		.insns = {
742386412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
742486412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
742586412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
742686412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
742786412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
742886412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
742986412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
743086412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
743186412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
743286412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
743386412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
743486412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
743586412502SDaniel Borkmann 			BPF_EXIT_INSN(),
743686412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
743786412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
743886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
743986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
744086412502SDaniel Borkmann 			BPF_EXIT_INSN(),
744186412502SDaniel Borkmann 		},
744286412502SDaniel Borkmann 		.fixup_map1 = { 3 },
74432255f8d5SJann Horn 		.errstr = "unbounded min value",
744486412502SDaniel Borkmann 		.result = REJECT,
744586412502SDaniel Borkmann 	},
744686412502SDaniel Borkmann 	{
7447f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 11",
744886412502SDaniel Borkmann 		.insns = {
744986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
745086412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
745186412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
745286412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
745386412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
745486412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
745586412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
745686412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
745786412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
745886412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
745986412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
746086412502SDaniel Borkmann 			/* Dead branch. */
746186412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
746286412502SDaniel Borkmann 			BPF_EXIT_INSN(),
746386412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
746486412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
746586412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
746686412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
746786412502SDaniel Borkmann 			BPF_EXIT_INSN(),
746886412502SDaniel Borkmann 		},
746986412502SDaniel Borkmann 		.fixup_map1 = { 3 },
74702255f8d5SJann Horn 		.errstr = "unbounded min value",
747186412502SDaniel Borkmann 		.result = REJECT,
747286412502SDaniel Borkmann 	},
747386412502SDaniel Borkmann 	{
7474f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 12",
747586412502SDaniel Borkmann 		.insns = {
747686412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
747786412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
747886412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
747986412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
748086412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
748186412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
748286412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
748386412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
748486412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
748586412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -6),
748686412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
748786412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
748886412502SDaniel Borkmann 			BPF_EXIT_INSN(),
748986412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
749086412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
749186412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
749286412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
749386412502SDaniel Borkmann 			BPF_EXIT_INSN(),
749486412502SDaniel Borkmann 		},
749586412502SDaniel Borkmann 		.fixup_map1 = { 3 },
74962255f8d5SJann Horn 		.errstr = "unbounded min value",
749786412502SDaniel Borkmann 		.result = REJECT,
749886412502SDaniel Borkmann 	},
749986412502SDaniel Borkmann 	{
7500f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 13",
750186412502SDaniel Borkmann 		.insns = {
750286412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
750386412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
750486412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
750586412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
750686412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
750786412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
750886412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
750986412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
751086412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
751186412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 2),
751286412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
751386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_7, 1),
751486412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
751586412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
751686412502SDaniel Borkmann 			BPF_EXIT_INSN(),
751786412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
751886412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
751986412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
752086412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
752186412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
752286412502SDaniel Borkmann 			BPF_EXIT_INSN(),
752386412502SDaniel Borkmann 		},
752486412502SDaniel Borkmann 		.fixup_map1 = { 3 },
75252255f8d5SJann Horn 		.errstr = "unbounded min value",
752686412502SDaniel Borkmann 		.result = REJECT,
752786412502SDaniel Borkmann 	},
752886412502SDaniel Borkmann 	{
7529f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 14",
753086412502SDaniel Borkmann 		.insns = {
753186412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
753286412502SDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
753386412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
753486412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
753586412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
753686412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
753786412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
753886412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
753986412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
754086412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
754186412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
754286412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -1),
754386412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_8, 2),
754486412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
754586412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
754686412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
754786412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
754886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
754986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
755086412502SDaniel Borkmann 			BPF_EXIT_INSN(),
755186412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
755286412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -7),
755386412502SDaniel Borkmann 		},
755486412502SDaniel Borkmann 		.fixup_map1 = { 4 },
75556f16101eSDaniel Borkmann 		.errstr = "R0 invalid mem access 'inv'",
755686412502SDaniel Borkmann 		.result = REJECT,
755786412502SDaniel Borkmann 	},
755886412502SDaniel Borkmann 	{
7559f65b1849SEdward Cree 		"bounds checks mixing signed and unsigned, variant 15",
756086412502SDaniel Borkmann 		.insns = {
756186412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
756286412502SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
756386412502SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
756486412502SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
756586412502SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
756686412502SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
756786412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
756886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
756986412502SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
757086412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -6),
757186412502SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
757286412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
757386412502SDaniel Borkmann 			BPF_EXIT_INSN(),
757486412502SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
757586412502SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
757686412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
757786412502SDaniel Borkmann 			BPF_EXIT_INSN(),
757886412502SDaniel Borkmann 			BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
757986412502SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
758086412502SDaniel Borkmann 			BPF_EXIT_INSN(),
758186412502SDaniel Borkmann 		},
758286412502SDaniel Borkmann 		.fixup_map1 = { 3 },
75832255f8d5SJann Horn 		.errstr = "unbounded min value",
758486412502SDaniel Borkmann 		.result = REJECT,
758586412502SDaniel Borkmann 		.result_unpriv = REJECT,
758686412502SDaniel Borkmann 	},
7587545722cbSEdward Cree 	{
7588f65b1849SEdward Cree 		"subtraction bounds (map value) variant 1",
7589545722cbSEdward Cree 		.insns = {
7590545722cbSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7591545722cbSEdward Cree 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7592545722cbSEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7593545722cbSEdward Cree 			BPF_LD_MAP_FD(BPF_REG_1, 0),
7594545722cbSEdward Cree 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7595545722cbSEdward Cree 				     BPF_FUNC_map_lookup_elem),
7596545722cbSEdward Cree 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
7597545722cbSEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7598545722cbSEdward Cree 			BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
7599545722cbSEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7600545722cbSEdward Cree 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
7601545722cbSEdward Cree 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7602545722cbSEdward Cree 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
7603545722cbSEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7604545722cbSEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7605545722cbSEdward Cree 			BPF_EXIT_INSN(),
7606545722cbSEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
7607545722cbSEdward Cree 			BPF_EXIT_INSN(),
7608545722cbSEdward Cree 		},
7609545722cbSEdward Cree 		.fixup_map1 = { 3 },
7610f65b1849SEdward Cree 		.errstr = "R0 max value is outside of the array range",
7611f65b1849SEdward Cree 		.result = REJECT,
7612f65b1849SEdward Cree 	},
7613f65b1849SEdward Cree 	{
7614f65b1849SEdward Cree 		"subtraction bounds (map value) variant 2",
7615f65b1849SEdward Cree 		.insns = {
7616f65b1849SEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7617f65b1849SEdward Cree 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7618f65b1849SEdward Cree 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7619f65b1849SEdward Cree 			BPF_LD_MAP_FD(BPF_REG_1, 0),
7620f65b1849SEdward Cree 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7621f65b1849SEdward Cree 				     BPF_FUNC_map_lookup_elem),
7622f65b1849SEdward Cree 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
7623f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
7624f65b1849SEdward Cree 			BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
7625f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
7626f65b1849SEdward Cree 			BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
7627f65b1849SEdward Cree 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
7628f65b1849SEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
7629f65b1849SEdward Cree 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
7630f65b1849SEdward Cree 			BPF_EXIT_INSN(),
7631f65b1849SEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
7632f65b1849SEdward Cree 			BPF_EXIT_INSN(),
7633f65b1849SEdward Cree 		},
7634f65b1849SEdward Cree 		.fixup_map1 = { 3 },
7635545722cbSEdward Cree 		.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
7636545722cbSEdward Cree 		.result = REJECT,
7637545722cbSEdward Cree 	},
763869c4e8adSEdward Cree 	{
76392255f8d5SJann Horn 		"bounds check based on zero-extended MOV",
76402255f8d5SJann Horn 		.insns = {
76412255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
76422255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
76432255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
76442255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
76452255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
76462255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
76472255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
76482255f8d5SJann Horn 			/* r2 = 0x0000'0000'ffff'ffff */
76492255f8d5SJann Horn 			BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
76502255f8d5SJann Horn 			/* r2 = 0 */
76512255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
76522255f8d5SJann Horn 			/* no-op */
76532255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
76542255f8d5SJann Horn 			/* access at offset 0 */
76552255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
76562255f8d5SJann Horn 			/* exit */
76572255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
76582255f8d5SJann Horn 			BPF_EXIT_INSN(),
76592255f8d5SJann Horn 		},
76602255f8d5SJann Horn 		.fixup_map1 = { 3 },
76612255f8d5SJann Horn 		.result = ACCEPT
76622255f8d5SJann Horn 	},
76632255f8d5SJann Horn 	{
76642255f8d5SJann Horn 		"bounds check based on sign-extended MOV. test1",
76652255f8d5SJann Horn 		.insns = {
76662255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
76672255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
76682255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
76692255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
76702255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
76712255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
76722255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
76732255f8d5SJann Horn 			/* r2 = 0xffff'ffff'ffff'ffff */
76742255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
76752255f8d5SJann Horn 			/* r2 = 0xffff'ffff */
76762255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
76772255f8d5SJann Horn 			/* r0 = <oob pointer> */
76782255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
76792255f8d5SJann Horn 			/* access to OOB pointer */
76802255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
76812255f8d5SJann Horn 			/* exit */
76822255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
76832255f8d5SJann Horn 			BPF_EXIT_INSN(),
76842255f8d5SJann Horn 		},
76852255f8d5SJann Horn 		.fixup_map1 = { 3 },
76862255f8d5SJann Horn 		.errstr = "map_value pointer and 4294967295",
76872255f8d5SJann Horn 		.result = REJECT
76882255f8d5SJann Horn 	},
76892255f8d5SJann Horn 	{
76902255f8d5SJann Horn 		"bounds check based on sign-extended MOV. test2",
76912255f8d5SJann Horn 		.insns = {
76922255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
76932255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
76942255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
76952255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
76962255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
76972255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
76982255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
76992255f8d5SJann Horn 			/* r2 = 0xffff'ffff'ffff'ffff */
77002255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
77012255f8d5SJann Horn 			/* r2 = 0xfff'ffff */
77022255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
77032255f8d5SJann Horn 			/* r0 = <oob pointer> */
77042255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
77052255f8d5SJann Horn 			/* access to OOB pointer */
77062255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
77072255f8d5SJann Horn 			/* exit */
77082255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
77092255f8d5SJann Horn 			BPF_EXIT_INSN(),
77102255f8d5SJann Horn 		},
77112255f8d5SJann Horn 		.fixup_map1 = { 3 },
77122255f8d5SJann Horn 		.errstr = "R0 min value is outside of the array range",
77132255f8d5SJann Horn 		.result = REJECT
77142255f8d5SJann Horn 	},
77152255f8d5SJann Horn 	{
77162255f8d5SJann Horn 		"bounds check based on reg_off + var_off + insn_off. test1",
77172255f8d5SJann Horn 		.insns = {
77182255f8d5SJann Horn 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
77192255f8d5SJann Horn 				    offsetof(struct __sk_buff, mark)),
77202255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
77212255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
77222255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
77232255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
77242255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
77252255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
77262255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
77272255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
77282255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
77292255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
77302255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
77312255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
77322255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
77332255f8d5SJann Horn 			BPF_EXIT_INSN(),
77342255f8d5SJann Horn 		},
77352255f8d5SJann Horn 		.fixup_map1 = { 4 },
77362255f8d5SJann Horn 		.errstr = "value_size=8 off=1073741825",
77372255f8d5SJann Horn 		.result = REJECT,
77382255f8d5SJann Horn 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
77392255f8d5SJann Horn 	},
77402255f8d5SJann Horn 	{
77412255f8d5SJann Horn 		"bounds check based on reg_off + var_off + insn_off. test2",
77422255f8d5SJann Horn 		.insns = {
77432255f8d5SJann Horn 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
77442255f8d5SJann Horn 				    offsetof(struct __sk_buff, mark)),
77452255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
77462255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
77472255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
77482255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
77492255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
77502255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
77512255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
77522255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
77532255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
77542255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
77552255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
77562255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
77572255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
77582255f8d5SJann Horn 			BPF_EXIT_INSN(),
77592255f8d5SJann Horn 		},
77602255f8d5SJann Horn 		.fixup_map1 = { 4 },
77612255f8d5SJann Horn 		.errstr = "value 1073741823",
77622255f8d5SJann Horn 		.result = REJECT,
77632255f8d5SJann Horn 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
77642255f8d5SJann Horn 	},
77652255f8d5SJann Horn 	{
77662255f8d5SJann Horn 		"bounds check after truncation of non-boundary-crossing range",
77672255f8d5SJann Horn 		.insns = {
77682255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
77692255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
77702255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
77712255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
77722255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
77732255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
77742255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
77752255f8d5SJann Horn 			/* r1 = [0x00, 0xff] */
77762255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
77772255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_2, 1),
77782255f8d5SJann Horn 			/* r2 = 0x10'0000'0000 */
77792255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
77802255f8d5SJann Horn 			/* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
77812255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
77822255f8d5SJann Horn 			/* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
77832255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
77842255f8d5SJann Horn 			/* r1 = [0x00, 0xff] */
77852255f8d5SJann Horn 			BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
77862255f8d5SJann Horn 			/* r1 = 0 */
77872255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
77882255f8d5SJann Horn 			/* no-op */
77892255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
77902255f8d5SJann Horn 			/* access at offset 0 */
77912255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
77922255f8d5SJann Horn 			/* exit */
77932255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
77942255f8d5SJann Horn 			BPF_EXIT_INSN(),
77952255f8d5SJann Horn 		},
77962255f8d5SJann Horn 		.fixup_map1 = { 3 },
77972255f8d5SJann Horn 		.result = ACCEPT
77982255f8d5SJann Horn 	},
77992255f8d5SJann Horn 	{
78002255f8d5SJann Horn 		"bounds check after truncation of boundary-crossing range (1)",
78012255f8d5SJann Horn 		.insns = {
78022255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
78032255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
78042255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
78052255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
78062255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
78072255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
78082255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
78092255f8d5SJann Horn 			/* r1 = [0x00, 0xff] */
78102255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
78112255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
78122255f8d5SJann Horn 			/* r1 = [0xffff'ff80, 0x1'0000'007f] */
78132255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
78142255f8d5SJann Horn 			/* r1 = [0xffff'ff80, 0xffff'ffff] or
78152255f8d5SJann Horn 			 *      [0x0000'0000, 0x0000'007f]
78162255f8d5SJann Horn 			 */
78172255f8d5SJann Horn 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
78182255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
78192255f8d5SJann Horn 			/* r1 = [0x00, 0xff] or
78202255f8d5SJann Horn 			 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
78212255f8d5SJann Horn 			 */
78222255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
78232255f8d5SJann Horn 			/* r1 = 0 or
78242255f8d5SJann Horn 			 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
78252255f8d5SJann Horn 			 */
78262255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
78272255f8d5SJann Horn 			/* no-op or OOB pointer computation */
78282255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
78292255f8d5SJann Horn 			/* potentially OOB access */
78302255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
78312255f8d5SJann Horn 			/* exit */
78322255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
78332255f8d5SJann Horn 			BPF_EXIT_INSN(),
78342255f8d5SJann Horn 		},
78352255f8d5SJann Horn 		.fixup_map1 = { 3 },
78362255f8d5SJann Horn 		/* not actually fully unbounded, but the bound is very high */
78372255f8d5SJann Horn 		.errstr = "R0 unbounded memory access",
78382255f8d5SJann Horn 		.result = REJECT
78392255f8d5SJann Horn 	},
78402255f8d5SJann Horn 	{
78412255f8d5SJann Horn 		"bounds check after truncation of boundary-crossing range (2)",
78422255f8d5SJann Horn 		.insns = {
78432255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
78442255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
78452255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
78462255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
78472255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
78482255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
78492255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
78502255f8d5SJann Horn 			/* r1 = [0x00, 0xff] */
78512255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
78522255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
78532255f8d5SJann Horn 			/* r1 = [0xffff'ff80, 0x1'0000'007f] */
78542255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
78552255f8d5SJann Horn 			/* r1 = [0xffff'ff80, 0xffff'ffff] or
78562255f8d5SJann Horn 			 *      [0x0000'0000, 0x0000'007f]
78572255f8d5SJann Horn 			 * difference to previous test: truncation via MOV32
78582255f8d5SJann Horn 			 * instead of ALU32.
78592255f8d5SJann Horn 			 */
78602255f8d5SJann Horn 			BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
78612255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
78622255f8d5SJann Horn 			/* r1 = [0x00, 0xff] or
78632255f8d5SJann Horn 			 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
78642255f8d5SJann Horn 			 */
78652255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
78662255f8d5SJann Horn 			/* r1 = 0 or
78672255f8d5SJann Horn 			 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
78682255f8d5SJann Horn 			 */
78692255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
78702255f8d5SJann Horn 			/* no-op or OOB pointer computation */
78712255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
78722255f8d5SJann Horn 			/* potentially OOB access */
78732255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
78742255f8d5SJann Horn 			/* exit */
78752255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
78762255f8d5SJann Horn 			BPF_EXIT_INSN(),
78772255f8d5SJann Horn 		},
78782255f8d5SJann Horn 		.fixup_map1 = { 3 },
78792255f8d5SJann Horn 		/* not actually fully unbounded, but the bound is very high */
78802255f8d5SJann Horn 		.errstr = "R0 unbounded memory access",
78812255f8d5SJann Horn 		.result = REJECT
78822255f8d5SJann Horn 	},
78832255f8d5SJann Horn 	{
78842255f8d5SJann Horn 		"bounds check after wrapping 32-bit addition",
78852255f8d5SJann Horn 		.insns = {
78862255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
78872255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
78882255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
78892255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
78902255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
78912255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
78922255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
78932255f8d5SJann Horn 			/* r1 = 0x7fff'ffff */
78942255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
78952255f8d5SJann Horn 			/* r1 = 0xffff'fffe */
78962255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
78972255f8d5SJann Horn 			/* r1 = 0 */
78982255f8d5SJann Horn 			BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
78992255f8d5SJann Horn 			/* no-op */
79002255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
79012255f8d5SJann Horn 			/* access at offset 0 */
79022255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
79032255f8d5SJann Horn 			/* exit */
79042255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
79052255f8d5SJann Horn 			BPF_EXIT_INSN(),
79062255f8d5SJann Horn 		},
79072255f8d5SJann Horn 		.fixup_map1 = { 3 },
79082255f8d5SJann Horn 		.result = ACCEPT
79092255f8d5SJann Horn 	},
79102255f8d5SJann Horn 	{
79112255f8d5SJann Horn 		"bounds check after shift with oversized count operand",
79122255f8d5SJann Horn 		.insns = {
79132255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
79142255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
79152255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
79162255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
79172255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
79182255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
79192255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
79202255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_2, 32),
79212255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_1, 1),
79222255f8d5SJann Horn 			/* r1 = (u32)1 << (u32)32 = ? */
79232255f8d5SJann Horn 			BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
79242255f8d5SJann Horn 			/* r1 = [0x0000, 0xffff] */
79252255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
79262255f8d5SJann Horn 			/* computes unknown pointer, potentially OOB */
79272255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
79282255f8d5SJann Horn 			/* potentially OOB access */
79292255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
79302255f8d5SJann Horn 			/* exit */
79312255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
79322255f8d5SJann Horn 			BPF_EXIT_INSN(),
79332255f8d5SJann Horn 		},
79342255f8d5SJann Horn 		.fixup_map1 = { 3 },
79352255f8d5SJann Horn 		.errstr = "R0 max value is outside of the array range",
79362255f8d5SJann Horn 		.result = REJECT
79372255f8d5SJann Horn 	},
79382255f8d5SJann Horn 	{
79392255f8d5SJann Horn 		"bounds check after right shift of maybe-negative number",
79402255f8d5SJann Horn 		.insns = {
79412255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
79422255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
79432255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
79442255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
79452255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
79462255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
79472255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
79482255f8d5SJann Horn 			/* r1 = [0x00, 0xff] */
79492255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
79502255f8d5SJann Horn 			/* r1 = [-0x01, 0xfe] */
79512255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
79522255f8d5SJann Horn 			/* r1 = 0 or 0xff'ffff'ffff'ffff */
79532255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
79542255f8d5SJann Horn 			/* r1 = 0 or 0xffff'ffff'ffff */
79552255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
79562255f8d5SJann Horn 			/* computes unknown pointer, potentially OOB */
79572255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
79582255f8d5SJann Horn 			/* potentially OOB access */
79592255f8d5SJann Horn 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
79602255f8d5SJann Horn 			/* exit */
79612255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
79622255f8d5SJann Horn 			BPF_EXIT_INSN(),
79632255f8d5SJann Horn 		},
79642255f8d5SJann Horn 		.fixup_map1 = { 3 },
79652255f8d5SJann Horn 		.errstr = "R0 unbounded memory access",
79662255f8d5SJann Horn 		.result = REJECT
79672255f8d5SJann Horn 	},
79682255f8d5SJann Horn 	{
79692255f8d5SJann Horn 		"bounds check map access with off+size signed 32bit overflow. test1",
79702255f8d5SJann Horn 		.insns = {
79712255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
79722255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
79732255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
79742255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
79752255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
79762255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
79772255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
79782255f8d5SJann Horn 			BPF_EXIT_INSN(),
79792255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
79802255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
79812255f8d5SJann Horn 			BPF_JMP_A(0),
79822255f8d5SJann Horn 			BPF_EXIT_INSN(),
79832255f8d5SJann Horn 		},
79842255f8d5SJann Horn 		.fixup_map1 = { 3 },
79852255f8d5SJann Horn 		.errstr = "map_value pointer and 2147483646",
79862255f8d5SJann Horn 		.result = REJECT
79872255f8d5SJann Horn 	},
79882255f8d5SJann Horn 	{
79892255f8d5SJann Horn 		"bounds check map access with off+size signed 32bit overflow. test2",
79902255f8d5SJann Horn 		.insns = {
79912255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
79922255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
79932255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
79942255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
79952255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
79962255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
79972255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
79982255f8d5SJann Horn 			BPF_EXIT_INSN(),
79992255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
80002255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
80012255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
80022255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
80032255f8d5SJann Horn 			BPF_JMP_A(0),
80042255f8d5SJann Horn 			BPF_EXIT_INSN(),
80052255f8d5SJann Horn 		},
80062255f8d5SJann Horn 		.fixup_map1 = { 3 },
80072255f8d5SJann Horn 		.errstr = "pointer offset 1073741822",
80082255f8d5SJann Horn 		.result = REJECT
80092255f8d5SJann Horn 	},
80102255f8d5SJann Horn 	{
80112255f8d5SJann Horn 		"bounds check map access with off+size signed 32bit overflow. test3",
80122255f8d5SJann Horn 		.insns = {
80132255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
80142255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
80152255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
80162255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
80172255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
80182255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
80192255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
80202255f8d5SJann Horn 			BPF_EXIT_INSN(),
80212255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
80222255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
80232255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
80242255f8d5SJann Horn 			BPF_JMP_A(0),
80252255f8d5SJann Horn 			BPF_EXIT_INSN(),
80262255f8d5SJann Horn 		},
80272255f8d5SJann Horn 		.fixup_map1 = { 3 },
80282255f8d5SJann Horn 		.errstr = "pointer offset -1073741822",
80292255f8d5SJann Horn 		.result = REJECT
80302255f8d5SJann Horn 	},
80312255f8d5SJann Horn 	{
80322255f8d5SJann Horn 		"bounds check map access with off+size signed 32bit overflow. test4",
80332255f8d5SJann Horn 		.insns = {
80342255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
80352255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
80362255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
80372255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
80382255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
80392255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
80402255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
80412255f8d5SJann Horn 			BPF_EXIT_INSN(),
80422255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_1, 1000000),
80432255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
80442255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
80452255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
80462255f8d5SJann Horn 			BPF_JMP_A(0),
80472255f8d5SJann Horn 			BPF_EXIT_INSN(),
80482255f8d5SJann Horn 		},
80492255f8d5SJann Horn 		.fixup_map1 = { 3 },
80502255f8d5SJann Horn 		.errstr = "map_value pointer and 1000000000000",
80512255f8d5SJann Horn 		.result = REJECT
80522255f8d5SJann Horn 	},
80532255f8d5SJann Horn 	{
80542255f8d5SJann Horn 		"pointer/scalar confusion in state equality check (way 1)",
80552255f8d5SJann Horn 		.insns = {
80562255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
80572255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
80582255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
80592255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
80602255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
80612255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
80622255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
80632255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
80642255f8d5SJann Horn 			BPF_JMP_A(1),
80652255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
80662255f8d5SJann Horn 			BPF_JMP_A(0),
80672255f8d5SJann Horn 			BPF_EXIT_INSN(),
80682255f8d5SJann Horn 		},
80692255f8d5SJann Horn 		.fixup_map1 = { 3 },
80702255f8d5SJann Horn 		.result = ACCEPT,
8071111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
80722255f8d5SJann Horn 		.result_unpriv = REJECT,
80732255f8d5SJann Horn 		.errstr_unpriv = "R0 leaks addr as return value"
80742255f8d5SJann Horn 	},
80752255f8d5SJann Horn 	{
80762255f8d5SJann Horn 		"pointer/scalar confusion in state equality check (way 2)",
80772255f8d5SJann Horn 		.insns = {
80782255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
80792255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
80802255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
80812255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
80822255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
80832255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
80842255f8d5SJann Horn 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
80852255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
80862255f8d5SJann Horn 			BPF_JMP_A(1),
80872255f8d5SJann Horn 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
80882255f8d5SJann Horn 			BPF_EXIT_INSN(),
80892255f8d5SJann Horn 		},
80902255f8d5SJann Horn 		.fixup_map1 = { 3 },
80912255f8d5SJann Horn 		.result = ACCEPT,
8092111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
80932255f8d5SJann Horn 		.result_unpriv = REJECT,
80942255f8d5SJann Horn 		.errstr_unpriv = "R0 leaks addr as return value"
80952255f8d5SJann Horn 	},
80962255f8d5SJann Horn 	{
809769c4e8adSEdward Cree 		"variable-offset ctx access",
809869c4e8adSEdward Cree 		.insns = {
809969c4e8adSEdward Cree 			/* Get an unknown value */
810069c4e8adSEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
810169c4e8adSEdward Cree 			/* Make it small and 4-byte aligned */
810269c4e8adSEdward Cree 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
810369c4e8adSEdward Cree 			/* add it to skb.  We now have either &skb->len or
810469c4e8adSEdward Cree 			 * &skb->pkt_type, but we don't know which
810569c4e8adSEdward Cree 			 */
810669c4e8adSEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
810769c4e8adSEdward Cree 			/* dereference it */
810869c4e8adSEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
810969c4e8adSEdward Cree 			BPF_EXIT_INSN(),
811069c4e8adSEdward Cree 		},
811169c4e8adSEdward Cree 		.errstr = "variable ctx access var_off=(0x0; 0x4)",
811269c4e8adSEdward Cree 		.result = REJECT,
811369c4e8adSEdward Cree 		.prog_type = BPF_PROG_TYPE_LWT_IN,
811469c4e8adSEdward Cree 	},
811569c4e8adSEdward Cree 	{
811669c4e8adSEdward Cree 		"variable-offset stack access",
811769c4e8adSEdward Cree 		.insns = {
811869c4e8adSEdward Cree 			/* Fill the top 8 bytes of the stack */
811969c4e8adSEdward Cree 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
812069c4e8adSEdward Cree 			/* Get an unknown value */
812169c4e8adSEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
812269c4e8adSEdward Cree 			/* Make it small and 4-byte aligned */
812369c4e8adSEdward Cree 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
812469c4e8adSEdward Cree 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
812569c4e8adSEdward Cree 			/* add it to fp.  We now have either fp-4 or fp-8, but
812669c4e8adSEdward Cree 			 * we don't know which
812769c4e8adSEdward Cree 			 */
812869c4e8adSEdward Cree 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
812969c4e8adSEdward Cree 			/* dereference it */
813069c4e8adSEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
813169c4e8adSEdward Cree 			BPF_EXIT_INSN(),
813269c4e8adSEdward Cree 		},
813369c4e8adSEdward Cree 		.errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
813469c4e8adSEdward Cree 		.result = REJECT,
813569c4e8adSEdward Cree 		.prog_type = BPF_PROG_TYPE_LWT_IN,
813669c4e8adSEdward Cree 	},
8137d893dc26SEdward Cree 	{
81382255f8d5SJann Horn 		"indirect variable-offset stack access",
81392255f8d5SJann Horn 		.insns = {
81402255f8d5SJann Horn 			/* Fill the top 8 bytes of the stack */
81412255f8d5SJann Horn 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
81422255f8d5SJann Horn 			/* Get an unknown value */
81432255f8d5SJann Horn 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
81442255f8d5SJann Horn 			/* Make it small and 4-byte aligned */
81452255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
81462255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
81472255f8d5SJann Horn 			/* add it to fp.  We now have either fp-4 or fp-8, but
81482255f8d5SJann Horn 			 * we don't know which
81492255f8d5SJann Horn 			 */
81502255f8d5SJann Horn 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
81512255f8d5SJann Horn 			/* dereference it indirectly */
81522255f8d5SJann Horn 			BPF_LD_MAP_FD(BPF_REG_1, 0),
81532255f8d5SJann Horn 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
81542255f8d5SJann Horn 				     BPF_FUNC_map_lookup_elem),
81552255f8d5SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
81562255f8d5SJann Horn 			BPF_EXIT_INSN(),
81572255f8d5SJann Horn 		},
81582255f8d5SJann Horn 		.fixup_map1 = { 5 },
81592255f8d5SJann Horn 		.errstr = "variable stack read R2",
81602255f8d5SJann Horn 		.result = REJECT,
81612255f8d5SJann Horn 		.prog_type = BPF_PROG_TYPE_LWT_IN,
81622255f8d5SJann Horn 	},
81632255f8d5SJann Horn 	{
81642255f8d5SJann Horn 		"direct stack access with 32-bit wraparound. test1",
81652255f8d5SJann Horn 		.insns = {
81662255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
81672255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
81682255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
81692255f8d5SJann Horn 			BPF_MOV32_IMM(BPF_REG_0, 0),
81702255f8d5SJann Horn 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
81712255f8d5SJann Horn 			BPF_EXIT_INSN()
81722255f8d5SJann Horn 		},
81732255f8d5SJann Horn 		.errstr = "fp pointer and 2147483647",
81742255f8d5SJann Horn 		.result = REJECT
81752255f8d5SJann Horn 	},
81762255f8d5SJann Horn 	{
81772255f8d5SJann Horn 		"direct stack access with 32-bit wraparound. test2",
81782255f8d5SJann Horn 		.insns = {
81792255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
81802255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
81812255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x3fffffff),
81822255f8d5SJann Horn 			BPF_MOV32_IMM(BPF_REG_0, 0),
81832255f8d5SJann Horn 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
81842255f8d5SJann Horn 			BPF_EXIT_INSN()
81852255f8d5SJann Horn 		},
81862255f8d5SJann Horn 		.errstr = "fp pointer and 1073741823",
81872255f8d5SJann Horn 		.result = REJECT
81882255f8d5SJann Horn 	},
81892255f8d5SJann Horn 	{
81902255f8d5SJann Horn 		"direct stack access with 32-bit wraparound. test3",
81912255f8d5SJann Horn 		.insns = {
81922255f8d5SJann Horn 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
81932255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
81942255f8d5SJann Horn 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x1fffffff),
81952255f8d5SJann Horn 			BPF_MOV32_IMM(BPF_REG_0, 0),
81962255f8d5SJann Horn 			BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
81972255f8d5SJann Horn 			BPF_EXIT_INSN()
81982255f8d5SJann Horn 		},
81992255f8d5SJann Horn 		.errstr = "fp pointer offset 1073741822",
82002255f8d5SJann Horn 		.result = REJECT
82012255f8d5SJann Horn 	},
82022255f8d5SJann Horn 	{
8203d893dc26SEdward Cree 		"liveness pruning and write screening",
8204d893dc26SEdward Cree 		.insns = {
8205d893dc26SEdward Cree 			/* Get an unknown value */
8206d893dc26SEdward Cree 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
8207d893dc26SEdward Cree 			/* branch conditions teach us nothing about R2 */
8208d893dc26SEdward Cree 			BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8209d893dc26SEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
8210d893dc26SEdward Cree 			BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
8211d893dc26SEdward Cree 			BPF_MOV64_IMM(BPF_REG_0, 0),
8212d893dc26SEdward Cree 			BPF_EXIT_INSN(),
8213d893dc26SEdward Cree 		},
8214d893dc26SEdward Cree 		.errstr = "R0 !read_ok",
8215d893dc26SEdward Cree 		.result = REJECT,
8216d893dc26SEdward Cree 		.prog_type = BPF_PROG_TYPE_LWT_IN,
8217d893dc26SEdward Cree 	},
8218df20cb7eSAlexei Starovoitov 	{
8219df20cb7eSAlexei Starovoitov 		"varlen_map_value_access pruning",
8220df20cb7eSAlexei Starovoitov 		.insns = {
8221df20cb7eSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8222df20cb7eSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8223df20cb7eSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8224df20cb7eSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
8225df20cb7eSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8226df20cb7eSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
8227df20cb7eSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
8228df20cb7eSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
8229df20cb7eSAlexei Starovoitov 			BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
8230df20cb7eSAlexei Starovoitov 			BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
8231df20cb7eSAlexei Starovoitov 			BPF_MOV32_IMM(BPF_REG_1, 0),
8232df20cb7eSAlexei Starovoitov 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
8233df20cb7eSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
8234df20cb7eSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
8235df20cb7eSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
8236df20cb7eSAlexei Starovoitov 				   offsetof(struct test_val, foo)),
8237df20cb7eSAlexei Starovoitov 			BPF_EXIT_INSN(),
8238df20cb7eSAlexei Starovoitov 		},
8239df20cb7eSAlexei Starovoitov 		.fixup_map2 = { 3 },
8240df20cb7eSAlexei Starovoitov 		.errstr_unpriv = "R0 leaks addr",
8241df20cb7eSAlexei Starovoitov 		.errstr = "R0 unbounded memory access",
8242df20cb7eSAlexei Starovoitov 		.result_unpriv = REJECT,
8243df20cb7eSAlexei Starovoitov 		.result = REJECT,
8244df20cb7eSAlexei Starovoitov 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8245df20cb7eSAlexei Starovoitov 	},
8246e67b8a68SEdward Cree 	{
8247e67b8a68SEdward Cree 		"invalid 64-bit BPF_END",
8248e67b8a68SEdward Cree 		.insns = {
8249e67b8a68SEdward Cree 			BPF_MOV32_IMM(BPF_REG_0, 0),
8250e67b8a68SEdward Cree 			{
8251e67b8a68SEdward Cree 				.code  = BPF_ALU64 | BPF_END | BPF_TO_LE,
8252e67b8a68SEdward Cree 				.dst_reg = BPF_REG_0,
8253e67b8a68SEdward Cree 				.src_reg = 0,
8254e67b8a68SEdward Cree 				.off   = 0,
8255e67b8a68SEdward Cree 				.imm   = 32,
8256e67b8a68SEdward Cree 			},
8257e67b8a68SEdward Cree 			BPF_EXIT_INSN(),
8258e67b8a68SEdward Cree 		},
825921ccaf21SDaniel Borkmann 		.errstr = "unknown opcode d7",
8260e67b8a68SEdward Cree 		.result = REJECT,
8261e67b8a68SEdward Cree 	},
826222c88526SDaniel Borkmann 	{
826365073a67SDaniel Borkmann 		"XDP, using ifindex from netdev",
826465073a67SDaniel Borkmann 		.insns = {
826565073a67SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
826665073a67SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
826765073a67SDaniel Borkmann 				    offsetof(struct xdp_md, ingress_ifindex)),
826865073a67SDaniel Borkmann 			BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
826965073a67SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
827065073a67SDaniel Borkmann 			BPF_EXIT_INSN(),
827165073a67SDaniel Borkmann 		},
827265073a67SDaniel Borkmann 		.result = ACCEPT,
827365073a67SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
827465073a67SDaniel Borkmann 		.retval = 1,
827565073a67SDaniel Borkmann 	},
827665073a67SDaniel Borkmann 	{
827722c88526SDaniel Borkmann 		"meta access, test1",
827822c88526SDaniel Borkmann 		.insns = {
827922c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
828022c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
828122c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
828222c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
828322c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
828422c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
828522c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
828622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
828722c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
828822c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
828922c88526SDaniel Borkmann 		},
829022c88526SDaniel Borkmann 		.result = ACCEPT,
829122c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
829222c88526SDaniel Borkmann 	},
829322c88526SDaniel Borkmann 	{
829422c88526SDaniel Borkmann 		"meta access, test2",
829522c88526SDaniel Borkmann 		.insns = {
829622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
829722c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
829822c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
829922c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
830022c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
830122c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 8),
830222c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
830322c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
830422c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
830522c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
830622c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
830722c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
830822c88526SDaniel Borkmann 		},
830922c88526SDaniel Borkmann 		.result = REJECT,
831022c88526SDaniel Borkmann 		.errstr = "invalid access to packet, off=-8",
831122c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
831222c88526SDaniel Borkmann 	},
831322c88526SDaniel Borkmann 	{
831422c88526SDaniel Borkmann 		"meta access, test3",
831522c88526SDaniel Borkmann 		.insns = {
831622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
831722c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
831822c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
831922c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
832022c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
832122c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
832222c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
832322c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
832422c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
832522c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
832622c88526SDaniel Borkmann 		},
832722c88526SDaniel Borkmann 		.result = REJECT,
832822c88526SDaniel Borkmann 		.errstr = "invalid access to packet",
832922c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
833022c88526SDaniel Borkmann 	},
833122c88526SDaniel Borkmann 	{
833222c88526SDaniel Borkmann 		"meta access, test4",
833322c88526SDaniel Borkmann 		.insns = {
833422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
833522c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
833622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
833722c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
833822c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
833922c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
834022c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
834122c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
834222c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
834322c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
834422c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
834522c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
834622c88526SDaniel Borkmann 		},
834722c88526SDaniel Borkmann 		.result = REJECT,
834822c88526SDaniel Borkmann 		.errstr = "invalid access to packet",
834922c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
835022c88526SDaniel Borkmann 	},
835122c88526SDaniel Borkmann 	{
835222c88526SDaniel Borkmann 		"meta access, test5",
835322c88526SDaniel Borkmann 		.insns = {
835422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
835522c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
835622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
835722c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
835822c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
835922c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
836022c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_4, 3),
836122c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, -8),
836222c88526SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
836322c88526SDaniel Borkmann 				     BPF_FUNC_xdp_adjust_meta),
836422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
836522c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
836622c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
836722c88526SDaniel Borkmann 		},
836822c88526SDaniel Borkmann 		.result = REJECT,
836922c88526SDaniel Borkmann 		.errstr = "R3 !read_ok",
837022c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
837122c88526SDaniel Borkmann 	},
837222c88526SDaniel Borkmann 	{
837322c88526SDaniel Borkmann 		"meta access, test6",
837422c88526SDaniel Borkmann 		.insns = {
837522c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
837622c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
837722c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
837822c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
837922c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
838022c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
838122c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
838222c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
838322c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 1),
838422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
838522c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
838622c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
838722c88526SDaniel Borkmann 		},
838822c88526SDaniel Borkmann 		.result = REJECT,
838922c88526SDaniel Borkmann 		.errstr = "invalid access to packet",
839022c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
839122c88526SDaniel Borkmann 	},
839222c88526SDaniel Borkmann 	{
839322c88526SDaniel Borkmann 		"meta access, test7",
839422c88526SDaniel Borkmann 		.insns = {
839522c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
839622c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
839722c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
839822c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
839922c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
840022c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
840122c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
840222c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
840322c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
840422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
840522c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
840622c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
840722c88526SDaniel Borkmann 		},
840822c88526SDaniel Borkmann 		.result = ACCEPT,
840922c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
841022c88526SDaniel Borkmann 	},
841122c88526SDaniel Borkmann 	{
841222c88526SDaniel Borkmann 		"meta access, test8",
841322c88526SDaniel Borkmann 		.insns = {
841422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
841522c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
841622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
841722c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
841822c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
841922c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
842022c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
842122c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
842222c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
842322c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
842422c88526SDaniel Borkmann 		},
842522c88526SDaniel Borkmann 		.result = ACCEPT,
842622c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
842722c88526SDaniel Borkmann 	},
842822c88526SDaniel Borkmann 	{
842922c88526SDaniel Borkmann 		"meta access, test9",
843022c88526SDaniel Borkmann 		.insns = {
843122c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
843222c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
843322c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
843422c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
843522c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
843622c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0xFFFF),
843722c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
843822c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1),
843922c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
844022c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
844122c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
844222c88526SDaniel Borkmann 		},
844322c88526SDaniel Borkmann 		.result = REJECT,
844422c88526SDaniel Borkmann 		.errstr = "invalid access to packet",
844522c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
844622c88526SDaniel Borkmann 	},
844722c88526SDaniel Borkmann 	{
844822c88526SDaniel Borkmann 		"meta access, test10",
844922c88526SDaniel Borkmann 		.insns = {
845022c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
845122c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
845222c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
845322c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
845422c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
845522c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
845622c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 42),
845722c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_6, 24),
845822c88526SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
845922c88526SDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
846022c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
846122c88526SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
846222c88526SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5),
846322c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
846422c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
846522c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
846622c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_5, 1),
846722c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
846822c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
846922c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
847022c88526SDaniel Borkmann 		},
847122c88526SDaniel Borkmann 		.result = REJECT,
847222c88526SDaniel Borkmann 		.errstr = "invalid access to packet",
847322c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
847422c88526SDaniel Borkmann 	},
847522c88526SDaniel Borkmann 	{
847622c88526SDaniel Borkmann 		"meta access, test11",
847722c88526SDaniel Borkmann 		.insns = {
847822c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
847922c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
848022c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
848122c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
848222c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 42),
848322c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_6, 24),
848422c88526SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8),
848522c88526SDaniel Borkmann 			BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
848622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8),
848722c88526SDaniel Borkmann 			BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6),
848822c88526SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5),
848922c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
849022c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
849122c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8),
849222c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_3, 1),
849322c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_5, 0),
849422c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
849522c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
849622c88526SDaniel Borkmann 		},
849722c88526SDaniel Borkmann 		.result = ACCEPT,
849822c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
849922c88526SDaniel Borkmann 	},
850022c88526SDaniel Borkmann 	{
850122c88526SDaniel Borkmann 		"meta access, test12",
850222c88526SDaniel Borkmann 		.insns = {
850322c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
850422c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
850522c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
850622c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
850722c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1,
850822c88526SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
850922c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
851022c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
851122c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 5),
851222c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 0),
851322c88526SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
851422c88526SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 16),
851522c88526SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 1),
851622c88526SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
851722c88526SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
851822c88526SDaniel Borkmann 			BPF_EXIT_INSN(),
851922c88526SDaniel Borkmann 		},
852022c88526SDaniel Borkmann 		.result = ACCEPT,
852122c88526SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
852222c88526SDaniel Borkmann 	},
8523390ee7e2SAlexei Starovoitov 	{
852428e33f9dSJakub Kicinski 		"arithmetic ops make PTR_TO_CTX unusable",
852528e33f9dSJakub Kicinski 		.insns = {
852628e33f9dSJakub Kicinski 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
852728e33f9dSJakub Kicinski 				      offsetof(struct __sk_buff, data) -
852828e33f9dSJakub Kicinski 				      offsetof(struct __sk_buff, mark)),
852928e33f9dSJakub Kicinski 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
853028e33f9dSJakub Kicinski 				    offsetof(struct __sk_buff, mark)),
853128e33f9dSJakub Kicinski 			BPF_EXIT_INSN(),
853228e33f9dSJakub Kicinski 		},
853328e33f9dSJakub Kicinski 		.errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
853428e33f9dSJakub Kicinski 		.result = REJECT,
853528e33f9dSJakub Kicinski 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
853628e33f9dSJakub Kicinski 	},
8537b37242c7SDaniel Borkmann 	{
853882abbf8dSAlexei Starovoitov 		"pkt_end - pkt_start is allowed",
853982abbf8dSAlexei Starovoitov 		.insns = {
854082abbf8dSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
854182abbf8dSAlexei Starovoitov 				    offsetof(struct __sk_buff, data_end)),
854282abbf8dSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
854382abbf8dSAlexei Starovoitov 				    offsetof(struct __sk_buff, data)),
854482abbf8dSAlexei Starovoitov 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
854582abbf8dSAlexei Starovoitov 			BPF_EXIT_INSN(),
854682abbf8dSAlexei Starovoitov 		},
854782abbf8dSAlexei Starovoitov 		.result = ACCEPT,
8548111e6b45SAlexei Starovoitov 		.retval = TEST_DATA_LEN,
854982abbf8dSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
855082abbf8dSAlexei Starovoitov 	},
855182abbf8dSAlexei Starovoitov 	{
8552b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end mangling, bad access 1",
8553b37242c7SDaniel Borkmann 		.insns = {
8554b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8555b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8556b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8557b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8558b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8559b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8560b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
8561b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8562b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8563b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8564b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8565b37242c7SDaniel Borkmann 		},
856682abbf8dSAlexei Starovoitov 		.errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
8567b37242c7SDaniel Borkmann 		.result = REJECT,
8568b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8569b37242c7SDaniel Borkmann 	},
8570b37242c7SDaniel Borkmann 	{
8571b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end mangling, bad access 2",
8572b37242c7SDaniel Borkmann 		.insns = {
8573b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8574b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8575b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8576b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8577b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8578b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8579b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
8580b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8581b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8582b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8583b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8584b37242c7SDaniel Borkmann 		},
858582abbf8dSAlexei Starovoitov 		.errstr = "R3 pointer arithmetic on PTR_TO_PACKET_END",
8586b37242c7SDaniel Borkmann 		.result = REJECT,
8587b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8588b37242c7SDaniel Borkmann 	},
8589b37242c7SDaniel Borkmann 	{
8590b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' > pkt_end, good access",
8591b37242c7SDaniel Borkmann 		.insns = {
8592b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8593b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8594b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8595b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8596b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8597b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8598b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8599b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8600b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8601b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8602b37242c7SDaniel Borkmann 		},
8603b37242c7SDaniel Borkmann 		.result = ACCEPT,
8604b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8605b37242c7SDaniel Borkmann 	},
8606b37242c7SDaniel Borkmann 	{
8607b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' > pkt_end, bad access 1",
8608b37242c7SDaniel Borkmann 		.insns = {
8609b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8610b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8611b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8612b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8613b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8614b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8615b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
8616b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8617b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8618b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8619b37242c7SDaniel Borkmann 		},
8620b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8621b37242c7SDaniel Borkmann 		.result = REJECT,
8622b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8623b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8624b37242c7SDaniel Borkmann 	},
8625b37242c7SDaniel Borkmann 	{
8626b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' > pkt_end, bad access 2",
8627b37242c7SDaniel Borkmann 		.insns = {
8628b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8629b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8630b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8631b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8632b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8633b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8634b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
8635b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8636b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8637b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8638b37242c7SDaniel Borkmann 		},
8639b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8640b37242c7SDaniel Borkmann 		.result = REJECT,
8641b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8642b37242c7SDaniel Borkmann 	},
8643b37242c7SDaniel Borkmann 	{
8644b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end > pkt_data', good access",
8645b37242c7SDaniel Borkmann 		.insns = {
8646b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8647b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8648b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8649b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8650b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8651b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8652b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8653b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8654b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8655b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8656b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8657b37242c7SDaniel Borkmann 		},
8658b37242c7SDaniel Borkmann 		.result = ACCEPT,
8659b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8660b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8661b37242c7SDaniel Borkmann 	},
8662b37242c7SDaniel Borkmann 	{
8663b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end > pkt_data', bad access 1",
8664b37242c7SDaniel Borkmann 		.insns = {
8665b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8666b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8667b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8668b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8669b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8670b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8671b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8672b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8673b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8674b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8675b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8676b37242c7SDaniel Borkmann 		},
8677b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8678b37242c7SDaniel Borkmann 		.result = REJECT,
8679b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8680b37242c7SDaniel Borkmann 	},
8681b37242c7SDaniel Borkmann 	{
8682b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end > pkt_data', bad access 2",
8683b37242c7SDaniel Borkmann 		.insns = {
8684b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8685b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8686b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8687b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8688b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8689b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8690b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
8691b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8692b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8693b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8694b37242c7SDaniel Borkmann 		},
8695b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8696b37242c7SDaniel Borkmann 		.result = REJECT,
8697b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8698b37242c7SDaniel Borkmann 	},
8699b37242c7SDaniel Borkmann 	{
8700b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' < pkt_end, good access",
8701b37242c7SDaniel Borkmann 		.insns = {
8702b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8703b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8704b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8705b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8706b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8707b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8708b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8709b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8710b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8711b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8712b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8713b37242c7SDaniel Borkmann 		},
8714b37242c7SDaniel Borkmann 		.result = ACCEPT,
8715b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8716b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8717b37242c7SDaniel Borkmann 	},
8718b37242c7SDaniel Borkmann 	{
8719b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' < pkt_end, bad access 1",
8720b37242c7SDaniel Borkmann 		.insns = {
8721b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8722b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8723b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8724b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8725b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8726b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8727b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8728b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8729b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8730b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8731b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8732b37242c7SDaniel Borkmann 		},
8733b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8734b37242c7SDaniel Borkmann 		.result = REJECT,
8735b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8736b37242c7SDaniel Borkmann 	},
8737b37242c7SDaniel Borkmann 	{
8738b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' < pkt_end, bad access 2",
8739b37242c7SDaniel Borkmann 		.insns = {
8740b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8741b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8742b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8743b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8744b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8745b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8746b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
8747b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8748b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8749b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8750b37242c7SDaniel Borkmann 		},
8751b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8752b37242c7SDaniel Borkmann 		.result = REJECT,
8753b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8754b37242c7SDaniel Borkmann 	},
8755b37242c7SDaniel Borkmann 	{
8756b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end < pkt_data', good access",
8757b37242c7SDaniel Borkmann 		.insns = {
8758b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8759b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8760b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8761b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8762b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8763b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8764b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8765b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8766b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8767b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8768b37242c7SDaniel Borkmann 		},
8769b37242c7SDaniel Borkmann 		.result = ACCEPT,
8770b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8771b37242c7SDaniel Borkmann 	},
8772b37242c7SDaniel Borkmann 	{
8773b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end < pkt_data', bad access 1",
8774b37242c7SDaniel Borkmann 		.insns = {
8775b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8776b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8777b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8778b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8779b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8780b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8781b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
8782b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8783b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8784b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8785b37242c7SDaniel Borkmann 		},
8786b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8787b37242c7SDaniel Borkmann 		.result = REJECT,
8788b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8789b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8790b37242c7SDaniel Borkmann 	},
8791b37242c7SDaniel Borkmann 	{
8792b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end < pkt_data', bad access 2",
8793b37242c7SDaniel Borkmann 		.insns = {
8794b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8795b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8796b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8797b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8798b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8799b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8800b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
8801b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8802b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8803b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8804b37242c7SDaniel Borkmann 		},
8805b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8806b37242c7SDaniel Borkmann 		.result = REJECT,
8807b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8808b37242c7SDaniel Borkmann 	},
8809b37242c7SDaniel Borkmann 	{
8810b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' >= pkt_end, good access",
8811b37242c7SDaniel Borkmann 		.insns = {
8812b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8813b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8814b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8815b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8816b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8817b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8818b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8819b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8820b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8821b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8822b37242c7SDaniel Borkmann 		},
8823b37242c7SDaniel Borkmann 		.result = ACCEPT,
8824b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8825b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8826b37242c7SDaniel Borkmann 	},
8827b37242c7SDaniel Borkmann 	{
8828b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' >= pkt_end, bad access 1",
8829b37242c7SDaniel Borkmann 		.insns = {
8830b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8831b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8832b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8833b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8834b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8835b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8836b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
8837b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8838b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8839b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8840b37242c7SDaniel Borkmann 		},
8841b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8842b37242c7SDaniel Borkmann 		.result = REJECT,
8843b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8844b37242c7SDaniel Borkmann 	},
8845b37242c7SDaniel Borkmann 	{
8846b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' >= pkt_end, bad access 2",
8847b37242c7SDaniel Borkmann 		.insns = {
8848b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8849b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8850b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8851b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8852b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8853b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8854b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
8855b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8856b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8857b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8858b37242c7SDaniel Borkmann 		},
8859b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8860b37242c7SDaniel Borkmann 		.result = REJECT,
8861b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8862b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8863b37242c7SDaniel Borkmann 	},
8864b37242c7SDaniel Borkmann 	{
8865b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end >= pkt_data', good access",
8866b37242c7SDaniel Borkmann 		.insns = {
8867b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8868b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8869b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8870b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8871b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8872b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8873b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8874b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8875b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8876b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8877b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8878b37242c7SDaniel Borkmann 		},
8879b37242c7SDaniel Borkmann 		.result = ACCEPT,
8880b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8881b37242c7SDaniel Borkmann 	},
8882b37242c7SDaniel Borkmann 	{
8883b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end >= pkt_data', bad access 1",
8884b37242c7SDaniel Borkmann 		.insns = {
8885b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8886b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8887b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8888b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8889b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8890b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8891b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8892b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8893b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8894b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8895b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8896b37242c7SDaniel Borkmann 		},
8897b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8898b37242c7SDaniel Borkmann 		.result = REJECT,
8899b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8900b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8901b37242c7SDaniel Borkmann 	},
8902b37242c7SDaniel Borkmann 	{
8903b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end >= pkt_data', bad access 2",
8904b37242c7SDaniel Borkmann 		.insns = {
8905b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8906b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8907b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8908b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8909b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8910b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8911b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
8912b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8913b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8914b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8915b37242c7SDaniel Borkmann 		},
8916b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8917b37242c7SDaniel Borkmann 		.result = REJECT,
8918b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8919b37242c7SDaniel Borkmann 	},
8920b37242c7SDaniel Borkmann 	{
8921b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' <= pkt_end, good access",
8922b37242c7SDaniel Borkmann 		.insns = {
8923b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8924b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8925b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8926b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8927b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8928b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8929b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8930b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8931b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8932b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8933b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8934b37242c7SDaniel Borkmann 		},
8935b37242c7SDaniel Borkmann 		.result = ACCEPT,
8936b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8937b37242c7SDaniel Borkmann 	},
8938b37242c7SDaniel Borkmann 	{
8939b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' <= pkt_end, bad access 1",
8940b37242c7SDaniel Borkmann 		.insns = {
8941b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8942b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8943b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8944b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8945b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8946b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8947b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8948b37242c7SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8949b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
8950b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8951b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8952b37242c7SDaniel Borkmann 		},
8953b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8954b37242c7SDaniel Borkmann 		.result = REJECT,
8955b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8956b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8957b37242c7SDaniel Borkmann 	},
8958b37242c7SDaniel Borkmann 	{
8959b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_data' <= pkt_end, bad access 2",
8960b37242c7SDaniel Borkmann 		.insns = {
8961b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8962b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8963b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8964b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8965b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8966b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8967b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
8968b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
8969b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8970b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8971b37242c7SDaniel Borkmann 		},
8972b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
8973b37242c7SDaniel Borkmann 		.result = REJECT,
8974b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8975b37242c7SDaniel Borkmann 	},
8976b37242c7SDaniel Borkmann 	{
8977b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end <= pkt_data', good access",
8978b37242c7SDaniel Borkmann 		.insns = {
8979b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8980b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8981b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
8982b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
8983b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
8984b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
8985b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
8986b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
8987b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
8988b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
8989b37242c7SDaniel Borkmann 		},
8990b37242c7SDaniel Borkmann 		.result = ACCEPT,
8991b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
8992b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8993b37242c7SDaniel Borkmann 	},
8994b37242c7SDaniel Borkmann 	{
8995b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end <= pkt_data', bad access 1",
8996b37242c7SDaniel Borkmann 		.insns = {
8997b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8998b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
8999b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9000b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
9001b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9002b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9003b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9004b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9005b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9006b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
9007b37242c7SDaniel Borkmann 		},
9008b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9009b37242c7SDaniel Borkmann 		.result = REJECT,
9010b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9011b37242c7SDaniel Borkmann 	},
9012b37242c7SDaniel Borkmann 	{
9013b37242c7SDaniel Borkmann 		"XDP pkt read, pkt_end <= pkt_data', bad access 2",
9014b37242c7SDaniel Borkmann 		.insns = {
9015b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9016b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9017b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9018b37242c7SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
9019b37242c7SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9020b37242c7SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9021b37242c7SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9022b37242c7SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9023b37242c7SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9024b37242c7SDaniel Borkmann 			BPF_EXIT_INSN(),
9025b37242c7SDaniel Borkmann 		},
9026b37242c7SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9027b37242c7SDaniel Borkmann 		.result = REJECT,
9028b37242c7SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9029b37242c7SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9030b37242c7SDaniel Borkmann 	},
9031b06723daSDaniel Borkmann 	{
9032634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' > pkt_data, good access",
9033634eab11SDaniel Borkmann 		.insns = {
9034634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9035634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9036634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9037634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9038634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9039634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9040634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9041634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9042634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9043634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9044634eab11SDaniel Borkmann 		},
9045634eab11SDaniel Borkmann 		.result = ACCEPT,
9046634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9047634eab11SDaniel Borkmann 	},
9048634eab11SDaniel Borkmann 	{
9049634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' > pkt_data, bad access 1",
9050634eab11SDaniel Borkmann 		.insns = {
9051634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9052634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9053634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9054634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9055634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9056634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9057634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
9058634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9059634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9060634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9061634eab11SDaniel Borkmann 		},
9062634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9063634eab11SDaniel Borkmann 		.result = REJECT,
9064634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9065634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9066634eab11SDaniel Borkmann 	},
9067634eab11SDaniel Borkmann 	{
9068634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' > pkt_data, bad access 2",
9069634eab11SDaniel Borkmann 		.insns = {
9070634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9071634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9072634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9073634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9074634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9075634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9076634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
9077634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9078634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9079634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9080634eab11SDaniel Borkmann 		},
9081634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9082634eab11SDaniel Borkmann 		.result = REJECT,
9083634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9084634eab11SDaniel Borkmann 	},
9085634eab11SDaniel Borkmann 	{
9086634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data > pkt_meta', good access",
9087634eab11SDaniel Borkmann 		.insns = {
9088634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9089634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9090634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9091634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9092634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9093634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9094634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9095634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9096634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9097634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9098634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9099634eab11SDaniel Borkmann 		},
9100634eab11SDaniel Borkmann 		.result = ACCEPT,
9101634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9102634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9103634eab11SDaniel Borkmann 	},
9104634eab11SDaniel Borkmann 	{
9105634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data > pkt_meta', bad access 1",
9106634eab11SDaniel Borkmann 		.insns = {
9107634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9108634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9109634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9110634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9111634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9112634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9113634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9114634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9115634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9116634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9117634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9118634eab11SDaniel Borkmann 		},
9119634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9120634eab11SDaniel Borkmann 		.result = REJECT,
9121634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9122634eab11SDaniel Borkmann 	},
9123634eab11SDaniel Borkmann 	{
9124634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data > pkt_meta', bad access 2",
9125634eab11SDaniel Borkmann 		.insns = {
9126634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9127634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9128634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9129634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9130634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9131634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9132634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
9133634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9134634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9135634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9136634eab11SDaniel Borkmann 		},
9137634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9138634eab11SDaniel Borkmann 		.result = REJECT,
9139634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9140634eab11SDaniel Borkmann 	},
9141634eab11SDaniel Borkmann 	{
9142634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' < pkt_data, good access",
9143634eab11SDaniel Borkmann 		.insns = {
9144634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9145634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9146634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9147634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9148634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9149634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9150634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9151634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9152634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9153634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9154634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9155634eab11SDaniel Borkmann 		},
9156634eab11SDaniel Borkmann 		.result = ACCEPT,
9157634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9158634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9159634eab11SDaniel Borkmann 	},
9160634eab11SDaniel Borkmann 	{
9161634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' < pkt_data, bad access 1",
9162634eab11SDaniel Borkmann 		.insns = {
9163634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9164634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9165634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9166634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9167634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9168634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9169634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9170634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9171634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9172634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9173634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9174634eab11SDaniel Borkmann 		},
9175634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9176634eab11SDaniel Borkmann 		.result = REJECT,
9177634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9178634eab11SDaniel Borkmann 	},
9179634eab11SDaniel Borkmann 	{
9180634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' < pkt_data, bad access 2",
9181634eab11SDaniel Borkmann 		.insns = {
9182634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9183634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9184634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9185634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9186634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9187634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9188634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
9189634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9190634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9191634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9192634eab11SDaniel Borkmann 		},
9193634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9194634eab11SDaniel Borkmann 		.result = REJECT,
9195634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9196634eab11SDaniel Borkmann 	},
9197634eab11SDaniel Borkmann 	{
9198634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data < pkt_meta', good access",
9199634eab11SDaniel Borkmann 		.insns = {
9200634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9201634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9202634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9203634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9204634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9205634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9206634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9207634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9208634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9209634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9210634eab11SDaniel Borkmann 		},
9211634eab11SDaniel Borkmann 		.result = ACCEPT,
9212634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9213634eab11SDaniel Borkmann 	},
9214634eab11SDaniel Borkmann 	{
9215634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data < pkt_meta', bad access 1",
9216634eab11SDaniel Borkmann 		.insns = {
9217634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9218634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9219634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9220634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9221634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9222634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9223634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
9224634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9225634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9226634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9227634eab11SDaniel Borkmann 		},
9228634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9229634eab11SDaniel Borkmann 		.result = REJECT,
9230634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9231634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9232634eab11SDaniel Borkmann 	},
9233634eab11SDaniel Borkmann 	{
9234634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data < pkt_meta', bad access 2",
9235634eab11SDaniel Borkmann 		.insns = {
9236634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9237634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9238634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9239634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9240634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9241634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9242634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
9243634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9244634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9245634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9246634eab11SDaniel Borkmann 		},
9247634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9248634eab11SDaniel Borkmann 		.result = REJECT,
9249634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9250634eab11SDaniel Borkmann 	},
9251634eab11SDaniel Borkmann 	{
9252634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' >= pkt_data, good access",
9253634eab11SDaniel Borkmann 		.insns = {
9254634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9255634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9256634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9257634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9258634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9259634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9260634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9261634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9262634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9263634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9264634eab11SDaniel Borkmann 		},
9265634eab11SDaniel Borkmann 		.result = ACCEPT,
9266634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9267634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9268634eab11SDaniel Borkmann 	},
9269634eab11SDaniel Borkmann 	{
9270634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
9271634eab11SDaniel Borkmann 		.insns = {
9272634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9273634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9274634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9275634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9276634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9277634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9278634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
9279634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9280634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9281634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9282634eab11SDaniel Borkmann 		},
9283634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9284634eab11SDaniel Borkmann 		.result = REJECT,
9285634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9286634eab11SDaniel Borkmann 	},
9287634eab11SDaniel Borkmann 	{
9288634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' >= pkt_data, bad access 2",
9289634eab11SDaniel Borkmann 		.insns = {
9290634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9291634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9292634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9293634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9294634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9295634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9296634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
9297634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9298634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9299634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9300634eab11SDaniel Borkmann 		},
9301634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9302634eab11SDaniel Borkmann 		.result = REJECT,
9303634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9304634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9305634eab11SDaniel Borkmann 	},
9306634eab11SDaniel Borkmann 	{
9307634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data >= pkt_meta', good access",
9308634eab11SDaniel Borkmann 		.insns = {
9309634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9310634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9311634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9312634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9313634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9314634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9315634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9316634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9317634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9318634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9319634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9320634eab11SDaniel Borkmann 		},
9321634eab11SDaniel Borkmann 		.result = ACCEPT,
9322634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9323634eab11SDaniel Borkmann 	},
9324634eab11SDaniel Borkmann 	{
9325634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data >= pkt_meta', bad access 1",
9326634eab11SDaniel Borkmann 		.insns = {
9327634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9328634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9329634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9330634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9331634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9332634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9333634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9334634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9335634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9336634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9337634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9338634eab11SDaniel Borkmann 		},
9339634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9340634eab11SDaniel Borkmann 		.result = REJECT,
9341634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9342634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9343634eab11SDaniel Borkmann 	},
9344634eab11SDaniel Borkmann 	{
9345634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data >= pkt_meta', bad access 2",
9346634eab11SDaniel Borkmann 		.insns = {
9347634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9348634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9349634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9350634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9351634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9352634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9353634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
9354634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9355634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9356634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9357634eab11SDaniel Borkmann 		},
9358634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9359634eab11SDaniel Borkmann 		.result = REJECT,
9360634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9361634eab11SDaniel Borkmann 	},
9362634eab11SDaniel Borkmann 	{
9363634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' <= pkt_data, good access",
9364634eab11SDaniel Borkmann 		.insns = {
9365634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9366634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9367634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9368634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9369634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9370634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9371634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9372634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9373634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9374634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9375634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9376634eab11SDaniel Borkmann 		},
9377634eab11SDaniel Borkmann 		.result = ACCEPT,
9378634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9379634eab11SDaniel Borkmann 	},
9380634eab11SDaniel Borkmann 	{
9381634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' <= pkt_data, bad access 1",
9382634eab11SDaniel Borkmann 		.insns = {
9383634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9384634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9385634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9386634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9387634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9388634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9389634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9390634eab11SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9391634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
9392634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9393634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9394634eab11SDaniel Borkmann 		},
9395634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9396634eab11SDaniel Borkmann 		.result = REJECT,
9397634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9398634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9399634eab11SDaniel Borkmann 	},
9400634eab11SDaniel Borkmann 	{
9401634eab11SDaniel Borkmann 		"XDP pkt read, pkt_meta' <= pkt_data, bad access 2",
9402634eab11SDaniel Borkmann 		.insns = {
9403634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9404634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9405634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9406634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9407634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9408634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9409634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
9410634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9411634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9412634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9413634eab11SDaniel Borkmann 		},
9414634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9415634eab11SDaniel Borkmann 		.result = REJECT,
9416634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9417634eab11SDaniel Borkmann 	},
9418634eab11SDaniel Borkmann 	{
9419634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data <= pkt_meta', good access",
9420634eab11SDaniel Borkmann 		.insns = {
9421634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9422634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9423634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9424634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9425634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9426634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9427634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9428634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9429634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9430634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9431634eab11SDaniel Borkmann 		},
9432634eab11SDaniel Borkmann 		.result = ACCEPT,
9433634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9434634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9435634eab11SDaniel Borkmann 	},
9436634eab11SDaniel Borkmann 	{
9437634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data <= pkt_meta', bad access 1",
9438634eab11SDaniel Borkmann 		.insns = {
9439634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9440634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9441634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9442634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9443634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9444634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9445634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
9446634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
9447634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9448634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9449634eab11SDaniel Borkmann 		},
9450634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9451634eab11SDaniel Borkmann 		.result = REJECT,
9452634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9453634eab11SDaniel Borkmann 	},
9454634eab11SDaniel Borkmann 	{
9455634eab11SDaniel Borkmann 		"XDP pkt read, pkt_data <= pkt_meta', bad access 2",
9456634eab11SDaniel Borkmann 		.insns = {
9457634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9458634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data_meta)),
9459634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9460634eab11SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
9461634eab11SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
9462634eab11SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
9463634eab11SDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
9464634eab11SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
9465634eab11SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
9466634eab11SDaniel Borkmann 			BPF_EXIT_INSN(),
9467634eab11SDaniel Borkmann 		},
9468634eab11SDaniel Borkmann 		.errstr = "R1 offset is outside of the packet",
9469634eab11SDaniel Borkmann 		.result = REJECT,
9470634eab11SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
9471634eab11SDaniel Borkmann 		.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9472634eab11SDaniel Borkmann 	},
9473634eab11SDaniel Borkmann 	{
94746f16101eSDaniel Borkmann 		"check deducing bounds from const, 1",
94756f16101eSDaniel Borkmann 		.insns = {
94766f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
94776f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
94786f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
94796f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
94806f16101eSDaniel Borkmann 		},
94816f16101eSDaniel Borkmann 		.result = REJECT,
94826f16101eSDaniel Borkmann 		.errstr = "R0 tried to subtract pointer from scalar",
94836f16101eSDaniel Borkmann 	},
94846f16101eSDaniel Borkmann 	{
94856f16101eSDaniel Borkmann 		"check deducing bounds from const, 2",
94866f16101eSDaniel Borkmann 		.insns = {
94876f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
94886f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
94896f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
94906f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
94916f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
94926f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
94936f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
94946f16101eSDaniel Borkmann 		},
94956f16101eSDaniel Borkmann 		.result = ACCEPT,
949635136920SYonghong Song 		.retval = 1,
94976f16101eSDaniel Borkmann 	},
94986f16101eSDaniel Borkmann 	{
94996f16101eSDaniel Borkmann 		"check deducing bounds from const, 3",
95006f16101eSDaniel Borkmann 		.insns = {
95016f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95026f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
95036f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
95046f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95056f16101eSDaniel Borkmann 		},
95066f16101eSDaniel Borkmann 		.result = REJECT,
95076f16101eSDaniel Borkmann 		.errstr = "R0 tried to subtract pointer from scalar",
95086f16101eSDaniel Borkmann 	},
95096f16101eSDaniel Borkmann 	{
95106f16101eSDaniel Borkmann 		"check deducing bounds from const, 4",
95116f16101eSDaniel Borkmann 		.insns = {
95126f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95136f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
95146f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95156f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
95166f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95176f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
95186f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95196f16101eSDaniel Borkmann 		},
95206f16101eSDaniel Borkmann 		.result = ACCEPT,
95216f16101eSDaniel Borkmann 	},
95226f16101eSDaniel Borkmann 	{
95236f16101eSDaniel Borkmann 		"check deducing bounds from const, 5",
95246f16101eSDaniel Borkmann 		.insns = {
95256f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95266f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
95276f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
95286f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95296f16101eSDaniel Borkmann 		},
95306f16101eSDaniel Borkmann 		.result = REJECT,
95316f16101eSDaniel Borkmann 		.errstr = "R0 tried to subtract pointer from scalar",
95326f16101eSDaniel Borkmann 	},
95336f16101eSDaniel Borkmann 	{
95346f16101eSDaniel Borkmann 		"check deducing bounds from const, 6",
95356f16101eSDaniel Borkmann 		.insns = {
95366f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95376f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
95386f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95396f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
95406f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95416f16101eSDaniel Borkmann 		},
95426f16101eSDaniel Borkmann 		.result = REJECT,
95436f16101eSDaniel Borkmann 		.errstr = "R0 tried to subtract pointer from scalar",
95446f16101eSDaniel Borkmann 	},
95456f16101eSDaniel Borkmann 	{
95466f16101eSDaniel Borkmann 		"check deducing bounds from const, 7",
95476f16101eSDaniel Borkmann 		.insns = {
95486f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, ~0),
95496f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
95506f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
95516f16101eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
95526f16101eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
95536f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95546f16101eSDaniel Borkmann 		},
95556f16101eSDaniel Borkmann 		.result = REJECT,
95566f16101eSDaniel Borkmann 		.errstr = "dereference of modified ctx ptr",
95576f16101eSDaniel Borkmann 	},
95586f16101eSDaniel Borkmann 	{
95596f16101eSDaniel Borkmann 		"check deducing bounds from const, 8",
95606f16101eSDaniel Borkmann 		.insns = {
95616f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, ~0),
95626f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
95636f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
95646f16101eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
95656f16101eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
95666f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95676f16101eSDaniel Borkmann 		},
95686f16101eSDaniel Borkmann 		.result = REJECT,
95696f16101eSDaniel Borkmann 		.errstr = "dereference of modified ctx ptr",
95706f16101eSDaniel Borkmann 	},
95716f16101eSDaniel Borkmann 	{
95726f16101eSDaniel Borkmann 		"check deducing bounds from const, 9",
95736f16101eSDaniel Borkmann 		.insns = {
95746f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95756f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
95766f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
95776f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95786f16101eSDaniel Borkmann 		},
95796f16101eSDaniel Borkmann 		.result = REJECT,
95806f16101eSDaniel Borkmann 		.errstr = "R0 tried to subtract pointer from scalar",
95816f16101eSDaniel Borkmann 	},
95826f16101eSDaniel Borkmann 	{
95836f16101eSDaniel Borkmann 		"check deducing bounds from const, 10",
95846f16101eSDaniel Borkmann 		.insns = {
95856f16101eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
95866f16101eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
95876f16101eSDaniel Borkmann 			/* Marks reg as unknown. */
95886f16101eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
95896f16101eSDaniel Borkmann 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
95906f16101eSDaniel Borkmann 			BPF_EXIT_INSN(),
95916f16101eSDaniel Borkmann 		},
95926f16101eSDaniel Borkmann 		.result = REJECT,
95936f16101eSDaniel Borkmann 		.errstr = "math between ctx pointer and register with unbounded min value is not allowed",
95946f16101eSDaniel Borkmann 	},
95956f16101eSDaniel Borkmann 	{
9596b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test1",
9597b06723daSDaniel Borkmann 		.insns = {
9598b06723daSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9599b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9600b06723daSDaniel Borkmann 		},
9601b06723daSDaniel Borkmann 		.errstr = "R0 has value (0x0; 0xffffffff)",
9602b06723daSDaniel Borkmann 		.result = REJECT,
9603b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9604b06723daSDaniel Borkmann 	},
9605b06723daSDaniel Borkmann 	{
9606b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test2",
9607b06723daSDaniel Borkmann 		.insns = {
9608b06723daSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9609b06723daSDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
9610b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9611b06723daSDaniel Borkmann 		},
9612b06723daSDaniel Borkmann 		.result = ACCEPT,
9613b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9614b06723daSDaniel Borkmann 	},
9615b06723daSDaniel Borkmann 	{
9616b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test3",
9617b06723daSDaniel Borkmann 		.insns = {
9618b06723daSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9619b06723daSDaniel Borkmann 			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 3),
9620b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9621b06723daSDaniel Borkmann 		},
9622b06723daSDaniel Borkmann 		.errstr = "R0 has value (0x0; 0x3)",
9623b06723daSDaniel Borkmann 		.result = REJECT,
9624b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9625b06723daSDaniel Borkmann 	},
9626b06723daSDaniel Borkmann 	{
9627b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test4",
9628b06723daSDaniel Borkmann 		.insns = {
9629b06723daSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
9630b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9631b06723daSDaniel Borkmann 		},
9632b06723daSDaniel Borkmann 		.result = ACCEPT,
9633b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9634b06723daSDaniel Borkmann 	},
9635b06723daSDaniel Borkmann 	{
9636b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test5",
9637b06723daSDaniel Borkmann 		.insns = {
9638b06723daSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
9639b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9640b06723daSDaniel Borkmann 		},
9641b06723daSDaniel Borkmann 		.errstr = "R0 has value (0x2; 0x0)",
9642b06723daSDaniel Borkmann 		.result = REJECT,
9643b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9644b06723daSDaniel Borkmann 	},
9645b06723daSDaniel Borkmann 	{
9646b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test6",
9647b06723daSDaniel Borkmann 		.insns = {
9648b06723daSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9649b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9650b06723daSDaniel Borkmann 		},
9651b06723daSDaniel Borkmann 		.errstr = "R0 is not a known value (ctx)",
9652b06723daSDaniel Borkmann 		.result = REJECT,
9653b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9654b06723daSDaniel Borkmann 	},
9655b06723daSDaniel Borkmann 	{
9656b06723daSDaniel Borkmann 		"bpf_exit with invalid return code. test7",
9657b06723daSDaniel Borkmann 		.insns = {
9658b06723daSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
9659b06723daSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 4),
9660b06723daSDaniel Borkmann 			BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_2),
9661b06723daSDaniel Borkmann 			BPF_EXIT_INSN(),
9662b06723daSDaniel Borkmann 		},
9663b06723daSDaniel Borkmann 		.errstr = "R0 has unknown scalar value",
9664b06723daSDaniel Borkmann 		.result = REJECT,
9665b06723daSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
9666b06723daSDaniel Borkmann 	},
9667a7ff3ecaSAlexei Starovoitov 	{
9668a7ff3ecaSAlexei Starovoitov 		"calls: basic sanity",
9669a7ff3ecaSAlexei Starovoitov 		.insns = {
9670a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
9671a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 1),
9672a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9673a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 2),
9674a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9675a7ff3ecaSAlexei Starovoitov 		},
9676a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
9677a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
9678a7ff3ecaSAlexei Starovoitov 	},
9679a7ff3ecaSAlexei Starovoitov 	{
968028ab173eSDaniel Borkmann 		"calls: not on unpriviledged",
968128ab173eSDaniel Borkmann 		.insns = {
968228ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
968328ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
968428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
968528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
968628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
968728ab173eSDaniel Borkmann 		},
968828ab173eSDaniel Borkmann 		.errstr_unpriv = "function calls to other bpf functions are allowed for root only",
968928ab173eSDaniel Borkmann 		.result_unpriv = REJECT,
969028ab173eSDaniel Borkmann 		.result = ACCEPT,
9691111e6b45SAlexei Starovoitov 		.retval = 1,
969228ab173eSDaniel Borkmann 	},
969328ab173eSDaniel Borkmann 	{
969421ccaf21SDaniel Borkmann 		"calls: div by 0 in subprog",
969521ccaf21SDaniel Borkmann 		.insns = {
969621ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
969721ccaf21SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
969821ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
969921ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
970021ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
970121ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
970221ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
970321ccaf21SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
970421ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
970521ccaf21SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
970621ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
970721ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_2, 0),
970821ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_3, 1),
970921ccaf21SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
971021ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
971121ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
971221ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
971321ccaf21SDaniel Borkmann 		},
971421ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
971521ccaf21SDaniel Borkmann 		.result = ACCEPT,
971621ccaf21SDaniel Borkmann 		.retval = 1,
971721ccaf21SDaniel Borkmann 	},
971821ccaf21SDaniel Borkmann 	{
971921ccaf21SDaniel Borkmann 		"calls: multiple ret types in subprog 1",
972021ccaf21SDaniel Borkmann 		.insns = {
972121ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
972221ccaf21SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
972321ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
972421ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
972521ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
972621ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
972721ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
972821ccaf21SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
972921ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
973021ccaf21SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
973121ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
973221ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
973321ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
973421ccaf21SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
973521ccaf21SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 42),
973621ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
973721ccaf21SDaniel Borkmann 		},
973821ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
973921ccaf21SDaniel Borkmann 		.result = REJECT,
974021ccaf21SDaniel Borkmann 		.errstr = "R0 invalid mem access 'inv'",
974121ccaf21SDaniel Borkmann 	},
974221ccaf21SDaniel Borkmann 	{
974321ccaf21SDaniel Borkmann 		"calls: multiple ret types in subprog 2",
974421ccaf21SDaniel Borkmann 		.insns = {
974521ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
974621ccaf21SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
974721ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
974821ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
974921ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
975021ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
975121ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
975221ccaf21SDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
975321ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
975421ccaf21SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
975521ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
975621ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
975721ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
975821ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
975921ccaf21SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
976021ccaf21SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
976121ccaf21SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
976221ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
976321ccaf21SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
976421ccaf21SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
976521ccaf21SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
976621ccaf21SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
976721ccaf21SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
976821ccaf21SDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
976921ccaf21SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
977021ccaf21SDaniel Borkmann 			BPF_EXIT_INSN(),
977121ccaf21SDaniel Borkmann 		},
977221ccaf21SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
977321ccaf21SDaniel Borkmann 		.fixup_map1 = { 16 },
977421ccaf21SDaniel Borkmann 		.result = REJECT,
977521ccaf21SDaniel Borkmann 		.errstr = "R0 min value is outside of the array range",
977621ccaf21SDaniel Borkmann 	},
977721ccaf21SDaniel Borkmann 	{
977828ab173eSDaniel Borkmann 		"calls: overlapping caller/callee",
977928ab173eSDaniel Borkmann 		.insns = {
978028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
978128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
978228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
978328ab173eSDaniel Borkmann 		},
978428ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
978528ab173eSDaniel Borkmann 		.errstr = "last insn is not an exit or jmp",
978628ab173eSDaniel Borkmann 		.result = REJECT,
978728ab173eSDaniel Borkmann 	},
978828ab173eSDaniel Borkmann 	{
978928ab173eSDaniel Borkmann 		"calls: wrong recursive calls",
979028ab173eSDaniel Borkmann 		.insns = {
979128ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 4),
979228ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 4),
979328ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
979428ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
979528ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
979628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
979728ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
979828ab173eSDaniel Borkmann 		},
979928ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
980028ab173eSDaniel Borkmann 		.errstr = "jump out of range",
980128ab173eSDaniel Borkmann 		.result = REJECT,
980228ab173eSDaniel Borkmann 	},
980328ab173eSDaniel Borkmann 	{
980428ab173eSDaniel Borkmann 		"calls: wrong src reg",
980528ab173eSDaniel Borkmann 		.insns = {
980628ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 2, 0, 0),
980728ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
980828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
980928ab173eSDaniel Borkmann 		},
981028ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
981128ab173eSDaniel Borkmann 		.errstr = "BPF_CALL uses reserved fields",
981228ab173eSDaniel Borkmann 		.result = REJECT,
981328ab173eSDaniel Borkmann 	},
981428ab173eSDaniel Borkmann 	{
981528ab173eSDaniel Borkmann 		"calls: wrong off value",
981628ab173eSDaniel Borkmann 		.insns = {
981728ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
981828ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
981928ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
982028ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
982128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
982228ab173eSDaniel Borkmann 		},
982328ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
982428ab173eSDaniel Borkmann 		.errstr = "BPF_CALL uses reserved fields",
982528ab173eSDaniel Borkmann 		.result = REJECT,
982628ab173eSDaniel Borkmann 	},
982728ab173eSDaniel Borkmann 	{
982828ab173eSDaniel Borkmann 		"calls: jump back loop",
982928ab173eSDaniel Borkmann 		.insns = {
983028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
983128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
983228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
983328ab173eSDaniel Borkmann 		},
983428ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
983528ab173eSDaniel Borkmann 		.errstr = "back-edge from insn 0 to 0",
983628ab173eSDaniel Borkmann 		.result = REJECT,
983728ab173eSDaniel Borkmann 	},
983828ab173eSDaniel Borkmann 	{
983928ab173eSDaniel Borkmann 		"calls: conditional call",
984028ab173eSDaniel Borkmann 		.insns = {
984128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
984228ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
984328ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
984428ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
984528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
984628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
984728ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
984828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
984928ab173eSDaniel Borkmann 		},
985028ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
985128ab173eSDaniel Borkmann 		.errstr = "jump out of range",
985228ab173eSDaniel Borkmann 		.result = REJECT,
985328ab173eSDaniel Borkmann 	},
985428ab173eSDaniel Borkmann 	{
985528ab173eSDaniel Borkmann 		"calls: conditional call 2",
985628ab173eSDaniel Borkmann 		.insns = {
985728ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
985828ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
985928ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
986028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
986128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
986228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
986328ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
986428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
986528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 3),
986628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
986728ab173eSDaniel Borkmann 		},
986828ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
986928ab173eSDaniel Borkmann 		.result = ACCEPT,
987028ab173eSDaniel Borkmann 	},
987128ab173eSDaniel Borkmann 	{
987228ab173eSDaniel Borkmann 		"calls: conditional call 3",
987328ab173eSDaniel Borkmann 		.insns = {
987428ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
987528ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
987628ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
987728ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 4),
987828ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
987928ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
988028ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
988128ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -6),
988228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 3),
988328ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -6),
988428ab173eSDaniel Borkmann 		},
988528ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
988628ab173eSDaniel Borkmann 		.errstr = "back-edge from insn",
988728ab173eSDaniel Borkmann 		.result = REJECT,
988828ab173eSDaniel Borkmann 	},
988928ab173eSDaniel Borkmann 	{
989028ab173eSDaniel Borkmann 		"calls: conditional call 4",
989128ab173eSDaniel Borkmann 		.insns = {
989228ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
989328ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
989428ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
989528ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
989628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
989728ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
989828ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
989928ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -5),
990028ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 3),
990128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
990228ab173eSDaniel Borkmann 		},
990328ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
990428ab173eSDaniel Borkmann 		.result = ACCEPT,
990528ab173eSDaniel Borkmann 	},
990628ab173eSDaniel Borkmann 	{
990728ab173eSDaniel Borkmann 		"calls: conditional call 5",
990828ab173eSDaniel Borkmann 		.insns = {
990928ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
991028ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
991128ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
991228ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
991328ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
991428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
991528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
991628ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -6),
991728ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 3),
991828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
991928ab173eSDaniel Borkmann 		},
992028ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
992128ab173eSDaniel Borkmann 		.errstr = "back-edge from insn",
992228ab173eSDaniel Borkmann 		.result = REJECT,
992328ab173eSDaniel Borkmann 	},
992428ab173eSDaniel Borkmann 	{
992528ab173eSDaniel Borkmann 		"calls: conditional call 6",
992628ab173eSDaniel Borkmann 		.insns = {
992728ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
992828ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -2),
992928ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
993028ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
993128ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, mark)),
993228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
993328ab173eSDaniel Borkmann 		},
993428ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
993528ab173eSDaniel Borkmann 		.errstr = "back-edge from insn",
993628ab173eSDaniel Borkmann 		.result = REJECT,
993728ab173eSDaniel Borkmann 	},
993828ab173eSDaniel Borkmann 	{
9939a7ff3ecaSAlexei Starovoitov 		"calls: using r0 returned by callee",
9940a7ff3ecaSAlexei Starovoitov 		.insns = {
9941a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9942a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9943a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 2),
9944a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9945a7ff3ecaSAlexei Starovoitov 		},
9946a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
9947a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
9948a7ff3ecaSAlexei Starovoitov 	},
9949a7ff3ecaSAlexei Starovoitov 	{
995028ab173eSDaniel Borkmann 		"calls: using uninit r0 from callee",
995128ab173eSDaniel Borkmann 		.insns = {
995228ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
995328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
995428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
995528ab173eSDaniel Borkmann 		},
995628ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
995728ab173eSDaniel Borkmann 		.errstr = "!read_ok",
995828ab173eSDaniel Borkmann 		.result = REJECT,
995928ab173eSDaniel Borkmann 	},
996028ab173eSDaniel Borkmann 	{
9961a7ff3ecaSAlexei Starovoitov 		"calls: callee is using r1",
9962a7ff3ecaSAlexei Starovoitov 		.insns = {
9963a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9964a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9965a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
9966a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
9967a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9968a7ff3ecaSAlexei Starovoitov 		},
9969a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_ACT,
9970a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
9971111e6b45SAlexei Starovoitov 		.retval = TEST_DATA_LEN,
9972a7ff3ecaSAlexei Starovoitov 	},
9973a7ff3ecaSAlexei Starovoitov 	{
9974a7ff3ecaSAlexei Starovoitov 		"calls: callee using args1",
9975a7ff3ecaSAlexei Starovoitov 		.insns = {
9976a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9977a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9978a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
9979a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9980a7ff3ecaSAlexei Starovoitov 		},
9981a7ff3ecaSAlexei Starovoitov 		.errstr_unpriv = "allowed for root only",
9982a7ff3ecaSAlexei Starovoitov 		.result_unpriv = REJECT,
9983a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
9984111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
9985a7ff3ecaSAlexei Starovoitov 	},
9986a7ff3ecaSAlexei Starovoitov 	{
9987a7ff3ecaSAlexei Starovoitov 		"calls: callee using wrong args2",
9988a7ff3ecaSAlexei Starovoitov 		.insns = {
9989a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9990a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9991a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9992a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
9993a7ff3ecaSAlexei Starovoitov 		},
9994a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
9995a7ff3ecaSAlexei Starovoitov 		.errstr = "R2 !read_ok",
9996a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
9997a7ff3ecaSAlexei Starovoitov 	},
9998a7ff3ecaSAlexei Starovoitov 	{
9999a7ff3ecaSAlexei Starovoitov 		"calls: callee using two args",
10000a7ff3ecaSAlexei Starovoitov 		.insns = {
10001a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10002a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
10003a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
10004a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
10005a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
10006a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10007a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10008a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
10009a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
10010a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10011a7ff3ecaSAlexei Starovoitov 		},
10012a7ff3ecaSAlexei Starovoitov 		.errstr_unpriv = "allowed for root only",
10013a7ff3ecaSAlexei Starovoitov 		.result_unpriv = REJECT,
10014a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10015111e6b45SAlexei Starovoitov 		.retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
10016a7ff3ecaSAlexei Starovoitov 	},
10017a7ff3ecaSAlexei Starovoitov 	{
10018a7ff3ecaSAlexei Starovoitov 		"calls: callee changing pkt pointers",
10019a7ff3ecaSAlexei Starovoitov 		.insns = {
10020a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
10021a7ff3ecaSAlexei Starovoitov 				    offsetof(struct xdp_md, data)),
10022a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
10023a7ff3ecaSAlexei Starovoitov 				    offsetof(struct xdp_md, data_end)),
10024a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
10025a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
10026a7ff3ecaSAlexei Starovoitov 			BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
10027a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10028a7ff3ecaSAlexei Starovoitov 			/* clear_all_pkt_pointers() has to walk all frames
10029a7ff3ecaSAlexei Starovoitov 			 * to make sure that pkt pointers in the caller
10030a7ff3ecaSAlexei Starovoitov 			 * are cleared when callee is calling a helper that
10031a7ff3ecaSAlexei Starovoitov 			 * adjusts packet size
10032a7ff3ecaSAlexei Starovoitov 			 */
10033a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10034a7ff3ecaSAlexei Starovoitov 			BPF_MOV32_IMM(BPF_REG_0, 0),
10035a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10036a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_2, 0),
10037a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10038a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_xdp_adjust_head),
10039a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10040a7ff3ecaSAlexei Starovoitov 		},
10041a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10042a7ff3ecaSAlexei Starovoitov 		.errstr = "R6 invalid mem access 'inv'",
10043a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10044a7ff3ecaSAlexei Starovoitov 	},
10045a7ff3ecaSAlexei Starovoitov 	{
10046a7ff3ecaSAlexei Starovoitov 		"calls: two calls with args",
10047a7ff3ecaSAlexei Starovoitov 		.insns = {
10048a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10049a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10050a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10051a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10052a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10053a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10054a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10055a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10056a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10057a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10058a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10059a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
10060a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10061a7ff3ecaSAlexei Starovoitov 		},
10062a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
10063a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10064111e6b45SAlexei Starovoitov 		.retval = TEST_DATA_LEN + TEST_DATA_LEN,
10065a7ff3ecaSAlexei Starovoitov 	},
10066a7ff3ecaSAlexei Starovoitov 	{
1006728ab173eSDaniel Borkmann 		"calls: calls with stack arith",
1006828ab173eSDaniel Borkmann 		.insns = {
1006928ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1007028ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
1007128ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1007228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1007328ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
1007428ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1007528ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1007628ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
1007728ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
1007828ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
1007928ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1008028ab173eSDaniel Borkmann 		},
1008128ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1008228ab173eSDaniel Borkmann 		.result = ACCEPT,
10083111e6b45SAlexei Starovoitov 		.retval = 42,
1008428ab173eSDaniel Borkmann 	},
1008528ab173eSDaniel Borkmann 	{
1008628ab173eSDaniel Borkmann 		"calls: calls with misaligned stack access",
1008728ab173eSDaniel Borkmann 		.insns = {
1008828ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1008928ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
1009028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1009128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1009228ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
1009328ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1009428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1009528ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
1009628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
1009728ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
1009828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1009928ab173eSDaniel Borkmann 		},
1010028ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1010128ab173eSDaniel Borkmann 		.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
1010228ab173eSDaniel Borkmann 		.errstr = "misaligned stack access",
1010328ab173eSDaniel Borkmann 		.result = REJECT,
1010428ab173eSDaniel Borkmann 	},
1010528ab173eSDaniel Borkmann 	{
1010628ab173eSDaniel Borkmann 		"calls: calls control flow, jump test",
1010728ab173eSDaniel Borkmann 		.insns = {
1010828ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
1010928ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1011028ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 43),
1011128ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1011228ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, -3),
1011328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1011428ab173eSDaniel Borkmann 		},
1011528ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1011628ab173eSDaniel Borkmann 		.result = ACCEPT,
10117111e6b45SAlexei Starovoitov 		.retval = 43,
1011828ab173eSDaniel Borkmann 	},
1011928ab173eSDaniel Borkmann 	{
1012028ab173eSDaniel Borkmann 		"calls: calls control flow, jump test 2",
1012128ab173eSDaniel Borkmann 		.insns = {
1012228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
1012328ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1012428ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 43),
1012528ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1012628ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
1012728ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1012828ab173eSDaniel Borkmann 		},
1012928ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1013028ab173eSDaniel Borkmann 		.errstr = "jump out of range from insn 1 to 4",
1013128ab173eSDaniel Borkmann 		.result = REJECT,
1013228ab173eSDaniel Borkmann 	},
1013328ab173eSDaniel Borkmann 	{
10134a7ff3ecaSAlexei Starovoitov 		"calls: two calls with bad jump",
10135a7ff3ecaSAlexei Starovoitov 		.insns = {
10136a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10137a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10138a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10139a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10140a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10141a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10142a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10143a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10144a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10145a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10146a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10147a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
10148a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
10149a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10150a7ff3ecaSAlexei Starovoitov 		},
10151a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10152a7ff3ecaSAlexei Starovoitov 		.errstr = "jump out of range from insn 11 to 9",
10153a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10154a7ff3ecaSAlexei Starovoitov 	},
10155a7ff3ecaSAlexei Starovoitov 	{
10156a7ff3ecaSAlexei Starovoitov 		"calls: recursive call. test1",
10157a7ff3ecaSAlexei Starovoitov 		.insns = {
10158a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10159a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10160a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
10161a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10162a7ff3ecaSAlexei Starovoitov 		},
10163a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10164a7ff3ecaSAlexei Starovoitov 		.errstr = "back-edge",
10165a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10166a7ff3ecaSAlexei Starovoitov 	},
10167a7ff3ecaSAlexei Starovoitov 	{
10168a7ff3ecaSAlexei Starovoitov 		"calls: recursive call. test2",
10169a7ff3ecaSAlexei Starovoitov 		.insns = {
10170a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10171a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10172a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
10173a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10174a7ff3ecaSAlexei Starovoitov 		},
10175a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10176a7ff3ecaSAlexei Starovoitov 		.errstr = "back-edge",
10177a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10178a7ff3ecaSAlexei Starovoitov 	},
10179a7ff3ecaSAlexei Starovoitov 	{
10180a7ff3ecaSAlexei Starovoitov 		"calls: unreachable code",
10181a7ff3ecaSAlexei Starovoitov 		.insns = {
10182a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10183a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10184a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10185a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10186a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10187a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10188a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10189a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10190a7ff3ecaSAlexei Starovoitov 		},
10191a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10192a7ff3ecaSAlexei Starovoitov 		.errstr = "unreachable insn 6",
10193a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10194a7ff3ecaSAlexei Starovoitov 	},
10195a7ff3ecaSAlexei Starovoitov 	{
10196a7ff3ecaSAlexei Starovoitov 		"calls: invalid call",
10197a7ff3ecaSAlexei Starovoitov 		.insns = {
10198a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10199a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10200a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
10201a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10202a7ff3ecaSAlexei Starovoitov 		},
10203a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10204a7ff3ecaSAlexei Starovoitov 		.errstr = "invalid destination",
10205a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10206a7ff3ecaSAlexei Starovoitov 	},
10207a7ff3ecaSAlexei Starovoitov 	{
1020828ab173eSDaniel Borkmann 		"calls: invalid call 2",
1020928ab173eSDaniel Borkmann 		.insns = {
1021028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1021128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1021228ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
1021328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1021428ab173eSDaniel Borkmann 		},
1021528ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
1021628ab173eSDaniel Borkmann 		.errstr = "invalid destination",
1021728ab173eSDaniel Borkmann 		.result = REJECT,
1021828ab173eSDaniel Borkmann 	},
1021928ab173eSDaniel Borkmann 	{
10220a7ff3ecaSAlexei Starovoitov 		"calls: jumping across function bodies. test1",
10221a7ff3ecaSAlexei Starovoitov 		.insns = {
10222a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10223a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10224a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10225a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
10226a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10227a7ff3ecaSAlexei Starovoitov 		},
10228a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10229a7ff3ecaSAlexei Starovoitov 		.errstr = "jump out of range",
10230a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10231a7ff3ecaSAlexei Starovoitov 	},
10232a7ff3ecaSAlexei Starovoitov 	{
10233a7ff3ecaSAlexei Starovoitov 		"calls: jumping across function bodies. test2",
10234a7ff3ecaSAlexei Starovoitov 		.insns = {
10235a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
10236a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10237a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10238a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10239a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10240a7ff3ecaSAlexei Starovoitov 		},
10241a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10242a7ff3ecaSAlexei Starovoitov 		.errstr = "jump out of range",
10243a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10244a7ff3ecaSAlexei Starovoitov 	},
10245a7ff3ecaSAlexei Starovoitov 	{
10246a7ff3ecaSAlexei Starovoitov 		"calls: call without exit",
10247a7ff3ecaSAlexei Starovoitov 		.insns = {
10248a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10249a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10250a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10251a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10252a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10253a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
10254a7ff3ecaSAlexei Starovoitov 		},
10255a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10256a7ff3ecaSAlexei Starovoitov 		.errstr = "not an exit",
10257a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10258a7ff3ecaSAlexei Starovoitov 	},
10259a7ff3ecaSAlexei Starovoitov 	{
10260a7ff3ecaSAlexei Starovoitov 		"calls: call into middle of ld_imm64",
10261a7ff3ecaSAlexei Starovoitov 		.insns = {
10262a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10263a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10264a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10265a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10266a7ff3ecaSAlexei Starovoitov 			BPF_LD_IMM64(BPF_REG_0, 0),
10267a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10268a7ff3ecaSAlexei Starovoitov 		},
10269a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10270a7ff3ecaSAlexei Starovoitov 		.errstr = "last insn",
10271a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10272a7ff3ecaSAlexei Starovoitov 	},
10273a7ff3ecaSAlexei Starovoitov 	{
10274a7ff3ecaSAlexei Starovoitov 		"calls: call into middle of other call",
10275a7ff3ecaSAlexei Starovoitov 		.insns = {
10276a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10277a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10278a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10279a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10280a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10281a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10282a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10283a7ff3ecaSAlexei Starovoitov 		},
10284a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10285a7ff3ecaSAlexei Starovoitov 		.errstr = "last insn",
10286a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10287a7ff3ecaSAlexei Starovoitov 	},
10288a7ff3ecaSAlexei Starovoitov 	{
1028928ab173eSDaniel Borkmann 		"calls: ld_abs with changing ctx data in callee",
1029028ab173eSDaniel Borkmann 		.insns = {
1029128ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1029228ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
1029328ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
1029428ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
1029528ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
1029628ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
1029728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
1029828ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
1029928ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
1030028ab173eSDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
1030128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1030228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
1030328ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 2),
1030428ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1030528ab173eSDaniel Borkmann 				     BPF_FUNC_skb_vlan_push),
1030628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1030728ab173eSDaniel Borkmann 		},
1030828ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1030928ab173eSDaniel Borkmann 		.errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
1031028ab173eSDaniel Borkmann 		.result = REJECT,
1031128ab173eSDaniel Borkmann 	},
1031228ab173eSDaniel Borkmann 	{
10313a7ff3ecaSAlexei Starovoitov 		"calls: two calls with bad fallthrough",
10314a7ff3ecaSAlexei Starovoitov 		.insns = {
10315a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10316a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10317a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10318a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10319a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10320a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10321a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10322a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10323a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10324a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
10325a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
10326a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, len)),
10327a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10328a7ff3ecaSAlexei Starovoitov 		},
10329a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
10330a7ff3ecaSAlexei Starovoitov 		.errstr = "not an exit",
10331a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10332a7ff3ecaSAlexei Starovoitov 	},
10333a7ff3ecaSAlexei Starovoitov 	{
10334a7ff3ecaSAlexei Starovoitov 		"calls: two calls with stack read",
10335a7ff3ecaSAlexei Starovoitov 		.insns = {
10336a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10337a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10338a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10339a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10340a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10341a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10342a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
10343a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
10344a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10345a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10346a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
10347a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
10348a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10349a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10350a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10351a7ff3ecaSAlexei Starovoitov 		},
10352a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10353a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10354a7ff3ecaSAlexei Starovoitov 	},
10355a7ff3ecaSAlexei Starovoitov 	{
10356a7ff3ecaSAlexei Starovoitov 		"calls: two calls with stack write",
10357a7ff3ecaSAlexei Starovoitov 		.insns = {
10358a7ff3ecaSAlexei Starovoitov 			/* main prog */
10359a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10360a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10361a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10362a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10363a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10364a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10365a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10366a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10367a7ff3ecaSAlexei Starovoitov 
10368a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10369a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10370a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10371a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
10372a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
10373a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10374a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10375a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
10376a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
10377a7ff3ecaSAlexei Starovoitov 			/* write into stack frame of main prog */
10378a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10379a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10380a7ff3ecaSAlexei Starovoitov 
10381a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10382a7ff3ecaSAlexei Starovoitov 			/* read from stack frame of main prog */
10383a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
10384a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10385a7ff3ecaSAlexei Starovoitov 		},
10386a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10387a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10388a7ff3ecaSAlexei Starovoitov 	},
10389a7ff3ecaSAlexei Starovoitov 	{
103906b80ad29SJann Horn 		"calls: stack overflow using two frames (pre-call access)",
103916b80ad29SJann Horn 		.insns = {
103926b80ad29SJann Horn 			/* prog 1 */
103936b80ad29SJann Horn 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
103946b80ad29SJann Horn 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
103956b80ad29SJann Horn 			BPF_EXIT_INSN(),
103966b80ad29SJann Horn 
103976b80ad29SJann Horn 			/* prog 2 */
103986b80ad29SJann Horn 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
103996b80ad29SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
104006b80ad29SJann Horn 			BPF_EXIT_INSN(),
104016b80ad29SJann Horn 		},
104026b80ad29SJann Horn 		.prog_type = BPF_PROG_TYPE_XDP,
104036b80ad29SJann Horn 		.errstr = "combined stack size",
104046b80ad29SJann Horn 		.result = REJECT,
104056b80ad29SJann Horn 	},
104066b80ad29SJann Horn 	{
104076b80ad29SJann Horn 		"calls: stack overflow using two frames (post-call access)",
104086b80ad29SJann Horn 		.insns = {
104096b80ad29SJann Horn 			/* prog 1 */
104106b80ad29SJann Horn 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
104116b80ad29SJann Horn 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
104126b80ad29SJann Horn 			BPF_EXIT_INSN(),
104136b80ad29SJann Horn 
104146b80ad29SJann Horn 			/* prog 2 */
104156b80ad29SJann Horn 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
104166b80ad29SJann Horn 			BPF_MOV64_IMM(BPF_REG_0, 0),
104176b80ad29SJann Horn 			BPF_EXIT_INSN(),
104186b80ad29SJann Horn 		},
104196b80ad29SJann Horn 		.prog_type = BPF_PROG_TYPE_XDP,
104206b80ad29SJann Horn 		.errstr = "combined stack size",
104216b80ad29SJann Horn 		.result = REJECT,
104226b80ad29SJann Horn 	},
104236b80ad29SJann Horn 	{
104246b86c421SAlexei Starovoitov 		"calls: stack depth check using three frames. test1",
104256b86c421SAlexei Starovoitov 		.insns = {
104266b86c421SAlexei Starovoitov 			/* main */
104276b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
104286b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
104296b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
104306b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
104316b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104326b86c421SAlexei Starovoitov 			/* A */
104336b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
104346b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104356b86c421SAlexei Starovoitov 			/* B */
104366b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
104376b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
104386b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104396b86c421SAlexei Starovoitov 		},
104406b86c421SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
104416b86c421SAlexei Starovoitov 		/* stack_main=32, stack_A=256, stack_B=64
104426b86c421SAlexei Starovoitov 		 * and max(main+A, main+A+B) < 512
104436b86c421SAlexei Starovoitov 		 */
104446b86c421SAlexei Starovoitov 		.result = ACCEPT,
104456b86c421SAlexei Starovoitov 	},
104466b86c421SAlexei Starovoitov 	{
104476b86c421SAlexei Starovoitov 		"calls: stack depth check using three frames. test2",
104486b86c421SAlexei Starovoitov 		.insns = {
104496b86c421SAlexei Starovoitov 			/* main */
104506b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
104516b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
104526b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
104536b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
104546b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104556b86c421SAlexei Starovoitov 			/* A */
104566b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
104576b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104586b86c421SAlexei Starovoitov 			/* B */
104596b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
104606b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
104616b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104626b86c421SAlexei Starovoitov 		},
104636b86c421SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
104646b86c421SAlexei Starovoitov 		/* stack_main=32, stack_A=64, stack_B=256
104656b86c421SAlexei Starovoitov 		 * and max(main+A, main+A+B) < 512
104666b86c421SAlexei Starovoitov 		 */
104676b86c421SAlexei Starovoitov 		.result = ACCEPT,
104686b86c421SAlexei Starovoitov 	},
104696b86c421SAlexei Starovoitov 	{
104706b86c421SAlexei Starovoitov 		"calls: stack depth check using three frames. test3",
104716b86c421SAlexei Starovoitov 		.insns = {
104726b86c421SAlexei Starovoitov 			/* main */
104736b86c421SAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
104746b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
104756b86c421SAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
104766b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
104776b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
104786b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
104796b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
104806b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104816b86c421SAlexei Starovoitov 			/* A */
104826b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
104836b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104846b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
104856b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, -3),
104866b86c421SAlexei Starovoitov 			/* B */
104876b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
104886b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
104896b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
104906b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
104916b86c421SAlexei Starovoitov 		},
104926b86c421SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
104936b86c421SAlexei Starovoitov 		/* stack_main=64, stack_A=224, stack_B=256
104946b86c421SAlexei Starovoitov 		 * and max(main+A, main+A+B) > 512
104956b86c421SAlexei Starovoitov 		 */
104966b86c421SAlexei Starovoitov 		.errstr = "combined stack",
104976b86c421SAlexei Starovoitov 		.result = REJECT,
104986b86c421SAlexei Starovoitov 	},
104996b86c421SAlexei Starovoitov 	{
105006b86c421SAlexei Starovoitov 		"calls: stack depth check using three frames. test4",
105016b86c421SAlexei Starovoitov 		/* void main(void) {
105026b86c421SAlexei Starovoitov 		 *   func1(0);
105036b86c421SAlexei Starovoitov 		 *   func1(1);
105046b86c421SAlexei Starovoitov 		 *   func2(1);
105056b86c421SAlexei Starovoitov 		 * }
105066b86c421SAlexei Starovoitov 		 * void func1(int alloc_or_recurse) {
105076b86c421SAlexei Starovoitov 		 *   if (alloc_or_recurse) {
105086b86c421SAlexei Starovoitov 		 *     frame_pointer[-300] = 1;
105096b86c421SAlexei Starovoitov 		 *   } else {
105106b86c421SAlexei Starovoitov 		 *     func2(alloc_or_recurse);
105116b86c421SAlexei Starovoitov 		 *   }
105126b86c421SAlexei Starovoitov 		 * }
105136b86c421SAlexei Starovoitov 		 * void func2(int alloc_or_recurse) {
105146b86c421SAlexei Starovoitov 		 *   if (alloc_or_recurse) {
105156b86c421SAlexei Starovoitov 		 *     frame_pointer[-300] = 1;
105166b86c421SAlexei Starovoitov 		 *   }
105176b86c421SAlexei Starovoitov 		 * }
105186b86c421SAlexei Starovoitov 		 */
105196b86c421SAlexei Starovoitov 		.insns = {
105206b86c421SAlexei Starovoitov 			/* main */
105216b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_1, 0),
105226b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
105236b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_1, 1),
105246b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
105256b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_1, 1),
105266b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
105276b86c421SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
105286b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
105296b86c421SAlexei Starovoitov 			/* A */
105306b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
105316b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
105326b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
105336b86c421SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
105346b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
105356b86c421SAlexei Starovoitov 			/* B */
105366b86c421SAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
105376b86c421SAlexei Starovoitov 			BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
105386b86c421SAlexei Starovoitov 			BPF_EXIT_INSN(),
105396b86c421SAlexei Starovoitov 		},
105406b86c421SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
105416b86c421SAlexei Starovoitov 		.result = REJECT,
105426b86c421SAlexei Starovoitov 		.errstr = "combined stack",
105436b86c421SAlexei Starovoitov 	},
105446b86c421SAlexei Starovoitov 	{
10545aada9ce6SAlexei Starovoitov 		"calls: stack depth check using three frames. test5",
10546aada9ce6SAlexei Starovoitov 		.insns = {
10547aada9ce6SAlexei Starovoitov 			/* main */
10548aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
10549aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10550aada9ce6SAlexei Starovoitov 			/* A */
10551aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
10552aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10553aada9ce6SAlexei Starovoitov 			/* B */
10554aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
10555aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10556aada9ce6SAlexei Starovoitov 			/* C */
10557aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
10558aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10559aada9ce6SAlexei Starovoitov 			/* D */
10560aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
10561aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10562aada9ce6SAlexei Starovoitov 			/* E */
10563aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
10564aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10565aada9ce6SAlexei Starovoitov 			/* F */
10566aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
10567aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10568aada9ce6SAlexei Starovoitov 			/* G */
10569aada9ce6SAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
10570aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10571aada9ce6SAlexei Starovoitov 			/* H */
10572aada9ce6SAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10573aada9ce6SAlexei Starovoitov 			BPF_EXIT_INSN(),
10574aada9ce6SAlexei Starovoitov 		},
10575aada9ce6SAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10576aada9ce6SAlexei Starovoitov 		.errstr = "call stack",
10577aada9ce6SAlexei Starovoitov 		.result = REJECT,
10578aada9ce6SAlexei Starovoitov 	},
10579aada9ce6SAlexei Starovoitov 	{
10580a7ff3ecaSAlexei Starovoitov 		"calls: spill into caller stack frame",
10581a7ff3ecaSAlexei Starovoitov 		.insns = {
10582a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10583a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10584a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10585a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10586a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10587a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
10588a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10589a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10590a7ff3ecaSAlexei Starovoitov 		},
10591a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10592a7ff3ecaSAlexei Starovoitov 		.errstr = "cannot spill",
10593a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10594a7ff3ecaSAlexei Starovoitov 	},
10595a7ff3ecaSAlexei Starovoitov 	{
1059628ab173eSDaniel Borkmann 		"calls: write into caller stack frame",
1059728ab173eSDaniel Borkmann 		.insns = {
1059828ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1059928ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1060028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1060128ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1060228ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1060328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1060428ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
1060528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 0),
1060628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1060728ab173eSDaniel Borkmann 		},
1060828ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
1060928ab173eSDaniel Borkmann 		.result = ACCEPT,
10610111e6b45SAlexei Starovoitov 		.retval = 42,
1061128ab173eSDaniel Borkmann 	},
1061228ab173eSDaniel Borkmann 	{
1061328ab173eSDaniel Borkmann 		"calls: write into callee stack frame",
1061428ab173eSDaniel Borkmann 		.insns = {
1061528ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1061628ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
1061728ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1061828ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1061928ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
1062028ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1062128ab173eSDaniel Borkmann 		},
1062228ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
1062328ab173eSDaniel Borkmann 		.errstr = "cannot return stack pointer",
1062428ab173eSDaniel Borkmann 		.result = REJECT,
1062528ab173eSDaniel Borkmann 	},
1062628ab173eSDaniel Borkmann 	{
10627a7ff3ecaSAlexei Starovoitov 		"calls: two calls with stack write and void return",
10628a7ff3ecaSAlexei Starovoitov 		.insns = {
10629a7ff3ecaSAlexei Starovoitov 			/* main prog */
10630a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10631a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10632a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10633a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10634a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10635a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10636a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10637a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10638a7ff3ecaSAlexei Starovoitov 
10639a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10640a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10641a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10642a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10643a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10644a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10645a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10646a7ff3ecaSAlexei Starovoitov 
10647a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10648a7ff3ecaSAlexei Starovoitov 			/* write into stack frame of main prog */
10649a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
10650a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* void return */
10651a7ff3ecaSAlexei Starovoitov 		},
10652a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10653a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10654a7ff3ecaSAlexei Starovoitov 	},
10655a7ff3ecaSAlexei Starovoitov 	{
10656a7ff3ecaSAlexei Starovoitov 		"calls: ambiguous return value",
10657a7ff3ecaSAlexei Starovoitov 		.insns = {
10658a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10659a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
10660a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10661a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
10662a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10663a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10664a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10665a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
10666a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10667a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10668a7ff3ecaSAlexei Starovoitov 		},
10669a7ff3ecaSAlexei Starovoitov 		.errstr_unpriv = "allowed for root only",
10670a7ff3ecaSAlexei Starovoitov 		.result_unpriv = REJECT,
10671a7ff3ecaSAlexei Starovoitov 		.errstr = "R0 !read_ok",
10672a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10673a7ff3ecaSAlexei Starovoitov 	},
10674a7ff3ecaSAlexei Starovoitov 	{
10675a7ff3ecaSAlexei Starovoitov 		"calls: two calls that return map_value",
10676a7ff3ecaSAlexei Starovoitov 		.insns = {
10677a7ff3ecaSAlexei Starovoitov 			/* main prog */
10678a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10679a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10680a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10681a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10682a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10683a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
10684a7ff3ecaSAlexei Starovoitov 
10685a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10686a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
10687a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10688a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10689a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10690a7ff3ecaSAlexei Starovoitov 			/* fetch secound map_value_ptr from the stack */
10691a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
10692a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
10693a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10694a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10695a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10696a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10697a7ff3ecaSAlexei Starovoitov 
10698a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10699a7ff3ecaSAlexei Starovoitov 			/* call 3rd function twice */
10700a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10701a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10702a7ff3ecaSAlexei Starovoitov 			/* first time with fp-8 */
10703a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
10704a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10705a7ff3ecaSAlexei Starovoitov 			/* second time with fp-16 */
10706a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
10707a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10708a7ff3ecaSAlexei Starovoitov 
10709a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10710a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10711a7ff3ecaSAlexei Starovoitov 			/* lookup from map */
10712a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10713a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10714a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10715a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10716a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10717a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10718a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog */
10719a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10720a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10721a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* return 0 */
10722a7ff3ecaSAlexei Starovoitov 		},
10723a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10724a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 23 },
10725a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10726a7ff3ecaSAlexei Starovoitov 	},
10727a7ff3ecaSAlexei Starovoitov 	{
10728a7ff3ecaSAlexei Starovoitov 		"calls: two calls that return map_value with bool condition",
10729a7ff3ecaSAlexei Starovoitov 		.insns = {
10730a7ff3ecaSAlexei Starovoitov 			/* main prog */
10731a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10732a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10733a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10734a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10735a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10736a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10737a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10738a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10739a7ff3ecaSAlexei Starovoitov 
10740a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10741a7ff3ecaSAlexei Starovoitov 			/* call 3rd function twice */
10742a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10743a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10744a7ff3ecaSAlexei Starovoitov 			/* first time with fp-8 */
10745a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10746a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10747a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10748a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10749a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10750a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10751a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10752a7ff3ecaSAlexei Starovoitov 			/* second time with fp-16 */
10753a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10754a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10755a7ff3ecaSAlexei Starovoitov 			/* fetch secound map_value_ptr from the stack */
10756a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10757a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10758a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10759a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10760a7ff3ecaSAlexei Starovoitov 
10761a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10762a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10763a7ff3ecaSAlexei Starovoitov 			/* lookup from map */
10764a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10765a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10766a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10767a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10768a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10769a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10770a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10771a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10772a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* return 0 */
10773a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog */
10774a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10775a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10776a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* return 1 */
10777a7ff3ecaSAlexei Starovoitov 		},
10778a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10779a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 23 },
10780a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10781a7ff3ecaSAlexei Starovoitov 	},
10782a7ff3ecaSAlexei Starovoitov 	{
10783a7ff3ecaSAlexei Starovoitov 		"calls: two calls that return map_value with incorrect bool check",
10784a7ff3ecaSAlexei Starovoitov 		.insns = {
10785a7ff3ecaSAlexei Starovoitov 			/* main prog */
10786a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10787a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10788a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10789a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10790a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10791a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10792a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10793a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10794a7ff3ecaSAlexei Starovoitov 
10795a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10796a7ff3ecaSAlexei Starovoitov 			/* call 3rd function twice */
10797a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10798a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10799a7ff3ecaSAlexei Starovoitov 			/* first time with fp-8 */
10800a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
10801a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
10802a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10803a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
10804a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10805a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10806a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10807a7ff3ecaSAlexei Starovoitov 			/* second time with fp-16 */
10808a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
10809a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10810a7ff3ecaSAlexei Starovoitov 			/* fetch secound map_value_ptr from the stack */
10811a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
10812a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10813a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10814a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10815a7ff3ecaSAlexei Starovoitov 
10816a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10817a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10818a7ff3ecaSAlexei Starovoitov 			/* lookup from map */
10819a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10820a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10821a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10822a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10823a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10824a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10825a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10826a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10827a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* return 0 */
10828a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog */
10829a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10830a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10831a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(), /* return 1 */
10832a7ff3ecaSAlexei Starovoitov 		},
10833a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
10834a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 23 },
10835a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10836a7ff3ecaSAlexei Starovoitov 		.errstr = "invalid read from stack off -16+0 size 8",
10837a7ff3ecaSAlexei Starovoitov 	},
10838a7ff3ecaSAlexei Starovoitov 	{
10839a7ff3ecaSAlexei Starovoitov 		"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
10840a7ff3ecaSAlexei Starovoitov 		.insns = {
10841a7ff3ecaSAlexei Starovoitov 			/* main prog */
10842a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10843a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10844a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10845a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10846a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10847a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10848a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10849a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10850a7ff3ecaSAlexei Starovoitov 
10851a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10852a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10853a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10854a7ff3ecaSAlexei Starovoitov 			/* 1st lookup from map */
10855a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10856a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10857a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10858a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10859a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10860a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10861a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10862a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 0),
10863a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10864a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-8 */
10865a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10866a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 1),
10867a7ff3ecaSAlexei Starovoitov 
10868a7ff3ecaSAlexei Starovoitov 			/* 2nd lookup from map */
10869a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
10870a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10871a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10872a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
10873a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10874a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10875a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 0),
10876a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10877a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-16 */
10878a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10879a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 1),
10880a7ff3ecaSAlexei Starovoitov 
10881a7ff3ecaSAlexei Starovoitov 			/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10882a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
10883a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10884a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10885a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10886a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
10887a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10888a7ff3ecaSAlexei Starovoitov 
10889a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10890a7ff3ecaSAlexei Starovoitov 			/* if arg2 == 1 do *arg1 = 0 */
10891a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10892a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10893a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10894a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10895a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10896a7ff3ecaSAlexei Starovoitov 
10897a7ff3ecaSAlexei Starovoitov 			/* if arg4 == 1 do *arg3 = 0 */
10898a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10899a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10900a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10901a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10902a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
10903a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10904a7ff3ecaSAlexei Starovoitov 		},
10905a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
10906a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 12, 22 },
10907a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
10908a7ff3ecaSAlexei Starovoitov 		.errstr = "invalid access to map value, value_size=8 off=2 size=8",
10909a7ff3ecaSAlexei Starovoitov 	},
10910a7ff3ecaSAlexei Starovoitov 	{
10911a7ff3ecaSAlexei Starovoitov 		"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
10912a7ff3ecaSAlexei Starovoitov 		.insns = {
10913a7ff3ecaSAlexei Starovoitov 			/* main prog */
10914a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10915a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10916a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10917a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10918a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10919a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
10920a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10921a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10922a7ff3ecaSAlexei Starovoitov 
10923a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10924a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10925a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10926a7ff3ecaSAlexei Starovoitov 			/* 1st lookup from map */
10927a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10928a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10929a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10930a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10931a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
10932a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10933a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10934a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 0),
10935a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10936a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-8 */
10937a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
10938a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 1),
10939a7ff3ecaSAlexei Starovoitov 
10940a7ff3ecaSAlexei Starovoitov 			/* 2nd lookup from map */
10941a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
10942a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
10943a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
10944a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
10945a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
10946a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
10947a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 0),
10948a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
10949a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-16 */
10950a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10951a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 1),
10952a7ff3ecaSAlexei Starovoitov 
10953a7ff3ecaSAlexei Starovoitov 			/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
10954a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
10955a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
10956a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
10957a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
10958a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
10959a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10960a7ff3ecaSAlexei Starovoitov 
10961a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
10962a7ff3ecaSAlexei Starovoitov 			/* if arg2 == 1 do *arg1 = 0 */
10963a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
10964a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10965a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
10966a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10967a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10968a7ff3ecaSAlexei Starovoitov 
10969a7ff3ecaSAlexei Starovoitov 			/* if arg4 == 1 do *arg3 = 0 */
10970a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
10971a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
10972a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
10973a7ff3ecaSAlexei Starovoitov 			/* write into map value */
10974a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
10975a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10976a7ff3ecaSAlexei Starovoitov 		},
10977a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
10978a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 12, 22 },
10979a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
10980a7ff3ecaSAlexei Starovoitov 	},
10981a7ff3ecaSAlexei Starovoitov 	{
10982a7ff3ecaSAlexei Starovoitov 		"calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
10983a7ff3ecaSAlexei Starovoitov 		.insns = {
10984a7ff3ecaSAlexei Starovoitov 			/* main prog */
10985a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
10986a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10987a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10988a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
10989a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
10990a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
10991a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10992a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
10993a7ff3ecaSAlexei Starovoitov 
10994a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
10995a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
10996a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
10997a7ff3ecaSAlexei Starovoitov 			/* 1st lookup from map */
10998a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
10999a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11000a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11001a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11002a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11003a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11004a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11005a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 0),
11006a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11007a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-8 */
11008a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11009a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 1),
11010a7ff3ecaSAlexei Starovoitov 
11011a7ff3ecaSAlexei Starovoitov 			/* 2nd lookup from map */
11012a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11013a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
11014a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11015a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11016a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11017a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11018a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 0),  // 26
11019a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 2),
11020a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr into stack frame of main prog at fp-16 */
11021a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11022a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 1),
11023a7ff3ecaSAlexei Starovoitov 
11024a7ff3ecaSAlexei Starovoitov 			/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11025a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
11026a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11027a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11028a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11029a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
11030a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, -30),
11031a7ff3ecaSAlexei Starovoitov 
11032a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
11033a7ff3ecaSAlexei Starovoitov 			/* if arg2 == 1 do *arg1 = 0 */
11034a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11035a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11036a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11037a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11038a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11039a7ff3ecaSAlexei Starovoitov 
11040a7ff3ecaSAlexei Starovoitov 			/* if arg4 == 1 do *arg3 = 0 */
11041a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11042a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11043a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11044a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11045a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
11046a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, -8),
11047a7ff3ecaSAlexei Starovoitov 		},
11048a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11049a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 12, 22 },
11050a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
11051a7ff3ecaSAlexei Starovoitov 		.errstr = "invalid access to map value, value_size=8 off=2 size=8",
11052a7ff3ecaSAlexei Starovoitov 	},
11053a7ff3ecaSAlexei Starovoitov 	{
11054a7ff3ecaSAlexei Starovoitov 		"calls: two calls that receive map_value_ptr_or_null via arg. test1",
11055a7ff3ecaSAlexei Starovoitov 		.insns = {
11056a7ff3ecaSAlexei Starovoitov 			/* main prog */
11057a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
11058a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11059a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11060a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11061a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11062a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11063a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11064a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11065a7ff3ecaSAlexei Starovoitov 
11066a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
11067a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11068a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11069a7ff3ecaSAlexei Starovoitov 			/* 1st lookup from map */
11070a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11071a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11072a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11073a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11074a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11075a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11076a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11077a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11078a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11079a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 0),
11080a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11081a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 1),
11082a7ff3ecaSAlexei Starovoitov 
11083a7ff3ecaSAlexei Starovoitov 			/* 2nd lookup from map */
11084a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11085a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11086a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11087a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11088a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11089a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11090a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11091a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11092a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 0),
11093a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11094a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 1),
11095a7ff3ecaSAlexei Starovoitov 
11096a7ff3ecaSAlexei Starovoitov 			/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11097a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11098a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11099a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11100a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11101a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11102a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11103a7ff3ecaSAlexei Starovoitov 
11104a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
11105a7ff3ecaSAlexei Starovoitov 			/* if arg2 == 1 do *arg1 = 0 */
11106a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11107a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11108a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11109a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11110a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11111a7ff3ecaSAlexei Starovoitov 
11112a7ff3ecaSAlexei Starovoitov 			/* if arg4 == 1 do *arg3 = 0 */
11113a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
11114a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11115a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11116a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11117a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11118a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11119a7ff3ecaSAlexei Starovoitov 		},
11120a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11121a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 12, 22 },
11122a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
11123a7ff3ecaSAlexei Starovoitov 	},
11124a7ff3ecaSAlexei Starovoitov 	{
11125a7ff3ecaSAlexei Starovoitov 		"calls: two calls that receive map_value_ptr_or_null via arg. test2",
11126a7ff3ecaSAlexei Starovoitov 		.insns = {
11127a7ff3ecaSAlexei Starovoitov 			/* main prog */
11128a7ff3ecaSAlexei Starovoitov 			/* pass fp-16, fp-8 into a function */
11129a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
11130a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
11131a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11132a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
11133a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
11134a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11135a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11136a7ff3ecaSAlexei Starovoitov 
11137a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
11138a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
11139a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
11140a7ff3ecaSAlexei Starovoitov 			/* 1st lookup from map */
11141a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11142a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11143a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11144a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11145a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11146a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11147a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11148a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11149a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11150a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 0),
11151a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11152a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_8, 1),
11153a7ff3ecaSAlexei Starovoitov 
11154a7ff3ecaSAlexei Starovoitov 			/* 2nd lookup from map */
11155a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11156a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11157a7ff3ecaSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11158a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11159a7ff3ecaSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11160a7ff3ecaSAlexei Starovoitov 			/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
11161a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11162a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
11163a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 0),
11164a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 1),
11165a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_9, 1),
11166a7ff3ecaSAlexei Starovoitov 
11167a7ff3ecaSAlexei Starovoitov 			/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
11168a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
11169a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
11170a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
11171a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
11172a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11173a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11174a7ff3ecaSAlexei Starovoitov 
11175a7ff3ecaSAlexei Starovoitov 			/* subprog 2 */
11176a7ff3ecaSAlexei Starovoitov 			/* if arg2 == 1 do *arg1 = 0 */
11177a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
11178a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11179a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
11180a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11181a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11182a7ff3ecaSAlexei Starovoitov 
11183a7ff3ecaSAlexei Starovoitov 			/* if arg4 == 0 do *arg3 = 0 */
11184a7ff3ecaSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
11185a7ff3ecaSAlexei Starovoitov 			/* fetch map_value_ptr from the stack of this function */
11186a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
11187a7ff3ecaSAlexei Starovoitov 			/* write into map value */
11188a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
11189a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11190a7ff3ecaSAlexei Starovoitov 		},
11191a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11192a7ff3ecaSAlexei Starovoitov 		.fixup_map1 = { 12, 22 },
11193a7ff3ecaSAlexei Starovoitov 		.result = REJECT,
11194a7ff3ecaSAlexei Starovoitov 		.errstr = "R0 invalid mem access 'inv'",
11195a7ff3ecaSAlexei Starovoitov 	},
11196a7ff3ecaSAlexei Starovoitov 	{
11197a7ff3ecaSAlexei Starovoitov 		"calls: pkt_ptr spill into caller stack",
11198a7ff3ecaSAlexei Starovoitov 		.insns = {
11199a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
11200a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
11201a7ff3ecaSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
11202a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11203a7ff3ecaSAlexei Starovoitov 
11204a7ff3ecaSAlexei Starovoitov 			/* subprog 1 */
11205a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11206a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, data)),
11207a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11208a7ff3ecaSAlexei Starovoitov 				    offsetof(struct __sk_buff, data_end)),
11209a7ff3ecaSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11210a7ff3ecaSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
11211a7ff3ecaSAlexei Starovoitov 			/* spill unchecked pkt_ptr into stack of caller */
11212a7ff3ecaSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
11213a7ff3ecaSAlexei Starovoitov 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
11214a7ff3ecaSAlexei Starovoitov 			/* now the pkt range is verified, read pkt_ptr from stack */
11215a7ff3ecaSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
11216a7ff3ecaSAlexei Starovoitov 			/* write 4 bytes into packet */
11217a7ff3ecaSAlexei Starovoitov 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11218a7ff3ecaSAlexei Starovoitov 			BPF_EXIT_INSN(),
11219a7ff3ecaSAlexei Starovoitov 		},
11220a7ff3ecaSAlexei Starovoitov 		.result = ACCEPT,
11221a7ff3ecaSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11222111e6b45SAlexei Starovoitov 		.retval = POINTER_VALUE,
11223a7ff3ecaSAlexei Starovoitov 	},
11224d98588ceSAlexei Starovoitov 	{
1122528ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 2",
1122628ab173eSDaniel Borkmann 		.insns = {
1122728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1122828ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1122928ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1123028ab173eSDaniel Borkmann 			/* Marking is still kept, but not in all cases safe. */
1123128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1123228ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1123328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1123428ab173eSDaniel Borkmann 
1123528ab173eSDaniel Borkmann 			/* subprog 1 */
1123628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1123728ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1123828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1123928ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1124028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1124128ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1124228ab173eSDaniel Borkmann 			/* spill unchecked pkt_ptr into stack of caller */
1124328ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1124428ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1124528ab173eSDaniel Borkmann 			/* now the pkt range is verified, read pkt_ptr from stack */
1124628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
1124728ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1124828ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1124928ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1125028ab173eSDaniel Borkmann 		},
1125128ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1125228ab173eSDaniel Borkmann 		.errstr = "invalid access to packet",
1125328ab173eSDaniel Borkmann 		.result = REJECT,
1125428ab173eSDaniel Borkmann 	},
1125528ab173eSDaniel Borkmann 	{
1125628ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 3",
1125728ab173eSDaniel Borkmann 		.insns = {
1125828ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1125928ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1126028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1126128ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1126228ab173eSDaniel Borkmann 			/* Marking is still kept and safe here. */
1126328ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1126428ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1126528ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1126628ab173eSDaniel Borkmann 
1126728ab173eSDaniel Borkmann 			/* subprog 1 */
1126828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1126928ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1127028ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1127128ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1127228ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1127328ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1127428ab173eSDaniel Borkmann 			/* spill unchecked pkt_ptr into stack of caller */
1127528ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1127628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1127728ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1127828ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1127928ab173eSDaniel Borkmann 			/* now the pkt range is verified, read pkt_ptr from stack */
1128028ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
1128128ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1128228ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1128328ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1128428ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1128528ab173eSDaniel Borkmann 		},
1128628ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1128728ab173eSDaniel Borkmann 		.result = ACCEPT,
11288111e6b45SAlexei Starovoitov 		.retval = 1,
1128928ab173eSDaniel Borkmann 	},
1129028ab173eSDaniel Borkmann 	{
1129128ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 4",
1129228ab173eSDaniel Borkmann 		.insns = {
1129328ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1129428ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1129528ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1129628ab173eSDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1129728ab173eSDaniel Borkmann 			/* Check marking propagated. */
1129828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1129928ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1130028ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1130128ab173eSDaniel Borkmann 
1130228ab173eSDaniel Borkmann 			/* subprog 1 */
1130328ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1130428ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1130528ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1130628ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1130728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1130828ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1130928ab173eSDaniel Borkmann 			/* spill unchecked pkt_ptr into stack of caller */
1131028ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1131128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1131228ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1131328ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1131428ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1131528ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1131628ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1131728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1131828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1131928ab173eSDaniel Borkmann 		},
1132028ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1132128ab173eSDaniel Borkmann 		.result = ACCEPT,
11322111e6b45SAlexei Starovoitov 		.retval = 1,
1132328ab173eSDaniel Borkmann 	},
1132428ab173eSDaniel Borkmann 	{
1132528ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 5",
1132628ab173eSDaniel Borkmann 		.insns = {
1132728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1132828ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1132928ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
1133028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1133128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1133228ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
1133328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1133428ab173eSDaniel Borkmann 
1133528ab173eSDaniel Borkmann 			/* subprog 1 */
1133628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1133728ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1133828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1133928ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1134028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1134128ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1134228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1134328ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1134428ab173eSDaniel Borkmann 			/* spill checked pkt_ptr into stack of caller */
1134528ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1134628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1134728ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1134828ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1134928ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1135028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1135128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1135228ab173eSDaniel Borkmann 		},
1135328ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1135428ab173eSDaniel Borkmann 		.errstr = "same insn cannot be used with different",
1135528ab173eSDaniel Borkmann 		.result = REJECT,
1135628ab173eSDaniel Borkmann 	},
1135728ab173eSDaniel Borkmann 	{
1135828ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 6",
1135928ab173eSDaniel Borkmann 		.insns = {
1136028ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1136128ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1136228ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1136328ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1136428ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1136528ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1136628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1136728ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
1136828ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1136928ab173eSDaniel Borkmann 
1137028ab173eSDaniel Borkmann 			/* subprog 1 */
1137128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1137228ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1137328ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1137428ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1137528ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1137628ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1137728ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1137828ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1137928ab173eSDaniel Borkmann 			/* spill checked pkt_ptr into stack of caller */
1138028ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1138128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1138228ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1138328ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1138428ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1138528ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1138628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1138728ab173eSDaniel Borkmann 		},
1138828ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1138928ab173eSDaniel Borkmann 		.errstr = "R4 invalid mem access",
1139028ab173eSDaniel Borkmann 		.result = REJECT,
1139128ab173eSDaniel Borkmann 	},
1139228ab173eSDaniel Borkmann 	{
1139328ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 7",
1139428ab173eSDaniel Borkmann 		.insns = {
1139528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 0),
1139628ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1139728ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1139828ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1139928ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1140028ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1140128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
1140228ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1140328ab173eSDaniel Borkmann 
1140428ab173eSDaniel Borkmann 			/* subprog 1 */
1140528ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1140628ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1140728ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1140828ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1140928ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1141028ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1141128ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1141228ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1141328ab173eSDaniel Borkmann 			/* spill checked pkt_ptr into stack of caller */
1141428ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1141528ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1141628ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1141728ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1141828ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1141928ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1142028ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1142128ab173eSDaniel Borkmann 		},
1142228ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1142328ab173eSDaniel Borkmann 		.errstr = "R4 invalid mem access",
1142428ab173eSDaniel Borkmann 		.result = REJECT,
1142528ab173eSDaniel Borkmann 	},
1142628ab173eSDaniel Borkmann 	{
1142728ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 8",
1142828ab173eSDaniel Borkmann 		.insns = {
1142928ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1143028ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1143128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1143228ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1143328ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1143428ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1143528ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
1143628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1143728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1143828ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1143928ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1144028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1144128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1144228ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
1144328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1144428ab173eSDaniel Borkmann 
1144528ab173eSDaniel Borkmann 			/* subprog 1 */
1144628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1144728ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1144828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1144928ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1145028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1145128ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1145228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1145328ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1145428ab173eSDaniel Borkmann 			/* spill checked pkt_ptr into stack of caller */
1145528ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1145628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1145728ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1145828ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1145928ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1146028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1146128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1146228ab173eSDaniel Borkmann 		},
1146328ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1146428ab173eSDaniel Borkmann 		.result = ACCEPT,
1146528ab173eSDaniel Borkmann 	},
1146628ab173eSDaniel Borkmann 	{
1146728ab173eSDaniel Borkmann 		"calls: pkt_ptr spill into caller stack 9",
1146828ab173eSDaniel Borkmann 		.insns = {
1146928ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1147028ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1147128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1147228ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1147328ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1147428ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1147528ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
1147628ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1147728ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1147828ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1147928ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1148028ab173eSDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1148128ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1148228ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
1148328ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1148428ab173eSDaniel Borkmann 
1148528ab173eSDaniel Borkmann 			/* subprog 1 */
1148628ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1148728ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data)),
1148828ab173eSDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1148928ab173eSDaniel Borkmann 				    offsetof(struct __sk_buff, data_end)),
1149028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1149128ab173eSDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1149228ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 0),
1149328ab173eSDaniel Borkmann 			/* spill unchecked pkt_ptr into stack of caller */
1149428ab173eSDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1149528ab173eSDaniel Borkmann 			BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1149628ab173eSDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_5, 1),
1149728ab173eSDaniel Borkmann 			/* don't read back pkt_ptr from stack here */
1149828ab173eSDaniel Borkmann 			/* write 4 bytes into packet */
1149928ab173eSDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1150028ab173eSDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1150128ab173eSDaniel Borkmann 			BPF_EXIT_INSN(),
1150228ab173eSDaniel Borkmann 		},
1150328ab173eSDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1150428ab173eSDaniel Borkmann 		.errstr = "invalid access to packet",
1150528ab173eSDaniel Borkmann 		.result = REJECT,
1150628ab173eSDaniel Borkmann 	},
1150728ab173eSDaniel Borkmann 	{
11508d98588ceSAlexei Starovoitov 		"calls: caller stack init to zero or map_value_or_null",
11509d98588ceSAlexei Starovoitov 		.insns = {
11510d98588ceSAlexei Starovoitov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11511d98588ceSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11512d98588ceSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11513d98588ceSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11514d98588ceSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
11515d98588ceSAlexei Starovoitov 			/* fetch map_value_or_null or const_zero from stack */
11516d98588ceSAlexei Starovoitov 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11517d98588ceSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
11518d98588ceSAlexei Starovoitov 			/* store into map_value */
11519d98588ceSAlexei Starovoitov 			BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
11520d98588ceSAlexei Starovoitov 			BPF_EXIT_INSN(),
11521d98588ceSAlexei Starovoitov 
11522d98588ceSAlexei Starovoitov 			/* subprog 1 */
11523d98588ceSAlexei Starovoitov 			/* if (ctx == 0) return; */
11524d98588ceSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
11525d98588ceSAlexei Starovoitov 			/* else bpf_map_lookup() and *(fp - 8) = r0 */
11526d98588ceSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
11527d98588ceSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11528d98588ceSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11529d98588ceSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11530d98588ceSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11531d98588ceSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11532d98588ceSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11533d98588ceSAlexei Starovoitov 			/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
11534d98588ceSAlexei Starovoitov 			BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
11535d98588ceSAlexei Starovoitov 			BPF_EXIT_INSN(),
11536d98588ceSAlexei Starovoitov 		},
11537d98588ceSAlexei Starovoitov 		.fixup_map1 = { 13 },
11538d98588ceSAlexei Starovoitov 		.result = ACCEPT,
11539d98588ceSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
11540d98588ceSAlexei Starovoitov 	},
11541d98588ceSAlexei Starovoitov 	{
11542d98588ceSAlexei Starovoitov 		"calls: stack init to zero and pruning",
11543d98588ceSAlexei Starovoitov 		.insns = {
11544d98588ceSAlexei Starovoitov 			/* first make allocated_stack 16 byte */
11545d98588ceSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
11546d98588ceSAlexei Starovoitov 			/* now fork the execution such that the false branch
11547d98588ceSAlexei Starovoitov 			 * of JGT insn will be verified second and it skisp zero
11548d98588ceSAlexei Starovoitov 			 * init of fp-8 stack slot. If stack liveness marking
11549d98588ceSAlexei Starovoitov 			 * is missing live_read marks from call map_lookup
11550d98588ceSAlexei Starovoitov 			 * processing then pruning will incorrectly assume
11551d98588ceSAlexei Starovoitov 			 * that fp-8 stack slot was unused in the fall-through
11552d98588ceSAlexei Starovoitov 			 * branch and will accept the program incorrectly
11553d98588ceSAlexei Starovoitov 			 */
11554d98588ceSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
11555d98588ceSAlexei Starovoitov 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11556d98588ceSAlexei Starovoitov 			BPF_JMP_IMM(BPF_JA, 0, 0, 0),
11557d98588ceSAlexei Starovoitov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11558d98588ceSAlexei Starovoitov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11559d98588ceSAlexei Starovoitov 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11560d98588ceSAlexei Starovoitov 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11561d98588ceSAlexei Starovoitov 				     BPF_FUNC_map_lookup_elem),
11562d98588ceSAlexei Starovoitov 			BPF_EXIT_INSN(),
11563d98588ceSAlexei Starovoitov 		},
11564d98588ceSAlexei Starovoitov 		.fixup_map2 = { 6 },
11565d98588ceSAlexei Starovoitov 		.errstr = "invalid indirect read from stack off -8+0 size 8",
11566d98588ceSAlexei Starovoitov 		.result = REJECT,
11567d98588ceSAlexei Starovoitov 		.prog_type = BPF_PROG_TYPE_XDP,
11568d98588ceSAlexei Starovoitov 	},
11569fd05e57bSGianluca Borello 	{
11570fd05e57bSGianluca Borello 		"search pruning: all branches should be verified (nop operation)",
11571fd05e57bSGianluca Borello 		.insns = {
11572fd05e57bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11573fd05e57bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11574fd05e57bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11575fd05e57bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11576fd05e57bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11577fd05e57bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
11578fd05e57bSGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11579fd05e57bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11580fd05e57bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
11581fd05e57bSGianluca Borello 			BPF_JMP_A(1),
11582fd05e57bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 1),
11583fd05e57bSGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11584fd05e57bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11585fd05e57bSGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11586fd05e57bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
11587fd05e57bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_6, 0),
11588fd05e57bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
11589fd05e57bSGianluca Borello 			BPF_EXIT_INSN(),
11590fd05e57bSGianluca Borello 		},
11591fd05e57bSGianluca Borello 		.fixup_map1 = { 3 },
11592fd05e57bSGianluca Borello 		.errstr = "R6 invalid mem access 'inv'",
11593fd05e57bSGianluca Borello 		.result = REJECT,
11594fd05e57bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
11595fd05e57bSGianluca Borello 	},
11596fd05e57bSGianluca Borello 	{
11597fd05e57bSGianluca Borello 		"search pruning: all branches should be verified (invalid stack access)",
11598fd05e57bSGianluca Borello 		.insns = {
11599fd05e57bSGianluca Borello 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11600fd05e57bSGianluca Borello 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11601fd05e57bSGianluca Borello 			BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
11602fd05e57bSGianluca Borello 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11603fd05e57bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
11604fd05e57bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
11605fd05e57bSGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
11606fd05e57bSGianluca Borello 			BPF_MOV64_IMM(BPF_REG_4, 0),
11607fd05e57bSGianluca Borello 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
11608fd05e57bSGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
11609fd05e57bSGianluca Borello 			BPF_JMP_A(1),
11610fd05e57bSGianluca Borello 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
11611fd05e57bSGianluca Borello 			BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
11612fd05e57bSGianluca Borello 			BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
11613fd05e57bSGianluca Borello 			BPF_EXIT_INSN(),
11614fd05e57bSGianluca Borello 		},
11615fd05e57bSGianluca Borello 		.fixup_map1 = { 3 },
11616fd05e57bSGianluca Borello 		.errstr = "invalid read from stack off -16+0 size 8",
11617fd05e57bSGianluca Borello 		.result = REJECT,
11618fd05e57bSGianluca Borello 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
11619fd05e57bSGianluca Borello 	},
1162023d191a8SDaniel Borkmann 	{
1162123d191a8SDaniel Borkmann 		"jit: lsh, rsh, arsh by 1",
1162223d191a8SDaniel Borkmann 		.insns = {
1162323d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1162423d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 0xff),
1162523d191a8SDaniel Borkmann 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
1162623d191a8SDaniel Borkmann 			BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
1162723d191a8SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
1162823d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1162923d191a8SDaniel Borkmann 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
1163023d191a8SDaniel Borkmann 			BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
1163123d191a8SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
1163223d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1163323d191a8SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
1163423d191a8SDaniel Borkmann 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
1163523d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1163623d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
1163723d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1163823d191a8SDaniel Borkmann 		},
1163923d191a8SDaniel Borkmann 		.result = ACCEPT,
1164023d191a8SDaniel Borkmann 		.retval = 2,
1164123d191a8SDaniel Borkmann 	},
1164223d191a8SDaniel Borkmann 	{
1164323d191a8SDaniel Borkmann 		"jit: mov32 for ldimm64, 1",
1164423d191a8SDaniel Borkmann 		.insns = {
1164523d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
1164623d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
1164723d191a8SDaniel Borkmann 			BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
1164823d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
1164923d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
1165023d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1165123d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1165223d191a8SDaniel Borkmann 		},
1165323d191a8SDaniel Borkmann 		.result = ACCEPT,
1165423d191a8SDaniel Borkmann 		.retval = 2,
1165523d191a8SDaniel Borkmann 	},
1165623d191a8SDaniel Borkmann 	{
1165723d191a8SDaniel Borkmann 		"jit: mov32 for ldimm64, 2",
1165823d191a8SDaniel Borkmann 		.insns = {
1165923d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1166023d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
1166123d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
1166223d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
1166323d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
1166423d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1166523d191a8SDaniel Borkmann 		},
1166623d191a8SDaniel Borkmann 		.result = ACCEPT,
1166723d191a8SDaniel Borkmann 		.retval = 2,
1166823d191a8SDaniel Borkmann 	},
1166923d191a8SDaniel Borkmann 	{
1167023d191a8SDaniel Borkmann 		"jit: various mul tests",
1167123d191a8SDaniel Borkmann 		.insns = {
1167223d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
1167323d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
1167423d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
1167523d191a8SDaniel Borkmann 			BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
1167623d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
1167723d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1167823d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1167923d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
1168023d191a8SDaniel Borkmann 			BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
1168123d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
1168223d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1168323d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1168423d191a8SDaniel Borkmann 			BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
1168523d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
1168623d191a8SDaniel Borkmann 			BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
1168723d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
1168823d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1168923d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1169023d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
1169123d191a8SDaniel Borkmann 			BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
1169223d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
1169323d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1169423d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1169523d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
1169623d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
1169723d191a8SDaniel Borkmann 			BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
1169823d191a8SDaniel Borkmann 			BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
1169923d191a8SDaniel Borkmann 			BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
1170023d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
1170123d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1170223d191a8SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 2),
1170323d191a8SDaniel Borkmann 			BPF_EXIT_INSN(),
1170423d191a8SDaniel Borkmann 		},
1170523d191a8SDaniel Borkmann 		.result = ACCEPT,
1170623d191a8SDaniel Borkmann 		.retval = 2,
1170723d191a8SDaniel Borkmann 	},
117080f3e9c97SDavid S. Miller 	{
11709ca369602SDaniel Borkmann 		"xadd/w check unaligned stack",
11710ca369602SDaniel Borkmann 		.insns = {
11711ca369602SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
11712ca369602SDaniel Borkmann 			BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11713ca369602SDaniel Borkmann 			BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
11714ca369602SDaniel Borkmann 			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11715ca369602SDaniel Borkmann 			BPF_EXIT_INSN(),
11716ca369602SDaniel Borkmann 		},
11717ca369602SDaniel Borkmann 		.result = REJECT,
11718ca369602SDaniel Borkmann 		.errstr = "misaligned stack access off",
11719ca369602SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11720ca369602SDaniel Borkmann 	},
11721ca369602SDaniel Borkmann 	{
11722ca369602SDaniel Borkmann 		"xadd/w check unaligned map",
11723ca369602SDaniel Borkmann 		.insns = {
11724ca369602SDaniel Borkmann 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11725ca369602SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11726ca369602SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11727ca369602SDaniel Borkmann 			BPF_LD_MAP_FD(BPF_REG_1, 0),
11728ca369602SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11729ca369602SDaniel Borkmann 				     BPF_FUNC_map_lookup_elem),
11730ca369602SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
11731ca369602SDaniel Borkmann 			BPF_EXIT_INSN(),
11732ca369602SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_1, 1),
11733ca369602SDaniel Borkmann 			BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
11734ca369602SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
11735ca369602SDaniel Borkmann 			BPF_EXIT_INSN(),
11736ca369602SDaniel Borkmann 		},
11737ca369602SDaniel Borkmann 		.fixup_map1 = { 3 },
11738ca369602SDaniel Borkmann 		.result = REJECT,
11739ca369602SDaniel Borkmann 		.errstr = "misaligned value access off",
11740ca369602SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11741ca369602SDaniel Borkmann 	},
11742ca369602SDaniel Borkmann 	{
11743ca369602SDaniel Borkmann 		"xadd/w check unaligned pkt",
11744ca369602SDaniel Borkmann 		.insns = {
11745ca369602SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11746ca369602SDaniel Borkmann 				    offsetof(struct xdp_md, data)),
11747ca369602SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11748ca369602SDaniel Borkmann 				    offsetof(struct xdp_md, data_end)),
11749ca369602SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
11750ca369602SDaniel Borkmann 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
11751ca369602SDaniel Borkmann 			BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
11752ca369602SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 99),
11753ca369602SDaniel Borkmann 			BPF_JMP_IMM(BPF_JA, 0, 0, 6),
11754ca369602SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 1),
11755ca369602SDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11756ca369602SDaniel Borkmann 			BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
11757ca369602SDaniel Borkmann 			BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
11758ca369602SDaniel Borkmann 			BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
11759ca369602SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
11760ca369602SDaniel Borkmann 			BPF_EXIT_INSN(),
11761ca369602SDaniel Borkmann 		},
11762ca369602SDaniel Borkmann 		.result = REJECT,
11763ca369602SDaniel Borkmann 		.errstr = "BPF_XADD stores into R2 packet",
11764ca369602SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_XDP,
11765ca369602SDaniel Borkmann 	},
117662abe611cSYonghong Song 	{
117672abe611cSYonghong Song 		"bpf_get_stack return R0 within range",
117682abe611cSYonghong Song 		.insns = {
117692abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
117702abe611cSYonghong Song 			BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
117712abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
117722abe611cSYonghong Song 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
117732abe611cSYonghong Song 			BPF_LD_MAP_FD(BPF_REG_1, 0),
117742abe611cSYonghong Song 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
117752abe611cSYonghong Song 				     BPF_FUNC_map_lookup_elem),
117762abe611cSYonghong Song 			BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
117772abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
117782abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
117792abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
117802abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
117812abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
117822abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 256),
117832abe611cSYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_get_stack),
117842abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_1, 0),
117852abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
117862abe611cSYonghong Song 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
117872abe611cSYonghong Song 			BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
117882abe611cSYonghong Song 			BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
117892abe611cSYonghong Song 			BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
117902abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
117912abe611cSYonghong Song 			BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
117922abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
117932abe611cSYonghong Song 			BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
117942abe611cSYonghong Song 			BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 32),
117952abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
117962abe611cSYonghong Song 			BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
117972abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
117982abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
117992abe611cSYonghong Song 			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
118002abe611cSYonghong Song 			BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
118012abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
118022abe611cSYonghong Song 			BPF_MOV64_REG(BPF_REG_3, BPF_REG_9),
118032abe611cSYonghong Song 			BPF_MOV64_IMM(BPF_REG_4, 0),
118042abe611cSYonghong Song 			BPF_EMIT_CALL(BPF_FUNC_get_stack),
118052abe611cSYonghong Song 			BPF_EXIT_INSN(),
118062abe611cSYonghong Song 		},
118072abe611cSYonghong Song 		.fixup_map2 = { 4 },
118082abe611cSYonghong Song 		.result = ACCEPT,
118092abe611cSYonghong Song 		.prog_type = BPF_PROG_TYPE_TRACEPOINT,
118102abe611cSYonghong Song 	},
1181193731ef0SDaniel Borkmann 	{
1181293731ef0SDaniel Borkmann 		"ld_abs: invalid op 1",
1181393731ef0SDaniel Borkmann 		.insns = {
1181493731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1181593731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_DW, 0),
1181693731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1181793731ef0SDaniel Borkmann 		},
1181893731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1181993731ef0SDaniel Borkmann 		.result = REJECT,
1182093731ef0SDaniel Borkmann 		.errstr = "unknown opcode",
1182193731ef0SDaniel Borkmann 	},
1182293731ef0SDaniel Borkmann 	{
1182393731ef0SDaniel Borkmann 		"ld_abs: invalid op 2",
1182493731ef0SDaniel Borkmann 		.insns = {
1182593731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 256),
1182693731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1182793731ef0SDaniel Borkmann 			BPF_LD_IND(BPF_DW, BPF_REG_0, 0),
1182893731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1182993731ef0SDaniel Borkmann 		},
1183093731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1183193731ef0SDaniel Borkmann 		.result = REJECT,
1183293731ef0SDaniel Borkmann 		.errstr = "unknown opcode",
1183393731ef0SDaniel Borkmann 	},
1183493731ef0SDaniel Borkmann 	{
1183593731ef0SDaniel Borkmann 		"ld_abs: nmap reduced",
1183693731ef0SDaniel Borkmann 		.insns = {
1183793731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1183893731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 12),
1183993731ef0SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 28),
1184093731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 12),
1184193731ef0SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 26),
1184293731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 18),
1184393731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -64),
1184493731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -64),
1184593731ef0SDaniel Borkmann 			BPF_LD_IND(BPF_W, BPF_REG_7, 14),
1184693731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -60),
1184793731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 280971478),
1184893731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
1184993731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
1185093731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -60),
1185193731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
1185293731ef0SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 15),
1185393731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 12),
1185493731ef0SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0x806, 13),
1185593731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 22),
1185693731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -56),
1185793731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -56),
1185893731ef0SDaniel Borkmann 			BPF_LD_IND(BPF_H, BPF_REG_7, 14),
1185993731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -52),
1186093731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 17366),
1186193731ef0SDaniel Borkmann 			BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -48),
1186293731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_10, -48),
1186393731ef0SDaniel Borkmann 			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -52),
1186493731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
1186593731ef0SDaniel Borkmann 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1186693731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 256),
1186793731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1186893731ef0SDaniel Borkmann 			BPF_MOV32_IMM(BPF_REG_0, 0),
1186993731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1187093731ef0SDaniel Borkmann 		},
1187193731ef0SDaniel Borkmann 		.data = {
1187293731ef0SDaniel Borkmann 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0,
1187393731ef0SDaniel Borkmann 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1187493731ef0SDaniel Borkmann 			0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
1187593731ef0SDaniel Borkmann 		},
1187693731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1187793731ef0SDaniel Borkmann 		.result = ACCEPT,
1187893731ef0SDaniel Borkmann 		.retval = 256,
1187993731ef0SDaniel Borkmann 	},
1188093731ef0SDaniel Borkmann 	{
1188193731ef0SDaniel Borkmann 		"ld_abs: div + abs, test 1",
1188293731ef0SDaniel Borkmann 		.insns = {
1188393731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
1188493731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 3),
1188593731ef0SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
1188693731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
1188793731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
1188893731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 4),
1188993731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
1189093731ef0SDaniel Borkmann 			BPF_LD_IND(BPF_B, BPF_REG_8, -70),
1189193731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1189293731ef0SDaniel Borkmann 		},
1189393731ef0SDaniel Borkmann 		.data = {
1189493731ef0SDaniel Borkmann 			10, 20, 30, 40, 50,
1189593731ef0SDaniel Borkmann 		},
1189693731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1189793731ef0SDaniel Borkmann 		.result = ACCEPT,
1189893731ef0SDaniel Borkmann 		.retval = 10,
1189993731ef0SDaniel Borkmann 	},
1190093731ef0SDaniel Borkmann 	{
1190193731ef0SDaniel Borkmann 		"ld_abs: div + abs, test 2",
1190293731ef0SDaniel Borkmann 		.insns = {
1190393731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
1190493731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 3),
1190593731ef0SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 2),
1190693731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_2),
1190793731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_8, BPF_REG_0),
1190893731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 128),
1190993731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
1191093731ef0SDaniel Borkmann 			BPF_LD_IND(BPF_B, BPF_REG_8, -70),
1191193731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1191293731ef0SDaniel Borkmann 		},
1191393731ef0SDaniel Borkmann 		.data = {
1191493731ef0SDaniel Borkmann 			10, 20, 30, 40, 50,
1191593731ef0SDaniel Borkmann 		},
1191693731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1191793731ef0SDaniel Borkmann 		.result = ACCEPT,
1191893731ef0SDaniel Borkmann 		.retval = 0,
1191993731ef0SDaniel Borkmann 	},
1192093731ef0SDaniel Borkmann 	{
1192193731ef0SDaniel Borkmann 		"ld_abs: div + abs, test 3",
1192293731ef0SDaniel Borkmann 		.insns = {
1192393731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
1192493731ef0SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
1192593731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 3),
1192693731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
1192793731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1192893731ef0SDaniel Borkmann 		},
1192993731ef0SDaniel Borkmann 		.data = {
1193093731ef0SDaniel Borkmann 			10, 20, 30, 40, 50,
1193193731ef0SDaniel Borkmann 		},
1193293731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1193393731ef0SDaniel Borkmann 		.result = ACCEPT,
1193493731ef0SDaniel Borkmann 		.retval = 0,
1193593731ef0SDaniel Borkmann 	},
1193693731ef0SDaniel Borkmann 	{
1193793731ef0SDaniel Borkmann 		"ld_abs: div + abs, test 4",
1193893731ef0SDaniel Borkmann 		.insns = {
1193993731ef0SDaniel Borkmann 			BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
1194093731ef0SDaniel Borkmann 			BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
1194193731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 256),
1194293731ef0SDaniel Borkmann 			BPF_ALU32_REG(BPF_DIV, BPF_REG_0, BPF_REG_7),
1194393731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1194493731ef0SDaniel Borkmann 		},
1194593731ef0SDaniel Borkmann 		.data = {
1194693731ef0SDaniel Borkmann 			10, 20, 30, 40, 50,
1194793731ef0SDaniel Borkmann 		},
1194893731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1194993731ef0SDaniel Borkmann 		.result = ACCEPT,
1195093731ef0SDaniel Borkmann 		.retval = 0,
1195193731ef0SDaniel Borkmann 	},
1195293731ef0SDaniel Borkmann 	{
1195393731ef0SDaniel Borkmann 		"ld_abs: vlan + abs, test 1",
1195493731ef0SDaniel Borkmann 		.insns = { },
1195593731ef0SDaniel Borkmann 		.data = {
1195693731ef0SDaniel Borkmann 			0x34,
1195793731ef0SDaniel Borkmann 		},
1195893731ef0SDaniel Borkmann 		.fill_helper = bpf_fill_ld_abs_vlan_push_pop,
1195993731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1196093731ef0SDaniel Borkmann 		.result = ACCEPT,
1196193731ef0SDaniel Borkmann 		.retval = 0xbef,
1196293731ef0SDaniel Borkmann 	},
1196393731ef0SDaniel Borkmann 	{
1196493731ef0SDaniel Borkmann 		"ld_abs: vlan + abs, test 2",
1196593731ef0SDaniel Borkmann 		.insns = {
1196693731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1196793731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
1196893731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
1196993731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
1197093731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
1197193731ef0SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_6, 0),
1197293731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1197393731ef0SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_2, 1),
1197493731ef0SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_3, 2),
1197593731ef0SDaniel Borkmann 			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
1197693731ef0SDaniel Borkmann 				     BPF_FUNC_skb_vlan_push),
1197793731ef0SDaniel Borkmann 			BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
1197893731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_B, 0),
1197993731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_H, 0),
1198093731ef0SDaniel Borkmann 			BPF_LD_ABS(BPF_W, 0),
1198193731ef0SDaniel Borkmann 			BPF_MOV64_IMM(BPF_REG_0, 42),
1198293731ef0SDaniel Borkmann 			BPF_EXIT_INSN(),
1198393731ef0SDaniel Borkmann 		},
1198493731ef0SDaniel Borkmann 		.data = {
1198593731ef0SDaniel Borkmann 			0x34,
1198693731ef0SDaniel Borkmann 		},
1198793731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1198893731ef0SDaniel Borkmann 		.result = ACCEPT,
1198993731ef0SDaniel Borkmann 		.retval = 42,
1199093731ef0SDaniel Borkmann 	},
1199193731ef0SDaniel Borkmann 	{
1199293731ef0SDaniel Borkmann 		"ld_abs: jump around ld_abs",
1199393731ef0SDaniel Borkmann 		.insns = { },
1199493731ef0SDaniel Borkmann 		.data = {
1199593731ef0SDaniel Borkmann 			10, 11,
1199693731ef0SDaniel Borkmann 		},
1199793731ef0SDaniel Borkmann 		.fill_helper = bpf_fill_jump_around_ld_abs,
1199893731ef0SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1199993731ef0SDaniel Borkmann 		.result = ACCEPT,
1200093731ef0SDaniel Borkmann 		.retval = 10,
1200193731ef0SDaniel Borkmann 	},
12002a82d8cd3SDaniel Borkmann 	{
12003a82d8cd3SDaniel Borkmann 		"ld_dw: xor semi-random 64 bit imms, test 1",
12004a82d8cd3SDaniel Borkmann 		.insns = { },
12005a82d8cd3SDaniel Borkmann 		.data = { },
12006a82d8cd3SDaniel Borkmann 		.fill_helper = bpf_fill_rand_ld_dw,
12007a82d8cd3SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
12008a82d8cd3SDaniel Borkmann 		.result = ACCEPT,
12009a82d8cd3SDaniel Borkmann 		.retval = 4090,
12010a82d8cd3SDaniel Borkmann 	},
12011a82d8cd3SDaniel Borkmann 	{
12012a82d8cd3SDaniel Borkmann 		"ld_dw: xor semi-random 64 bit imms, test 2",
12013a82d8cd3SDaniel Borkmann 		.insns = { },
12014a82d8cd3SDaniel Borkmann 		.data = { },
12015a82d8cd3SDaniel Borkmann 		.fill_helper = bpf_fill_rand_ld_dw,
12016a82d8cd3SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
12017a82d8cd3SDaniel Borkmann 		.result = ACCEPT,
12018a82d8cd3SDaniel Borkmann 		.retval = 2047,
12019a82d8cd3SDaniel Borkmann 	},
12020a82d8cd3SDaniel Borkmann 	{
12021a82d8cd3SDaniel Borkmann 		"ld_dw: xor semi-random 64 bit imms, test 3",
12022a82d8cd3SDaniel Borkmann 		.insns = { },
12023a82d8cd3SDaniel Borkmann 		.data = { },
12024a82d8cd3SDaniel Borkmann 		.fill_helper = bpf_fill_rand_ld_dw,
12025a82d8cd3SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
12026a82d8cd3SDaniel Borkmann 		.result = ACCEPT,
12027a82d8cd3SDaniel Borkmann 		.retval = 511,
12028a82d8cd3SDaniel Borkmann 	},
12029a82d8cd3SDaniel Borkmann 	{
12030a82d8cd3SDaniel Borkmann 		"ld_dw: xor semi-random 64 bit imms, test 4",
12031a82d8cd3SDaniel Borkmann 		.insns = { },
12032a82d8cd3SDaniel Borkmann 		.data = { },
12033a82d8cd3SDaniel Borkmann 		.fill_helper = bpf_fill_rand_ld_dw,
12034a82d8cd3SDaniel Borkmann 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
12035a82d8cd3SDaniel Borkmann 		.result = ACCEPT,
12036a82d8cd3SDaniel Borkmann 		.retval = 5,
12037a82d8cd3SDaniel Borkmann 	},
120385aa5bd14SDaniel Borkmann };
120395aa5bd14SDaniel Borkmann 
120405aa5bd14SDaniel Borkmann static int probe_filter_length(const struct bpf_insn *fp)
120415aa5bd14SDaniel Borkmann {
120425aa5bd14SDaniel Borkmann 	int len;
120435aa5bd14SDaniel Borkmann 
120445aa5bd14SDaniel Borkmann 	for (len = MAX_INSNS - 1; len > 0; --len)
120455aa5bd14SDaniel Borkmann 		if (fp[len].code != 0 || fp[len].imm != 0)
120465aa5bd14SDaniel Borkmann 			break;
120475aa5bd14SDaniel Borkmann 	return len + 1;
120485aa5bd14SDaniel Borkmann }
120495aa5bd14SDaniel Borkmann 
120505aa5bd14SDaniel Borkmann static int create_map(uint32_t size_value, uint32_t max_elem)
120515aa5bd14SDaniel Borkmann {
120525aa5bd14SDaniel Borkmann 	int fd;
120535aa5bd14SDaniel Borkmann 
12054f4874d01SMickaël Salaün 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
120555aa5bd14SDaniel Borkmann 			    size_value, max_elem, BPF_F_NO_PREALLOC);
120565aa5bd14SDaniel Borkmann 	if (fd < 0)
120575aa5bd14SDaniel Borkmann 		printf("Failed to create hash map '%s'!\n", strerror(errno));
120585aa5bd14SDaniel Borkmann 
120595aa5bd14SDaniel Borkmann 	return fd;
120605aa5bd14SDaniel Borkmann }
120615aa5bd14SDaniel Borkmann 
12062b33eb735SDaniel Borkmann static int create_prog_dummy1(void)
12063b33eb735SDaniel Borkmann {
12064b33eb735SDaniel Borkmann 	struct bpf_insn prog[] = {
12065b33eb735SDaniel Borkmann 		BPF_MOV64_IMM(BPF_REG_0, 42),
12066b33eb735SDaniel Borkmann 		BPF_EXIT_INSN(),
12067b33eb735SDaniel Borkmann 	};
12068b33eb735SDaniel Borkmann 
12069b33eb735SDaniel Borkmann 	return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12070b33eb735SDaniel Borkmann 				ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12071b33eb735SDaniel Borkmann }
12072b33eb735SDaniel Borkmann 
12073b33eb735SDaniel Borkmann static int create_prog_dummy2(int mfd, int idx)
12074b33eb735SDaniel Borkmann {
12075b33eb735SDaniel Borkmann 	struct bpf_insn prog[] = {
12076b33eb735SDaniel Borkmann 		BPF_MOV64_IMM(BPF_REG_3, idx),
12077b33eb735SDaniel Borkmann 		BPF_LD_MAP_FD(BPF_REG_2, mfd),
12078b33eb735SDaniel Borkmann 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
12079b33eb735SDaniel Borkmann 			     BPF_FUNC_tail_call),
12080b33eb735SDaniel Borkmann 		BPF_MOV64_IMM(BPF_REG_0, 41),
12081b33eb735SDaniel Borkmann 		BPF_EXIT_INSN(),
12082b33eb735SDaniel Borkmann 	};
12083b33eb735SDaniel Borkmann 
12084b33eb735SDaniel Borkmann 	return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
12085b33eb735SDaniel Borkmann 				ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
12086b33eb735SDaniel Borkmann }
12087b33eb735SDaniel Borkmann 
120885aa5bd14SDaniel Borkmann static int create_prog_array(void)
120895aa5bd14SDaniel Borkmann {
12090b33eb735SDaniel Borkmann 	int p1key = 0, p2key = 1;
12091b33eb735SDaniel Borkmann 	int mfd, p1fd, p2fd;
120925aa5bd14SDaniel Borkmann 
12093b33eb735SDaniel Borkmann 	mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
120945aa5bd14SDaniel Borkmann 			     sizeof(int), 4, 0);
12095b33eb735SDaniel Borkmann 	if (mfd < 0) {
120965aa5bd14SDaniel Borkmann 		printf("Failed to create prog array '%s'!\n", strerror(errno));
12097b33eb735SDaniel Borkmann 		return -1;
12098b33eb735SDaniel Borkmann 	}
120995aa5bd14SDaniel Borkmann 
12100b33eb735SDaniel Borkmann 	p1fd = create_prog_dummy1();
12101b33eb735SDaniel Borkmann 	p2fd = create_prog_dummy2(mfd, p2key);
12102b33eb735SDaniel Borkmann 	if (p1fd < 0 || p2fd < 0)
12103b33eb735SDaniel Borkmann 		goto out;
12104b33eb735SDaniel Borkmann 	if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
12105b33eb735SDaniel Borkmann 		goto out;
12106b33eb735SDaniel Borkmann 	if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
12107b33eb735SDaniel Borkmann 		goto out;
12108b33eb735SDaniel Borkmann 	close(p2fd);
12109b33eb735SDaniel Borkmann 	close(p1fd);
12110b33eb735SDaniel Borkmann 
12111b33eb735SDaniel Borkmann 	return mfd;
12112b33eb735SDaniel Borkmann out:
12113b33eb735SDaniel Borkmann 	close(p2fd);
12114b33eb735SDaniel Borkmann 	close(p1fd);
12115b33eb735SDaniel Borkmann 	close(mfd);
12116b33eb735SDaniel Borkmann 	return -1;
121175aa5bd14SDaniel Borkmann }
121185aa5bd14SDaniel Borkmann 
12119fb30d4b7SMartin KaFai Lau static int create_map_in_map(void)
12120fb30d4b7SMartin KaFai Lau {
12121fb30d4b7SMartin KaFai Lau 	int inner_map_fd, outer_map_fd;
12122fb30d4b7SMartin KaFai Lau 
12123fb30d4b7SMartin KaFai Lau 	inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
12124fb30d4b7SMartin KaFai Lau 				      sizeof(int), 1, 0);
12125fb30d4b7SMartin KaFai Lau 	if (inner_map_fd < 0) {
12126fb30d4b7SMartin KaFai Lau 		printf("Failed to create array '%s'!\n", strerror(errno));
12127fb30d4b7SMartin KaFai Lau 		return inner_map_fd;
12128fb30d4b7SMartin KaFai Lau 	}
12129fb30d4b7SMartin KaFai Lau 
1213088cda1c9SMartin KaFai Lau 	outer_map_fd = bpf_create_map_in_map(BPF_MAP_TYPE_ARRAY_OF_MAPS, NULL,
12131fb30d4b7SMartin KaFai Lau 					     sizeof(int), inner_map_fd, 1, 0);
12132fb30d4b7SMartin KaFai Lau 	if (outer_map_fd < 0)
12133fb30d4b7SMartin KaFai Lau 		printf("Failed to create array of maps '%s'!\n",
12134fb30d4b7SMartin KaFai Lau 		       strerror(errno));
12135fb30d4b7SMartin KaFai Lau 
12136fb30d4b7SMartin KaFai Lau 	close(inner_map_fd);
12137fb30d4b7SMartin KaFai Lau 
12138fb30d4b7SMartin KaFai Lau 	return outer_map_fd;
12139fb30d4b7SMartin KaFai Lau }
12140fb30d4b7SMartin KaFai Lau 
1214193731ef0SDaniel Borkmann static char bpf_vlog[UINT_MAX >> 8];
121425aa5bd14SDaniel Borkmann 
121435aa5bd14SDaniel Borkmann static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12144fb30d4b7SMartin KaFai Lau 			  int *map_fds)
121455aa5bd14SDaniel Borkmann {
121465aa5bd14SDaniel Borkmann 	int *fixup_map1 = test->fixup_map1;
121475aa5bd14SDaniel Borkmann 	int *fixup_map2 = test->fixup_map2;
121485f90dd6aSPaul Chaignon 	int *fixup_map3 = test->fixup_map3;
121495aa5bd14SDaniel Borkmann 	int *fixup_prog = test->fixup_prog;
12150fb30d4b7SMartin KaFai Lau 	int *fixup_map_in_map = test->fixup_map_in_map;
121515aa5bd14SDaniel Borkmann 
1215293731ef0SDaniel Borkmann 	if (test->fill_helper)
1215393731ef0SDaniel Borkmann 		test->fill_helper(test);
1215493731ef0SDaniel Borkmann 
121555aa5bd14SDaniel Borkmann 	/* Allocating HTs with 1 elem is fine here, since we only test
121565aa5bd14SDaniel Borkmann 	 * for verifier and not do a runtime lookup, so the only thing
121575aa5bd14SDaniel Borkmann 	 * that really matters is value size in this case.
121585aa5bd14SDaniel Borkmann 	 */
121595aa5bd14SDaniel Borkmann 	if (*fixup_map1) {
12160fb30d4b7SMartin KaFai Lau 		map_fds[0] = create_map(sizeof(long long), 1);
121615aa5bd14SDaniel Borkmann 		do {
12162fb30d4b7SMartin KaFai Lau 			prog[*fixup_map1].imm = map_fds[0];
121635aa5bd14SDaniel Borkmann 			fixup_map1++;
121645aa5bd14SDaniel Borkmann 		} while (*fixup_map1);
121655aa5bd14SDaniel Borkmann 	}
121665aa5bd14SDaniel Borkmann 
121675aa5bd14SDaniel Borkmann 	if (*fixup_map2) {
12168fb30d4b7SMartin KaFai Lau 		map_fds[1] = create_map(sizeof(struct test_val), 1);
121695aa5bd14SDaniel Borkmann 		do {
12170fb30d4b7SMartin KaFai Lau 			prog[*fixup_map2].imm = map_fds[1];
121715aa5bd14SDaniel Borkmann 			fixup_map2++;
121725aa5bd14SDaniel Borkmann 		} while (*fixup_map2);
121735aa5bd14SDaniel Borkmann 	}
121745aa5bd14SDaniel Borkmann 
121755f90dd6aSPaul Chaignon 	if (*fixup_map3) {
121765f90dd6aSPaul Chaignon 		map_fds[1] = create_map(sizeof(struct other_val), 1);
121775f90dd6aSPaul Chaignon 		do {
121785f90dd6aSPaul Chaignon 			prog[*fixup_map3].imm = map_fds[1];
121795f90dd6aSPaul Chaignon 			fixup_map3++;
121805f90dd6aSPaul Chaignon 		} while (*fixup_map3);
121815f90dd6aSPaul Chaignon 	}
121825f90dd6aSPaul Chaignon 
121835aa5bd14SDaniel Borkmann 	if (*fixup_prog) {
12184fb30d4b7SMartin KaFai Lau 		map_fds[2] = create_prog_array();
121855aa5bd14SDaniel Borkmann 		do {
12186fb30d4b7SMartin KaFai Lau 			prog[*fixup_prog].imm = map_fds[2];
121875aa5bd14SDaniel Borkmann 			fixup_prog++;
121885aa5bd14SDaniel Borkmann 		} while (*fixup_prog);
121895aa5bd14SDaniel Borkmann 	}
12190fb30d4b7SMartin KaFai Lau 
12191fb30d4b7SMartin KaFai Lau 	if (*fixup_map_in_map) {
12192fb30d4b7SMartin KaFai Lau 		map_fds[3] = create_map_in_map();
12193fb30d4b7SMartin KaFai Lau 		do {
12194fb30d4b7SMartin KaFai Lau 			prog[*fixup_map_in_map].imm = map_fds[3];
12195fb30d4b7SMartin KaFai Lau 			fixup_map_in_map++;
12196fb30d4b7SMartin KaFai Lau 		} while (*fixup_map_in_map);
12197fb30d4b7SMartin KaFai Lau 	}
121985aa5bd14SDaniel Borkmann }
121995aa5bd14SDaniel Borkmann 
122005aa5bd14SDaniel Borkmann static void do_test_single(struct bpf_test *test, bool unpriv,
122015aa5bd14SDaniel Borkmann 			   int *passes, int *errors)
122025aa5bd14SDaniel Borkmann {
1220302ea80b1SDaniel Borkmann 	int fd_prog, expected_ret, reject_from_alignment;
1220493731ef0SDaniel Borkmann 	int prog_len, prog_type = test->prog_type;
122055aa5bd14SDaniel Borkmann 	struct bpf_insn *prog = test->insns;
12206fb30d4b7SMartin KaFai Lau 	int map_fds[MAX_NR_MAPS];
122075aa5bd14SDaniel Borkmann 	const char *expected_err;
12208111e6b45SAlexei Starovoitov 	uint32_t retval;
12209111e6b45SAlexei Starovoitov 	int i, err;
122105aa5bd14SDaniel Borkmann 
12211fb30d4b7SMartin KaFai Lau 	for (i = 0; i < MAX_NR_MAPS; i++)
12212fb30d4b7SMartin KaFai Lau 		map_fds[i] = -1;
12213fb30d4b7SMartin KaFai Lau 
12214fb30d4b7SMartin KaFai Lau 	do_test_fixup(test, prog, map_fds);
1221593731ef0SDaniel Borkmann 	prog_len = probe_filter_length(prog);
122165aa5bd14SDaniel Borkmann 
12217614d0d77SDaniel Borkmann 	fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
12218614d0d77SDaniel Borkmann 				     prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
12219d6554904SDaniel Borkmann 				     "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
122205aa5bd14SDaniel Borkmann 
122215aa5bd14SDaniel Borkmann 	expected_ret = unpriv && test->result_unpriv != UNDEF ?
122225aa5bd14SDaniel Borkmann 		       test->result_unpriv : test->result;
122235aa5bd14SDaniel Borkmann 	expected_err = unpriv && test->errstr_unpriv ?
122245aa5bd14SDaniel Borkmann 		       test->errstr_unpriv : test->errstr;
1222502ea80b1SDaniel Borkmann 
1222602ea80b1SDaniel Borkmann 	reject_from_alignment = fd_prog < 0 &&
1222702ea80b1SDaniel Borkmann 				(test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
1222802ea80b1SDaniel Borkmann 				strstr(bpf_vlog, "Unknown alignment.");
1222902ea80b1SDaniel Borkmann #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
1223002ea80b1SDaniel Borkmann 	if (reject_from_alignment) {
1223102ea80b1SDaniel Borkmann 		printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
1223202ea80b1SDaniel Borkmann 		       strerror(errno));
1223302ea80b1SDaniel Borkmann 		goto fail_log;
1223402ea80b1SDaniel Borkmann 	}
1223502ea80b1SDaniel Borkmann #endif
122365aa5bd14SDaniel Borkmann 	if (expected_ret == ACCEPT) {
1223702ea80b1SDaniel Borkmann 		if (fd_prog < 0 && !reject_from_alignment) {
122385aa5bd14SDaniel Borkmann 			printf("FAIL\nFailed to load prog '%s'!\n",
122395aa5bd14SDaniel Borkmann 			       strerror(errno));
122405aa5bd14SDaniel Borkmann 			goto fail_log;
122415aa5bd14SDaniel Borkmann 		}
122425aa5bd14SDaniel Borkmann 	} else {
122435aa5bd14SDaniel Borkmann 		if (fd_prog >= 0) {
122445aa5bd14SDaniel Borkmann 			printf("FAIL\nUnexpected success to load!\n");
122455aa5bd14SDaniel Borkmann 			goto fail_log;
122465aa5bd14SDaniel Borkmann 		}
1224702ea80b1SDaniel Borkmann 		if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
1224895f87a97SJoe Stringer 			printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
1224995f87a97SJoe Stringer 			      expected_err, bpf_vlog);
122505aa5bd14SDaniel Borkmann 			goto fail_log;
122515aa5bd14SDaniel Borkmann 		}
122525aa5bd14SDaniel Borkmann 	}
122535aa5bd14SDaniel Borkmann 
12254111e6b45SAlexei Starovoitov 	if (fd_prog >= 0) {
1225593731ef0SDaniel Borkmann 		err = bpf_prog_test_run(fd_prog, 1, test->data,
1225693731ef0SDaniel Borkmann 					sizeof(test->data), NULL, NULL,
1225793731ef0SDaniel Borkmann 					&retval, NULL);
12258111e6b45SAlexei Starovoitov 		if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
12259111e6b45SAlexei Starovoitov 			printf("Unexpected bpf_prog_test_run error\n");
12260111e6b45SAlexei Starovoitov 			goto fail_log;
12261111e6b45SAlexei Starovoitov 		}
12262111e6b45SAlexei Starovoitov 		if (!err && retval != test->retval &&
12263111e6b45SAlexei Starovoitov 		    test->retval != POINTER_VALUE) {
12264111e6b45SAlexei Starovoitov 			printf("FAIL retval %d != %d\n", retval, test->retval);
12265111e6b45SAlexei Starovoitov 			goto fail_log;
12266111e6b45SAlexei Starovoitov 		}
12267111e6b45SAlexei Starovoitov 	}
122685aa5bd14SDaniel Borkmann 	(*passes)++;
1226902ea80b1SDaniel Borkmann 	printf("OK%s\n", reject_from_alignment ?
1227002ea80b1SDaniel Borkmann 	       " (NOTE: reject due to unknown alignment)" : "");
122715aa5bd14SDaniel Borkmann close_fds:
122725aa5bd14SDaniel Borkmann 	close(fd_prog);
12273fb30d4b7SMartin KaFai Lau 	for (i = 0; i < MAX_NR_MAPS; i++)
12274fb30d4b7SMartin KaFai Lau 		close(map_fds[i]);
122755aa5bd14SDaniel Borkmann 	sched_yield();
122765aa5bd14SDaniel Borkmann 	return;
122775aa5bd14SDaniel Borkmann fail_log:
122785aa5bd14SDaniel Borkmann 	(*errors)++;
122795aa5bd14SDaniel Borkmann 	printf("%s", bpf_vlog);
122805aa5bd14SDaniel Borkmann 	goto close_fds;
122815aa5bd14SDaniel Borkmann }
122825aa5bd14SDaniel Borkmann 
12283d02d8986SMickaël Salaün static bool is_admin(void)
12284d02d8986SMickaël Salaün {
12285d02d8986SMickaël Salaün 	cap_t caps;
12286d02d8986SMickaël Salaün 	cap_flag_value_t sysadmin = CAP_CLEAR;
12287d02d8986SMickaël Salaün 	const cap_value_t cap_val = CAP_SYS_ADMIN;
12288d02d8986SMickaël Salaün 
122891da8ac7cSAlexei Starovoitov #ifdef CAP_IS_SUPPORTED
12290d02d8986SMickaël Salaün 	if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
12291d02d8986SMickaël Salaün 		perror("cap_get_flag");
12292d02d8986SMickaël Salaün 		return false;
12293d02d8986SMickaël Salaün 	}
122941da8ac7cSAlexei Starovoitov #endif
12295d02d8986SMickaël Salaün 	caps = cap_get_proc();
12296d02d8986SMickaël Salaün 	if (!caps) {
12297d02d8986SMickaël Salaün 		perror("cap_get_proc");
12298d02d8986SMickaël Salaün 		return false;
12299d02d8986SMickaël Salaün 	}
12300d02d8986SMickaël Salaün 	if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
12301d02d8986SMickaël Salaün 		perror("cap_get_flag");
12302d02d8986SMickaël Salaün 	if (cap_free(caps))
12303d02d8986SMickaël Salaün 		perror("cap_free");
12304d02d8986SMickaël Salaün 	return (sysadmin == CAP_SET);
12305d02d8986SMickaël Salaün }
12306d02d8986SMickaël Salaün 
12307d02d8986SMickaël Salaün static int set_admin(bool admin)
12308d02d8986SMickaël Salaün {
12309d02d8986SMickaël Salaün 	cap_t caps;
12310d02d8986SMickaël Salaün 	const cap_value_t cap_val = CAP_SYS_ADMIN;
12311d02d8986SMickaël Salaün 	int ret = -1;
12312d02d8986SMickaël Salaün 
12313d02d8986SMickaël Salaün 	caps = cap_get_proc();
12314d02d8986SMickaël Salaün 	if (!caps) {
12315d02d8986SMickaël Salaün 		perror("cap_get_proc");
12316d02d8986SMickaël Salaün 		return -1;
12317d02d8986SMickaël Salaün 	}
12318d02d8986SMickaël Salaün 	if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
12319d02d8986SMickaël Salaün 				admin ? CAP_SET : CAP_CLEAR)) {
12320d02d8986SMickaël Salaün 		perror("cap_set_flag");
12321d02d8986SMickaël Salaün 		goto out;
12322d02d8986SMickaël Salaün 	}
12323d02d8986SMickaël Salaün 	if (cap_set_proc(caps)) {
12324d02d8986SMickaël Salaün 		perror("cap_set_proc");
12325d02d8986SMickaël Salaün 		goto out;
12326d02d8986SMickaël Salaün 	}
12327d02d8986SMickaël Salaün 	ret = 0;
12328d02d8986SMickaël Salaün out:
12329d02d8986SMickaël Salaün 	if (cap_free(caps))
12330d02d8986SMickaël Salaün 		perror("cap_free");
12331d02d8986SMickaël Salaün 	return ret;
12332d02d8986SMickaël Salaün }
12333d02d8986SMickaël Salaün 
123340a674874SJoe Stringer static void get_unpriv_disabled()
123350a674874SJoe Stringer {
123360a674874SJoe Stringer 	char buf[2];
123370a674874SJoe Stringer 	FILE *fd;
123380a674874SJoe Stringer 
123390a674874SJoe Stringer 	fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
123400a674874SJoe Stringer 	if (fgets(buf, 2, fd) == buf && atoi(buf))
123410a674874SJoe Stringer 		unpriv_disabled = true;
123420a674874SJoe Stringer 	fclose(fd);
123430a674874SJoe Stringer }
123440a674874SJoe Stringer 
123455aa5bd14SDaniel Borkmann static int do_test(bool unpriv, unsigned int from, unsigned int to)
123465aa5bd14SDaniel Borkmann {
12347d0a0e495SJoe Stringer 	int i, passes = 0, errors = 0, skips = 0;
123485aa5bd14SDaniel Borkmann 
123495aa5bd14SDaniel Borkmann 	for (i = from; i < to; i++) {
123505aa5bd14SDaniel Borkmann 		struct bpf_test *test = &tests[i];
123515aa5bd14SDaniel Borkmann 
123525aa5bd14SDaniel Borkmann 		/* Program types that are not supported by non-root we
123535aa5bd14SDaniel Borkmann 		 * skip right away.
123545aa5bd14SDaniel Borkmann 		 */
123550a674874SJoe Stringer 		if (!test->prog_type && unpriv_disabled) {
123560a674874SJoe Stringer 			printf("#%d/u %s SKIP\n", i, test->descr);
123570a674874SJoe Stringer 			skips++;
123580a674874SJoe Stringer 		} else if (!test->prog_type) {
12359d02d8986SMickaël Salaün 			if (!unpriv)
12360d02d8986SMickaël Salaün 				set_admin(false);
12361d02d8986SMickaël Salaün 			printf("#%d/u %s ", i, test->descr);
12362d02d8986SMickaël Salaün 			do_test_single(test, true, &passes, &errors);
12363d02d8986SMickaël Salaün 			if (!unpriv)
12364d02d8986SMickaël Salaün 				set_admin(true);
12365d02d8986SMickaël Salaün 		}
123665aa5bd14SDaniel Borkmann 
12367d0a0e495SJoe Stringer 		if (unpriv) {
12368d0a0e495SJoe Stringer 			printf("#%d/p %s SKIP\n", i, test->descr);
12369d0a0e495SJoe Stringer 			skips++;
12370d0a0e495SJoe Stringer 		} else {
12371d02d8986SMickaël Salaün 			printf("#%d/p %s ", i, test->descr);
12372d02d8986SMickaël Salaün 			do_test_single(test, false, &passes, &errors);
12373d02d8986SMickaël Salaün 		}
123745aa5bd14SDaniel Borkmann 	}
123755aa5bd14SDaniel Borkmann 
12376d0a0e495SJoe Stringer 	printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
12377d0a0e495SJoe Stringer 	       skips, errors);
12378efe5f9c0SJesper Dangaard Brouer 	return errors ? EXIT_FAILURE : EXIT_SUCCESS;
123795aa5bd14SDaniel Borkmann }
123805aa5bd14SDaniel Borkmann 
123815aa5bd14SDaniel Borkmann int main(int argc, char **argv)
123825aa5bd14SDaniel Borkmann {
123835aa5bd14SDaniel Borkmann 	unsigned int from = 0, to = ARRAY_SIZE(tests);
12384d02d8986SMickaël Salaün 	bool unpriv = !is_admin();
123855aa5bd14SDaniel Borkmann 
123865aa5bd14SDaniel Borkmann 	if (argc == 3) {
123875aa5bd14SDaniel Borkmann 		unsigned int l = atoi(argv[argc - 2]);
123885aa5bd14SDaniel Borkmann 		unsigned int u = atoi(argv[argc - 1]);
123895aa5bd14SDaniel Borkmann 
123905aa5bd14SDaniel Borkmann 		if (l < to && u < to) {
123915aa5bd14SDaniel Borkmann 			from = l;
123925aa5bd14SDaniel Borkmann 			to   = u + 1;
123935aa5bd14SDaniel Borkmann 		}
123945aa5bd14SDaniel Borkmann 	} else if (argc == 2) {
123955aa5bd14SDaniel Borkmann 		unsigned int t = atoi(argv[argc - 1]);
123965aa5bd14SDaniel Borkmann 
123975aa5bd14SDaniel Borkmann 		if (t < to) {
123985aa5bd14SDaniel Borkmann 			from = t;
123995aa5bd14SDaniel Borkmann 			to   = t + 1;
124005aa5bd14SDaniel Borkmann 		}
124015aa5bd14SDaniel Borkmann 	}
124025aa5bd14SDaniel Borkmann 
124030a674874SJoe Stringer 	get_unpriv_disabled();
124040a674874SJoe Stringer 	if (unpriv && unpriv_disabled) {
124050a674874SJoe Stringer 		printf("Cannot run as unprivileged user with sysctl %s.\n",
124060a674874SJoe Stringer 		       UNPRIV_SYSCTL);
124070a674874SJoe Stringer 		return EXIT_FAILURE;
124080a674874SJoe Stringer 	}
124090a674874SJoe Stringer 
12410a82d8cd3SDaniel Borkmann 	bpf_semi_rand_init();
124115aa5bd14SDaniel Borkmann 	return do_test(unpriv, from, to);
124125aa5bd14SDaniel Borkmann }
12413