~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/verifier/calls.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php