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