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