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 | |
8 | struct { |
9 | __uint(type, BPF_MAP_TYPE_RINGBUF); |
10 | __uint(max_entries, 4096); |
11 | } map_ringbuf SEC(".maps" ); |
12 | |
13 | SEC("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]; \ |
44 | l0_%=: 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 | |
53 | SEC("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]; \ |
84 | l0_%=: 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 | |
93 | SEC("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; \ |
111 | l0_%=: /* 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 | |
131 | char _license[] SEC("license" ) = "GPL" ; |
132 | |