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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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 // SPDX-License-Identifier: GPL-2.0
  2 /* Converted from tools/testing/selftests/bpf/verifier/direct_packet_access.c */
  3 
  4 #include <linux/bpf.h>
  5 #include <bpf/bpf_helpers.h>
  6 #include "bpf_misc.h"
  7 
  8 SEC("tc")
  9 __description("pkt_end - pkt_start is allowed")
 10 __success __retval(TEST_DATA_LEN)
 11 __naked void end_pkt_start_is_allowed(void)
 12 {
 13         asm volatile ("                                 \
 14         r0 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
 15         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
 16         r0 -= r2;                                       \
 17         exit;                                           \
 18 "       :
 19         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
 20           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
 21         : __clobber_all);
 22 }
 23 
 24 SEC("tc")
 25 __description("direct packet access: test1")
 26 __success __retval(0)
 27 __naked void direct_packet_access_test1(void)
 28 {
 29         asm volatile ("                                 \
 30         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
 31         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
 32         r0 = r2;                                        \
 33         r0 += 8;                                        \
 34         if r0 > r3 goto l0_%=;                          \
 35         r0 = *(u8*)(r2 + 0);                            \
 36 l0_%=:  r0 = 0;                                         \
 37         exit;                                           \
 38 "       :
 39         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
 40           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
 41         : __clobber_all);
 42 }
 43 
 44 SEC("tc")
 45 __description("direct packet access: test2")
 46 __success __retval(0)
 47 __naked void direct_packet_access_test2(void)
 48 {
 49         asm volatile ("                                 \
 50         r0 = 1;                                         \
 51         r4 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
 52         r3 = *(u32*)(r1 + %[__sk_buff_data]);           \
 53         r5 = r3;                                        \
 54         r5 += 14;                                       \
 55         if r5 > r4 goto l0_%=;                          \
 56         r0 = *(u8*)(r3 + 7);                            \
 57         r4 = *(u8*)(r3 + 12);                           \
 58         r4 *= 14;                                       \
 59         r3 = *(u32*)(r1 + %[__sk_buff_data]);           \
 60         r3 += r4;                                       \
 61         r2 = *(u32*)(r1 + %[__sk_buff_len]);            \
 62         r2 <<= 49;                                      \
 63         r2 >>= 49;                                      \
 64         r3 += r2;                                       \
 65         r2 = r3;                                        \
 66         r2 += 8;                                        \
 67         r1 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
 68         if r2 > r1 goto l1_%=;                          \
 69         r1 = *(u8*)(r3 + 4);                            \
 70 l1_%=:  r0 = 0;                                         \
 71 l0_%=:  exit;                                           \
 72 "       :
 73         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
 74           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),
 75           __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 76         : __clobber_all);
 77 }
 78 
 79 SEC("socket")
 80 __description("direct packet access: test3")
 81 __failure __msg("invalid bpf_context access off=76")
 82 __failure_unpriv
 83 __naked void direct_packet_access_test3(void)
 84 {
 85         asm volatile ("                                 \
 86         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
 87         r0 = 0;                                         \
 88         exit;                                           \
 89 "       :
 90         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data))
 91         : __clobber_all);
 92 }
 93 
 94 SEC("tc")
 95 __description("direct packet access: test4 (write)")
 96 __success __retval(0)
 97 __naked void direct_packet_access_test4_write(void)
 98 {
 99         asm volatile ("                                 \
100         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
101         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
102         r0 = r2;                                        \
103         r0 += 8;                                        \
104         if r0 > r3 goto l0_%=;                          \
105         *(u8*)(r2 + 0) = r2;                            \
106 l0_%=:  r0 = 0;                                         \
107         exit;                                           \
108 "       :
109         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
110           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
111         : __clobber_all);
112 }
113 
114 SEC("tc")
115 __description("direct packet access: test5 (pkt_end >= reg, good access)")
116 __success __retval(0)
117 __naked void pkt_end_reg_good_access(void)
118 {
119         asm volatile ("                                 \
120         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
121         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
122         r0 = r2;                                        \
123         r0 += 8;                                        \
124         if r3 >= r0 goto l0_%=;                         \
125         r0 = 1;                                         \
126         exit;                                           \
127 l0_%=:  r0 = *(u8*)(r2 + 0);                            \
128         r0 = 0;                                         \
129         exit;                                           \
130 "       :
131         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
132           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
133         : __clobber_all);
134 }
135 
136 SEC("tc")
137 __description("direct packet access: test6 (pkt_end >= reg, bad access)")
138 __failure __msg("invalid access to packet")
139 __naked void pkt_end_reg_bad_access(void)
140 {
141         asm volatile ("                                 \
142         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
143         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
144         r0 = r2;                                        \
145         r0 += 8;                                        \
146         if r3 >= r0 goto l0_%=;                         \
147         r0 = *(u8*)(r2 + 0);                            \
148         r0 = 1;                                         \
149         exit;                                           \
150 l0_%=:  r0 = 0;                                         \
151         exit;                                           \
152 "       :
153         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
154           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
155         : __clobber_all);
156 }
157 
158 SEC("tc")
159 __description("direct packet access: test7 (pkt_end >= reg, both accesses)")
160 __failure __msg("invalid access to packet")
161 __naked void pkt_end_reg_both_accesses(void)
162 {
163         asm volatile ("                                 \
164         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
165         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
166         r0 = r2;                                        \
167         r0 += 8;                                        \
168         if r3 >= r0 goto l0_%=;                         \
169         r0 = *(u8*)(r2 + 0);                            \
170         r0 = 1;                                         \
171         exit;                                           \
172 l0_%=:  r0 = *(u8*)(r2 + 0);                            \
173         r0 = 0;                                         \
174         exit;                                           \
175 "       :
176         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
177           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
178         : __clobber_all);
179 }
180 
181 SEC("tc")
182 __description("direct packet access: test8 (double test, variant 1)")
183 __success __retval(0)
184 __naked void test8_double_test_variant_1(void)
185 {
186         asm volatile ("                                 \
187         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
188         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
189         r0 = r2;                                        \
190         r0 += 8;                                        \
191         if r3 >= r0 goto l0_%=;                         \
192         if r0 > r3 goto l1_%=;                          \
193         r0 = *(u8*)(r2 + 0);                            \
194 l1_%=:  r0 = 1;                                         \
195         exit;                                           \
196 l0_%=:  r0 = *(u8*)(r2 + 0);                            \
197         r0 = 0;                                         \
198         exit;                                           \
199 "       :
200         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
201           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
202         : __clobber_all);
203 }
204 
205 SEC("tc")
206 __description("direct packet access: test9 (double test, variant 2)")
207 __success __retval(0)
208 __naked void test9_double_test_variant_2(void)
209 {
210         asm volatile ("                                 \
211         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
212         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
213         r0 = r2;                                        \
214         r0 += 8;                                        \
215         if r3 >= r0 goto l0_%=;                         \
216         r0 = 1;                                         \
217         exit;                                           \
218 l0_%=:  if r0 > r3 goto l1_%=;                          \
219         r0 = *(u8*)(r2 + 0);                            \
220 l1_%=:  r0 = *(u8*)(r2 + 0);                            \
221         r0 = 0;                                         \
222         exit;                                           \
223 "       :
224         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
225           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
226         : __clobber_all);
227 }
228 
229 SEC("tc")
230 __description("direct packet access: test10 (write invalid)")
231 __failure __msg("invalid access to packet")
232 __naked void packet_access_test10_write_invalid(void)
233 {
234         asm volatile ("                                 \
235         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
236         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
237         r0 = r2;                                        \
238         r0 += 8;                                        \
239         if r0 > r3 goto l0_%=;                          \
240         r0 = 0;                                         \
241         exit;                                           \
242 l0_%=:  *(u8*)(r2 + 0) = r2;                            \
243         r0 = 0;                                         \
244         exit;                                           \
245 "       :
246         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
247           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
248         : __clobber_all);
249 }
250 
251 SEC("tc")
252 __description("direct packet access: test11 (shift, good access)")
253 __success __retval(1)
254 __naked void access_test11_shift_good_access(void)
255 {
256         asm volatile ("                                 \
257         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
258         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
259         r0 = r2;                                        \
260         r0 += 22;                                       \
261         if r0 > r3 goto l0_%=;                          \
262         r3 = 144;                                       \
263         r5 = r3;                                        \
264         r5 += 23;                                       \
265         r5 >>= 3;                                       \
266         r6 = r2;                                        \
267         r6 += r5;                                       \
268         r0 = 1;                                         \
269         exit;                                           \
270 l0_%=:  r0 = 0;                                         \
271         exit;                                           \
272 "       :
273         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
274           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
275         : __clobber_all);
276 }
277 
278 SEC("tc")
279 __description("direct packet access: test12 (and, good access)")
280 __success __retval(1)
281 __naked void access_test12_and_good_access(void)
282 {
283         asm volatile ("                                 \
284         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
285         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
286         r0 = r2;                                        \
287         r0 += 22;                                       \
288         if r0 > r3 goto l0_%=;                          \
289         r3 = 144;                                       \
290         r5 = r3;                                        \
291         r5 += 23;                                       \
292         r5 &= 15;                                       \
293         r6 = r2;                                        \
294         r6 += r5;                                       \
295         r0 = 1;                                         \
296         exit;                                           \
297 l0_%=:  r0 = 0;                                         \
298         exit;                                           \
299 "       :
300         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
301           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
302         : __clobber_all);
303 }
304 
305 SEC("tc")
306 __description("direct packet access: test13 (branches, good access)")
307 __success __retval(1)
308 __naked void access_test13_branches_good_access(void)
309 {
310         asm volatile ("                                 \
311         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
312         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
313         r0 = r2;                                        \
314         r0 += 22;                                       \
315         if r0 > r3 goto l0_%=;                          \
316         r3 = *(u32*)(r1 + %[__sk_buff_mark]);           \
317         r4 = 1;                                         \
318         if r3 > r4 goto l1_%=;                          \
319         r3 = 14;                                        \
320         goto l2_%=;                                     \
321 l1_%=:  r3 = 24;                                        \
322 l2_%=:  r5 = r3;                                        \
323         r5 += 23;                                       \
324         r5 &= 15;                                       \
325         r6 = r2;                                        \
326         r6 += r5;                                       \
327         r0 = 1;                                         \
328         exit;                                           \
329 l0_%=:  r0 = 0;                                         \
330         exit;                                           \
331 "       :
332         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
333           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),
334           __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))
335         : __clobber_all);
336 }
337 
338 SEC("tc")
339 __description("direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)")
340 __success __retval(1)
341 __naked void _0_const_imm_good_access(void)
342 {
343         asm volatile ("                                 \
344         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
345         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
346         r0 = r2;                                        \
347         r0 += 22;                                       \
348         if r0 > r3 goto l0_%=;                          \
349         r5 = 12;                                        \
350         r5 >>= 4;                                       \
351         r6 = r2;                                        \
352         r6 += r5;                                       \
353         r0 = *(u8*)(r6 + 0);                            \
354         r0 = 1;                                         \
355         exit;                                           \
356 l0_%=:  r0 = 0;                                         \
357         exit;                                           \
358 "       :
359         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
360           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
361         : __clobber_all);
362 }
363 
364 SEC("tc")
365 __description("direct packet access: test15 (spill with xadd)")
366 __failure __msg("R2 invalid mem access 'scalar'")
367 __flag(BPF_F_ANY_ALIGNMENT)
368 __naked void access_test15_spill_with_xadd(void)
369 {
370         asm volatile ("                                 \
371         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
372         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
373         r0 = r2;                                        \
374         r0 += 8;                                        \
375         if r0 > r3 goto l0_%=;                          \
376         r5 = 4096;                                      \
377         r4 = r10;                                       \
378         r4 += -8;                                       \
379         *(u64*)(r4 + 0) = r2;                           \
380         lock *(u64 *)(r4 + 0) += r5;                    \
381         r2 = *(u64*)(r4 + 0);                           \
382         *(u32*)(r2 + 0) = r5;                           \
383         r0 = 0;                                         \
384 l0_%=:  exit;                                           \
385 "       :
386         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
387           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
388         : __clobber_all);
389 }
390 
391 SEC("tc")
392 __description("direct packet access: test16 (arith on data_end)")
393 __failure __msg("R3 pointer arithmetic on pkt_end")
394 __naked void test16_arith_on_data_end(void)
395 {
396         asm volatile ("                                 \
397         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
398         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
399         r0 = r2;                                        \
400         r0 += 8;                                        \
401         r3 += 16;                                       \
402         if r0 > r3 goto l0_%=;                          \
403         *(u8*)(r2 + 0) = r2;                            \
404 l0_%=:  r0 = 0;                                         \
405         exit;                                           \
406 "       :
407         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
408           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
409         : __clobber_all);
410 }
411 
412 SEC("tc")
413 __description("direct packet access: test17 (pruning, alignment)")
414 __failure __msg("misaligned packet access off 2+0+15+-4 size 4")
415 __flag(BPF_F_STRICT_ALIGNMENT)
416 __naked void packet_access_test17_pruning_alignment(void)
417 {
418         asm volatile ("                                 \
419         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
420         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
421         r7 = *(u32*)(r1 + %[__sk_buff_mark]);           \
422         r0 = r2;                                        \
423         r0 += 14;                                       \
424         if r7 > 1 goto l0_%=;                           \
425 l2_%=:  if r0 > r3 goto l1_%=;                          \
426         *(u32*)(r0 - 4) = r0;                           \
427 l1_%=:  r0 = 0;                                         \
428         exit;                                           \
429 l0_%=:  r0 += 1;                                        \
430         goto l2_%=;                                     \
431 "       :
432         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
433           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),
434           __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))
435         : __clobber_all);
436 }
437 
438 SEC("tc")
439 __description("direct packet access: test18 (imm += pkt_ptr, 1)")
440 __success __retval(0)
441 __naked void test18_imm_pkt_ptr_1(void)
442 {
443         asm volatile ("                                 \
444         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
445         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
446         r0 = 8;                                         \
447         r0 += r2;                                       \
448         if r0 > r3 goto l0_%=;                          \
449         *(u8*)(r2 + 0) = r2;                            \
450 l0_%=:  r0 = 0;                                         \
451         exit;                                           \
452 "       :
453         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
454           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
455         : __clobber_all);
456 }
457 
458 SEC("tc")
459 __description("direct packet access: test19 (imm += pkt_ptr, 2)")
460 __success __retval(0)
461 __naked void test19_imm_pkt_ptr_2(void)
462 {
463         asm volatile ("                                 \
464         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
465         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
466         r0 = r2;                                        \
467         r0 += 8;                                        \
468         if r0 > r3 goto l0_%=;                          \
469         r4 = 4;                                         \
470         r4 += r2;                                       \
471         *(u8*)(r4 + 0) = r4;                            \
472 l0_%=:  r0 = 0;                                         \
473         exit;                                           \
474 "       :
475         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
476           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
477         : __clobber_all);
478 }
479 
480 SEC("tc")
481 __description("direct packet access: test20 (x += pkt_ptr, 1)")
482 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
483 __naked void test20_x_pkt_ptr_1(void)
484 {
485         asm volatile ("                                 \
486         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
487         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
488         r0 = 0xffffffff;                                \
489         *(u64*)(r10 - 8) = r0;                          \
490         r0 = *(u64*)(r10 - 8);                          \
491         r0 &= 0x7fff;                                   \
492         r4 = r0;                                        \
493         r4 += r2;                                       \
494         r5 = r4;                                        \
495         r4 += %[__imm_0];                               \
496         if r4 > r3 goto l0_%=;                          \
497         *(u64*)(r5 + 0) = r4;                           \
498 l0_%=:  r0 = 0;                                         \
499         exit;                                           \
500 "       :
501         : __imm_const(__imm_0, 0x7fff - 1),
502           __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
503           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
504         : __clobber_all);
505 }
506 
507 SEC("tc")
508 __description("direct packet access: test21 (x += pkt_ptr, 2)")
509 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
510 __naked void test21_x_pkt_ptr_2(void)
511 {
512         asm volatile ("                                 \
513         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
514         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
515         r0 = r2;                                        \
516         r0 += 8;                                        \
517         if r0 > r3 goto l0_%=;                          \
518         r4 = 0xffffffff;                                \
519         *(u64*)(r10 - 8) = r4;                          \
520         r4 = *(u64*)(r10 - 8);                          \
521         r4 &= 0x7fff;                                   \
522         r4 += r2;                                       \
523         r5 = r4;                                        \
524         r4 += %[__imm_0];                               \
525         if r4 > r3 goto l0_%=;                          \
526         *(u64*)(r5 + 0) = r4;                           \
527 l0_%=:  r0 = 0;                                         \
528         exit;                                           \
529 "       :
530         : __imm_const(__imm_0, 0x7fff - 1),
531           __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
532           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
533         : __clobber_all);
534 }
535 
536 SEC("tc")
537 __description("direct packet access: test22 (x += pkt_ptr, 3)")
538 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
539 __naked void test22_x_pkt_ptr_3(void)
540 {
541         asm volatile ("                                 \
542         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
543         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
544         r0 = r2;                                        \
545         r0 += 8;                                        \
546         *(u64*)(r10 - 8) = r2;                          \
547         *(u64*)(r10 - 16) = r3;                         \
548         r3 = *(u64*)(r10 - 16);                         \
549         if r0 > r3 goto l0_%=;                          \
550         r2 = *(u64*)(r10 - 8);                          \
551         r4 = 0xffffffff;                                \
552         lock *(u64 *)(r10 - 8) += r4;                   \
553         r4 = *(u64*)(r10 - 8);                          \
554         r4 >>= 49;                                      \
555         r4 += r2;                                       \
556         r0 = r4;                                        \
557         r0 += 2;                                        \
558         if r0 > r3 goto l0_%=;                          \
559         r2 = 1;                                         \
560         *(u16*)(r4 + 0) = r2;                           \
561 l0_%=:  r0 = 0;                                         \
562         exit;                                           \
563 "       :
564         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
565           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
566         : __clobber_all);
567 }
568 
569 SEC("tc")
570 __description("direct packet access: test23 (x += pkt_ptr, 4)")
571 __failure __msg("invalid access to packet, off=0 size=8, R5(id=3,off=0,r=0)")
572 __flag(BPF_F_ANY_ALIGNMENT)
573 __naked void test23_x_pkt_ptr_4(void)
574 {
575         asm volatile ("                                 \
576         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
577         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
578         r0 = *(u32*)(r1 + %[__sk_buff_mark]);           \
579         *(u64*)(r10 - 8) = r0;                          \
580         r0 = *(u64*)(r10 - 8);                          \
581         r0 &= 0xffff;                                   \
582         r4 = r0;                                        \
583         r0 = 31;                                        \
584         r0 += r4;                                       \
585         r0 += r2;                                       \
586         r5 = r0;                                        \
587         r0 += %[__imm_0];                               \
588         if r0 > r3 goto l0_%=;                          \
589         *(u64*)(r5 + 0) = r0;                           \
590 l0_%=:  r0 = 0;                                         \
591         exit;                                           \
592 "       :
593         : __imm_const(__imm_0, 0xffff - 1),
594           __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
595           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),
596           __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))
597         : __clobber_all);
598 }
599 
600 SEC("tc")
601 __description("direct packet access: test24 (x += pkt_ptr, 5)")
602 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
603 __naked void test24_x_pkt_ptr_5(void)
604 {
605         asm volatile ("                                 \
606         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
607         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
608         r0 = 0xffffffff;                                \
609         *(u64*)(r10 - 8) = r0;                          \
610         r0 = *(u64*)(r10 - 8);                          \
611         r0 &= 0xff;                                     \
612         r4 = r0;                                        \
613         r0 = 64;                                        \
614         r0 += r4;                                       \
615         r0 += r2;                                       \
616         r5 = r0;                                        \
617         r0 += %[__imm_0];                               \
618         if r0 > r3 goto l0_%=;                          \
619         *(u64*)(r5 + 0) = r0;                           \
620 l0_%=:  r0 = 0;                                         \
621         exit;                                           \
622 "       :
623         : __imm_const(__imm_0, 0x7fff - 1),
624           __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
625           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
626         : __clobber_all);
627 }
628 
629 SEC("tc")
630 __description("direct packet access: test25 (marking on <, good access)")
631 __success __retval(0)
632 __naked void test25_marking_on_good_access(void)
633 {
634         asm volatile ("                                 \
635         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
636         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
637         r0 = r2;                                        \
638         r0 += 8;                                        \
639         if r0 < r3 goto l0_%=;                          \
640 l1_%=:  r0 = 0;                                         \
641         exit;                                           \
642 l0_%=:  r0 = *(u8*)(r2 + 0);                            \
643         goto l1_%=;                                     \
644 "       :
645         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
646           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
647         : __clobber_all);
648 }
649 
650 SEC("tc")
651 __description("direct packet access: test26 (marking on <, bad access)")
652 __failure __msg("invalid access to packet")
653 __naked void test26_marking_on_bad_access(void)
654 {
655         asm volatile ("                                 \
656         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
657         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
658         r0 = r2;                                        \
659         r0 += 8;                                        \
660         if r0 < r3 goto l0_%=;                          \
661         r0 = *(u8*)(r2 + 0);                            \
662 l1_%=:  r0 = 0;                                         \
663         exit;                                           \
664 l0_%=:  goto l1_%=;                                     \
665 "       :
666         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
667           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
668         : __clobber_all);
669 }
670 
671 SEC("tc")
672 __description("direct packet access: test27 (marking on <=, good access)")
673 __success __retval(1)
674 __naked void test27_marking_on_good_access(void)
675 {
676         asm volatile ("                                 \
677         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
678         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
679         r0 = r2;                                        \
680         r0 += 8;                                        \
681         if r3 <= r0 goto l0_%=;                         \
682         r0 = *(u8*)(r2 + 0);                            \
683 l0_%=:  r0 = 1;                                         \
684         exit;                                           \
685 "       :
686         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
687           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
688         : __clobber_all);
689 }
690 
691 SEC("tc")
692 __description("direct packet access: test28 (marking on <=, bad access)")
693 __failure __msg("invalid access to packet")
694 __naked void test28_marking_on_bad_access(void)
695 {
696         asm volatile ("                                 \
697         r2 = *(u32*)(r1 + %[__sk_buff_data]);           \
698         r3 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
699         r0 = r2;                                        \
700         r0 += 8;                                        \
701         if r3 <= r0 goto l0_%=;                         \
702 l1_%=:  r0 = 1;                                         \
703         exit;                                           \
704 l0_%=:  r0 = *(u8*)(r2 + 0);                            \
705         goto l1_%=;                                     \
706 "       :
707         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
708           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
709         : __clobber_all);
710 }
711 
712 SEC("tc")
713 __description("direct packet access: test29 (reg > pkt_end in subprog)")
714 __success __retval(0)
715 __naked void reg_pkt_end_in_subprog(void)
716 {
717         asm volatile ("                                 \
718         r6 = *(u32*)(r1 + %[__sk_buff_data]);           \
719         r2 = *(u32*)(r1 + %[__sk_buff_data_end]);       \
720         r3 = r6;                                        \
721         r3 += 8;                                        \
722         call reg_pkt_end_in_subprog__1;                 \
723         if r0 == 0 goto l0_%=;                          \
724         r0 = *(u8*)(r6 + 0);                            \
725 l0_%=:  r0 = 0;                                         \
726         exit;                                           \
727 "       :
728         : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
729           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
730         : __clobber_all);
731 }
732 
733 static __naked __noinline __attribute__((used))
734 void reg_pkt_end_in_subprog__1(void)
735 {
736         asm volatile ("                                 \
737         r0 = 0;                                         \
738         if r3 > r2 goto l0_%=;                          \
739         r0 = 1;                                         \
740 l0_%=:  exit;                                           \
741 "       ::: __clobber_all);
742 }
743 
744 SEC("tc")
745 __description("direct packet access: test30 (check_id() in regsafe(), bad access)")
746 __failure __msg("invalid access to packet, off=0 size=1, R2")
747 __flag(BPF_F_TEST_STATE_FREQ)
748 __naked void id_in_regsafe_bad_access(void)
749 {
750         asm volatile ("                                 \
751         /* r9 = ctx */                                  \
752         r9 = r1;                                        \
753         /* r7 = ktime_get_ns() */                       \
754         call %[bpf_ktime_get_ns];                       \
755         r7 = r0;                                        \
756         /* r6 = ktime_get_ns() */                       \
757         call %[bpf_ktime_get_ns];                       \
758         r6 = r0;                                        \
759         /* r2 = ctx->data                               \
760          * r3 = ctx->data                               \
761          * r4 = ctx->data_end                           \
762          */                                             \
763         r2 = *(u32*)(r9 + %[__sk_buff_data]);           \
764         r3 = *(u32*)(r9 + %[__sk_buff_data]);           \
765         r4 = *(u32*)(r9 + %[__sk_buff_data_end]);       \
766         /* if r6 > 100 goto exit                        \
767          * if r7 > 100 goto exit                        \
768          */                                             \
769         if r6 > 100 goto l0_%=;                         \
770         if r7 > 100 goto l0_%=;                         \
771         /* r2 += r6              ; this forces assignment of ID to r2\
772          * r2 += 1               ; get some fixed off for r2\
773          * r3 += r7              ; this forces assignment of ID to r3\
774          * r3 += 1               ; get some fixed off for r3\
775          */                                             \
776         r2 += r6;                                       \
777         r2 += 1;                                        \
778         r3 += r7;                                       \
779         r3 += 1;                                        \
780         /* if r6 > r7 goto +1    ; no new information about the state is derived from\
781          *                       ; this check, thus produced verifier states differ\
782          *                       ; only in 'insn_idx'   \
783          * r2 = r3               ; optionally share ID between r2 and r3\
784          */                                             \
785         if r6 != r7 goto l1_%=;                         \
786         r2 = r3;                                        \
787 l1_%=:  /* if r3 > ctx->data_end goto exit */           \
788         if r3 > r4 goto l0_%=;                          \
789         /* r5 = *(u8 *) (r2 - 1) ; access packet memory using r2,\
790          *                       ; this is not always safe\
791          */                                             \
792         r5 = *(u8*)(r2 - 1);                            \
793 l0_%=:  /* exit(0) */                                   \
794         r0 = 0;                                         \
795         exit;                                           \
796 "       :
797         : __imm(bpf_ktime_get_ns),
798           __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
799           __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
800         : __clobber_all);
801 }
802 
803 char _license[] SEC("license") = "GPL";
804 

~ [ 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