1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/ringbuf.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include "bpf_misc.h"
7
8struct {
9 __uint(type, BPF_MAP_TYPE_RINGBUF);
10 __uint(max_entries, 4096);
11} map_ringbuf SEC(".maps");
12
13SEC("socket")
14__description("ringbuf: invalid reservation offset 1")
15__failure __msg("R1 must have zero offset when passed to release func")
16__failure_unpriv
17__naked void ringbuf_invalid_reservation_offset_1(void)
18{
19 asm volatile (" \
20 /* reserve 8 byte ringbuf memory */ \
21 r1 = 0; \
22 *(u64*)(r10 - 8) = r1; \
23 r1 = %[map_ringbuf] ll; \
24 r2 = 8; \
25 r3 = 0; \
26 call %[bpf_ringbuf_reserve]; \
27 /* store a pointer to the reserved memory in R6 */\
28 r6 = r0; \
29 /* check whether the reservation was successful */\
30 if r0 == 0 goto l0_%=; \
31 /* spill R6(mem) into the stack */ \
32 *(u64*)(r10 - 8) = r6; \
33 /* fill it back in R7 */ \
34 r7 = *(u64*)(r10 - 8); \
35 /* should be able to access *(R7) = 0 */ \
36 r1 = 0; \
37 *(u64*)(r7 + 0) = r1; \
38 /* submit the reserved ringbuf memory */ \
39 r1 = r7; \
40 /* add invalid offset to reserved ringbuf memory */\
41 r1 += 0xcafe; \
42 r2 = 0; \
43 call %[bpf_ringbuf_submit]; \
44l0_%=: r0 = 0; \
45 exit; \
46" :
47 : __imm(bpf_ringbuf_reserve),
48 __imm(bpf_ringbuf_submit),
49 __imm_addr(map_ringbuf)
50 : __clobber_all);
51}
52
53SEC("socket")
54__description("ringbuf: invalid reservation offset 2")
55__failure __msg("R7 min value is outside of the allowed memory range")
56__failure_unpriv
57__naked void ringbuf_invalid_reservation_offset_2(void)
58{
59 asm volatile (" \
60 /* reserve 8 byte ringbuf memory */ \
61 r1 = 0; \
62 *(u64*)(r10 - 8) = r1; \
63 r1 = %[map_ringbuf] ll; \
64 r2 = 8; \
65 r3 = 0; \
66 call %[bpf_ringbuf_reserve]; \
67 /* store a pointer to the reserved memory in R6 */\
68 r6 = r0; \
69 /* check whether the reservation was successful */\
70 if r0 == 0 goto l0_%=; \
71 /* spill R6(mem) into the stack */ \
72 *(u64*)(r10 - 8) = r6; \
73 /* fill it back in R7 */ \
74 r7 = *(u64*)(r10 - 8); \
75 /* add invalid offset to reserved ringbuf memory */\
76 r7 += 0xcafe; \
77 /* should be able to access *(R7) = 0 */ \
78 r1 = 0; \
79 *(u64*)(r7 + 0) = r1; \
80 /* submit the reserved ringbuf memory */ \
81 r1 = r7; \
82 r2 = 0; \
83 call %[bpf_ringbuf_submit]; \
84l0_%=: r0 = 0; \
85 exit; \
86" :
87 : __imm(bpf_ringbuf_reserve),
88 __imm(bpf_ringbuf_submit),
89 __imm_addr(map_ringbuf)
90 : __clobber_all);
91}
92
93SEC("xdp")
94__description("ringbuf: check passing rb mem to helpers")
95__success __retval(0)
96__naked void passing_rb_mem_to_helpers(void)
97{
98 asm volatile (" \
99 r6 = r1; \
100 /* reserve 8 byte ringbuf memory */ \
101 r1 = 0; \
102 *(u64*)(r10 - 8) = r1; \
103 r1 = %[map_ringbuf] ll; \
104 r2 = 8; \
105 r3 = 0; \
106 call %[bpf_ringbuf_reserve]; \
107 r7 = r0; \
108 /* check whether the reservation was successful */\
109 if r0 != 0 goto l0_%=; \
110 exit; \
111l0_%=: /* pass allocated ring buffer memory to fib lookup */\
112 r1 = r6; \
113 r2 = r0; \
114 r3 = 8; \
115 r4 = 0; \
116 call %[bpf_fib_lookup]; \
117 /* submit the ringbuf memory */ \
118 r1 = r7; \
119 r2 = 0; \
120 call %[bpf_ringbuf_submit]; \
121 r0 = 0; \
122 exit; \
123" :
124 : __imm(bpf_fib_lookup),
125 __imm(bpf_ringbuf_reserve),
126 __imm(bpf_ringbuf_submit),
127 __imm_addr(map_ringbuf)
128 : __clobber_all);
129}
130
131char _license[] SEC("license") = "GPL";
132

source code of linux/tools/testing/selftests/bpf/progs/verifier_ringbuf.c