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