1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/cgroup_storage.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include "../../../include/linux/filter.h"
7#include "bpf_misc.h"
8
9struct {
10	__uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
11	__uint(max_entries, 0);
12	__type(key, struct bpf_cgroup_storage_key);
13	__type(value, char[TEST_DATA_LEN]);
14} cgroup_storage SEC(".maps");
15
16struct {
17	__uint(type, BPF_MAP_TYPE_HASH);
18	__uint(max_entries, 1);
19	__type(key, long long);
20	__type(value, long long);
21} map_hash_8b SEC(".maps");
22
23struct {
24	__uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE);
25	__uint(max_entries, 0);
26	__type(key, struct bpf_cgroup_storage_key);
27	__type(value, char[64]);
28} percpu_cgroup_storage SEC(".maps");
29
30SEC("cgroup/skb")
31__description("valid cgroup storage access")
32__success __success_unpriv __retval(0)
33__naked void valid_cgroup_storage_access(void)
34{
35	asm volatile ("					\
36	r2 = 0;						\
37	r1 = %[cgroup_storage] ll;			\
38	call %[bpf_get_local_storage];			\
39	r1 = *(u32*)(r0 + 0);				\
40	r0 = r1;					\
41	r0 &= 1;					\
42	exit;						\
43"	:
44	: __imm(bpf_get_local_storage),
45	  __imm_addr(cgroup_storage)
46	: __clobber_all);
47}
48
49SEC("cgroup/skb")
50__description("invalid cgroup storage access 1")
51__failure __msg("cannot pass map_type 1 into func bpf_get_local_storage")
52__failure_unpriv
53__naked void invalid_cgroup_storage_access_1(void)
54{
55	asm volatile ("					\
56	r2 = 0;						\
57	r1 = %[map_hash_8b] ll;				\
58	call %[bpf_get_local_storage];			\
59	r1 = *(u32*)(r0 + 0);				\
60	r0 = r1;					\
61	r0 &= 1;					\
62	exit;						\
63"	:
64	: __imm(bpf_get_local_storage),
65	  __imm_addr(map_hash_8b)
66	: __clobber_all);
67}
68
69SEC("cgroup/skb")
70__description("invalid cgroup storage access 2")
71__failure __msg("fd 1 is not pointing to valid bpf_map")
72__failure_unpriv
73__naked void invalid_cgroup_storage_access_2(void)
74{
75	asm volatile ("					\
76	r2 = 0;						\
77	.8byte %[ld_map_fd];				\
78	.8byte 0;					\
79	call %[bpf_get_local_storage];			\
80	r0 &= 1;					\
81	exit;						\
82"	:
83	: __imm(bpf_get_local_storage),
84	  __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1))
85	: __clobber_all);
86}
87
88SEC("cgroup/skb")
89__description("invalid cgroup storage access 3")
90__failure __msg("invalid access to map value, value_size=64 off=256 size=4")
91__failure_unpriv
92__naked void invalid_cgroup_storage_access_3(void)
93{
94	asm volatile ("					\
95	r2 = 0;						\
96	r1 = %[cgroup_storage] ll;			\
97	call %[bpf_get_local_storage];			\
98	r1 = *(u32*)(r0 + 256);				\
99	r1 += 1;					\
100	r0 = 0;						\
101	exit;						\
102"	:
103	: __imm(bpf_get_local_storage),
104	  __imm_addr(cgroup_storage)
105	: __clobber_all);
106}
107
108SEC("cgroup/skb")
109__description("invalid cgroup storage access 4")
110__failure __msg("invalid access to map value, value_size=64 off=-2 size=4")
111__failure_unpriv
112__flag(BPF_F_ANY_ALIGNMENT)
113__naked void invalid_cgroup_storage_access_4(void)
114{
115	asm volatile ("					\
116	r2 = 0;						\
117	r1 = %[cgroup_storage] ll;			\
118	call %[bpf_get_local_storage];			\
119	r1 = *(u32*)(r0 - 2);				\
120	r0 = r1;					\
121	r1 += 1;					\
122	exit;						\
123"	:
124	: __imm(bpf_get_local_storage),
125	  __imm_addr(cgroup_storage)
126	: __clobber_all);
127}
128
129SEC("cgroup/skb")
130__description("invalid cgroup storage access 5")
131__failure __msg("get_local_storage() doesn't support non-zero flags")
132__failure_unpriv
133__naked void invalid_cgroup_storage_access_5(void)
134{
135	asm volatile ("					\
136	r2 = 7;						\
137	r1 = %[cgroup_storage] ll;			\
138	call %[bpf_get_local_storage];			\
139	r1 = *(u32*)(r0 + 0);				\
140	r0 = r1;					\
141	r0 &= 1;					\
142	exit;						\
143"	:
144	: __imm(bpf_get_local_storage),
145	  __imm_addr(cgroup_storage)
146	: __clobber_all);
147}
148
149SEC("cgroup/skb")
150__description("invalid cgroup storage access 6")
151__failure __msg("get_local_storage() doesn't support non-zero flags")
152__msg_unpriv("R2 leaks addr into helper function")
153__naked void invalid_cgroup_storage_access_6(void)
154{
155	asm volatile ("					\
156	r2 = r1;					\
157	r1 = %[cgroup_storage] ll;			\
158	call %[bpf_get_local_storage];			\
159	r1 = *(u32*)(r0 + 0);				\
160	r0 = r1;					\
161	r0 &= 1;					\
162	exit;						\
163"	:
164	: __imm(bpf_get_local_storage),
165	  __imm_addr(cgroup_storage)
166	: __clobber_all);
167}
168
169SEC("cgroup/skb")
170__description("valid per-cpu cgroup storage access")
171__success __success_unpriv __retval(0)
172__naked void per_cpu_cgroup_storage_access(void)
173{
174	asm volatile ("					\
175	r2 = 0;						\
176	r1 = %[percpu_cgroup_storage] ll;		\
177	call %[bpf_get_local_storage];			\
178	r1 = *(u32*)(r0 + 0);				\
179	r0 = r1;					\
180	r0 &= 1;					\
181	exit;						\
182"	:
183	: __imm(bpf_get_local_storage),
184	  __imm_addr(percpu_cgroup_storage)
185	: __clobber_all);
186}
187
188SEC("cgroup/skb")
189__description("invalid per-cpu cgroup storage access 1")
190__failure __msg("cannot pass map_type 1 into func bpf_get_local_storage")
191__failure_unpriv
192__naked void cpu_cgroup_storage_access_1(void)
193{
194	asm volatile ("					\
195	r2 = 0;						\
196	r1 = %[map_hash_8b] ll;				\
197	call %[bpf_get_local_storage];			\
198	r1 = *(u32*)(r0 + 0);				\
199	r0 = r1;					\
200	r0 &= 1;					\
201	exit;						\
202"	:
203	: __imm(bpf_get_local_storage),
204	  __imm_addr(map_hash_8b)
205	: __clobber_all);
206}
207
208SEC("cgroup/skb")
209__description("invalid per-cpu cgroup storage access 2")
210__failure __msg("fd 1 is not pointing to valid bpf_map")
211__failure_unpriv
212__naked void cpu_cgroup_storage_access_2(void)
213{
214	asm volatile ("					\
215	r2 = 0;						\
216	.8byte %[ld_map_fd];				\
217	.8byte 0;					\
218	call %[bpf_get_local_storage];			\
219	r0 &= 1;					\
220	exit;						\
221"	:
222	: __imm(bpf_get_local_storage),
223	  __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1))
224	: __clobber_all);
225}
226
227SEC("cgroup/skb")
228__description("invalid per-cpu cgroup storage access 3")
229__failure __msg("invalid access to map value, value_size=64 off=256 size=4")
230__failure_unpriv
231__naked void cpu_cgroup_storage_access_3(void)
232{
233	asm volatile ("					\
234	r2 = 0;						\
235	r1 = %[percpu_cgroup_storage] ll;		\
236	call %[bpf_get_local_storage];			\
237	r1 = *(u32*)(r0 + 256);				\
238	r1 += 1;					\
239	r0 = 0;						\
240	exit;						\
241"	:
242	: __imm(bpf_get_local_storage),
243	  __imm_addr(percpu_cgroup_storage)
244	: __clobber_all);
245}
246
247SEC("cgroup/skb")
248__description("invalid per-cpu cgroup storage access 4")
249__failure __msg("invalid access to map value, value_size=64 off=-2 size=4")
250__failure_unpriv
251__flag(BPF_F_ANY_ALIGNMENT)
252__naked void cpu_cgroup_storage_access_4(void)
253{
254	asm volatile ("					\
255	r2 = 0;						\
256	r1 = %[cgroup_storage] ll;			\
257	call %[bpf_get_local_storage];			\
258	r1 = *(u32*)(r0 - 2);				\
259	r0 = r1;					\
260	r1 += 1;					\
261	exit;						\
262"	:
263	: __imm(bpf_get_local_storage),
264	  __imm_addr(cgroup_storage)
265	: __clobber_all);
266}
267
268SEC("cgroup/skb")
269__description("invalid per-cpu cgroup storage access 5")
270__failure __msg("get_local_storage() doesn't support non-zero flags")
271__failure_unpriv
272__naked void cpu_cgroup_storage_access_5(void)
273{
274	asm volatile ("					\
275	r2 = 7;						\
276	r1 = %[percpu_cgroup_storage] ll;		\
277	call %[bpf_get_local_storage];			\
278	r1 = *(u32*)(r0 + 0);				\
279	r0 = r1;					\
280	r0 &= 1;					\
281	exit;						\
282"	:
283	: __imm(bpf_get_local_storage),
284	  __imm_addr(percpu_cgroup_storage)
285	: __clobber_all);
286}
287
288SEC("cgroup/skb")
289__description("invalid per-cpu cgroup storage access 6")
290__failure __msg("get_local_storage() doesn't support non-zero flags")
291__msg_unpriv("R2 leaks addr into helper function")
292__naked void cpu_cgroup_storage_access_6(void)
293{
294	asm volatile ("					\
295	r2 = r1;					\
296	r1 = %[percpu_cgroup_storage] ll;		\
297	call %[bpf_get_local_storage];			\
298	r1 = *(u32*)(r0 + 0);				\
299	r0 = r1;					\
300	r0 &= 1;					\
301	exit;						\
302"	:
303	: __imm(bpf_get_local_storage),
304	  __imm_addr(percpu_cgroup_storage)
305	: __clobber_all);
306}
307
308char _license[] SEC("license") = "GPL";
309