xref: /linux/tools/testing/selftests/bpf/verifier/calls.c (revision 6fdcba32711044c35c0e1b094cbd8f3f0b4472c9)
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 root only",
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 array 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 root only",
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 root only",
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 root only",
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: ld_abs with changing ctx data in callee",
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_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
658 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
659 	BPF_LD_ABS(BPF_B, 0),
660 	BPF_LD_ABS(BPF_H, 0),
661 	BPF_LD_ABS(BPF_W, 0),
662 	BPF_EXIT_INSN(),
663 	BPF_MOV64_IMM(BPF_REG_2, 1),
664 	BPF_MOV64_IMM(BPF_REG_3, 2),
665 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push),
666 	BPF_EXIT_INSN(),
667 	},
668 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
669 	.errstr = "BPF_LD_[ABS|IND] instructions cannot be mixed",
670 	.result = REJECT,
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 root only",
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 off -16+0 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 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 root only",
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 root only",
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 root only",
2032 	.errstr = "!read_ok",
2033 	.result = REJECT,
2034 },
2035