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