xref: /linux/tools/testing/selftests/bpf/verifier/calls.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
148729226SJakub Kicinski {
2c48e51c8SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call not eliminated",
3c48e51c8SKumar Kartikeya Dwivedi 	.insns = {
4c48e51c8SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
5c48e51c8SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 1),
6c48e51c8SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
7c48e51c8SKumar Kartikeya Dwivedi 	},
8c48e51c8SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
9c48e51c8SKumar Kartikeya Dwivedi 	.result  = REJECT,
10c48e51c8SKumar Kartikeya Dwivedi 	.errstr = "invalid kernel function call not eliminated in verifier pass",
11c48e51c8SKumar Kartikeya Dwivedi },
12c48e51c8SKumar Kartikeya Dwivedi {
13c48e51c8SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call unreachable",
14c48e51c8SKumar Kartikeya Dwivedi 	.insns = {
15c48e51c8SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 1),
16c48e51c8SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 0, 2),
17c48e51c8SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
18c48e51c8SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 1),
19c48e51c8SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
20c48e51c8SKumar Kartikeya Dwivedi 	},
21c48e51c8SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
22c48e51c8SKumar Kartikeya Dwivedi 	.result  = ACCEPT,
23c48e51c8SKumar Kartikeya Dwivedi },
24c48e51c8SKumar Kartikeya Dwivedi {
25c1ff181fSKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: ptr_to_mem to struct with non-scalar",
26c1ff181fSKumar Kartikeya Dwivedi 	.insns = {
27c1ff181fSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
28c1ff181fSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
29c1ff181fSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
30c1ff181fSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
31c1ff181fSKumar Kartikeya Dwivedi 	},
32c1ff181fSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33c1ff181fSKumar Kartikeya Dwivedi 	.result = REJECT,
34c1ff181fSKumar Kartikeya Dwivedi 	.errstr = "arg#0 pointer type STRUCT prog_test_fail1 must point to scalar",
35c1ff181fSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
36c1ff181fSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_fail1", 2 },
37c1ff181fSKumar Kartikeya Dwivedi 	},
38c1ff181fSKumar Kartikeya Dwivedi },
39c1ff181fSKumar Kartikeya Dwivedi {
40c1ff181fSKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: ptr_to_mem to struct with nesting depth > 4",
41c1ff181fSKumar Kartikeya Dwivedi 	.insns = {
42c1ff181fSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
43c1ff181fSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
44c1ff181fSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
45c1ff181fSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
46c1ff181fSKumar Kartikeya Dwivedi 	},
47c1ff181fSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
48c1ff181fSKumar Kartikeya Dwivedi 	.result = REJECT,
49c1ff181fSKumar Kartikeya Dwivedi 	.errstr = "max struct nesting depth exceeded\narg#0 pointer type STRUCT prog_test_fail2",
50c1ff181fSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
51c1ff181fSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_fail2", 2 },
52c1ff181fSKumar Kartikeya Dwivedi 	},
53c1ff181fSKumar Kartikeya Dwivedi },
54c1ff181fSKumar Kartikeya Dwivedi {
55c1ff181fSKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: ptr_to_mem to struct with FAM",
56c1ff181fSKumar Kartikeya Dwivedi 	.insns = {
57c1ff181fSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
58c1ff181fSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
59c1ff181fSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
60c1ff181fSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
61c1ff181fSKumar Kartikeya Dwivedi 	},
62c1ff181fSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
63c1ff181fSKumar Kartikeya Dwivedi 	.result = REJECT,
64c1ff181fSKumar Kartikeya Dwivedi 	.errstr = "arg#0 pointer type STRUCT prog_test_fail3 must point to scalar",
65c1ff181fSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
66c1ff181fSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_fail3", 2 },
67c1ff181fSKumar Kartikeya Dwivedi 	},
68c1ff181fSKumar Kartikeya Dwivedi },
69c1ff181fSKumar Kartikeya Dwivedi {
70c1ff181fSKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: reg->type != PTR_TO_CTX",
71c1ff181fSKumar Kartikeya Dwivedi 	.insns = {
72c1ff181fSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
73c1ff181fSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
74c1ff181fSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
75c1ff181fSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
76c1ff181fSKumar Kartikeya Dwivedi 	},
77c1ff181fSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
78c1ff181fSKumar Kartikeya Dwivedi 	.result = REJECT,
79*bee109b7SMaxim Mikityanskiy 	.errstr = "arg#0 expected pointer to ctx, but got fp",
80c1ff181fSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
81c1ff181fSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_pass_ctx", 2 },
82c1ff181fSKumar Kartikeya Dwivedi 	},
83c1ff181fSKumar Kartikeya Dwivedi },
84c1ff181fSKumar Kartikeya Dwivedi {
85c1ff181fSKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: void * not allowed in func proto without mem size arg",
86c1ff181fSKumar Kartikeya Dwivedi 	.insns = {
87c1ff181fSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
88c1ff181fSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
89c1ff181fSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
90c1ff181fSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
91c1ff181fSKumar Kartikeya Dwivedi 	},
92c1ff181fSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
93c1ff181fSKumar Kartikeya Dwivedi 	.result = REJECT,
94c1ff181fSKumar Kartikeya Dwivedi 	.errstr = "arg#0 pointer type UNKNOWN  must point to scalar",
95c1ff181fSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
96c1ff181fSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_mem_len_fail1", 2 },
97c1ff181fSKumar Kartikeya Dwivedi 	},
98c1ff181fSKumar Kartikeya Dwivedi },
99c1ff181fSKumar Kartikeya Dwivedi {
10013c6a37dSKumar Kartikeya Dwivedi 	"calls: trigger reg2btf_ids[reg->type] for reg->type > __BPF_REG_TYPE_MAX",
10113c6a37dSKumar Kartikeya Dwivedi 	.insns = {
10213c6a37dSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
10313c6a37dSKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
10413c6a37dSKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
10513c6a37dSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
10613c6a37dSKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
10713c6a37dSKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
10813c6a37dSKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
10913c6a37dSKumar Kartikeya Dwivedi 	},
11013c6a37dSKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11113c6a37dSKumar Kartikeya Dwivedi 	.result = REJECT,
1126c831c46SDavid Vernet 	.errstr = "Possibly NULL pointer passed to trusted arg0",
11313c6a37dSKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
11413c6a37dSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
11513c6a37dSKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_release", 5 },
11613c6a37dSKumar Kartikeya Dwivedi 	},
11713c6a37dSKumar Kartikeya Dwivedi },
11813c6a37dSKumar Kartikeya Dwivedi {
1198218ccb5SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: reg->off must be zero when passed to release kfunc",
1208218ccb5SKumar Kartikeya Dwivedi 	.insns = {
1218218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1228218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1238218ccb5SKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
1248218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1258218ccb5SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1268218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
1278218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1288218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1298218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1308218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
1318218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
1328218ccb5SKumar Kartikeya Dwivedi 	},
1338218ccb5SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1348218ccb5SKumar Kartikeya Dwivedi 	.result = REJECT,
1358218ccb5SKumar Kartikeya Dwivedi 	.errstr = "R1 must have zero offset when passed to release func",
1368218ccb5SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
1378218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
1388218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_memb_release", 8 },
1398218ccb5SKumar Kartikeya Dwivedi 	},
1408218ccb5SKumar Kartikeya Dwivedi },
1418218ccb5SKumar Kartikeya Dwivedi {
142792c0a34SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: don't match first member type when passed to release kfunc",
143792c0a34SKumar Kartikeya Dwivedi 	.insns = {
144792c0a34SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
145792c0a34SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
146792c0a34SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
147792c0a34SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
148792c0a34SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
149792c0a34SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
150792c0a34SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
151792c0a34SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
152792c0a34SKumar Kartikeya Dwivedi 	},
153792c0a34SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
154792c0a34SKumar Kartikeya Dwivedi 	.result = REJECT,
155792c0a34SKumar Kartikeya Dwivedi 	.errstr = "kernel function bpf_kfunc_call_memb1_release args#0 expected pointer",
156792c0a34SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
157792c0a34SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_memb_acquire", 1 },
158792c0a34SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_memb1_release", 5 },
159792c0a34SKumar Kartikeya Dwivedi 	},
160792c0a34SKumar Kartikeya Dwivedi },
161792c0a34SKumar Kartikeya Dwivedi {
1628218ccb5SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset",
1638218ccb5SKumar Kartikeya Dwivedi 	.insns = {
1648218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1658218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1668218ccb5SKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
1678218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1686c831c46SDavid Vernet 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
1698218ccb5SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1708218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
1718218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1728218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4),
1738218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1748218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
1756c831c46SDavid Vernet 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1766c831c46SDavid Vernet 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1776c831c46SDavid Vernet 	BPF_MOV64_IMM(BPF_REG_0, 0),
1788218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
1798218ccb5SKumar Kartikeya Dwivedi 	},
1808218ccb5SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1818218ccb5SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
1828218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
1836c831c46SDavid Vernet 		{ "bpf_kfunc_call_test_offset", 9 },
1846c831c46SDavid Vernet 		{ "bpf_kfunc_call_test_release", 12 },
1858218ccb5SKumar Kartikeya Dwivedi 	},
1868218ccb5SKumar Kartikeya Dwivedi 	.result_unpriv = REJECT,
1878218ccb5SKumar Kartikeya Dwivedi 	.result = REJECT,
1886fcd486bSAlexei Starovoitov 	.errstr = "ptr R1 off=-4 disallowed",
1898218ccb5SKumar Kartikeya Dwivedi },
1908218ccb5SKumar Kartikeya Dwivedi {
1918218ccb5SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset",
1928218ccb5SKumar Kartikeya Dwivedi 	.insns = {
1938218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1948218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1958218ccb5SKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
1968218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
1978218ccb5SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1988218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
1998218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2008218ccb5SKumar Kartikeya Dwivedi 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
2018218ccb5SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3),
2028218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2038218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
2048218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2058218ccb5SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3),
2068218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2078218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
2088218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2098218ccb5SKumar Kartikeya Dwivedi 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
2108218ccb5SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2118218ccb5SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
2128218ccb5SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2138218ccb5SKumar Kartikeya Dwivedi 	},
2148218ccb5SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2158218ccb5SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
2168218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
2178218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_release", 9 },
2188218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_release", 13 },
2198218ccb5SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_release", 17 },
2208218ccb5SKumar Kartikeya Dwivedi 	},
2218218ccb5SKumar Kartikeya Dwivedi 	.result_unpriv = REJECT,
2228218ccb5SKumar Kartikeya Dwivedi 	.result = REJECT,
2238218ccb5SKumar Kartikeya Dwivedi 	.errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed",
2248218ccb5SKumar Kartikeya Dwivedi },
2258218ccb5SKumar Kartikeya Dwivedi {
2268dd5e756SKumar Kartikeya Dwivedi 	"calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
2278dd5e756SKumar Kartikeya Dwivedi 	.insns = {
2288dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2298dd5e756SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2308dd5e756SKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
2318dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2328dd5e756SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
2338dd5e756SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2348dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
2358dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2368dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2378dd5e756SKumar Kartikeya Dwivedi 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 16),
2388dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2398dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
2408dd5e756SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2418dd5e756SKumar Kartikeya Dwivedi 	},
2428dd5e756SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2438dd5e756SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
2448dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
2458dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_ref", 8 },
2468dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_ref", 10 },
2478dd5e756SKumar Kartikeya Dwivedi 	},
2488dd5e756SKumar Kartikeya Dwivedi 	.result_unpriv = REJECT,
2498dd5e756SKumar Kartikeya Dwivedi 	.result = REJECT,
25020c09d92SAlexei Starovoitov 	.errstr = "R1 must be",
2518dd5e756SKumar Kartikeya Dwivedi },
2528dd5e756SKumar Kartikeya Dwivedi {
2538dd5e756SKumar Kartikeya Dwivedi 	"calls: valid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
2548dd5e756SKumar Kartikeya Dwivedi 	.insns = {
2558dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
2568dd5e756SKumar Kartikeya Dwivedi 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
2578dd5e756SKumar Kartikeya Dwivedi 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
2588dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2598dd5e756SKumar Kartikeya Dwivedi 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
2608dd5e756SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2618dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
2628dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2638dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2648dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2658dd5e756SKumar Kartikeya Dwivedi 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
2668dd5e756SKumar Kartikeya Dwivedi 	BPF_MOV64_IMM(BPF_REG_0, 0),
2678dd5e756SKumar Kartikeya Dwivedi 	BPF_EXIT_INSN(),
2688dd5e756SKumar Kartikeya Dwivedi 	},
2698dd5e756SKumar Kartikeya Dwivedi 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2708dd5e756SKumar Kartikeya Dwivedi 	.fixup_kfunc_btf_id = {
2718dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_acquire", 3 },
2728dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_ref", 8 },
2738dd5e756SKumar Kartikeya Dwivedi 		{ "bpf_kfunc_call_test_release", 10 },
2748dd5e756SKumar Kartikeya Dwivedi 	},
2758dd5e756SKumar Kartikeya Dwivedi 	.result_unpriv = REJECT,
2768dd5e756SKumar Kartikeya Dwivedi 	.result = ACCEPT,
2778dd5e756SKumar Kartikeya Dwivedi },
2788dd5e756SKumar Kartikeya Dwivedi {
279e435b043STengda Wu 	"calls: invalid kfunc call: must provide (attach_prog_fd, btf_id) pair when freplace",
280e435b043STengda Wu 	.insns = {
281e435b043STengda Wu 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
282e435b043STengda Wu 	BPF_EXIT_INSN(),
283e435b043STengda Wu 	},
284e435b043STengda Wu 	.prog_type = BPF_PROG_TYPE_EXT,
285e435b043STengda Wu 	.result = REJECT,
286e435b043STengda Wu 	.errstr = "Tracing programs must provide btf_id",
287e435b043STengda Wu 	.fixup_kfunc_btf_id = {
288e435b043STengda Wu 		{ "bpf_dynptr_from_skb", 0 },
289e435b043STengda Wu 	},
290e435b043STengda Wu },
291e435b043STengda Wu {
29248729226SJakub Kicinski 	"calls: basic sanity",
29348729226SJakub Kicinski 	.insns = {
29448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
29548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
29648729226SJakub Kicinski 	BPF_EXIT_INSN(),
29748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
29848729226SJakub Kicinski 	BPF_EXIT_INSN(),
29948729226SJakub Kicinski 	},
30048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
30148729226SJakub Kicinski 	.result = ACCEPT,
30248729226SJakub Kicinski },
30348729226SJakub Kicinski {
3042efcf695SColin Ian King 	"calls: not on unprivileged",
30548729226SJakub Kicinski 	.insns = {
30648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
30748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
30848729226SJakub Kicinski 	BPF_EXIT_INSN(),
30948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
31048729226SJakub Kicinski 	BPF_EXIT_INSN(),
31148729226SJakub Kicinski 	},
312e6ac2450SMartin KaFai Lau 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
31348729226SJakub Kicinski 	.result_unpriv = REJECT,
31448729226SJakub Kicinski 	.result = ACCEPT,
31548729226SJakub Kicinski 	.retval = 1,
31648729226SJakub Kicinski },
31748729226SJakub Kicinski {
31848729226SJakub Kicinski 	"calls: div by 0 in subprog",
31948729226SJakub Kicinski 	.insns = {
32048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
32148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
32248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
32348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
32448729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
32548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
32648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
32748729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
32848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
32948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
33048729226SJakub Kicinski 	BPF_EXIT_INSN(),
33148729226SJakub Kicinski 	BPF_MOV32_IMM(BPF_REG_2, 0),
33248729226SJakub Kicinski 	BPF_MOV32_IMM(BPF_REG_3, 1),
33348729226SJakub Kicinski 	BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
33448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
33548729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
33648729226SJakub Kicinski 	BPF_EXIT_INSN(),
33748729226SJakub Kicinski 	},
33848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33948729226SJakub Kicinski 	.result = ACCEPT,
34048729226SJakub Kicinski 	.retval = 1,
34148729226SJakub Kicinski },
34248729226SJakub Kicinski {
34348729226SJakub Kicinski 	"calls: multiple ret types in subprog 1",
34448729226SJakub Kicinski 	.insns = {
34548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
34648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
34748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
34848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
34948729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
35048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
35148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
35248729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
35348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
35448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
35548729226SJakub Kicinski 	BPF_EXIT_INSN(),
35648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
35748729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
35848729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
35948729226SJakub Kicinski 	BPF_MOV32_IMM(BPF_REG_0, 42),
36048729226SJakub Kicinski 	BPF_EXIT_INSN(),
36148729226SJakub Kicinski 	},
36248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
36348729226SJakub Kicinski 	.result = REJECT,
3647df5072cSMykola Lysenko 	.errstr = "R0 invalid mem access 'scalar'",
36548729226SJakub Kicinski },
36648729226SJakub Kicinski {
36748729226SJakub Kicinski 	"calls: multiple ret types in subprog 2",
36848729226SJakub Kicinski 	.insns = {
36948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
37048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
37148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
37248729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
37348729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
37448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
37548729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
37648729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
37748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
37848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
37948729226SJakub Kicinski 	BPF_EXIT_INSN(),
38048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
38148729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
38248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
38348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
38448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
38548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
38648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
38748729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
38848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
38948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
39048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
39148729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
39248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
39348729226SJakub Kicinski 	BPF_EXIT_INSN(),
39448729226SJakub Kicinski 	},
39548729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
39648729226SJakub Kicinski 	.fixup_map_hash_8b = { 16 },
39748729226SJakub Kicinski 	.result = REJECT,
398457f4436SAndrii Nakryiko 	.errstr = "R0 min value is outside of the allowed memory range",
39948729226SJakub Kicinski },
40048729226SJakub Kicinski {
40148729226SJakub Kicinski 	"calls: overlapping caller/callee",
40248729226SJakub Kicinski 	.insns = {
40348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
40448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
40548729226SJakub Kicinski 	BPF_EXIT_INSN(),
40648729226SJakub Kicinski 	},
40748729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
40848729226SJakub Kicinski 	.errstr = "last insn is not an exit or jmp",
40948729226SJakub Kicinski 	.result = REJECT,
41048729226SJakub Kicinski },
41148729226SJakub Kicinski {
41248729226SJakub Kicinski 	"calls: wrong recursive calls",
41348729226SJakub Kicinski 	.insns = {
41448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
41548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
41648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
41748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
41848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
41948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
42048729226SJakub Kicinski 	BPF_EXIT_INSN(),
42148729226SJakub Kicinski 	},
42248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
42348729226SJakub Kicinski 	.errstr = "jump out of range",
42448729226SJakub Kicinski 	.result = REJECT,
42548729226SJakub Kicinski },
42648729226SJakub Kicinski {
42748729226SJakub Kicinski 	"calls: wrong src reg",
42848729226SJakub Kicinski 	.insns = {
429e6ac2450SMartin KaFai Lau 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 3, 0, 0),
43048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
43148729226SJakub Kicinski 	BPF_EXIT_INSN(),
43248729226SJakub Kicinski 	},
43348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
43448729226SJakub Kicinski 	.errstr = "BPF_CALL uses reserved fields",
43548729226SJakub Kicinski 	.result = REJECT,
43648729226SJakub Kicinski },
43748729226SJakub Kicinski {
43848729226SJakub Kicinski 	"calls: wrong off value",
43948729226SJakub Kicinski 	.insns = {
44048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
44148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
44248729226SJakub Kicinski 	BPF_EXIT_INSN(),
44348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
44448729226SJakub Kicinski 	BPF_EXIT_INSN(),
44548729226SJakub Kicinski 	},
44648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
44748729226SJakub Kicinski 	.errstr = "BPF_CALL uses reserved fields",
44848729226SJakub Kicinski 	.result = REJECT,
44948729226SJakub Kicinski },
45048729226SJakub Kicinski {
45148729226SJakub Kicinski 	"calls: jump back loop",
45248729226SJakub Kicinski 	.insns = {
45348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
45448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
45548729226SJakub Kicinski 	BPF_EXIT_INSN(),
45648729226SJakub Kicinski 	},
45748729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
45810e14e96SAndrii Nakryiko 	.errstr = "the call stack of 9 frames is too deep",
45948729226SJakub Kicinski 	.result = REJECT,
46048729226SJakub Kicinski },
46148729226SJakub Kicinski {
46248729226SJakub Kicinski 	"calls: conditional call",
46348729226SJakub Kicinski 	.insns = {
46448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
46548729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
46648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
46748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
46848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
46948729226SJakub Kicinski 	BPF_EXIT_INSN(),
47048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
47148729226SJakub Kicinski 	BPF_EXIT_INSN(),
47248729226SJakub Kicinski 	},
47348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
47448729226SJakub Kicinski 	.errstr = "jump out of range",
47548729226SJakub Kicinski 	.result = REJECT,
47648729226SJakub Kicinski },
47748729226SJakub Kicinski {
47848729226SJakub Kicinski 	"calls: conditional call 2",
47948729226SJakub Kicinski 	.insns = {
48048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
48148729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
48248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
48348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
48448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
48548729226SJakub Kicinski 	BPF_EXIT_INSN(),
48648729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
48748729226SJakub Kicinski 	BPF_EXIT_INSN(),
48848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 3),
48948729226SJakub Kicinski 	BPF_EXIT_INSN(),
49048729226SJakub Kicinski 	},
49148729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
49248729226SJakub Kicinski 	.result = ACCEPT,
49348729226SJakub Kicinski },
49448729226SJakub Kicinski {
49548729226SJakub Kicinski 	"calls: conditional call 3",
49648729226SJakub Kicinski 	.insns = {
49748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
49848729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
49948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
50048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
50148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
50248729226SJakub Kicinski 	BPF_EXIT_INSN(),
50348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
50448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
50548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 3),
50648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
50748729226SJakub Kicinski 	},
508aeee380cSAlexei Starovoitov 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
509aeee380cSAlexei Starovoitov 	.errstr_unpriv = "back-edge from insn",
510aeee380cSAlexei Starovoitov 	.result_unpriv = REJECT,
511aeee380cSAlexei Starovoitov 	.result = ACCEPT,
512aeee380cSAlexei Starovoitov 	.retval = 1,
51348729226SJakub Kicinski },
51448729226SJakub Kicinski {
51548729226SJakub Kicinski 	"calls: conditional call 4",
51648729226SJakub Kicinski 	.insns = {
51748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
51848729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
51948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
52048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
52148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
52248729226SJakub Kicinski 	BPF_EXIT_INSN(),
52348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
52448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -5),
52548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 3),
52648729226SJakub Kicinski 	BPF_EXIT_INSN(),
52748729226SJakub Kicinski 	},
52848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
52948729226SJakub Kicinski 	.result = ACCEPT,
53048729226SJakub Kicinski },
53148729226SJakub Kicinski {
53248729226SJakub Kicinski 	"calls: conditional call 5",
53348729226SJakub Kicinski 	.insns = {
53448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
53548729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
53648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
53748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
53848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
53948729226SJakub Kicinski 	BPF_EXIT_INSN(),
54048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
54148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
54248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 3),
54348729226SJakub Kicinski 	BPF_EXIT_INSN(),
54448729226SJakub Kicinski 	},
545aeee380cSAlexei Starovoitov 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
546aeee380cSAlexei Starovoitov 	.result = ACCEPT,
547aeee380cSAlexei Starovoitov 	.retval = 1,
54848729226SJakub Kicinski },
54948729226SJakub Kicinski {
55048729226SJakub Kicinski 	"calls: conditional call 6",
55148729226SJakub Kicinski 	.insns = {
552aeee380cSAlexei Starovoitov 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
553aeee380cSAlexei Starovoitov 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
55448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
555aeee380cSAlexei Starovoitov 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
55648729226SJakub Kicinski 	BPF_EXIT_INSN(),
55748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
55848729226SJakub Kicinski 		    offsetof(struct __sk_buff, mark)),
55948729226SJakub Kicinski 	BPF_EXIT_INSN(),
56048729226SJakub Kicinski 	},
561aeee380cSAlexei Starovoitov 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
562aeee380cSAlexei Starovoitov 	.errstr = "infinite loop detected",
56348729226SJakub Kicinski 	.result = REJECT,
56448729226SJakub Kicinski },
56548729226SJakub Kicinski {
56648729226SJakub Kicinski 	"calls: using r0 returned by callee",
56748729226SJakub Kicinski 	.insns = {
56848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
56948729226SJakub Kicinski 	BPF_EXIT_INSN(),
57048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 2),
57148729226SJakub Kicinski 	BPF_EXIT_INSN(),
57248729226SJakub Kicinski 	},
57348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
57448729226SJakub Kicinski 	.result = ACCEPT,
57548729226SJakub Kicinski },
57648729226SJakub Kicinski {
57748729226SJakub Kicinski 	"calls: using uninit r0 from callee",
57848729226SJakub Kicinski 	.insns = {
57948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
58048729226SJakub Kicinski 	BPF_EXIT_INSN(),
58148729226SJakub Kicinski 	BPF_EXIT_INSN(),
58248729226SJakub Kicinski 	},
58348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
58448729226SJakub Kicinski 	.errstr = "!read_ok",
58548729226SJakub Kicinski 	.result = REJECT,
58648729226SJakub Kicinski },
58748729226SJakub Kicinski {
58848729226SJakub Kicinski 	"calls: callee is using r1",
58948729226SJakub Kicinski 	.insns = {
59048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
59148729226SJakub Kicinski 	BPF_EXIT_INSN(),
59248729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
59348729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
59448729226SJakub Kicinski 	BPF_EXIT_INSN(),
59548729226SJakub Kicinski 	},
59648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_ACT,
59748729226SJakub Kicinski 	.result = ACCEPT,
59848729226SJakub Kicinski 	.retval = TEST_DATA_LEN,
59948729226SJakub Kicinski },
60048729226SJakub Kicinski {
60148729226SJakub Kicinski 	"calls: callee using args1",
60248729226SJakub Kicinski 	.insns = {
60348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
60448729226SJakub Kicinski 	BPF_EXIT_INSN(),
60548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
60648729226SJakub Kicinski 	BPF_EXIT_INSN(),
60748729226SJakub Kicinski 	},
60881626001SAlexei Starovoitov 	.errstr_unpriv = "allowed for",
60948729226SJakub Kicinski 	.result_unpriv = REJECT,
61048729226SJakub Kicinski 	.result = ACCEPT,
61148729226SJakub Kicinski 	.retval = POINTER_VALUE,
61248729226SJakub Kicinski },
61348729226SJakub Kicinski {
61448729226SJakub Kicinski 	"calls: callee using wrong args2",
61548729226SJakub Kicinski 	.insns = {
61648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
61748729226SJakub Kicinski 	BPF_EXIT_INSN(),
61848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
61948729226SJakub Kicinski 	BPF_EXIT_INSN(),
62048729226SJakub Kicinski 	},
62148729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
62248729226SJakub Kicinski 	.errstr = "R2 !read_ok",
62348729226SJakub Kicinski 	.result = REJECT,
62448729226SJakub Kicinski },
62548729226SJakub Kicinski {
62648729226SJakub Kicinski 	"calls: callee using two args",
62748729226SJakub Kicinski 	.insns = {
62848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
62948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
63048729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
63148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
63248729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
63348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
63448729226SJakub Kicinski 	BPF_EXIT_INSN(),
63548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
63648729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
63748729226SJakub Kicinski 	BPF_EXIT_INSN(),
63848729226SJakub Kicinski 	},
63981626001SAlexei Starovoitov 	.errstr_unpriv = "allowed for",
64048729226SJakub Kicinski 	.result_unpriv = REJECT,
64148729226SJakub Kicinski 	.result = ACCEPT,
64248729226SJakub Kicinski 	.retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
64348729226SJakub Kicinski },
64448729226SJakub Kicinski {
64548729226SJakub Kicinski 	"calls: callee changing pkt pointers",
64648729226SJakub Kicinski 	.insns = {
64748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct xdp_md, data)),
64848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
64948729226SJakub Kicinski 		    offsetof(struct xdp_md, data_end)),
65048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
65148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
65248729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
65348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
65448729226SJakub Kicinski 	/* clear_all_pkt_pointers() has to walk all frames
65548729226SJakub Kicinski 	 * to make sure that pkt pointers in the caller
65648729226SJakub Kicinski 	 * are cleared when callee is calling a helper that
65748729226SJakub Kicinski 	 * adjusts packet size
65848729226SJakub Kicinski 	 */
65948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
66048729226SJakub Kicinski 	BPF_MOV32_IMM(BPF_REG_0, 0),
66148729226SJakub Kicinski 	BPF_EXIT_INSN(),
66248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_2, 0),
66348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_xdp_adjust_head),
66448729226SJakub Kicinski 	BPF_EXIT_INSN(),
66548729226SJakub Kicinski 	},
66648729226SJakub Kicinski 	.result = REJECT,
6677df5072cSMykola Lysenko 	.errstr = "R6 invalid mem access 'scalar'",
66848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
66948729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
67048729226SJakub Kicinski },
67148729226SJakub Kicinski {
6726dd7f140SPaul Chaignon 	"calls: ptr null check in subprog",
6736dd7f140SPaul Chaignon 	.insns = {
6746dd7f140SPaul Chaignon 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6756dd7f140SPaul Chaignon 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6766dd7f140SPaul Chaignon 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
6776dd7f140SPaul Chaignon 	BPF_LD_MAP_FD(BPF_REG_1, 0),
6786dd7f140SPaul Chaignon 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
6796dd7f140SPaul Chaignon 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6806dd7f140SPaul Chaignon 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
6816dd7f140SPaul Chaignon 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
6826dd7f140SPaul Chaignon 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
6836dd7f140SPaul Chaignon 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
6846dd7f140SPaul Chaignon 	BPF_EXIT_INSN(),
6856dd7f140SPaul Chaignon 	BPF_MOV64_IMM(BPF_REG_0, 0),
6866dd7f140SPaul Chaignon 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
6876dd7f140SPaul Chaignon 	BPF_MOV64_IMM(BPF_REG_0, 1),
6886dd7f140SPaul Chaignon 	BPF_EXIT_INSN(),
6896dd7f140SPaul Chaignon 	},
690e6ac2450SMartin KaFai Lau 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
6916dd7f140SPaul Chaignon 	.fixup_map_hash_48b = { 3 },
6926dd7f140SPaul Chaignon 	.result_unpriv = REJECT,
6936dd7f140SPaul Chaignon 	.result = ACCEPT,
6946dd7f140SPaul Chaignon 	.retval = 0,
6956dd7f140SPaul Chaignon },
6966dd7f140SPaul Chaignon {
69748729226SJakub Kicinski 	"calls: two calls with args",
69848729226SJakub Kicinski 	.insns = {
69948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
70048729226SJakub Kicinski 	BPF_EXIT_INSN(),
70148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
70248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
70348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
70448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
70548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
70648729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
70748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
70848729226SJakub Kicinski 	BPF_EXIT_INSN(),
70948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
71048729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
71148729226SJakub Kicinski 	BPF_EXIT_INSN(),
71248729226SJakub Kicinski 	},
71348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
71448729226SJakub Kicinski 	.result = ACCEPT,
71548729226SJakub Kicinski 	.retval = TEST_DATA_LEN + TEST_DATA_LEN,
71648729226SJakub Kicinski },
71748729226SJakub Kicinski {
71848729226SJakub Kicinski 	"calls: calls with stack arith",
71948729226SJakub Kicinski 	.insns = {
72048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
72148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
72248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
72348729226SJakub Kicinski 	BPF_EXIT_INSN(),
72448729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
72548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
72648729226SJakub Kicinski 	BPF_EXIT_INSN(),
72748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
72848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 42),
72948729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
73048729226SJakub Kicinski 	BPF_EXIT_INSN(),
73148729226SJakub Kicinski 	},
73248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
73348729226SJakub Kicinski 	.result = ACCEPT,
73448729226SJakub Kicinski 	.retval = 42,
73548729226SJakub Kicinski },
73648729226SJakub Kicinski {
73748729226SJakub Kicinski 	"calls: calls with misaligned stack access",
73848729226SJakub Kicinski 	.insns = {
73948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
74048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
74148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
74248729226SJakub Kicinski 	BPF_EXIT_INSN(),
74348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
74448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
74548729226SJakub Kicinski 	BPF_EXIT_INSN(),
74648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
74748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 42),
74848729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
74948729226SJakub Kicinski 	BPF_EXIT_INSN(),
75048729226SJakub Kicinski 	},
75148729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
75248729226SJakub Kicinski 	.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
75348729226SJakub Kicinski 	.errstr = "misaligned stack access",
75448729226SJakub Kicinski 	.result = REJECT,
75548729226SJakub Kicinski },
75648729226SJakub Kicinski {
75748729226SJakub Kicinski 	"calls: calls control flow, jump test",
75848729226SJakub Kicinski 	.insns = {
75948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 42),
76048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
76148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 43),
76248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
76348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
76448729226SJakub Kicinski 	BPF_EXIT_INSN(),
76548729226SJakub Kicinski 	},
76648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
76748729226SJakub Kicinski 	.result = ACCEPT,
76848729226SJakub Kicinski 	.retval = 43,
76948729226SJakub Kicinski },
77048729226SJakub Kicinski {
77148729226SJakub Kicinski 	"calls: calls control flow, jump test 2",
77248729226SJakub Kicinski 	.insns = {
77348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 42),
77448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
77548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 43),
77648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
77748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
77848729226SJakub Kicinski 	BPF_EXIT_INSN(),
77948729226SJakub Kicinski 	},
78048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
78148729226SJakub Kicinski 	.errstr = "jump out of range from insn 1 to 4",
78248729226SJakub Kicinski 	.result = REJECT,
78348729226SJakub Kicinski },
78448729226SJakub Kicinski {
78548729226SJakub Kicinski 	"calls: two calls with bad jump",
78648729226SJakub Kicinski 	.insns = {
78748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
78848729226SJakub Kicinski 	BPF_EXIT_INSN(),
78948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
79048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
79148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
79248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
79348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
79448729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
79548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
79648729226SJakub Kicinski 	BPF_EXIT_INSN(),
79748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
79848729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
79948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
80048729226SJakub Kicinski 	BPF_EXIT_INSN(),
80148729226SJakub Kicinski 	},
80248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
80348729226SJakub Kicinski 	.errstr = "jump out of range from insn 11 to 9",
80448729226SJakub Kicinski 	.result = REJECT,
80548729226SJakub Kicinski },
80648729226SJakub Kicinski {
80748729226SJakub Kicinski 	"calls: recursive call. test1",
80848729226SJakub Kicinski 	.insns = {
80948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
81048729226SJakub Kicinski 	BPF_EXIT_INSN(),
81148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
81248729226SJakub Kicinski 	BPF_EXIT_INSN(),
81348729226SJakub Kicinski 	},
81448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
81510e14e96SAndrii Nakryiko 	.errstr = "the call stack of 9 frames is too deep",
81648729226SJakub Kicinski 	.result = REJECT,
81748729226SJakub Kicinski },
81848729226SJakub Kicinski {
81948729226SJakub Kicinski 	"calls: recursive call. test2",
82048729226SJakub Kicinski 	.insns = {
82148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
82248729226SJakub Kicinski 	BPF_EXIT_INSN(),
82348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
82448729226SJakub Kicinski 	BPF_EXIT_INSN(),
82548729226SJakub Kicinski 	},
82648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
82710e14e96SAndrii Nakryiko 	.errstr = "the call stack of 9 frames is too deep",
82848729226SJakub Kicinski 	.result = REJECT,
82948729226SJakub Kicinski },
83048729226SJakub Kicinski {
83148729226SJakub Kicinski 	"calls: unreachable code",
83248729226SJakub Kicinski 	.insns = {
83348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
83448729226SJakub Kicinski 	BPF_EXIT_INSN(),
83548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
83648729226SJakub Kicinski 	BPF_EXIT_INSN(),
83748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
83848729226SJakub Kicinski 	BPF_EXIT_INSN(),
83948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
84048729226SJakub Kicinski 	BPF_EXIT_INSN(),
84148729226SJakub Kicinski 	},
84248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
84348729226SJakub Kicinski 	.errstr = "unreachable insn 6",
84448729226SJakub Kicinski 	.result = REJECT,
84548729226SJakub Kicinski },
84648729226SJakub Kicinski {
84748729226SJakub Kicinski 	"calls: invalid call",
84848729226SJakub Kicinski 	.insns = {
84948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
85048729226SJakub Kicinski 	BPF_EXIT_INSN(),
85148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
85248729226SJakub Kicinski 	BPF_EXIT_INSN(),
85348729226SJakub Kicinski 	},
85448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
85548729226SJakub Kicinski 	.errstr = "invalid destination",
85648729226SJakub Kicinski 	.result = REJECT,
85748729226SJakub Kicinski },
85848729226SJakub Kicinski {
85948729226SJakub Kicinski 	"calls: invalid call 2",
86048729226SJakub Kicinski 	.insns = {
86148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
86248729226SJakub Kicinski 	BPF_EXIT_INSN(),
86348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
86448729226SJakub Kicinski 	BPF_EXIT_INSN(),
86548729226SJakub Kicinski 	},
86648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
86748729226SJakub Kicinski 	.errstr = "invalid destination",
86848729226SJakub Kicinski 	.result = REJECT,
86948729226SJakub Kicinski },
87048729226SJakub Kicinski {
87148729226SJakub Kicinski 	"calls: jumping across function bodies. test1",
87248729226SJakub Kicinski 	.insns = {
87348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
87448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
87548729226SJakub Kicinski 	BPF_EXIT_INSN(),
87648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
87748729226SJakub Kicinski 	BPF_EXIT_INSN(),
87848729226SJakub Kicinski 	},
87948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
88048729226SJakub Kicinski 	.errstr = "jump out of range",
88148729226SJakub Kicinski 	.result = REJECT,
88248729226SJakub Kicinski },
88348729226SJakub Kicinski {
88448729226SJakub Kicinski 	"calls: jumping across function bodies. test2",
88548729226SJakub Kicinski 	.insns = {
88648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
88748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
88848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
88948729226SJakub Kicinski 	BPF_EXIT_INSN(),
89048729226SJakub Kicinski 	BPF_EXIT_INSN(),
89148729226SJakub Kicinski 	},
89248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
89348729226SJakub Kicinski 	.errstr = "jump out of range",
89448729226SJakub Kicinski 	.result = REJECT,
89548729226SJakub Kicinski },
89648729226SJakub Kicinski {
89748729226SJakub Kicinski 	"calls: call without exit",
89848729226SJakub Kicinski 	.insns = {
89948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
90048729226SJakub Kicinski 	BPF_EXIT_INSN(),
90148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
90248729226SJakub Kicinski 	BPF_EXIT_INSN(),
90348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
90448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
90548729226SJakub Kicinski 	},
90648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
90748729226SJakub Kicinski 	.errstr = "not an exit",
90848729226SJakub Kicinski 	.result = REJECT,
90948729226SJakub Kicinski },
91048729226SJakub Kicinski {
91148729226SJakub Kicinski 	"calls: call into middle of ld_imm64",
91248729226SJakub Kicinski 	.insns = {
91348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
91448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
91548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
91648729226SJakub Kicinski 	BPF_EXIT_INSN(),
91748729226SJakub Kicinski 	BPF_LD_IMM64(BPF_REG_0, 0),
91848729226SJakub Kicinski 	BPF_EXIT_INSN(),
91948729226SJakub Kicinski 	},
92048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
92148729226SJakub Kicinski 	.errstr = "last insn",
92248729226SJakub Kicinski 	.result = REJECT,
92348729226SJakub Kicinski },
92448729226SJakub Kicinski {
92548729226SJakub Kicinski 	"calls: call into middle of other call",
92648729226SJakub Kicinski 	.insns = {
92748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
92848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
92948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
93048729226SJakub Kicinski 	BPF_EXIT_INSN(),
93148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
93248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
93348729226SJakub Kicinski 	BPF_EXIT_INSN(),
93448729226SJakub Kicinski 	},
93548729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
93648729226SJakub Kicinski 	.errstr = "last insn",
93748729226SJakub Kicinski 	.result = REJECT,
93848729226SJakub Kicinski },
93948729226SJakub Kicinski {
94009b28d76SAlexei Starovoitov 	"calls: subprog call with ld_abs in main prog",
94148729226SJakub Kicinski 	.insns = {
94248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
94348729226SJakub Kicinski 	BPF_LD_ABS(BPF_B, 0),
94448729226SJakub Kicinski 	BPF_LD_ABS(BPF_H, 0),
94548729226SJakub Kicinski 	BPF_LD_ABS(BPF_W, 0),
94648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
94709b28d76SAlexei Starovoitov 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
94848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
94948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
95048729226SJakub Kicinski 	BPF_LD_ABS(BPF_B, 0),
95148729226SJakub Kicinski 	BPF_LD_ABS(BPF_H, 0),
95248729226SJakub Kicinski 	BPF_LD_ABS(BPF_W, 0),
95348729226SJakub Kicinski 	BPF_EXIT_INSN(),
95448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_2, 1),
95548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_3, 2),
95648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push),
95748729226SJakub Kicinski 	BPF_EXIT_INSN(),
95848729226SJakub Kicinski 	},
95948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
96009b28d76SAlexei Starovoitov 	.result = ACCEPT,
96148729226SJakub Kicinski },
96248729226SJakub Kicinski {
96348729226SJakub Kicinski 	"calls: two calls with bad fallthrough",
96448729226SJakub Kicinski 	.insns = {
96548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
96648729226SJakub Kicinski 	BPF_EXIT_INSN(),
96748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
96848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
96948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
97048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
97148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
97248729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
97348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
97448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
97548729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
97648729226SJakub Kicinski 		    offsetof(struct __sk_buff, len)),
97748729226SJakub Kicinski 	BPF_EXIT_INSN(),
97848729226SJakub Kicinski 	},
97948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
98048729226SJakub Kicinski 	.errstr = "not an exit",
98148729226SJakub Kicinski 	.result = REJECT,
98248729226SJakub Kicinski },
98348729226SJakub Kicinski {
98448729226SJakub Kicinski 	"calls: two calls with stack read",
98548729226SJakub Kicinski 	.insns = {
98648729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
98748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
98848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
98948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
99048729226SJakub Kicinski 	BPF_EXIT_INSN(),
99148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
99248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
99348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
99448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
99548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
99648729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
99748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
99848729226SJakub Kicinski 	BPF_EXIT_INSN(),
99948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
100048729226SJakub Kicinski 	BPF_EXIT_INSN(),
100148729226SJakub Kicinski 	},
100248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
100348729226SJakub Kicinski 	.result = ACCEPT,
100448729226SJakub Kicinski },
100548729226SJakub Kicinski {
100648729226SJakub Kicinski 	"calls: two calls with stack write",
100748729226SJakub Kicinski 	.insns = {
100848729226SJakub Kicinski 	/* main prog */
100948729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
101048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
101148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
101248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
101348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
101448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
101548729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
101648729226SJakub Kicinski 	BPF_EXIT_INSN(),
101748729226SJakub Kicinski 
101848729226SJakub Kicinski 	/* subprog 1 */
101948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
102048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
102148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
102248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
102348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
102448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
102548729226SJakub Kicinski 	BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
102648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
102748729226SJakub Kicinski 	/* write into stack frame of main prog */
102848729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
102948729226SJakub Kicinski 	BPF_EXIT_INSN(),
103048729226SJakub Kicinski 
103148729226SJakub Kicinski 	/* subprog 2 */
103248729226SJakub Kicinski 	/* read from stack frame of main prog */
103348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
103448729226SJakub Kicinski 	BPF_EXIT_INSN(),
103548729226SJakub Kicinski 	},
103648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
103748729226SJakub Kicinski 	.result = ACCEPT,
103848729226SJakub Kicinski },
103948729226SJakub Kicinski {
104048729226SJakub Kicinski 	"calls: stack overflow using two frames (pre-call access)",
104148729226SJakub Kicinski 	.insns = {
104248729226SJakub Kicinski 	/* prog 1 */
104348729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
104448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
104548729226SJakub Kicinski 	BPF_EXIT_INSN(),
104648729226SJakub Kicinski 
104748729226SJakub Kicinski 	/* prog 2 */
104848729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
104948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
105048729226SJakub Kicinski 	BPF_EXIT_INSN(),
105148729226SJakub Kicinski 	},
105248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
105348729226SJakub Kicinski 	.errstr = "combined stack size",
105448729226SJakub Kicinski 	.result = REJECT,
105548729226SJakub Kicinski },
105648729226SJakub Kicinski {
105748729226SJakub Kicinski 	"calls: stack overflow using two frames (post-call access)",
105848729226SJakub Kicinski 	.insns = {
105948729226SJakub Kicinski 	/* prog 1 */
106048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
106148729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
106248729226SJakub Kicinski 	BPF_EXIT_INSN(),
106348729226SJakub Kicinski 
106448729226SJakub Kicinski 	/* prog 2 */
106548729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
106648729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
106748729226SJakub Kicinski 	BPF_EXIT_INSN(),
106848729226SJakub Kicinski 	},
106948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
107048729226SJakub Kicinski 	.errstr = "combined stack size",
107148729226SJakub Kicinski 	.result = REJECT,
107248729226SJakub Kicinski },
107348729226SJakub Kicinski {
107448729226SJakub Kicinski 	"calls: stack depth check using three frames. test1",
107548729226SJakub Kicinski 	.insns = {
107648729226SJakub Kicinski 	/* main */
107748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
107848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
107948729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
108048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
108148729226SJakub Kicinski 	BPF_EXIT_INSN(),
108248729226SJakub Kicinski 	/* A */
108348729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
108448729226SJakub Kicinski 	BPF_EXIT_INSN(),
108548729226SJakub Kicinski 	/* B */
108648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
108748729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
108848729226SJakub Kicinski 	BPF_EXIT_INSN(),
108948729226SJakub Kicinski 	},
109048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
109148729226SJakub Kicinski 	/* stack_main=32, stack_A=256, stack_B=64
109248729226SJakub Kicinski 	 * and max(main+A, main+A+B) < 512
109348729226SJakub Kicinski 	 */
109448729226SJakub Kicinski 	.result = ACCEPT,
109548729226SJakub Kicinski },
109648729226SJakub Kicinski {
109748729226SJakub Kicinski 	"calls: stack depth check using three frames. test2",
109848729226SJakub Kicinski 	.insns = {
109948729226SJakub Kicinski 	/* main */
110048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
110148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
110248729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
110348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
110448729226SJakub Kicinski 	BPF_EXIT_INSN(),
110548729226SJakub Kicinski 	/* A */
110648729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
110748729226SJakub Kicinski 	BPF_EXIT_INSN(),
110848729226SJakub Kicinski 	/* B */
110948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
111048729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
111148729226SJakub Kicinski 	BPF_EXIT_INSN(),
111248729226SJakub Kicinski 	},
111348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
111448729226SJakub Kicinski 	/* stack_main=32, stack_A=64, stack_B=256
111548729226SJakub Kicinski 	 * and max(main+A, main+A+B) < 512
111648729226SJakub Kicinski 	 */
111748729226SJakub Kicinski 	.result = ACCEPT,
111848729226SJakub Kicinski },
111948729226SJakub Kicinski {
112048729226SJakub Kicinski 	"calls: stack depth check using three frames. test3",
112148729226SJakub Kicinski 	.insns = {
112248729226SJakub Kicinski 	/* main */
112348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
112448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
112548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
112648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
112748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
112848729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
112948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
113048729226SJakub Kicinski 	BPF_EXIT_INSN(),
113148729226SJakub Kicinski 	/* A */
113248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
113348729226SJakub Kicinski 	BPF_EXIT_INSN(),
113448729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
113548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
113648729226SJakub Kicinski 	/* B */
113748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
113848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
113948729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
114048729226SJakub Kicinski 	BPF_EXIT_INSN(),
114148729226SJakub Kicinski 	},
114248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
114348729226SJakub Kicinski 	/* stack_main=64, stack_A=224, stack_B=256
114448729226SJakub Kicinski 	 * and max(main+A, main+A+B) > 512
114548729226SJakub Kicinski 	 */
114648729226SJakub Kicinski 	.errstr = "combined stack",
114748729226SJakub Kicinski 	.result = REJECT,
114848729226SJakub Kicinski },
114948729226SJakub Kicinski {
115048729226SJakub Kicinski 	"calls: stack depth check using three frames. test4",
115148729226SJakub Kicinski 	/* void main(void) {
115248729226SJakub Kicinski 	 *   func1(0);
115348729226SJakub Kicinski 	 *   func1(1);
115448729226SJakub Kicinski 	 *   func2(1);
115548729226SJakub Kicinski 	 * }
115648729226SJakub Kicinski 	 * void func1(int alloc_or_recurse) {
115748729226SJakub Kicinski 	 *   if (alloc_or_recurse) {
115848729226SJakub Kicinski 	 *     frame_pointer[-300] = 1;
115948729226SJakub Kicinski 	 *   } else {
116048729226SJakub Kicinski 	 *     func2(alloc_or_recurse);
116148729226SJakub Kicinski 	 *   }
116248729226SJakub Kicinski 	 * }
116348729226SJakub Kicinski 	 * void func2(int alloc_or_recurse) {
116448729226SJakub Kicinski 	 *   if (alloc_or_recurse) {
116548729226SJakub Kicinski 	 *     frame_pointer[-300] = 1;
116648729226SJakub Kicinski 	 *   }
116748729226SJakub Kicinski 	 * }
116848729226SJakub Kicinski 	 */
116948729226SJakub Kicinski 	.insns = {
117048729226SJakub Kicinski 	/* main */
117148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_1, 0),
117248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
117348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_1, 1),
117448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
117548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_1, 1),
117648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
117748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
117848729226SJakub Kicinski 	BPF_EXIT_INSN(),
117948729226SJakub Kicinski 	/* A */
118048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
118148729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
118248729226SJakub Kicinski 	BPF_EXIT_INSN(),
118348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
118448729226SJakub Kicinski 	BPF_EXIT_INSN(),
118548729226SJakub Kicinski 	/* B */
118648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
118748729226SJakub Kicinski 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
118848729226SJakub Kicinski 	BPF_EXIT_INSN(),
118948729226SJakub Kicinski 	},
119048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
119148729226SJakub Kicinski 	.result = REJECT,
119248729226SJakub Kicinski 	.errstr = "combined stack",
119348729226SJakub Kicinski },
119448729226SJakub Kicinski {
119548729226SJakub Kicinski 	"calls: stack depth check using three frames. test5",
119648729226SJakub Kicinski 	.insns = {
119748729226SJakub Kicinski 	/* main */
119848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
119948729226SJakub Kicinski 	BPF_EXIT_INSN(),
120048729226SJakub Kicinski 	/* A */
120148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
120248729226SJakub Kicinski 	BPF_EXIT_INSN(),
120348729226SJakub Kicinski 	/* B */
120448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
120548729226SJakub Kicinski 	BPF_EXIT_INSN(),
120648729226SJakub Kicinski 	/* C */
120748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
120848729226SJakub Kicinski 	BPF_EXIT_INSN(),
120948729226SJakub Kicinski 	/* D */
121048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
121148729226SJakub Kicinski 	BPF_EXIT_INSN(),
121248729226SJakub Kicinski 	/* E */
121348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
121448729226SJakub Kicinski 	BPF_EXIT_INSN(),
121548729226SJakub Kicinski 	/* F */
121648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
121748729226SJakub Kicinski 	BPF_EXIT_INSN(),
121848729226SJakub Kicinski 	/* G */
121948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
122048729226SJakub Kicinski 	BPF_EXIT_INSN(),
122148729226SJakub Kicinski 	/* H */
122248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
122348729226SJakub Kicinski 	BPF_EXIT_INSN(),
122448729226SJakub Kicinski 	},
122548729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
122648729226SJakub Kicinski 	.errstr = "call stack",
122748729226SJakub Kicinski 	.result = REJECT,
122848729226SJakub Kicinski },
122948729226SJakub Kicinski {
1230cabacfbbSPaul Chaignon 	"calls: stack depth check in dead code",
1231cabacfbbSPaul Chaignon 	.insns = {
1232cabacfbbSPaul Chaignon 	/* main */
1233cabacfbbSPaul Chaignon 	BPF_MOV64_IMM(BPF_REG_1, 0),
1234cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
1235cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1236cabacfbbSPaul Chaignon 	/* A */
1237cabacfbbSPaul Chaignon 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1238cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */
1239cabacfbbSPaul Chaignon 	BPF_MOV64_IMM(BPF_REG_0, 0),
1240cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1241cabacfbbSPaul Chaignon 	/* B */
1242cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
1243cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1244cabacfbbSPaul Chaignon 	/* C */
1245cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
1246cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1247cabacfbbSPaul Chaignon 	/* D */
1248cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
1249cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1250cabacfbbSPaul Chaignon 	/* E */
1251cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
1252cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1253cabacfbbSPaul Chaignon 	/* F */
1254cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
1255cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1256cabacfbbSPaul Chaignon 	/* G */
1257cabacfbbSPaul Chaignon 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
1258cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1259cabacfbbSPaul Chaignon 	/* H */
1260cabacfbbSPaul Chaignon 	BPF_MOV64_IMM(BPF_REG_0, 0),
1261cabacfbbSPaul Chaignon 	BPF_EXIT_INSN(),
1262cabacfbbSPaul Chaignon 	},
1263cabacfbbSPaul Chaignon 	.prog_type = BPF_PROG_TYPE_XDP,
1264cabacfbbSPaul Chaignon 	.errstr = "call stack",
1265cabacfbbSPaul Chaignon 	.result = REJECT,
1266cabacfbbSPaul Chaignon },
1267cabacfbbSPaul Chaignon {
126848729226SJakub Kicinski 	"calls: spill into caller stack frame",
126948729226SJakub Kicinski 	.insns = {
127048729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
127148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
127248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
127348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
127448729226SJakub Kicinski 	BPF_EXIT_INSN(),
127548729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
127648729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
127748729226SJakub Kicinski 	BPF_EXIT_INSN(),
127848729226SJakub Kicinski 	},
127948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
128048729226SJakub Kicinski 	.errstr = "cannot spill",
128148729226SJakub Kicinski 	.result = REJECT,
128248729226SJakub Kicinski },
128348729226SJakub Kicinski {
128448729226SJakub Kicinski 	"calls: write into caller stack frame",
128548729226SJakub Kicinski 	.insns = {
128648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
128748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
128848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
128948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
129048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
129148729226SJakub Kicinski 	BPF_EXIT_INSN(),
129248729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
129348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
129448729226SJakub Kicinski 	BPF_EXIT_INSN(),
129548729226SJakub Kicinski 	},
129648729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
129748729226SJakub Kicinski 	.result = ACCEPT,
129848729226SJakub Kicinski 	.retval = 42,
129948729226SJakub Kicinski },
130048729226SJakub Kicinski {
130148729226SJakub Kicinski 	"calls: write into callee stack frame",
130248729226SJakub Kicinski 	.insns = {
130348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
130448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
130548729226SJakub Kicinski 	BPF_EXIT_INSN(),
130648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
130748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
130848729226SJakub Kicinski 	BPF_EXIT_INSN(),
130948729226SJakub Kicinski 	},
131048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
131148729226SJakub Kicinski 	.errstr = "cannot return stack pointer",
131248729226SJakub Kicinski 	.result = REJECT,
131348729226SJakub Kicinski },
131448729226SJakub Kicinski {
131548729226SJakub Kicinski 	"calls: two calls with stack write and void return",
131648729226SJakub Kicinski 	.insns = {
131748729226SJakub Kicinski 	/* main prog */
131848729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
131948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
132048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
132148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
132248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
132348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
132448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
132548729226SJakub Kicinski 	BPF_EXIT_INSN(),
132648729226SJakub Kicinski 
132748729226SJakub Kicinski 	/* subprog 1 */
132848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
132948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
133048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
133148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
133248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
133348729226SJakub Kicinski 	BPF_EXIT_INSN(),
133448729226SJakub Kicinski 
133548729226SJakub Kicinski 	/* subprog 2 */
133648729226SJakub Kicinski 	/* write into stack frame of main prog */
133748729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
133848729226SJakub Kicinski 	BPF_EXIT_INSN(), /* void return */
133948729226SJakub Kicinski 	},
134048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
134148729226SJakub Kicinski 	.result = ACCEPT,
134248729226SJakub Kicinski },
134348729226SJakub Kicinski {
134448729226SJakub Kicinski 	"calls: ambiguous return value",
134548729226SJakub Kicinski 	.insns = {
134648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
134748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
134848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
134948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
135048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
135148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
135248729226SJakub Kicinski 	BPF_EXIT_INSN(),
135348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
135448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
135548729226SJakub Kicinski 	BPF_EXIT_INSN(),
135648729226SJakub Kicinski 	},
135781626001SAlexei Starovoitov 	.errstr_unpriv = "allowed for",
135848729226SJakub Kicinski 	.result_unpriv = REJECT,
135948729226SJakub Kicinski 	.errstr = "R0 !read_ok",
136048729226SJakub Kicinski 	.result = REJECT,
136148729226SJakub Kicinski },
136248729226SJakub Kicinski {
136348729226SJakub Kicinski 	"calls: two calls that return map_value",
136448729226SJakub Kicinski 	.insns = {
136548729226SJakub Kicinski 	/* main prog */
136648729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
136748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
136848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
136948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
137048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
137148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
137248729226SJakub Kicinski 
137348729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
137448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
137548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
137648729226SJakub Kicinski 	/* write into map value */
137748729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
137848729226SJakub Kicinski 	/* fetch secound map_value_ptr from the stack */
137948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
138048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
138148729226SJakub Kicinski 	/* write into map value */
138248729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
138348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
138448729226SJakub Kicinski 	BPF_EXIT_INSN(),
138548729226SJakub Kicinski 
138648729226SJakub Kicinski 	/* subprog 1 */
138748729226SJakub Kicinski 	/* call 3rd function twice */
138848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
138948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
139048729226SJakub Kicinski 	/* first time with fp-8 */
139148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
139248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
139348729226SJakub Kicinski 	/* second time with fp-16 */
139448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
139548729226SJakub Kicinski 	BPF_EXIT_INSN(),
139648729226SJakub Kicinski 
139748729226SJakub Kicinski 	/* subprog 2 */
139848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
139948729226SJakub Kicinski 	/* lookup from map */
140048729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
140148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
140248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
140348729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
140448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
140548729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog */
140648729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
140748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
140848729226SJakub Kicinski 	BPF_EXIT_INSN(), /* return 0 */
140948729226SJakub Kicinski 	},
141048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
141148729226SJakub Kicinski 	.fixup_map_hash_8b = { 23 },
141248729226SJakub Kicinski 	.result = ACCEPT,
141348729226SJakub Kicinski },
141448729226SJakub Kicinski {
141548729226SJakub Kicinski 	"calls: two calls that return map_value with bool condition",
141648729226SJakub Kicinski 	.insns = {
141748729226SJakub Kicinski 	/* main prog */
141848729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
141948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
142048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
142148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
142248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
142348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
142448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
142548729226SJakub Kicinski 	BPF_EXIT_INSN(),
142648729226SJakub Kicinski 
142748729226SJakub Kicinski 	/* subprog 1 */
142848729226SJakub Kicinski 	/* call 3rd function twice */
142948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
143048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
143148729226SJakub Kicinski 	/* first time with fp-8 */
143248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
143348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
143448729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
143548729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
143648729226SJakub Kicinski 	/* write into map value */
143748729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
143848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
143948729226SJakub Kicinski 	/* second time with fp-16 */
144048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
144148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
144248729226SJakub Kicinski 	/* fetch secound map_value_ptr from the stack */
144348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
144448729226SJakub Kicinski 	/* write into map value */
144548729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
144648729226SJakub Kicinski 	BPF_EXIT_INSN(),
144748729226SJakub Kicinski 
144848729226SJakub Kicinski 	/* subprog 2 */
144948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
145048729226SJakub Kicinski 	/* lookup from map */
145148729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
145248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
145348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
145448729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
145548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
145648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
145748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
145848729226SJakub Kicinski 	BPF_EXIT_INSN(), /* return 0 */
145948729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog */
146048729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
146148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
146248729226SJakub Kicinski 	BPF_EXIT_INSN(), /* return 1 */
146348729226SJakub Kicinski 	},
146448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
146548729226SJakub Kicinski 	.fixup_map_hash_8b = { 23 },
146648729226SJakub Kicinski 	.result = ACCEPT,
146748729226SJakub Kicinski },
146848729226SJakub Kicinski {
146948729226SJakub Kicinski 	"calls: two calls that return map_value with incorrect bool check",
147048729226SJakub Kicinski 	.insns = {
147148729226SJakub Kicinski 	/* main prog */
147248729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
147348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
147448729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
147548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
147648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
147748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
147848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
147948729226SJakub Kicinski 	BPF_EXIT_INSN(),
148048729226SJakub Kicinski 
148148729226SJakub Kicinski 	/* subprog 1 */
148248729226SJakub Kicinski 	/* call 3rd function twice */
148348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
148448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
148548729226SJakub Kicinski 	/* first time with fp-8 */
148648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
148748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
148848729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
148948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
149048729226SJakub Kicinski 	/* write into map value */
149148729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
149248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
149348729226SJakub Kicinski 	/* second time with fp-16 */
149448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
149548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
149648729226SJakub Kicinski 	/* fetch secound map_value_ptr from the stack */
149748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
149848729226SJakub Kicinski 	/* write into map value */
149948729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
150048729226SJakub Kicinski 	BPF_EXIT_INSN(),
150148729226SJakub Kicinski 
150248729226SJakub Kicinski 	/* subprog 2 */
150348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
150448729226SJakub Kicinski 	/* lookup from map */
150548729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
150648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
150748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
150848729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
150948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
151048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
151148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
151248729226SJakub Kicinski 	BPF_EXIT_INSN(), /* return 0 */
151348729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog */
151448729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
151548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 1),
151648729226SJakub Kicinski 	BPF_EXIT_INSN(), /* return 1 */
151748729226SJakub Kicinski 	},
151848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
151948729226SJakub Kicinski 	.fixup_map_hash_8b = { 23 },
152048729226SJakub Kicinski 	.result = REJECT,
15216b4a64baSAndrei Matei 	.errstr = "R0 invalid mem access 'scalar'",
15226b4a64baSAndrei Matei 	.result_unpriv = REJECT,
15236b4a64baSAndrei Matei 	.errstr_unpriv = "invalid read from stack R7 off=-16 size=8",
152448729226SJakub Kicinski },
152548729226SJakub Kicinski {
152648729226SJakub Kicinski 	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
152748729226SJakub Kicinski 	.insns = {
152848729226SJakub Kicinski 	/* main prog */
152948729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
153048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
153148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
153248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
153348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
153448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
153548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
153648729226SJakub Kicinski 	BPF_EXIT_INSN(),
153748729226SJakub Kicinski 
153848729226SJakub Kicinski 	/* subprog 1 */
153948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
154048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
154148729226SJakub Kicinski 	/* 1st lookup from map */
154248729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
154348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
154448729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
154548729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
154648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
154748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
154848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
154948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
155048729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-8 */
155148729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
155248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
155348729226SJakub Kicinski 
155448729226SJakub Kicinski 	/* 2nd lookup from map */
155548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
155648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
155748729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
155848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
155948729226SJakub Kicinski 		     BPF_FUNC_map_lookup_elem),
156048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
156148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),
156248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
156348729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-16 */
156448729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
156548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
156648729226SJakub Kicinski 
156748729226SJakub Kicinski 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
156848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
156948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
157048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
157148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
157248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
157348729226SJakub Kicinski 	BPF_EXIT_INSN(),
157448729226SJakub Kicinski 
157548729226SJakub Kicinski 	/* subprog 2 */
157648729226SJakub Kicinski 	/* if arg2 == 1 do *arg1 = 0 */
157748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
157848729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
157948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
158048729226SJakub Kicinski 	/* write into map value */
158148729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
158248729226SJakub Kicinski 
158348729226SJakub Kicinski 	/* if arg4 == 1 do *arg3 = 0 */
158448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
158548729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
158648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
158748729226SJakub Kicinski 	/* write into map value */
158848729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
158948729226SJakub Kicinski 	BPF_EXIT_INSN(),
159048729226SJakub Kicinski 	},
159148729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
159248729226SJakub Kicinski 	.fixup_map_hash_8b = { 12, 22 },
159348729226SJakub Kicinski 	.result = REJECT,
159448729226SJakub Kicinski 	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
159548729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
159648729226SJakub Kicinski },
159748729226SJakub Kicinski {
159848729226SJakub Kicinski 	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
159948729226SJakub Kicinski 	.insns = {
160048729226SJakub Kicinski 	/* main prog */
160148729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
160248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
160348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
160448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
160548729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
160648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
160748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
160848729226SJakub Kicinski 	BPF_EXIT_INSN(),
160948729226SJakub Kicinski 
161048729226SJakub Kicinski 	/* subprog 1 */
161148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
161248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
161348729226SJakub Kicinski 	/* 1st lookup from map */
161448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
161548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
161648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
161748729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
161848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
161948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
162048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
162148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
162248729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-8 */
162348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
162448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
162548729226SJakub Kicinski 
162648729226SJakub Kicinski 	/* 2nd lookup from map */
162748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
162848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
162948729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
163048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
163148729226SJakub Kicinski 		     BPF_FUNC_map_lookup_elem),
163248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
163348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),
163448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
163548729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-16 */
163648729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
163748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
163848729226SJakub Kicinski 
163948729226SJakub Kicinski 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
164048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
164148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
164248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
164348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
164448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
164548729226SJakub Kicinski 	BPF_EXIT_INSN(),
164648729226SJakub Kicinski 
164748729226SJakub Kicinski 	/* subprog 2 */
164848729226SJakub Kicinski 	/* if arg2 == 1 do *arg1 = 0 */
164948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
165048729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
165148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
165248729226SJakub Kicinski 	/* write into map value */
165348729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
165448729226SJakub Kicinski 
165548729226SJakub Kicinski 	/* if arg4 == 1 do *arg3 = 0 */
165648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
165748729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
165848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
165948729226SJakub Kicinski 	/* write into map value */
166048729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
166148729226SJakub Kicinski 	BPF_EXIT_INSN(),
166248729226SJakub Kicinski 	},
166348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
166448729226SJakub Kicinski 	.fixup_map_hash_8b = { 12, 22 },
166548729226SJakub Kicinski 	.result = ACCEPT,
166648729226SJakub Kicinski },
166748729226SJakub Kicinski {
166848729226SJakub Kicinski 	"calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
166948729226SJakub Kicinski 	.insns = {
167048729226SJakub Kicinski 	/* main prog */
167148729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
167248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
167348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
167448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
167548729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
167648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
167748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
167848729226SJakub Kicinski 	BPF_EXIT_INSN(),
167948729226SJakub Kicinski 
168048729226SJakub Kicinski 	/* subprog 1 */
168148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
168248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
168348729226SJakub Kicinski 	/* 1st lookup from map */
168448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
168548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
168648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
168748729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
168848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
168948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
169048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
169148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
169248729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-8 */
169348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
169448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
169548729226SJakub Kicinski 
169648729226SJakub Kicinski 	/* 2nd lookup from map */
169748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
169848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
169948729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
170048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
170148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
170248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),  // 26
170348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
170448729226SJakub Kicinski 	/* write map_value_ptr into stack frame of main prog at fp-16 */
170548729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
170648729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
170748729226SJakub Kicinski 
170848729226SJakub Kicinski 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
170948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
171048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
171148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
171248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
171348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
171448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -30),
171548729226SJakub Kicinski 
171648729226SJakub Kicinski 	/* subprog 2 */
171748729226SJakub Kicinski 	/* if arg2 == 1 do *arg1 = 0 */
171848729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
171948729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
172048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
172148729226SJakub Kicinski 	/* write into map value */
172248729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
172348729226SJakub Kicinski 
172448729226SJakub Kicinski 	/* if arg4 == 1 do *arg3 = 0 */
172548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
172648729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
172748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
172848729226SJakub Kicinski 	/* write into map value */
172948729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
173048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, -8),
173148729226SJakub Kicinski 	},
173248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
173348729226SJakub Kicinski 	.fixup_map_hash_8b = { 12, 22 },
173448729226SJakub Kicinski 	.result = REJECT,
173548729226SJakub Kicinski 	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
173648729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
173748729226SJakub Kicinski },
173848729226SJakub Kicinski {
173948729226SJakub Kicinski 	"calls: two calls that receive map_value_ptr_or_null via arg. test1",
174048729226SJakub Kicinski 	.insns = {
174148729226SJakub Kicinski 	/* main prog */
174248729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
174348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
174448729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
174548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
174648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
174748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
174848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
174948729226SJakub Kicinski 	BPF_EXIT_INSN(),
175048729226SJakub Kicinski 
175148729226SJakub Kicinski 	/* subprog 1 */
175248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
175348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
175448729226SJakub Kicinski 	/* 1st lookup from map */
175548729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
175648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
175748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
175848729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
175948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
176048729226SJakub Kicinski 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
176148729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
176248729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
176348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
176448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
176548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
176648729226SJakub Kicinski 
176748729226SJakub Kicinski 	/* 2nd lookup from map */
176848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
176948729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
177048729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
177148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
177248729226SJakub Kicinski 	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
177348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
177448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
177548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),
177648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
177748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
177848729226SJakub Kicinski 
177948729226SJakub Kicinski 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
178048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
178148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
178248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
178348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
178448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
178548729226SJakub Kicinski 	BPF_EXIT_INSN(),
178648729226SJakub Kicinski 
178748729226SJakub Kicinski 	/* subprog 2 */
178848729226SJakub Kicinski 	/* if arg2 == 1 do *arg1 = 0 */
178948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
179048729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
179148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
179248729226SJakub Kicinski 	/* write into map value */
179348729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
179448729226SJakub Kicinski 
179548729226SJakub Kicinski 	/* if arg4 == 1 do *arg3 = 0 */
179648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
179748729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
179848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
179948729226SJakub Kicinski 	/* write into map value */
180048729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
180148729226SJakub Kicinski 	BPF_EXIT_INSN(),
180248729226SJakub Kicinski 	},
180348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
180448729226SJakub Kicinski 	.fixup_map_hash_8b = { 12, 22 },
180548729226SJakub Kicinski 	.result = ACCEPT,
180648729226SJakub Kicinski },
180748729226SJakub Kicinski {
180848729226SJakub Kicinski 	"calls: two calls that receive map_value_ptr_or_null via arg. test2",
180948729226SJakub Kicinski 	.insns = {
181048729226SJakub Kicinski 	/* main prog */
181148729226SJakub Kicinski 	/* pass fp-16, fp-8 into a function */
181248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
181348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
181448729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
181548729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
181648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
181748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
181848729226SJakub Kicinski 	BPF_EXIT_INSN(),
181948729226SJakub Kicinski 
182048729226SJakub Kicinski 	/* subprog 1 */
182148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
182248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
182348729226SJakub Kicinski 	/* 1st lookup from map */
182448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
182548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
182648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
182748729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
182848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
182948729226SJakub Kicinski 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
183048729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
183148729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
183248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
183348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
183448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
183548729226SJakub Kicinski 
183648729226SJakub Kicinski 	/* 2nd lookup from map */
183748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
183848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
183948729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
184048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
184148729226SJakub Kicinski 	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
184248729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
184348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
184448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),
184548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
184648729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
184748729226SJakub Kicinski 
184848729226SJakub Kicinski 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
184948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
185048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
185148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
185248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
185348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
185448729226SJakub Kicinski 	BPF_EXIT_INSN(),
185548729226SJakub Kicinski 
185648729226SJakub Kicinski 	/* subprog 2 */
185748729226SJakub Kicinski 	/* if arg2 == 1 do *arg1 = 0 */
185848729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
185948729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
186048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
186148729226SJakub Kicinski 	/* write into map value */
186248729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
186348729226SJakub Kicinski 
186448729226SJakub Kicinski 	/* if arg4 == 0 do *arg3 = 0 */
186548729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
186648729226SJakub Kicinski 	/* fetch map_value_ptr from the stack of this function */
186748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
186848729226SJakub Kicinski 	/* write into map value */
186948729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
187048729226SJakub Kicinski 	BPF_EXIT_INSN(),
187148729226SJakub Kicinski 	},
187248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
187348729226SJakub Kicinski 	.fixup_map_hash_8b = { 12, 22 },
187448729226SJakub Kicinski 	.result = REJECT,
18757df5072cSMykola Lysenko 	.errstr = "R0 invalid mem access 'scalar'",
187648729226SJakub Kicinski },
187748729226SJakub Kicinski {
187848729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack",
187948729226SJakub Kicinski 	.insns = {
188048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
188148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
188248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
188348729226SJakub Kicinski 	BPF_EXIT_INSN(),
188448729226SJakub Kicinski 
188548729226SJakub Kicinski 	/* subprog 1 */
188648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
188748729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
188848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
188948729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
189048729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
189148729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
189248729226SJakub Kicinski 	/* spill unchecked pkt_ptr into stack of caller */
189348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
189448729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
189548729226SJakub Kicinski 	/* now the pkt range is verified, read pkt_ptr from stack */
189648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
189748729226SJakub Kicinski 	/* write 4 bytes into packet */
189848729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
189948729226SJakub Kicinski 	BPF_EXIT_INSN(),
190048729226SJakub Kicinski 	},
190148729226SJakub Kicinski 	.result = ACCEPT,
190248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
190348729226SJakub Kicinski 	.retval = POINTER_VALUE,
190448729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
190548729226SJakub Kicinski },
190648729226SJakub Kicinski {
190748729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 2",
190848729226SJakub Kicinski 	.insns = {
190948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
191048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
191148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
191248729226SJakub Kicinski 	/* Marking is still kept, but not in all cases safe. */
191348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
191448729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
191548729226SJakub Kicinski 	BPF_EXIT_INSN(),
191648729226SJakub Kicinski 
191748729226SJakub Kicinski 	/* subprog 1 */
191848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
191948729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
192048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
192148729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
192248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
192348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
192448729226SJakub Kicinski 	/* spill unchecked pkt_ptr into stack of caller */
192548729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
192648729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
192748729226SJakub Kicinski 	/* now the pkt range is verified, read pkt_ptr from stack */
192848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
192948729226SJakub Kicinski 	/* write 4 bytes into packet */
193048729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
193148729226SJakub Kicinski 	BPF_EXIT_INSN(),
193248729226SJakub Kicinski 	},
193348729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
193448729226SJakub Kicinski 	.errstr = "invalid access to packet",
193548729226SJakub Kicinski 	.result = REJECT,
193648729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
193748729226SJakub Kicinski },
193848729226SJakub Kicinski {
193948729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 3",
194048729226SJakub Kicinski 	.insns = {
194148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
194248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
194348729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
194448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
194548729226SJakub Kicinski 	/* Marking is still kept and safe here. */
194648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
194748729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
194848729226SJakub Kicinski 	BPF_EXIT_INSN(),
194948729226SJakub Kicinski 
195048729226SJakub Kicinski 	/* subprog 1 */
195148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
195248729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
195348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
195448729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
195548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
195648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
195748729226SJakub Kicinski 	/* spill unchecked pkt_ptr into stack of caller */
195848729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
195948729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
196048729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
196148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
196248729226SJakub Kicinski 	/* now the pkt range is verified, read pkt_ptr from stack */
196348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
196448729226SJakub Kicinski 	/* write 4 bytes into packet */
196548729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
196648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
196748729226SJakub Kicinski 	BPF_EXIT_INSN(),
196848729226SJakub Kicinski 	},
196948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
197048729226SJakub Kicinski 	.result = ACCEPT,
197148729226SJakub Kicinski 	.retval = 1,
197248729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
197348729226SJakub Kicinski },
197448729226SJakub Kicinski {
197548729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 4",
197648729226SJakub Kicinski 	.insns = {
197748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
197848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
197948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
198048729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
198148729226SJakub Kicinski 	/* Check marking propagated. */
198248729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
198348729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
198448729226SJakub Kicinski 	BPF_EXIT_INSN(),
198548729226SJakub Kicinski 
198648729226SJakub Kicinski 	/* subprog 1 */
198748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
198848729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
198948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
199048729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
199148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
199248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
199348729226SJakub Kicinski 	/* spill unchecked pkt_ptr into stack of caller */
199448729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
199548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
199648729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
199748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
199848729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
199948729226SJakub Kicinski 	/* write 4 bytes into packet */
200048729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
200148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
200248729226SJakub Kicinski 	BPF_EXIT_INSN(),
200348729226SJakub Kicinski 	},
200448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
200548729226SJakub Kicinski 	.result = ACCEPT,
200648729226SJakub Kicinski 	.retval = 1,
200748729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
200848729226SJakub Kicinski },
200948729226SJakub Kicinski {
201048729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 5",
201148729226SJakub Kicinski 	.insns = {
201248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
201348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
201448729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
201548729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
201648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
201748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
201848729226SJakub Kicinski 	BPF_EXIT_INSN(),
201948729226SJakub Kicinski 
202048729226SJakub Kicinski 	/* subprog 1 */
202148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
202248729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
202348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
202448729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
202548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
202648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
202748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
202848729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
202948729226SJakub Kicinski 	/* spill checked pkt_ptr into stack of caller */
203048729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
203148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
203248729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
203348729226SJakub Kicinski 	/* write 4 bytes into packet */
203448729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
203548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
203648729226SJakub Kicinski 	BPF_EXIT_INSN(),
203748729226SJakub Kicinski 	},
203848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
203948729226SJakub Kicinski 	.errstr = "same insn cannot be used with different",
204048729226SJakub Kicinski 	.result = REJECT,
204148729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
204248729226SJakub Kicinski },
204348729226SJakub Kicinski {
204448729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 6",
204548729226SJakub Kicinski 	.insns = {
204648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
204748729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
204848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
204948729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
205048729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
205148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
205248729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
205348729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
205448729226SJakub Kicinski 	BPF_EXIT_INSN(),
205548729226SJakub Kicinski 
205648729226SJakub Kicinski 	/* subprog 1 */
205748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
205848729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
205948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
206048729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
206148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
206248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
206348729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
206448729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
206548729226SJakub Kicinski 	/* spill checked pkt_ptr into stack of caller */
206648729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
206748729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
206848729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
206948729226SJakub Kicinski 	/* write 4 bytes into packet */
207048729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
207148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
207248729226SJakub Kicinski 	BPF_EXIT_INSN(),
207348729226SJakub Kicinski 	},
207448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
207548729226SJakub Kicinski 	.errstr = "R4 invalid mem access",
207648729226SJakub Kicinski 	.result = REJECT,
207748729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
207848729226SJakub Kicinski },
207948729226SJakub Kicinski {
208048729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 7",
208148729226SJakub Kicinski 	.insns = {
208248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_2, 0),
208348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
208448729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
208548729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
208648729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
208748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
208848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
208948729226SJakub Kicinski 	BPF_EXIT_INSN(),
209048729226SJakub Kicinski 
209148729226SJakub Kicinski 	/* subprog 1 */
209248729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
209348729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
209448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
209548729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
209648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
209748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
209848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
209948729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
210048729226SJakub Kicinski 	/* spill checked pkt_ptr into stack of caller */
210148729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
210248729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
210348729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
210448729226SJakub Kicinski 	/* write 4 bytes into packet */
210548729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
210648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
210748729226SJakub Kicinski 	BPF_EXIT_INSN(),
210848729226SJakub Kicinski 	},
210948729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
211048729226SJakub Kicinski 	.errstr = "R4 invalid mem access",
211148729226SJakub Kicinski 	.result = REJECT,
211248729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
211348729226SJakub Kicinski },
211448729226SJakub Kicinski {
211548729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 8",
211648729226SJakub Kicinski 	.insns = {
211748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
211848729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
211948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
212048729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
212148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
212248729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
212348729226SJakub Kicinski 	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
212448729226SJakub Kicinski 	BPF_EXIT_INSN(),
212548729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
212648729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
212748729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
212848729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
212948729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
213048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
213148729226SJakub Kicinski 	BPF_EXIT_INSN(),
213248729226SJakub Kicinski 
213348729226SJakub Kicinski 	/* subprog 1 */
213448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
213548729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
213648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
213748729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
213848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
213948729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
214048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
214148729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
214248729226SJakub Kicinski 	/* spill checked pkt_ptr into stack of caller */
214348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
214448729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
214548729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
214648729226SJakub Kicinski 	/* write 4 bytes into packet */
214748729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
214848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
214948729226SJakub Kicinski 	BPF_EXIT_INSN(),
215048729226SJakub Kicinski 	},
215148729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
215248729226SJakub Kicinski 	.result = ACCEPT,
215348729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
215448729226SJakub Kicinski },
215548729226SJakub Kicinski {
215648729226SJakub Kicinski 	"calls: pkt_ptr spill into caller stack 9",
215748729226SJakub Kicinski 	.insns = {
215848729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
215948729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
216048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
216148729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
216248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
216348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
216448729226SJakub Kicinski 	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
216548729226SJakub Kicinski 	BPF_EXIT_INSN(),
216648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
216748729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
216848729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
216948729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
217048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
217148729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
217248729226SJakub Kicinski 	BPF_EXIT_INSN(),
217348729226SJakub Kicinski 
217448729226SJakub Kicinski 	/* subprog 1 */
217548729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
217648729226SJakub Kicinski 		    offsetof(struct __sk_buff, data)),
217748729226SJakub Kicinski 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
217848729226SJakub Kicinski 		    offsetof(struct __sk_buff, data_end)),
217948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
218048729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
218148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 0),
218248729226SJakub Kicinski 	/* spill unchecked pkt_ptr into stack of caller */
218348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
218448729226SJakub Kicinski 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
218548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_5, 1),
218648729226SJakub Kicinski 	/* don't read back pkt_ptr from stack here */
218748729226SJakub Kicinski 	/* write 4 bytes into packet */
218848729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
218948729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
219048729226SJakub Kicinski 	BPF_EXIT_INSN(),
219148729226SJakub Kicinski 	},
219248729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
219348729226SJakub Kicinski 	.errstr = "invalid access to packet",
219448729226SJakub Kicinski 	.result = REJECT,
219548729226SJakub Kicinski 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
219648729226SJakub Kicinski },
219748729226SJakub Kicinski {
219848729226SJakub Kicinski 	"calls: caller stack init to zero or map_value_or_null",
219948729226SJakub Kicinski 	.insns = {
220048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
220148729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
220248729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
220348729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
220448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
220548729226SJakub Kicinski 	/* fetch map_value_or_null or const_zero from stack */
220648729226SJakub Kicinski 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
220748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
220848729226SJakub Kicinski 	/* store into map_value */
220948729226SJakub Kicinski 	BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
221048729226SJakub Kicinski 	BPF_EXIT_INSN(),
221148729226SJakub Kicinski 
221248729226SJakub Kicinski 	/* subprog 1 */
221348729226SJakub Kicinski 	/* if (ctx == 0) return; */
221448729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
221548729226SJakub Kicinski 	/* else bpf_map_lookup() and *(fp - 8) = r0 */
221648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
221748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
221848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
221948729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
222048729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
222148729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
222248729226SJakub Kicinski 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
222348729226SJakub Kicinski 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
222448729226SJakub Kicinski 	BPF_EXIT_INSN(),
222548729226SJakub Kicinski 	},
222648729226SJakub Kicinski 	.fixup_map_hash_8b = { 13 },
222748729226SJakub Kicinski 	.result = ACCEPT,
222848729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_XDP,
222948729226SJakub Kicinski },
223048729226SJakub Kicinski {
223148729226SJakub Kicinski 	"calls: stack init to zero and pruning",
223248729226SJakub Kicinski 	.insns = {
223348729226SJakub Kicinski 	/* first make allocated_stack 16 byte */
223448729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
223548729226SJakub Kicinski 	/* now fork the execution such that the false branch
223648729226SJakub Kicinski 	 * of JGT insn will be verified second and it skisp zero
223748729226SJakub Kicinski 	 * init of fp-8 stack slot. If stack liveness marking
223848729226SJakub Kicinski 	 * is missing live_read marks from call map_lookup
223948729226SJakub Kicinski 	 * processing then pruning will incorrectly assume
224048729226SJakub Kicinski 	 * that fp-8 stack slot was unused in the fall-through
224148729226SJakub Kicinski 	 * branch and will accept the program incorrectly
224248729226SJakub Kicinski 	 */
22436715df8dSEduard Zingerman 	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
22446715df8dSEduard Zingerman 	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2),
224548729226SJakub Kicinski 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
224648729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JA, 0, 0, 0),
224748729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
224848729226SJakub Kicinski 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
224948729226SJakub Kicinski 	BPF_LD_MAP_FD(BPF_REG_1, 0),
225048729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
22516715df8dSEduard Zingerman 	BPF_MOV64_IMM(BPF_REG_0, 0),
225248729226SJakub Kicinski 	BPF_EXIT_INSN(),
225348729226SJakub Kicinski 	},
22546715df8dSEduard Zingerman 	.fixup_map_hash_48b = { 7 },
22556715df8dSEduard Zingerman 	.errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8",
22566715df8dSEduard Zingerman 	.result_unpriv = REJECT,
22576715df8dSEduard Zingerman 	/* in privileged mode reads from uninitialized stack locations are permitted */
22586715df8dSEduard Zingerman 	.result = ACCEPT,
225948729226SJakub Kicinski },
226048729226SJakub Kicinski {
226148729226SJakub Kicinski 	"calls: ctx read at start of subprog",
226248729226SJakub Kicinski 	.insns = {
226348729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
226448729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
226548729226SJakub Kicinski 	BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
226648729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
226748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
226848729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
226948729226SJakub Kicinski 	BPF_EXIT_INSN(),
227048729226SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
227148729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
227248729226SJakub Kicinski 	BPF_EXIT_INSN(),
227348729226SJakub Kicinski 	},
227448729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2275e6ac2450SMartin KaFai Lau 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
227648729226SJakub Kicinski 	.result_unpriv = REJECT,
227748729226SJakub Kicinski 	.result = ACCEPT,
227848729226SJakub Kicinski },
227948729226SJakub Kicinski {
228048729226SJakub Kicinski 	"calls: cross frame pruning",
228148729226SJakub Kicinski 	.insns = {
228248729226SJakub Kicinski 	/* r8 = !!random();
228348729226SJakub Kicinski 	 * call pruner()
228448729226SJakub Kicinski 	 * if (r8)
228548729226SJakub Kicinski 	 *     do something bad;
228648729226SJakub Kicinski 	 */
228748729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
228848729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
228948729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
229048729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
229148729226SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
229248729226SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
229348729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
229448729226SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
229548729226SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
229648729226SJakub Kicinski 	BPF_EXIT_INSN(),
229748729226SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
229848729226SJakub Kicinski 	BPF_EXIT_INSN(),
229948729226SJakub Kicinski 	},
230048729226SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2301e6ac2450SMartin KaFai Lau 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
230248729226SJakub Kicinski 	.errstr = "!read_ok",
230348729226SJakub Kicinski 	.result = REJECT,
230448729226SJakub Kicinski },
230583d16312SJakub Kicinski {
230683d16312SJakub Kicinski 	"calls: cross frame pruning - liveness propagation",
230783d16312SJakub Kicinski 	.insns = {
230883d16312SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
230983d16312SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 0),
231083d16312SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
231183d16312SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_8, 1),
231283d16312SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
231383d16312SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 0),
231483d16312SJakub Kicinski 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
231583d16312SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_9, 1),
231683d16312SJakub Kicinski 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
231783d16312SJakub Kicinski 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
231883d16312SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
231983d16312SJakub Kicinski 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
232083d16312SJakub Kicinski 	BPF_MOV64_IMM(BPF_REG_0, 0),
232183d16312SJakub Kicinski 	BPF_EXIT_INSN(),
232283d16312SJakub Kicinski 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
232383d16312SJakub Kicinski 	BPF_EXIT_INSN(),
232483d16312SJakub Kicinski 	},
232583d16312SJakub Kicinski 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2326e6ac2450SMartin KaFai Lau 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
232783d16312SJakub Kicinski 	.errstr = "!read_ok",
232883d16312SJakub Kicinski 	.result = REJECT,
232983d16312SJakub Kicinski },
23307d057943SEduard Zingerman /* Make sure that verifier.c:states_equal() considers IDs from all
23317d057943SEduard Zingerman  * frames when building 'idmap' for check_ids().
23327d057943SEduard Zingerman  */
23337d057943SEduard Zingerman {
23347d057943SEduard Zingerman 	"calls: check_ids() across call boundary",
23357d057943SEduard Zingerman 	.insns = {
23367d057943SEduard Zingerman 	/* Function main() */
23377d057943SEduard Zingerman 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
23387d057943SEduard Zingerman 	/* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
23397d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
23407d057943SEduard Zingerman 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
23417d057943SEduard Zingerman 	BPF_LD_MAP_FD(BPF_REG_1,
23427d057943SEduard Zingerman 		      0),
23437d057943SEduard Zingerman 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
23447d057943SEduard Zingerman 	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24),
23457d057943SEduard Zingerman 	/* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
23467d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
23477d057943SEduard Zingerman 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
23487d057943SEduard Zingerman 	BPF_LD_MAP_FD(BPF_REG_1,
23497d057943SEduard Zingerman 		      0),
23507d057943SEduard Zingerman 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
23517d057943SEduard Zingerman 	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32),
23527d057943SEduard Zingerman 	/* call foo(&fp[-24], &fp[-32])   ; both arguments have IDs in the current
23537d057943SEduard Zingerman 	 *                                ; stack frame
23547d057943SEduard Zingerman 	 */
23557d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP),
23567d057943SEduard Zingerman 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24),
23577d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
23587d057943SEduard Zingerman 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
23597d057943SEduard Zingerman 	BPF_CALL_REL(2),
23607d057943SEduard Zingerman 	/* exit 0 */
23617d057943SEduard Zingerman 	BPF_MOV64_IMM(BPF_REG_0, 0),
23627d057943SEduard Zingerman 	BPF_EXIT_INSN(),
23637d057943SEduard Zingerman 	/* Function foo()
23647d057943SEduard Zingerman 	 *
23657d057943SEduard Zingerman 	 * r9 = &frame[0].fp[-24]  ; save arguments in the callee saved registers,
23667d057943SEduard Zingerman 	 * r8 = &frame[0].fp[-32]  ; arguments are pointers to pointers to map value
23677d057943SEduard Zingerman 	 */
23687d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
23697d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_2),
23707d057943SEduard Zingerman 	/* r7 = ktime_get_ns() */
23717d057943SEduard Zingerman 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
23727d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
23737d057943SEduard Zingerman 	/* r6 = ktime_get_ns() */
23747d057943SEduard Zingerman 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
23757d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
23767d057943SEduard Zingerman 	/* if r6 > r7 goto +1      ; no new information about the state is derived from
23777d057943SEduard Zingerman 	 *                         ; this check, thus produced verifier states differ
23787d057943SEduard Zingerman 	 *                         ; only in 'insn_idx'
23797d057943SEduard Zingerman 	 * r9 = r8
23807d057943SEduard Zingerman 	 */
23817d057943SEduard Zingerman 	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1),
23827d057943SEduard Zingerman 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_8),
23837d057943SEduard Zingerman 	/* r9 = *r9                ; verifier get's to this point via two paths:
23847d057943SEduard Zingerman 	 *                         ; (I) one including r9 = r8, verified first;
23857d057943SEduard Zingerman 	 *                         ; (II) one excluding r9 = r8, verified next.
23867d057943SEduard Zingerman 	 *                         ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id.
23877d057943SEduard Zingerman 	 *                         ; Suppose that checkpoint is created here via path (I).
23887d057943SEduard Zingerman 	 *                         ; When verifying via (II) the r9.id must be compared against
23897d057943SEduard Zingerman 	 *                         ; frame[0].fp[-24].id, otherwise (I) and (II) would be
23907d057943SEduard Zingerman 	 *                         ; incorrectly deemed equivalent.
23917d057943SEduard Zingerman 	 * if r9 == 0 goto <exit>
23927d057943SEduard Zingerman 	 */
23937d057943SEduard Zingerman 	BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0),
23947d057943SEduard Zingerman 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1),
23957d057943SEduard Zingerman 	/* r8 = *r8                ; read map value via r8, this is not safe
23967d057943SEduard Zingerman 	 * r0 = *r8                ; because r8 might be not equal to r9.
23977d057943SEduard Zingerman 	 */
23987d057943SEduard Zingerman 	BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0),
23997d057943SEduard Zingerman 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0),
24007d057943SEduard Zingerman 	/* exit 0 */
24017d057943SEduard Zingerman 	BPF_MOV64_IMM(BPF_REG_0, 0),
24027d057943SEduard Zingerman 	BPF_EXIT_INSN(),
24037d057943SEduard Zingerman 	},
24047d057943SEduard Zingerman 	.flags = BPF_F_TEST_STATE_FREQ,
24057d057943SEduard Zingerman 	.fixup_map_hash_8b = { 3, 9 },
24067d057943SEduard Zingerman 	.result = REJECT,
24077d057943SEduard Zingerman 	.errstr = "R8 invalid mem access 'map_value_or_null'",
24087d057943SEduard Zingerman 	.result_unpriv = REJECT,
24097d057943SEduard Zingerman 	.errstr_unpriv = "",
24107d057943SEduard Zingerman 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
24117d057943SEduard Zingerman },
2412