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