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