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 
9 struct {
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 
16 struct {
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 
23 struct {
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 
30 SEC("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 
49 SEC("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 
69 SEC("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 
88 SEC("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 
108 SEC("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 
129 SEC("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 
149 SEC("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 
169 SEC("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 
188 SEC("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 
208 SEC("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 
227 SEC("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 
247 SEC("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 
268 SEC("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 
288 SEC("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 
308 char _license[] SEC("license") = "GPL";
309