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