xref: /linux/tools/testing/selftests/bpf/verifier/calls.c (revision 24168c5e6dfbdd5b414f048f47f75d64533296ca)
1 {
2 	"calls: invalid kfunc call not eliminated",
3 	.insns = {
4 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
5 	BPF_MOV64_IMM(BPF_REG_0, 1),
6 	BPF_EXIT_INSN(),
7 	},
8 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
9 	.result  = REJECT,
10 	.errstr = "invalid kernel function call not eliminated in verifier pass",
11 },
12 {
13 	"calls: invalid kfunc call unreachable",
14 	.insns = {
15 	BPF_MOV64_IMM(BPF_REG_0, 1),
16 	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 0, 2),
17 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
18 	BPF_MOV64_IMM(BPF_REG_0, 1),
19 	BPF_EXIT_INSN(),
20 	},
21 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
22 	.result  = ACCEPT,
23 },
24 {
25 	"calls: invalid kfunc call: ptr_to_mem to struct with non-scalar",
26 	.insns = {
27 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
28 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
29 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
30 	BPF_EXIT_INSN(),
31 	},
32 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
33 	.result = REJECT,
34 	.errstr = "arg#0 pointer type STRUCT prog_test_fail1 must point to scalar",
35 	.fixup_kfunc_btf_id = {
36 		{ "bpf_kfunc_call_test_fail1", 2 },
37 	},
38 },
39 {
40 	"calls: invalid kfunc call: ptr_to_mem to struct with nesting depth > 4",
41 	.insns = {
42 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
43 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
44 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
45 	BPF_EXIT_INSN(),
46 	},
47 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
48 	.result = REJECT,
49 	.errstr = "max struct nesting depth exceeded\narg#0 pointer type STRUCT prog_test_fail2",
50 	.fixup_kfunc_btf_id = {
51 		{ "bpf_kfunc_call_test_fail2", 2 },
52 	},
53 },
54 {
55 	"calls: invalid kfunc call: ptr_to_mem to struct with FAM",
56 	.insns = {
57 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
58 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
59 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
60 	BPF_EXIT_INSN(),
61 	},
62 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
63 	.result = REJECT,
64 	.errstr = "arg#0 pointer type STRUCT prog_test_fail3 must point to scalar",
65 	.fixup_kfunc_btf_id = {
66 		{ "bpf_kfunc_call_test_fail3", 2 },
67 	},
68 },
69 {
70 	"calls: invalid kfunc call: reg->type != PTR_TO_CTX",
71 	.insns = {
72 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
73 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
74 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
75 	BPF_EXIT_INSN(),
76 	},
77 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
78 	.result = REJECT,
79 	.errstr = "R1 must have zero offset when passed to release func or trusted arg to kfunc",
80 	.fixup_kfunc_btf_id = {
81 		{ "bpf_kfunc_call_test_pass_ctx", 2 },
82 	},
83 },
84 {
85 	"calls: invalid kfunc call: void * not allowed in func proto without mem size arg",
86 	.insns = {
87 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
88 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
89 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
90 	BPF_EXIT_INSN(),
91 	},
92 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
93 	.result = REJECT,
94 	.errstr = "arg#0 pointer type UNKNOWN  must point to scalar",
95 	.fixup_kfunc_btf_id = {
96 		{ "bpf_kfunc_call_test_mem_len_fail1", 2 },
97 	},
98 },
99 {
100 	"calls: trigger reg2btf_ids[reg->type] for reg->type > __BPF_REG_TYPE_MAX",
101 	.insns = {
102 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
103 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
104 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
105 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
106 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
107 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
108 	BPF_EXIT_INSN(),
109 	},
110 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
111 	.result = REJECT,
112 	.errstr = "Possibly NULL pointer passed to trusted arg0",
113 	.fixup_kfunc_btf_id = {
114 		{ "bpf_kfunc_call_test_acquire", 3 },
115 		{ "bpf_kfunc_call_test_release", 5 },
116 	},
117 },
118 {
119 	"calls: invalid kfunc call: reg->off must be zero when passed to release kfunc",
120 	.insns = {
121 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
122 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
123 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
124 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
125 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
126 	BPF_EXIT_INSN(),
127 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
128 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
129 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
130 	BPF_MOV64_IMM(BPF_REG_0, 0),
131 	BPF_EXIT_INSN(),
132 	},
133 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
134 	.result = REJECT,
135 	.errstr = "R1 must have zero offset when passed to release func",
136 	.fixup_kfunc_btf_id = {
137 		{ "bpf_kfunc_call_test_acquire", 3 },
138 		{ "bpf_kfunc_call_memb_release", 8 },
139 	},
140 },
141 {
142 	"calls: invalid kfunc call: don't match first member type when passed to release kfunc",
143 	.insns = {
144 	BPF_MOV64_IMM(BPF_REG_0, 0),
145 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
146 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
147 	BPF_EXIT_INSN(),
148 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
149 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
150 	BPF_MOV64_IMM(BPF_REG_0, 0),
151 	BPF_EXIT_INSN(),
152 	},
153 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
154 	.result = REJECT,
155 	.errstr = "kernel function bpf_kfunc_call_memb1_release args#0 expected pointer",
156 	.fixup_kfunc_btf_id = {
157 		{ "bpf_kfunc_call_memb_acquire", 1 },
158 		{ "bpf_kfunc_call_memb1_release", 5 },
159 	},
160 },
161 {
162 	"calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset",
163 	.insns = {
164 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
165 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
166 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
167 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
168 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
169 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
170 	BPF_EXIT_INSN(),
171 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
172 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4),
173 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
174 	BPF_MOV64_IMM(BPF_REG_0, 0),
175 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
176 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
177 	BPF_MOV64_IMM(BPF_REG_0, 0),
178 	BPF_EXIT_INSN(),
179 	},
180 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
181 	.fixup_kfunc_btf_id = {
182 		{ "bpf_kfunc_call_test_acquire", 3 },
183 		{ "bpf_kfunc_call_test_offset", 9 },
184 		{ "bpf_kfunc_call_test_release", 12 },
185 	},
186 	.result_unpriv = REJECT,
187 	.result = REJECT,
188 	.errstr = "ptr R1 off=-4 disallowed",
189 },
190 {
191 	"calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset",
192 	.insns = {
193 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
194 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
195 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
196 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
197 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
198 	BPF_EXIT_INSN(),
199 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
200 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
201 	BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3),
202 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
203 	BPF_MOV64_IMM(BPF_REG_0, 0),
204 	BPF_EXIT_INSN(),
205 	BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3),
206 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
207 	BPF_MOV64_IMM(BPF_REG_0, 0),
208 	BPF_EXIT_INSN(),
209 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
210 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
211 	BPF_MOV64_IMM(BPF_REG_0, 0),
212 	BPF_EXIT_INSN(),
213 	},
214 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
215 	.fixup_kfunc_btf_id = {
216 		{ "bpf_kfunc_call_test_acquire", 3 },
217 		{ "bpf_kfunc_call_test_release", 9 },
218 		{ "bpf_kfunc_call_test_release", 13 },
219 		{ "bpf_kfunc_call_test_release", 17 },
220 	},
221 	.result_unpriv = REJECT,
222 	.result = REJECT,
223 	.errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed",
224 },
225 {
226 	"calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
227 	.insns = {
228 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
229 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
230 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
231 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
232 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
233 	BPF_EXIT_INSN(),
234 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
235 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
236 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
237 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 16),
238 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
239 	BPF_MOV64_IMM(BPF_REG_0, 0),
240 	BPF_EXIT_INSN(),
241 	},
242 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
243 	.fixup_kfunc_btf_id = {
244 		{ "bpf_kfunc_call_test_acquire", 3 },
245 		{ "bpf_kfunc_call_test_ref", 8 },
246 		{ "bpf_kfunc_call_test_ref", 10 },
247 	},
248 	.result_unpriv = REJECT,
249 	.result = REJECT,
250 	.errstr = "R1 must be",
251 },
252 {
253 	"calls: valid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
254 	.insns = {
255 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
256 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
257 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
258 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
259 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
260 	BPF_EXIT_INSN(),
261 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
262 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
263 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
264 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
265 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
266 	BPF_MOV64_IMM(BPF_REG_0, 0),
267 	BPF_EXIT_INSN(),
268 	},
269 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
270 	.fixup_kfunc_btf_id = {
271 		{ "bpf_kfunc_call_test_acquire", 3 },
272 		{ "bpf_kfunc_call_test_ref", 8 },
273 		{ "bpf_kfunc_call_test_release", 10 },
274 	},
275 	.result_unpriv = REJECT,
276 	.result = ACCEPT,
277 },
278 {
279 	"calls: basic sanity",
280 	.insns = {
281 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
282 	BPF_MOV64_IMM(BPF_REG_0, 1),
283 	BPF_EXIT_INSN(),
284 	BPF_MOV64_IMM(BPF_REG_0, 2),
285 	BPF_EXIT_INSN(),
286 	},
287 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
288 	.result = ACCEPT,
289 },
290 {
291 	"calls: not on unprivileged",
292 	.insns = {
293 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
294 	BPF_MOV64_IMM(BPF_REG_0, 1),
295 	BPF_EXIT_INSN(),
296 	BPF_MOV64_IMM(BPF_REG_0, 2),
297 	BPF_EXIT_INSN(),
298 	},
299 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
300 	.result_unpriv = REJECT,
301 	.result = ACCEPT,
302 	.retval = 1,
303 },
304 {
305 	"calls: div by 0 in subprog",
306 	.insns = {
307 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
308 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
309 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
310 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
311 		    offsetof(struct __sk_buff, data_end)),
312 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
313 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
314 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
315 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
316 	BPF_MOV64_IMM(BPF_REG_0, 1),
317 	BPF_EXIT_INSN(),
318 	BPF_MOV32_IMM(BPF_REG_2, 0),
319 	BPF_MOV32_IMM(BPF_REG_3, 1),
320 	BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
321 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
322 		    offsetof(struct __sk_buff, data)),
323 	BPF_EXIT_INSN(),
324 	},
325 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
326 	.result = ACCEPT,
327 	.retval = 1,
328 },
329 {
330 	"calls: multiple ret types in subprog 1",
331 	.insns = {
332 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
333 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
334 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
335 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
336 		    offsetof(struct __sk_buff, data_end)),
337 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
338 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
339 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
340 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
341 	BPF_MOV64_IMM(BPF_REG_0, 1),
342 	BPF_EXIT_INSN(),
343 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
344 		    offsetof(struct __sk_buff, data)),
345 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
346 	BPF_MOV32_IMM(BPF_REG_0, 42),
347 	BPF_EXIT_INSN(),
348 	},
349 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
350 	.result = REJECT,
351 	.errstr = "R0 invalid mem access 'scalar'",
352 },
353 {
354 	"calls: multiple ret types in subprog 2",
355 	.insns = {
356 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
357 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
358 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
359 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
360 		    offsetof(struct __sk_buff, data_end)),
361 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
362 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
363 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
364 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
365 	BPF_MOV64_IMM(BPF_REG_0, 1),
366 	BPF_EXIT_INSN(),
367 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
368 		    offsetof(struct __sk_buff, data)),
369 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
370 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
371 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
372 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
373 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
374 	BPF_LD_MAP_FD(BPF_REG_1, 0),
375 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
376 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
377 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
378 		    offsetof(struct __sk_buff, data)),
379 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
380 	BPF_EXIT_INSN(),
381 	},
382 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
383 	.fixup_map_hash_8b = { 16 },
384 	.result = REJECT,
385 	.errstr = "R0 min value is outside of the allowed memory range",
386 },
387 {
388 	"calls: overlapping caller/callee",
389 	.insns = {
390 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
391 	BPF_MOV64_IMM(BPF_REG_0, 1),
392 	BPF_EXIT_INSN(),
393 	},
394 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
395 	.errstr = "last insn is not an exit or jmp",
396 	.result = REJECT,
397 },
398 {
399 	"calls: wrong recursive calls",
400 	.insns = {
401 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
402 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
403 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
404 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
405 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
406 	BPF_MOV64_IMM(BPF_REG_0, 1),
407 	BPF_EXIT_INSN(),
408 	},
409 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
410 	.errstr = "jump out of range",
411 	.result = REJECT,
412 },
413 {
414 	"calls: wrong src reg",
415 	.insns = {
416 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 3, 0, 0),
417 	BPF_MOV64_IMM(BPF_REG_0, 1),
418 	BPF_EXIT_INSN(),
419 	},
420 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
421 	.errstr = "BPF_CALL uses reserved fields",
422 	.result = REJECT,
423 },
424 {
425 	"calls: wrong off value",
426 	.insns = {
427 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
428 	BPF_MOV64_IMM(BPF_REG_0, 1),
429 	BPF_EXIT_INSN(),
430 	BPF_MOV64_IMM(BPF_REG_0, 2),
431 	BPF_EXIT_INSN(),
432 	},
433 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
434 	.errstr = "BPF_CALL uses reserved fields",
435 	.result = REJECT,
436 },
437 {
438 	"calls: jump back loop",
439 	.insns = {
440 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
441 	BPF_MOV64_IMM(BPF_REG_0, 1),
442 	BPF_EXIT_INSN(),
443 	},
444 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
445 	.errstr = "the call stack of 9 frames is too deep",
446 	.result = REJECT,
447 },
448 {
449 	"calls: conditional call",
450 	.insns = {
451 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
452 		    offsetof(struct __sk_buff, mark)),
453 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
454 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
455 	BPF_MOV64_IMM(BPF_REG_0, 1),
456 	BPF_EXIT_INSN(),
457 	BPF_MOV64_IMM(BPF_REG_0, 2),
458 	BPF_EXIT_INSN(),
459 	},
460 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
461 	.errstr = "jump out of range",
462 	.result = REJECT,
463 },
464 {
465 	"calls: conditional call 2",
466 	.insns = {
467 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
468 		    offsetof(struct __sk_buff, mark)),
469 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
470 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
471 	BPF_MOV64_IMM(BPF_REG_0, 1),
472 	BPF_EXIT_INSN(),
473 	BPF_MOV64_IMM(BPF_REG_0, 2),
474 	BPF_EXIT_INSN(),
475 	BPF_MOV64_IMM(BPF_REG_0, 3),
476 	BPF_EXIT_INSN(),
477 	},
478 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
479 	.result = ACCEPT,
480 },
481 {
482 	"calls: conditional call 3",
483 	.insns = {
484 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
485 		    offsetof(struct __sk_buff, mark)),
486 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
487 	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
488 	BPF_MOV64_IMM(BPF_REG_0, 1),
489 	BPF_EXIT_INSN(),
490 	BPF_MOV64_IMM(BPF_REG_0, 1),
491 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
492 	BPF_MOV64_IMM(BPF_REG_0, 3),
493 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
494 	},
495 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
496 	.errstr_unpriv = "back-edge from insn",
497 	.result_unpriv = REJECT,
498 	.result = ACCEPT,
499 	.retval = 1,
500 },
501 {
502 	"calls: conditional call 4",
503 	.insns = {
504 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
505 		    offsetof(struct __sk_buff, mark)),
506 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
507 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
508 	BPF_MOV64_IMM(BPF_REG_0, 1),
509 	BPF_EXIT_INSN(),
510 	BPF_MOV64_IMM(BPF_REG_0, 1),
511 	BPF_JMP_IMM(BPF_JA, 0, 0, -5),
512 	BPF_MOV64_IMM(BPF_REG_0, 3),
513 	BPF_EXIT_INSN(),
514 	},
515 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
516 	.result = ACCEPT,
517 },
518 {
519 	"calls: conditional call 5",
520 	.insns = {
521 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
522 		    offsetof(struct __sk_buff, mark)),
523 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
524 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
525 	BPF_MOV64_IMM(BPF_REG_0, 1),
526 	BPF_EXIT_INSN(),
527 	BPF_MOV64_IMM(BPF_REG_0, 1),
528 	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
529 	BPF_MOV64_IMM(BPF_REG_0, 3),
530 	BPF_EXIT_INSN(),
531 	},
532 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
533 	.result = ACCEPT,
534 	.retval = 1,
535 },
536 {
537 	"calls: conditional call 6",
538 	.insns = {
539 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
540 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
541 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
542 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
543 	BPF_EXIT_INSN(),
544 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
545 		    offsetof(struct __sk_buff, mark)),
546 	BPF_EXIT_INSN(),
547 	},
548 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
549 	.errstr = "infinite loop detected",
550 	.result = REJECT,
551 },
552 {
553 	"calls: using r0 returned by callee",
554 	.insns = {
555 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
556 	BPF_EXIT_INSN(),
557 	BPF_MOV64_IMM(BPF_REG_0, 2),
558 	BPF_EXIT_INSN(),
559 	},
560 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
561 	.result = ACCEPT,
562 },
563 {
564 	"calls: using uninit r0 from callee",
565 	.insns = {
566 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
567 	BPF_EXIT_INSN(),
568 	BPF_EXIT_INSN(),
569 	},
570 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
571 	.errstr = "!read_ok",
572 	.result = REJECT,
573 },
574 {
575 	"calls: callee is using r1",
576 	.insns = {
577 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
578 	BPF_EXIT_INSN(),
579 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
580 		    offsetof(struct __sk_buff, len)),
581 	BPF_EXIT_INSN(),
582 	},
583 	.prog_type = BPF_PROG_TYPE_SCHED_ACT,
584 	.result = ACCEPT,
585 	.retval = TEST_DATA_LEN,
586 },
587 {
588 	"calls: callee using args1",
589 	.insns = {
590 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
591 	BPF_EXIT_INSN(),
592 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
593 	BPF_EXIT_INSN(),
594 	},
595 	.errstr_unpriv = "allowed for",
596 	.result_unpriv = REJECT,
597 	.result = ACCEPT,
598 	.retval = POINTER_VALUE,
599 },
600 {
601 	"calls: callee using wrong args2",
602 	.insns = {
603 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
604 	BPF_EXIT_INSN(),
605 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
606 	BPF_EXIT_INSN(),
607 	},
608 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
609 	.errstr = "R2 !read_ok",
610 	.result = REJECT,
611 },
612 {
613 	"calls: callee using two args",
614 	.insns = {
615 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
616 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
617 		    offsetof(struct __sk_buff, len)),
618 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
619 		    offsetof(struct __sk_buff, len)),
620 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
621 	BPF_EXIT_INSN(),
622 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
623 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
624 	BPF_EXIT_INSN(),
625 	},
626 	.errstr_unpriv = "allowed for",
627 	.result_unpriv = REJECT,
628 	.result = ACCEPT,
629 	.retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
630 },
631 {
632 	"calls: callee changing pkt pointers",
633 	.insns = {
634 	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct xdp_md, data)),
635 	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
636 		    offsetof(struct xdp_md, data_end)),
637 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
638 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
639 	BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
640 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
641 	/* clear_all_pkt_pointers() has to walk all frames
642 	 * to make sure that pkt pointers in the caller
643 	 * are cleared when callee is calling a helper that
644 	 * adjusts packet size
645 	 */
646 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
647 	BPF_MOV32_IMM(BPF_REG_0, 0),
648 	BPF_EXIT_INSN(),
649 	BPF_MOV64_IMM(BPF_REG_2, 0),
650 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_xdp_adjust_head),
651 	BPF_EXIT_INSN(),
652 	},
653 	.result = REJECT,
654 	.errstr = "R6 invalid mem access 'scalar'",
655 	.prog_type = BPF_PROG_TYPE_XDP,
656 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
657 },
658 {
659 	"calls: ptr null check in subprog",
660 	.insns = {
661 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
662 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
663 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
664 	BPF_LD_MAP_FD(BPF_REG_1, 0),
665 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
666 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
667 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
668 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
669 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
670 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
671 	BPF_EXIT_INSN(),
672 	BPF_MOV64_IMM(BPF_REG_0, 0),
673 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
674 	BPF_MOV64_IMM(BPF_REG_0, 1),
675 	BPF_EXIT_INSN(),
676 	},
677 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
678 	.fixup_map_hash_48b = { 3 },
679 	.result_unpriv = REJECT,
680 	.result = ACCEPT,
681 	.retval = 0,
682 },
683 {
684 	"calls: two calls with args",
685 	.insns = {
686 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
687 	BPF_EXIT_INSN(),
688 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
689 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
690 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
691 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
692 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
693 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
694 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
695 	BPF_EXIT_INSN(),
696 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
697 		    offsetof(struct __sk_buff, len)),
698 	BPF_EXIT_INSN(),
699 	},
700 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
701 	.result = ACCEPT,
702 	.retval = TEST_DATA_LEN + TEST_DATA_LEN,
703 },
704 {
705 	"calls: calls with stack arith",
706 	.insns = {
707 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
708 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
709 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
710 	BPF_EXIT_INSN(),
711 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
712 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
713 	BPF_EXIT_INSN(),
714 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
715 	BPF_MOV64_IMM(BPF_REG_0, 42),
716 	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
717 	BPF_EXIT_INSN(),
718 	},
719 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
720 	.result = ACCEPT,
721 	.retval = 42,
722 },
723 {
724 	"calls: calls with misaligned stack access",
725 	.insns = {
726 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
727 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
728 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
729 	BPF_EXIT_INSN(),
730 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
731 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
732 	BPF_EXIT_INSN(),
733 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
734 	BPF_MOV64_IMM(BPF_REG_0, 42),
735 	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
736 	BPF_EXIT_INSN(),
737 	},
738 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
739 	.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
740 	.errstr = "misaligned stack access",
741 	.result = REJECT,
742 },
743 {
744 	"calls: calls control flow, jump test",
745 	.insns = {
746 	BPF_MOV64_IMM(BPF_REG_0, 42),
747 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
748 	BPF_MOV64_IMM(BPF_REG_0, 43),
749 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
750 	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
751 	BPF_EXIT_INSN(),
752 	},
753 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
754 	.result = ACCEPT,
755 	.retval = 43,
756 },
757 {
758 	"calls: calls control flow, jump test 2",
759 	.insns = {
760 	BPF_MOV64_IMM(BPF_REG_0, 42),
761 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
762 	BPF_MOV64_IMM(BPF_REG_0, 43),
763 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
764 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
765 	BPF_EXIT_INSN(),
766 	},
767 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
768 	.errstr = "jump out of range from insn 1 to 4",
769 	.result = REJECT,
770 },
771 {
772 	"calls: two calls with bad jump",
773 	.insns = {
774 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
775 	BPF_EXIT_INSN(),
776 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
777 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
778 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
779 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
780 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
781 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
782 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
783 	BPF_EXIT_INSN(),
784 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
785 		    offsetof(struct __sk_buff, len)),
786 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
787 	BPF_EXIT_INSN(),
788 	},
789 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
790 	.errstr = "jump out of range from insn 11 to 9",
791 	.result = REJECT,
792 },
793 {
794 	"calls: recursive call. test1",
795 	.insns = {
796 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
797 	BPF_EXIT_INSN(),
798 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
799 	BPF_EXIT_INSN(),
800 	},
801 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
802 	.errstr = "the call stack of 9 frames is too deep",
803 	.result = REJECT,
804 },
805 {
806 	"calls: recursive call. test2",
807 	.insns = {
808 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
809 	BPF_EXIT_INSN(),
810 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
811 	BPF_EXIT_INSN(),
812 	},
813 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
814 	.errstr = "the call stack of 9 frames is too deep",
815 	.result = REJECT,
816 },
817 {
818 	"calls: unreachable code",
819 	.insns = {
820 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
821 	BPF_EXIT_INSN(),
822 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
823 	BPF_EXIT_INSN(),
824 	BPF_MOV64_IMM(BPF_REG_0, 0),
825 	BPF_EXIT_INSN(),
826 	BPF_MOV64_IMM(BPF_REG_0, 0),
827 	BPF_EXIT_INSN(),
828 	},
829 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
830 	.errstr = "unreachable insn 6",
831 	.result = REJECT,
832 },
833 {
834 	"calls: invalid call",
835 	.insns = {
836 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
837 	BPF_EXIT_INSN(),
838 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
839 	BPF_EXIT_INSN(),
840 	},
841 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
842 	.errstr = "invalid destination",
843 	.result = REJECT,
844 },
845 {
846 	"calls: invalid call 2",
847 	.insns = {
848 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
849 	BPF_EXIT_INSN(),
850 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
851 	BPF_EXIT_INSN(),
852 	},
853 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
854 	.errstr = "invalid destination",
855 	.result = REJECT,
856 },
857 {
858 	"calls: jumping across function bodies. test1",
859 	.insns = {
860 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
861 	BPF_MOV64_IMM(BPF_REG_0, 0),
862 	BPF_EXIT_INSN(),
863 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
864 	BPF_EXIT_INSN(),
865 	},
866 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
867 	.errstr = "jump out of range",
868 	.result = REJECT,
869 },
870 {
871 	"calls: jumping across function bodies. test2",
872 	.insns = {
873 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
874 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
875 	BPF_MOV64_IMM(BPF_REG_0, 0),
876 	BPF_EXIT_INSN(),
877 	BPF_EXIT_INSN(),
878 	},
879 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
880 	.errstr = "jump out of range",
881 	.result = REJECT,
882 },
883 {
884 	"calls: call without exit",
885 	.insns = {
886 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
887 	BPF_EXIT_INSN(),
888 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
889 	BPF_EXIT_INSN(),
890 	BPF_MOV64_IMM(BPF_REG_0, 0),
891 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
892 	},
893 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
894 	.errstr = "not an exit",
895 	.result = REJECT,
896 },
897 {
898 	"calls: call into middle of ld_imm64",
899 	.insns = {
900 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
901 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
902 	BPF_MOV64_IMM(BPF_REG_0, 0),
903 	BPF_EXIT_INSN(),
904 	BPF_LD_IMM64(BPF_REG_0, 0),
905 	BPF_EXIT_INSN(),
906 	},
907 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
908 	.errstr = "last insn",
909 	.result = REJECT,
910 },
911 {
912 	"calls: call into middle of other call",
913 	.insns = {
914 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
915 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
916 	BPF_MOV64_IMM(BPF_REG_0, 0),
917 	BPF_EXIT_INSN(),
918 	BPF_MOV64_IMM(BPF_REG_0, 0),
919 	BPF_MOV64_IMM(BPF_REG_0, 0),
920 	BPF_EXIT_INSN(),
921 	},
922 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
923 	.errstr = "last insn",
924 	.result = REJECT,
925 },
926 {
927 	"calls: subprog call with ld_abs in main prog",
928 	.insns = {
929 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
930 	BPF_LD_ABS(BPF_B, 0),
931 	BPF_LD_ABS(BPF_H, 0),
932 	BPF_LD_ABS(BPF_W, 0),
933 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
934 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
935 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
936 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
937 	BPF_LD_ABS(BPF_B, 0),
938 	BPF_LD_ABS(BPF_H, 0),
939 	BPF_LD_ABS(BPF_W, 0),
940 	BPF_EXIT_INSN(),
941 	BPF_MOV64_IMM(BPF_REG_2, 1),
942 	BPF_MOV64_IMM(BPF_REG_3, 2),
943 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push),
944 	BPF_EXIT_INSN(),
945 	},
946 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
947 	.result = ACCEPT,
948 },
949 {
950 	"calls: two calls with bad fallthrough",
951 	.insns = {
952 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
953 	BPF_EXIT_INSN(),
954 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
955 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
956 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
957 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
958 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
959 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
960 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
961 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
962 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
963 		    offsetof(struct __sk_buff, len)),
964 	BPF_EXIT_INSN(),
965 	},
966 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
967 	.errstr = "not an exit",
968 	.result = REJECT,
969 },
970 {
971 	"calls: two calls with stack read",
972 	.insns = {
973 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
974 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
975 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
976 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
977 	BPF_EXIT_INSN(),
978 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
979 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
980 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
981 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
982 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
983 	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
984 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
985 	BPF_EXIT_INSN(),
986 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
987 	BPF_EXIT_INSN(),
988 	},
989 	.prog_type = BPF_PROG_TYPE_XDP,
990 	.result = ACCEPT,
991 },
992 {
993 	"calls: two calls with stack write",
994 	.insns = {
995 	/* main prog */
996 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
997 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
998 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
999 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1000 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1001 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1002 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
1003 	BPF_EXIT_INSN(),
1004 
1005 	/* subprog 1 */
1006 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1007 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1008 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
1009 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
1010 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1011 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1012 	BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
1013 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
1014 	/* write into stack frame of main prog */
1015 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1016 	BPF_EXIT_INSN(),
1017 
1018 	/* subprog 2 */
1019 	/* read from stack frame of main prog */
1020 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
1021 	BPF_EXIT_INSN(),
1022 	},
1023 	.prog_type = BPF_PROG_TYPE_XDP,
1024 	.result = ACCEPT,
1025 },
1026 {
1027 	"calls: stack overflow using two frames (pre-call access)",
1028 	.insns = {
1029 	/* prog 1 */
1030 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1031 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
1032 	BPF_EXIT_INSN(),
1033 
1034 	/* prog 2 */
1035 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1036 	BPF_MOV64_IMM(BPF_REG_0, 0),
1037 	BPF_EXIT_INSN(),
1038 	},
1039 	.prog_type = BPF_PROG_TYPE_XDP,
1040 	.errstr = "combined stack size",
1041 	.result = REJECT,
1042 },
1043 {
1044 	"calls: stack overflow using two frames (post-call access)",
1045 	.insns = {
1046 	/* prog 1 */
1047 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
1048 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1049 	BPF_EXIT_INSN(),
1050 
1051 	/* prog 2 */
1052 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1053 	BPF_MOV64_IMM(BPF_REG_0, 0),
1054 	BPF_EXIT_INSN(),
1055 	},
1056 	.prog_type = BPF_PROG_TYPE_XDP,
1057 	.errstr = "combined stack size",
1058 	.result = REJECT,
1059 },
1060 {
1061 	"calls: stack depth check using three frames. test1",
1062 	.insns = {
1063 	/* main */
1064 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
1065 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
1066 	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
1067 	BPF_MOV64_IMM(BPF_REG_0, 0),
1068 	BPF_EXIT_INSN(),
1069 	/* A */
1070 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
1071 	BPF_EXIT_INSN(),
1072 	/* B */
1073 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
1074 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
1075 	BPF_EXIT_INSN(),
1076 	},
1077 	.prog_type = BPF_PROG_TYPE_XDP,
1078 	/* stack_main=32, stack_A=256, stack_B=64
1079 	 * and max(main+A, main+A+B) < 512
1080 	 */
1081 	.result = ACCEPT,
1082 },
1083 {
1084 	"calls: stack depth check using three frames. test2",
1085 	.insns = {
1086 	/* main */
1087 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
1088 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
1089 	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
1090 	BPF_MOV64_IMM(BPF_REG_0, 0),
1091 	BPF_EXIT_INSN(),
1092 	/* A */
1093 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
1094 	BPF_EXIT_INSN(),
1095 	/* B */
1096 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
1097 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
1098 	BPF_EXIT_INSN(),
1099 	},
1100 	.prog_type = BPF_PROG_TYPE_XDP,
1101 	/* stack_main=32, stack_A=64, stack_B=256
1102 	 * and max(main+A, main+A+B) < 512
1103 	 */
1104 	.result = ACCEPT,
1105 },
1106 {
1107 	"calls: stack depth check using three frames. test3",
1108 	.insns = {
1109 	/* main */
1110 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1111 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
1112 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1113 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
1114 	BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
1115 	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
1116 	BPF_MOV64_IMM(BPF_REG_0, 0),
1117 	BPF_EXIT_INSN(),
1118 	/* A */
1119 	BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
1120 	BPF_EXIT_INSN(),
1121 	BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
1122 	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
1123 	/* B */
1124 	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
1125 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
1126 	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
1127 	BPF_EXIT_INSN(),
1128 	},
1129 	.prog_type = BPF_PROG_TYPE_XDP,
1130 	/* stack_main=64, stack_A=224, stack_B=256
1131 	 * and max(main+A, main+A+B) > 512
1132 	 */
1133 	.errstr = "combined stack",
1134 	.result = REJECT,
1135 },
1136 {
1137 	"calls: stack depth check using three frames. test4",
1138 	/* void main(void) {
1139 	 *   func1(0);
1140 	 *   func1(1);
1141 	 *   func2(1);
1142 	 * }
1143 	 * void func1(int alloc_or_recurse) {
1144 	 *   if (alloc_or_recurse) {
1145 	 *     frame_pointer[-300] = 1;
1146 	 *   } else {
1147 	 *     func2(alloc_or_recurse);
1148 	 *   }
1149 	 * }
1150 	 * void func2(int alloc_or_recurse) {
1151 	 *   if (alloc_or_recurse) {
1152 	 *     frame_pointer[-300] = 1;
1153 	 *   }
1154 	 * }
1155 	 */
1156 	.insns = {
1157 	/* main */
1158 	BPF_MOV64_IMM(BPF_REG_1, 0),
1159 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
1160 	BPF_MOV64_IMM(BPF_REG_1, 1),
1161 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
1162 	BPF_MOV64_IMM(BPF_REG_1, 1),
1163 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
1164 	BPF_MOV64_IMM(BPF_REG_0, 0),
1165 	BPF_EXIT_INSN(),
1166 	/* A */
1167 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
1168 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1169 	BPF_EXIT_INSN(),
1170 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
1171 	BPF_EXIT_INSN(),
1172 	/* B */
1173 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1174 	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
1175 	BPF_EXIT_INSN(),
1176 	},
1177 	.prog_type = BPF_PROG_TYPE_XDP,
1178 	.result = REJECT,
1179 	.errstr = "combined stack",
1180 },
1181 {
1182 	"calls: stack depth check using three frames. test5",
1183 	.insns = {
1184 	/* main */
1185 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
1186 	BPF_EXIT_INSN(),
1187 	/* A */
1188 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
1189 	BPF_EXIT_INSN(),
1190 	/* B */
1191 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
1192 	BPF_EXIT_INSN(),
1193 	/* C */
1194 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
1195 	BPF_EXIT_INSN(),
1196 	/* D */
1197 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
1198 	BPF_EXIT_INSN(),
1199 	/* E */
1200 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
1201 	BPF_EXIT_INSN(),
1202 	/* F */
1203 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
1204 	BPF_EXIT_INSN(),
1205 	/* G */
1206 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
1207 	BPF_EXIT_INSN(),
1208 	/* H */
1209 	BPF_MOV64_IMM(BPF_REG_0, 0),
1210 	BPF_EXIT_INSN(),
1211 	},
1212 	.prog_type = BPF_PROG_TYPE_XDP,
1213 	.errstr = "call stack",
1214 	.result = REJECT,
1215 },
1216 {
1217 	"calls: stack depth check in dead code",
1218 	.insns = {
1219 	/* main */
1220 	BPF_MOV64_IMM(BPF_REG_1, 0),
1221 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
1222 	BPF_EXIT_INSN(),
1223 	/* A */
1224 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1225 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */
1226 	BPF_MOV64_IMM(BPF_REG_0, 0),
1227 	BPF_EXIT_INSN(),
1228 	/* B */
1229 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
1230 	BPF_EXIT_INSN(),
1231 	/* C */
1232 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
1233 	BPF_EXIT_INSN(),
1234 	/* D */
1235 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
1236 	BPF_EXIT_INSN(),
1237 	/* E */
1238 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
1239 	BPF_EXIT_INSN(),
1240 	/* F */
1241 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
1242 	BPF_EXIT_INSN(),
1243 	/* G */
1244 	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
1245 	BPF_EXIT_INSN(),
1246 	/* H */
1247 	BPF_MOV64_IMM(BPF_REG_0, 0),
1248 	BPF_EXIT_INSN(),
1249 	},
1250 	.prog_type = BPF_PROG_TYPE_XDP,
1251 	.errstr = "call stack",
1252 	.result = REJECT,
1253 },
1254 {
1255 	"calls: spill into caller stack frame",
1256 	.insns = {
1257 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1258 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1259 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1260 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1261 	BPF_EXIT_INSN(),
1262 	BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
1263 	BPF_MOV64_IMM(BPF_REG_0, 0),
1264 	BPF_EXIT_INSN(),
1265 	},
1266 	.prog_type = BPF_PROG_TYPE_XDP,
1267 	.errstr = "cannot spill",
1268 	.result = REJECT,
1269 },
1270 {
1271 	"calls: write into caller stack frame",
1272 	.insns = {
1273 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1274 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1275 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1276 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1277 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1278 	BPF_EXIT_INSN(),
1279 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
1280 	BPF_MOV64_IMM(BPF_REG_0, 0),
1281 	BPF_EXIT_INSN(),
1282 	},
1283 	.prog_type = BPF_PROG_TYPE_XDP,
1284 	.result = ACCEPT,
1285 	.retval = 42,
1286 },
1287 {
1288 	"calls: write into callee stack frame",
1289 	.insns = {
1290 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1291 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
1292 	BPF_EXIT_INSN(),
1293 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
1294 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
1295 	BPF_EXIT_INSN(),
1296 	},
1297 	.prog_type = BPF_PROG_TYPE_XDP,
1298 	.errstr = "cannot return stack pointer",
1299 	.result = REJECT,
1300 },
1301 {
1302 	"calls: two calls with stack write and void return",
1303 	.insns = {
1304 	/* main prog */
1305 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1306 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1307 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1308 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1309 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1310 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1311 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
1312 	BPF_EXIT_INSN(),
1313 
1314 	/* subprog 1 */
1315 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1316 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1317 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1318 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1319 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1320 	BPF_EXIT_INSN(),
1321 
1322 	/* subprog 2 */
1323 	/* write into stack frame of main prog */
1324 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
1325 	BPF_EXIT_INSN(), /* void return */
1326 	},
1327 	.prog_type = BPF_PROG_TYPE_XDP,
1328 	.result = ACCEPT,
1329 },
1330 {
1331 	"calls: ambiguous return value",
1332 	.insns = {
1333 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1334 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
1335 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1336 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1337 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1338 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1339 	BPF_EXIT_INSN(),
1340 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
1341 	BPF_MOV64_IMM(BPF_REG_0, 0),
1342 	BPF_EXIT_INSN(),
1343 	},
1344 	.errstr_unpriv = "allowed for",
1345 	.result_unpriv = REJECT,
1346 	.errstr = "R0 !read_ok",
1347 	.result = REJECT,
1348 },
1349 {
1350 	"calls: two calls that return map_value",
1351 	.insns = {
1352 	/* main prog */
1353 	/* pass fp-16, fp-8 into a function */
1354 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1355 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1356 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1357 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1358 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
1359 
1360 	/* fetch map_value_ptr from the stack of this function */
1361 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1362 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1363 	/* write into map value */
1364 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1365 	/* fetch secound map_value_ptr from the stack */
1366 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
1367 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
1368 	/* write into map value */
1369 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1370 	BPF_MOV64_IMM(BPF_REG_0, 0),
1371 	BPF_EXIT_INSN(),
1372 
1373 	/* subprog 1 */
1374 	/* call 3rd function twice */
1375 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1376 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1377 	/* first time with fp-8 */
1378 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1379 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1380 	/* second time with fp-16 */
1381 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1382 	BPF_EXIT_INSN(),
1383 
1384 	/* subprog 2 */
1385 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1386 	/* lookup from map */
1387 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1388 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1389 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1390 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1391 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1392 	/* write map_value_ptr into stack frame of main prog */
1393 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1394 	BPF_MOV64_IMM(BPF_REG_0, 0),
1395 	BPF_EXIT_INSN(), /* return 0 */
1396 	},
1397 	.prog_type = BPF_PROG_TYPE_XDP,
1398 	.fixup_map_hash_8b = { 23 },
1399 	.result = ACCEPT,
1400 },
1401 {
1402 	"calls: two calls that return map_value with bool condition",
1403 	.insns = {
1404 	/* main prog */
1405 	/* pass fp-16, fp-8 into a function */
1406 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1407 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1408 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1409 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1410 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1411 	BPF_MOV64_IMM(BPF_REG_0, 0),
1412 	BPF_EXIT_INSN(),
1413 
1414 	/* subprog 1 */
1415 	/* call 3rd function twice */
1416 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1417 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1418 	/* first time with fp-8 */
1419 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
1420 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
1421 	/* fetch map_value_ptr from the stack of this function */
1422 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1423 	/* write into map value */
1424 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1425 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1426 	/* second time with fp-16 */
1427 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1428 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
1429 	/* fetch secound map_value_ptr from the stack */
1430 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
1431 	/* write into map value */
1432 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1433 	BPF_EXIT_INSN(),
1434 
1435 	/* subprog 2 */
1436 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1437 	/* lookup from map */
1438 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1439 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1440 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1441 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1442 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1443 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1444 	BPF_MOV64_IMM(BPF_REG_0, 0),
1445 	BPF_EXIT_INSN(), /* return 0 */
1446 	/* write map_value_ptr into stack frame of main prog */
1447 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1448 	BPF_MOV64_IMM(BPF_REG_0, 1),
1449 	BPF_EXIT_INSN(), /* return 1 */
1450 	},
1451 	.prog_type = BPF_PROG_TYPE_XDP,
1452 	.fixup_map_hash_8b = { 23 },
1453 	.result = ACCEPT,
1454 },
1455 {
1456 	"calls: two calls that return map_value with incorrect bool check",
1457 	.insns = {
1458 	/* main prog */
1459 	/* pass fp-16, fp-8 into a function */
1460 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1461 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1462 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1463 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1464 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1465 	BPF_MOV64_IMM(BPF_REG_0, 0),
1466 	BPF_EXIT_INSN(),
1467 
1468 	/* subprog 1 */
1469 	/* call 3rd function twice */
1470 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1471 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1472 	/* first time with fp-8 */
1473 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
1474 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
1475 	/* fetch map_value_ptr from the stack of this function */
1476 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
1477 	/* write into map value */
1478 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1479 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1480 	/* second time with fp-16 */
1481 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1482 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1483 	/* fetch secound map_value_ptr from the stack */
1484 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
1485 	/* write into map value */
1486 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1487 	BPF_EXIT_INSN(),
1488 
1489 	/* subprog 2 */
1490 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1491 	/* lookup from map */
1492 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1493 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1494 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1495 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1496 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1497 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1498 	BPF_MOV64_IMM(BPF_REG_0, 0),
1499 	BPF_EXIT_INSN(), /* return 0 */
1500 	/* write map_value_ptr into stack frame of main prog */
1501 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1502 	BPF_MOV64_IMM(BPF_REG_0, 1),
1503 	BPF_EXIT_INSN(), /* return 1 */
1504 	},
1505 	.prog_type = BPF_PROG_TYPE_XDP,
1506 	.fixup_map_hash_8b = { 23 },
1507 	.result = REJECT,
1508 	.errstr = "R0 invalid mem access 'scalar'",
1509 	.result_unpriv = REJECT,
1510 	.errstr_unpriv = "invalid read from stack R7 off=-16 size=8",
1511 },
1512 {
1513 	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
1514 	.insns = {
1515 	/* main prog */
1516 	/* pass fp-16, fp-8 into a function */
1517 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1518 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1519 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1520 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1521 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1522 	BPF_MOV64_IMM(BPF_REG_0, 0),
1523 	BPF_EXIT_INSN(),
1524 
1525 	/* subprog 1 */
1526 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1527 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1528 	/* 1st lookup from map */
1529 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1530 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1531 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1532 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1533 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1534 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1535 	BPF_MOV64_IMM(BPF_REG_8, 0),
1536 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1537 	/* write map_value_ptr into stack frame of main prog at fp-8 */
1538 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1539 	BPF_MOV64_IMM(BPF_REG_8, 1),
1540 
1541 	/* 2nd lookup from map */
1542 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
1543 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1544 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1545 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
1546 		     BPF_FUNC_map_lookup_elem),
1547 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1548 	BPF_MOV64_IMM(BPF_REG_9, 0),
1549 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1550 	/* write map_value_ptr into stack frame of main prog at fp-16 */
1551 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1552 	BPF_MOV64_IMM(BPF_REG_9, 1),
1553 
1554 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
1555 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
1556 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
1557 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
1558 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
1559 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
1560 	BPF_EXIT_INSN(),
1561 
1562 	/* subprog 2 */
1563 	/* if arg2 == 1 do *arg1 = 0 */
1564 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
1565 	/* fetch map_value_ptr from the stack of this function */
1566 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
1567 	/* write into map value */
1568 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1569 
1570 	/* if arg4 == 1 do *arg3 = 0 */
1571 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
1572 	/* fetch map_value_ptr from the stack of this function */
1573 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
1574 	/* write into map value */
1575 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
1576 	BPF_EXIT_INSN(),
1577 	},
1578 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1579 	.fixup_map_hash_8b = { 12, 22 },
1580 	.result = REJECT,
1581 	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
1582 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1583 },
1584 {
1585 	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
1586 	.insns = {
1587 	/* main prog */
1588 	/* pass fp-16, fp-8 into a function */
1589 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1590 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1591 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1592 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1593 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1594 	BPF_MOV64_IMM(BPF_REG_0, 0),
1595 	BPF_EXIT_INSN(),
1596 
1597 	/* subprog 1 */
1598 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1599 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1600 	/* 1st lookup from map */
1601 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1602 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1603 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1604 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1605 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1606 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1607 	BPF_MOV64_IMM(BPF_REG_8, 0),
1608 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1609 	/* write map_value_ptr into stack frame of main prog at fp-8 */
1610 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1611 	BPF_MOV64_IMM(BPF_REG_8, 1),
1612 
1613 	/* 2nd lookup from map */
1614 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
1615 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1616 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1617 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
1618 		     BPF_FUNC_map_lookup_elem),
1619 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1620 	BPF_MOV64_IMM(BPF_REG_9, 0),
1621 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1622 	/* write map_value_ptr into stack frame of main prog at fp-16 */
1623 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1624 	BPF_MOV64_IMM(BPF_REG_9, 1),
1625 
1626 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
1627 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
1628 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
1629 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
1630 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
1631 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
1632 	BPF_EXIT_INSN(),
1633 
1634 	/* subprog 2 */
1635 	/* if arg2 == 1 do *arg1 = 0 */
1636 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
1637 	/* fetch map_value_ptr from the stack of this function */
1638 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
1639 	/* write into map value */
1640 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1641 
1642 	/* if arg4 == 1 do *arg3 = 0 */
1643 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
1644 	/* fetch map_value_ptr from the stack of this function */
1645 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
1646 	/* write into map value */
1647 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1648 	BPF_EXIT_INSN(),
1649 	},
1650 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1651 	.fixup_map_hash_8b = { 12, 22 },
1652 	.result = ACCEPT,
1653 },
1654 {
1655 	"calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
1656 	.insns = {
1657 	/* main prog */
1658 	/* pass fp-16, fp-8 into a function */
1659 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1660 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1661 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1662 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1663 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
1664 	BPF_MOV64_IMM(BPF_REG_0, 0),
1665 	BPF_EXIT_INSN(),
1666 
1667 	/* subprog 1 */
1668 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1669 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1670 	/* 1st lookup from map */
1671 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
1672 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1673 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
1674 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1675 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1676 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1677 	BPF_MOV64_IMM(BPF_REG_8, 0),
1678 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1679 	/* write map_value_ptr into stack frame of main prog at fp-8 */
1680 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1681 	BPF_MOV64_IMM(BPF_REG_8, 1),
1682 
1683 	/* 2nd lookup from map */
1684 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1685 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
1686 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1687 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1688 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1689 	BPF_MOV64_IMM(BPF_REG_9, 0),  // 26
1690 	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
1691 	/* write map_value_ptr into stack frame of main prog at fp-16 */
1692 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1693 	BPF_MOV64_IMM(BPF_REG_9, 1),
1694 
1695 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
1696 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
1697 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
1698 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
1699 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
1700 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
1701 	BPF_JMP_IMM(BPF_JA, 0, 0, -30),
1702 
1703 	/* subprog 2 */
1704 	/* if arg2 == 1 do *arg1 = 0 */
1705 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
1706 	/* fetch map_value_ptr from the stack of this function */
1707 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
1708 	/* write into map value */
1709 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1710 
1711 	/* if arg4 == 1 do *arg3 = 0 */
1712 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
1713 	/* fetch map_value_ptr from the stack of this function */
1714 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
1715 	/* write into map value */
1716 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
1717 	BPF_JMP_IMM(BPF_JA, 0, 0, -8),
1718 	},
1719 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1720 	.fixup_map_hash_8b = { 12, 22 },
1721 	.result = REJECT,
1722 	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
1723 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1724 },
1725 {
1726 	"calls: two calls that receive map_value_ptr_or_null via arg. test1",
1727 	.insns = {
1728 	/* main prog */
1729 	/* pass fp-16, fp-8 into a function */
1730 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1731 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1732 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1733 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1734 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1735 	BPF_MOV64_IMM(BPF_REG_0, 0),
1736 	BPF_EXIT_INSN(),
1737 
1738 	/* subprog 1 */
1739 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1740 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1741 	/* 1st lookup from map */
1742 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1743 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1744 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1745 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1746 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1747 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
1748 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1749 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1750 	BPF_MOV64_IMM(BPF_REG_8, 0),
1751 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1752 	BPF_MOV64_IMM(BPF_REG_8, 1),
1753 
1754 	/* 2nd lookup from map */
1755 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1756 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1757 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1758 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1759 	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
1760 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1761 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1762 	BPF_MOV64_IMM(BPF_REG_9, 0),
1763 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1764 	BPF_MOV64_IMM(BPF_REG_9, 1),
1765 
1766 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
1767 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1768 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
1769 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
1770 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
1771 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1772 	BPF_EXIT_INSN(),
1773 
1774 	/* subprog 2 */
1775 	/* if arg2 == 1 do *arg1 = 0 */
1776 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
1777 	/* fetch map_value_ptr from the stack of this function */
1778 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
1779 	/* write into map value */
1780 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1781 
1782 	/* if arg4 == 1 do *arg3 = 0 */
1783 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
1784 	/* fetch map_value_ptr from the stack of this function */
1785 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
1786 	/* write into map value */
1787 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1788 	BPF_EXIT_INSN(),
1789 	},
1790 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1791 	.fixup_map_hash_8b = { 12, 22 },
1792 	.result = ACCEPT,
1793 },
1794 {
1795 	"calls: two calls that receive map_value_ptr_or_null via arg. test2",
1796 	.insns = {
1797 	/* main prog */
1798 	/* pass fp-16, fp-8 into a function */
1799 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
1800 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
1801 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1802 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
1803 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
1804 	BPF_MOV64_IMM(BPF_REG_0, 0),
1805 	BPF_EXIT_INSN(),
1806 
1807 	/* subprog 1 */
1808 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1809 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
1810 	/* 1st lookup from map */
1811 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
1812 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1813 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1814 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1815 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1816 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
1817 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
1818 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1819 	BPF_MOV64_IMM(BPF_REG_8, 0),
1820 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1821 	BPF_MOV64_IMM(BPF_REG_8, 1),
1822 
1823 	/* 2nd lookup from map */
1824 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1825 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
1826 	BPF_LD_MAP_FD(BPF_REG_1, 0),
1827 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
1828 	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
1829 	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1830 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
1831 	BPF_MOV64_IMM(BPF_REG_9, 0),
1832 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1833 	BPF_MOV64_IMM(BPF_REG_9, 1),
1834 
1835 	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
1836 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1837 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
1838 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
1839 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
1840 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1841 	BPF_EXIT_INSN(),
1842 
1843 	/* subprog 2 */
1844 	/* if arg2 == 1 do *arg1 = 0 */
1845 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
1846 	/* fetch map_value_ptr from the stack of this function */
1847 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
1848 	/* write into map value */
1849 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1850 
1851 	/* if arg4 == 0 do *arg3 = 0 */
1852 	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
1853 	/* fetch map_value_ptr from the stack of this function */
1854 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
1855 	/* write into map value */
1856 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
1857 	BPF_EXIT_INSN(),
1858 	},
1859 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1860 	.fixup_map_hash_8b = { 12, 22 },
1861 	.result = REJECT,
1862 	.errstr = "R0 invalid mem access 'scalar'",
1863 },
1864 {
1865 	"calls: pkt_ptr spill into caller stack",
1866 	.insns = {
1867 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1868 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1869 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
1870 	BPF_EXIT_INSN(),
1871 
1872 	/* subprog 1 */
1873 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1874 		    offsetof(struct __sk_buff, data)),
1875 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1876 		    offsetof(struct __sk_buff, data_end)),
1877 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1878 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1879 	/* spill unchecked pkt_ptr into stack of caller */
1880 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1881 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1882 	/* now the pkt range is verified, read pkt_ptr from stack */
1883 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
1884 	/* write 4 bytes into packet */
1885 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1886 	BPF_EXIT_INSN(),
1887 	},
1888 	.result = ACCEPT,
1889 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1890 	.retval = POINTER_VALUE,
1891 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1892 },
1893 {
1894 	"calls: pkt_ptr spill into caller stack 2",
1895 	.insns = {
1896 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1897 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1898 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
1899 	/* Marking is still kept, but not in all cases safe. */
1900 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1901 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1902 	BPF_EXIT_INSN(),
1903 
1904 	/* subprog 1 */
1905 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1906 		    offsetof(struct __sk_buff, data)),
1907 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1908 		    offsetof(struct __sk_buff, data_end)),
1909 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1910 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1911 	/* spill unchecked pkt_ptr into stack of caller */
1912 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1913 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1914 	/* now the pkt range is verified, read pkt_ptr from stack */
1915 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
1916 	/* write 4 bytes into packet */
1917 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1918 	BPF_EXIT_INSN(),
1919 	},
1920 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1921 	.errstr = "invalid access to packet",
1922 	.result = REJECT,
1923 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1924 },
1925 {
1926 	"calls: pkt_ptr spill into caller stack 3",
1927 	.insns = {
1928 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1929 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1930 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1931 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1932 	/* Marking is still kept and safe here. */
1933 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1934 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1935 	BPF_EXIT_INSN(),
1936 
1937 	/* subprog 1 */
1938 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1939 		    offsetof(struct __sk_buff, data)),
1940 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1941 		    offsetof(struct __sk_buff, data_end)),
1942 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1943 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1944 	/* spill unchecked pkt_ptr into stack of caller */
1945 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1946 	BPF_MOV64_IMM(BPF_REG_5, 0),
1947 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
1948 	BPF_MOV64_IMM(BPF_REG_5, 1),
1949 	/* now the pkt range is verified, read pkt_ptr from stack */
1950 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
1951 	/* write 4 bytes into packet */
1952 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1953 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1954 	BPF_EXIT_INSN(),
1955 	},
1956 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1957 	.result = ACCEPT,
1958 	.retval = 1,
1959 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1960 },
1961 {
1962 	"calls: pkt_ptr spill into caller stack 4",
1963 	.insns = {
1964 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
1965 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
1966 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
1967 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
1968 	/* Check marking propagated. */
1969 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
1970 	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
1971 	BPF_EXIT_INSN(),
1972 
1973 	/* subprog 1 */
1974 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1975 		    offsetof(struct __sk_buff, data)),
1976 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
1977 		    offsetof(struct __sk_buff, data_end)),
1978 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1979 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1980 	/* spill unchecked pkt_ptr into stack of caller */
1981 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
1982 	BPF_MOV64_IMM(BPF_REG_5, 0),
1983 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
1984 	BPF_MOV64_IMM(BPF_REG_5, 1),
1985 	/* don't read back pkt_ptr from stack here */
1986 	/* write 4 bytes into packet */
1987 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
1988 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
1989 	BPF_EXIT_INSN(),
1990 	},
1991 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
1992 	.result = ACCEPT,
1993 	.retval = 1,
1994 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1995 },
1996 {
1997 	"calls: pkt_ptr spill into caller stack 5",
1998 	.insns = {
1999 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2000 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2001 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
2002 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
2003 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
2004 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
2005 	BPF_EXIT_INSN(),
2006 
2007 	/* subprog 1 */
2008 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2009 		    offsetof(struct __sk_buff, data)),
2010 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2011 		    offsetof(struct __sk_buff, data_end)),
2012 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2013 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2014 	BPF_MOV64_IMM(BPF_REG_5, 0),
2015 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2016 	/* spill checked pkt_ptr into stack of caller */
2017 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2018 	BPF_MOV64_IMM(BPF_REG_5, 1),
2019 	/* don't read back pkt_ptr from stack here */
2020 	/* write 4 bytes into packet */
2021 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
2022 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
2023 	BPF_EXIT_INSN(),
2024 	},
2025 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2026 	.errstr = "same insn cannot be used with different",
2027 	.result = REJECT,
2028 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2029 },
2030 {
2031 	"calls: pkt_ptr spill into caller stack 6",
2032 	.insns = {
2033 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2034 		    offsetof(struct __sk_buff, data_end)),
2035 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2036 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2037 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2038 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
2039 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
2040 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
2041 	BPF_EXIT_INSN(),
2042 
2043 	/* subprog 1 */
2044 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2045 		    offsetof(struct __sk_buff, data)),
2046 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2047 		    offsetof(struct __sk_buff, data_end)),
2048 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2049 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2050 	BPF_MOV64_IMM(BPF_REG_5, 0),
2051 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2052 	/* spill checked pkt_ptr into stack of caller */
2053 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2054 	BPF_MOV64_IMM(BPF_REG_5, 1),
2055 	/* don't read back pkt_ptr from stack here */
2056 	/* write 4 bytes into packet */
2057 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
2058 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
2059 	BPF_EXIT_INSN(),
2060 	},
2061 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2062 	.errstr = "R4 invalid mem access",
2063 	.result = REJECT,
2064 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2065 },
2066 {
2067 	"calls: pkt_ptr spill into caller stack 7",
2068 	.insns = {
2069 	BPF_MOV64_IMM(BPF_REG_2, 0),
2070 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2071 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2072 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2073 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
2074 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
2075 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
2076 	BPF_EXIT_INSN(),
2077 
2078 	/* subprog 1 */
2079 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2080 		    offsetof(struct __sk_buff, data)),
2081 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2082 		    offsetof(struct __sk_buff, data_end)),
2083 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2084 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2085 	BPF_MOV64_IMM(BPF_REG_5, 0),
2086 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2087 	/* spill checked pkt_ptr into stack of caller */
2088 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2089 	BPF_MOV64_IMM(BPF_REG_5, 1),
2090 	/* don't read back pkt_ptr from stack here */
2091 	/* write 4 bytes into packet */
2092 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
2093 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
2094 	BPF_EXIT_INSN(),
2095 	},
2096 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2097 	.errstr = "R4 invalid mem access",
2098 	.result = REJECT,
2099 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2100 },
2101 {
2102 	"calls: pkt_ptr spill into caller stack 8",
2103 	.insns = {
2104 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2105 		    offsetof(struct __sk_buff, data)),
2106 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2107 		    offsetof(struct __sk_buff, data_end)),
2108 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2109 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2110 	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
2111 	BPF_EXIT_INSN(),
2112 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2113 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2114 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2115 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
2116 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
2117 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
2118 	BPF_EXIT_INSN(),
2119 
2120 	/* subprog 1 */
2121 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2122 		    offsetof(struct __sk_buff, data)),
2123 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2124 		    offsetof(struct __sk_buff, data_end)),
2125 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2126 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2127 	BPF_MOV64_IMM(BPF_REG_5, 0),
2128 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
2129 	/* spill checked pkt_ptr into stack of caller */
2130 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2131 	BPF_MOV64_IMM(BPF_REG_5, 1),
2132 	/* don't read back pkt_ptr from stack here */
2133 	/* write 4 bytes into packet */
2134 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
2135 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
2136 	BPF_EXIT_INSN(),
2137 	},
2138 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2139 	.result = ACCEPT,
2140 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2141 },
2142 {
2143 	"calls: pkt_ptr spill into caller stack 9",
2144 	.insns = {
2145 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2146 		    offsetof(struct __sk_buff, data)),
2147 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2148 		    offsetof(struct __sk_buff, data_end)),
2149 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2150 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2151 	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
2152 	BPF_EXIT_INSN(),
2153 	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2154 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2155 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2156 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
2157 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
2158 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
2159 	BPF_EXIT_INSN(),
2160 
2161 	/* subprog 1 */
2162 	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2163 		    offsetof(struct __sk_buff, data)),
2164 	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2165 		    offsetof(struct __sk_buff, data_end)),
2166 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2167 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2168 	BPF_MOV64_IMM(BPF_REG_5, 0),
2169 	/* spill unchecked pkt_ptr into stack of caller */
2170 	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2171 	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
2172 	BPF_MOV64_IMM(BPF_REG_5, 1),
2173 	/* don't read back pkt_ptr from stack here */
2174 	/* write 4 bytes into packet */
2175 	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
2176 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
2177 	BPF_EXIT_INSN(),
2178 	},
2179 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
2180 	.errstr = "invalid access to packet",
2181 	.result = REJECT,
2182 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2183 },
2184 {
2185 	"calls: caller stack init to zero or map_value_or_null",
2186 	.insns = {
2187 	BPF_MOV64_IMM(BPF_REG_0, 0),
2188 	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
2189 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2190 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2191 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
2192 	/* fetch map_value_or_null or const_zero from stack */
2193 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
2194 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
2195 	/* store into map_value */
2196 	BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
2197 	BPF_EXIT_INSN(),
2198 
2199 	/* subprog 1 */
2200 	/* if (ctx == 0) return; */
2201 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
2202 	/* else bpf_map_lookup() and *(fp - 8) = r0 */
2203 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2204 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2205 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2206 	BPF_LD_MAP_FD(BPF_REG_1, 0),
2207 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2208 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2209 	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
2210 	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
2211 	BPF_EXIT_INSN(),
2212 	},
2213 	.fixup_map_hash_8b = { 13 },
2214 	.result = ACCEPT,
2215 	.prog_type = BPF_PROG_TYPE_XDP,
2216 },
2217 {
2218 	"calls: stack init to zero and pruning",
2219 	.insns = {
2220 	/* first make allocated_stack 16 byte */
2221 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
2222 	/* now fork the execution such that the false branch
2223 	 * of JGT insn will be verified second and it skisp zero
2224 	 * init of fp-8 stack slot. If stack liveness marking
2225 	 * is missing live_read marks from call map_lookup
2226 	 * processing then pruning will incorrectly assume
2227 	 * that fp-8 stack slot was unused in the fall-through
2228 	 * branch and will accept the program incorrectly
2229 	 */
2230 	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
2231 	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2),
2232 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2233 	BPF_JMP_IMM(BPF_JA, 0, 0, 0),
2234 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2235 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2236 	BPF_LD_MAP_FD(BPF_REG_1, 0),
2237 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
2238 	BPF_MOV64_IMM(BPF_REG_0, 0),
2239 	BPF_EXIT_INSN(),
2240 	},
2241 	.fixup_map_hash_48b = { 7 },
2242 	.errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8",
2243 	.result_unpriv = REJECT,
2244 	/* in privileged mode reads from uninitialized stack locations are permitted */
2245 	.result = ACCEPT,
2246 },
2247 {
2248 	"calls: ctx read at start of subprog",
2249 	.insns = {
2250 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
2251 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
2252 	BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
2253 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
2254 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
2255 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2256 	BPF_EXIT_INSN(),
2257 	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
2258 	BPF_MOV64_IMM(BPF_REG_0, 0),
2259 	BPF_EXIT_INSN(),
2260 	},
2261 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2262 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
2263 	.result_unpriv = REJECT,
2264 	.result = ACCEPT,
2265 },
2266 {
2267 	"calls: cross frame pruning",
2268 	.insns = {
2269 	/* r8 = !!random();
2270 	 * call pruner()
2271 	 * if (r8)
2272 	 *     do something bad;
2273 	 */
2274 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
2275 	BPF_MOV64_IMM(BPF_REG_8, 0),
2276 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
2277 	BPF_MOV64_IMM(BPF_REG_8, 1),
2278 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
2279 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
2280 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
2281 	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
2282 	BPF_MOV64_IMM(BPF_REG_0, 0),
2283 	BPF_EXIT_INSN(),
2284 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2285 	BPF_EXIT_INSN(),
2286 	},
2287 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2288 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
2289 	.errstr = "!read_ok",
2290 	.result = REJECT,
2291 },
2292 {
2293 	"calls: cross frame pruning - liveness propagation",
2294 	.insns = {
2295 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
2296 	BPF_MOV64_IMM(BPF_REG_8, 0),
2297 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
2298 	BPF_MOV64_IMM(BPF_REG_8, 1),
2299 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
2300 	BPF_MOV64_IMM(BPF_REG_9, 0),
2301 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
2302 	BPF_MOV64_IMM(BPF_REG_9, 1),
2303 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
2304 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
2305 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
2306 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
2307 	BPF_MOV64_IMM(BPF_REG_0, 0),
2308 	BPF_EXIT_INSN(),
2309 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
2310 	BPF_EXIT_INSN(),
2311 	},
2312 	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
2313 	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
2314 	.errstr = "!read_ok",
2315 	.result = REJECT,
2316 },
2317 /* Make sure that verifier.c:states_equal() considers IDs from all
2318  * frames when building 'idmap' for check_ids().
2319  */
2320 {
2321 	"calls: check_ids() across call boundary",
2322 	.insns = {
2323 	/* Function main() */
2324 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
2325 	/* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
2326 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2327 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2328 	BPF_LD_MAP_FD(BPF_REG_1,
2329 		      0),
2330 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2331 	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24),
2332 	/* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
2333 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
2334 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
2335 	BPF_LD_MAP_FD(BPF_REG_1,
2336 		      0),
2337 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
2338 	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32),
2339 	/* call foo(&fp[-24], &fp[-32])   ; both arguments have IDs in the current
2340 	 *                                ; stack frame
2341 	 */
2342 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP),
2343 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24),
2344 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
2345 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
2346 	BPF_CALL_REL(2),
2347 	/* exit 0 */
2348 	BPF_MOV64_IMM(BPF_REG_0, 0),
2349 	BPF_EXIT_INSN(),
2350 	/* Function foo()
2351 	 *
2352 	 * r9 = &frame[0].fp[-24]  ; save arguments in the callee saved registers,
2353 	 * r8 = &frame[0].fp[-32]  ; arguments are pointers to pointers to map value
2354 	 */
2355 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
2356 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_2),
2357 	/* r7 = ktime_get_ns() */
2358 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
2359 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
2360 	/* r6 = ktime_get_ns() */
2361 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
2362 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
2363 	/* if r6 > r7 goto +1      ; no new information about the state is derived from
2364 	 *                         ; this check, thus produced verifier states differ
2365 	 *                         ; only in 'insn_idx'
2366 	 * r9 = r8
2367 	 */
2368 	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1),
2369 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_8),
2370 	/* r9 = *r9                ; verifier get's to this point via two paths:
2371 	 *                         ; (I) one including r9 = r8, verified first;
2372 	 *                         ; (II) one excluding r9 = r8, verified next.
2373 	 *                         ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id.
2374 	 *                         ; Suppose that checkpoint is created here via path (I).
2375 	 *                         ; When verifying via (II) the r9.id must be compared against
2376 	 *                         ; frame[0].fp[-24].id, otherwise (I) and (II) would be
2377 	 *                         ; incorrectly deemed equivalent.
2378 	 * if r9 == 0 goto <exit>
2379 	 */
2380 	BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0),
2381 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1),
2382 	/* r8 = *r8                ; read map value via r8, this is not safe
2383 	 * r0 = *r8                ; because r8 might be not equal to r9.
2384 	 */
2385 	BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0),
2386 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0),
2387 	/* exit 0 */
2388 	BPF_MOV64_IMM(BPF_REG_0, 0),
2389 	BPF_EXIT_INSN(),
2390 	},
2391 	.flags = BPF_F_TEST_STATE_FREQ,
2392 	.fixup_map_hash_8b = { 3, 9 },
2393 	.result = REJECT,
2394 	.errstr = "R8 invalid mem access 'map_value_or_null'",
2395 	.result_unpriv = REJECT,
2396 	.errstr_unpriv = "",
2397 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
2398 },
2399