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
ringbuf_invalid_reservation_offset_1(void)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
ringbuf_invalid_reservation_offset_2(void)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)
passing_rb_mem_to_helpers(void)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