1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/ctx_sk_msg.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 SEC("sk_msg")
9 __description("valid access family in SK_MSG")
10 __success
access_family_in_sk_msg(void)11 __naked void access_family_in_sk_msg(void)
12 {
13 	asm volatile ("					\
14 	r0 = *(u32*)(r1 + %[sk_msg_md_family]);		\
15 	exit;						\
16 "	:
17 	: __imm_const(sk_msg_md_family, offsetof(struct sk_msg_md, family))
18 	: __clobber_all);
19 }
20 
21 SEC("sk_msg")
22 __description("valid access remote_ip4 in SK_MSG")
23 __success
remote_ip4_in_sk_msg(void)24 __naked void remote_ip4_in_sk_msg(void)
25 {
26 	asm volatile ("					\
27 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip4]);	\
28 	exit;						\
29 "	:
30 	: __imm_const(sk_msg_md_remote_ip4, offsetof(struct sk_msg_md, remote_ip4))
31 	: __clobber_all);
32 }
33 
34 SEC("sk_msg")
35 __description("valid access local_ip4 in SK_MSG")
36 __success
local_ip4_in_sk_msg(void)37 __naked void local_ip4_in_sk_msg(void)
38 {
39 	asm volatile ("					\
40 	r0 = *(u32*)(r1 + %[sk_msg_md_local_ip4]);	\
41 	exit;						\
42 "	:
43 	: __imm_const(sk_msg_md_local_ip4, offsetof(struct sk_msg_md, local_ip4))
44 	: __clobber_all);
45 }
46 
47 SEC("sk_msg")
48 __description("valid access remote_port in SK_MSG")
49 __success
remote_port_in_sk_msg(void)50 __naked void remote_port_in_sk_msg(void)
51 {
52 	asm volatile ("					\
53 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_port]);	\
54 	exit;						\
55 "	:
56 	: __imm_const(sk_msg_md_remote_port, offsetof(struct sk_msg_md, remote_port))
57 	: __clobber_all);
58 }
59 
60 SEC("sk_msg")
61 __description("valid access local_port in SK_MSG")
62 __success
local_port_in_sk_msg(void)63 __naked void local_port_in_sk_msg(void)
64 {
65 	asm volatile ("					\
66 	r0 = *(u32*)(r1 + %[sk_msg_md_local_port]);	\
67 	exit;						\
68 "	:
69 	: __imm_const(sk_msg_md_local_port, offsetof(struct sk_msg_md, local_port))
70 	: __clobber_all);
71 }
72 
73 SEC("sk_skb")
74 __description("valid access remote_ip6 in SK_MSG")
75 __success
remote_ip6_in_sk_msg(void)76 __naked void remote_ip6_in_sk_msg(void)
77 {
78 	asm volatile ("					\
79 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_0]);	\
80 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_1]);	\
81 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_2]);	\
82 	r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_3]);	\
83 	exit;						\
84 "	:
85 	: __imm_const(sk_msg_md_remote_ip6_0, offsetof(struct sk_msg_md, remote_ip6[0])),
86 	  __imm_const(sk_msg_md_remote_ip6_1, offsetof(struct sk_msg_md, remote_ip6[1])),
87 	  __imm_const(sk_msg_md_remote_ip6_2, offsetof(struct sk_msg_md, remote_ip6[2])),
88 	  __imm_const(sk_msg_md_remote_ip6_3, offsetof(struct sk_msg_md, remote_ip6[3]))
89 	: __clobber_all);
90 }
91 
92 SEC("sk_skb")
93 __description("valid access local_ip6 in SK_MSG")
94 __success
local_ip6_in_sk_msg(void)95 __naked void local_ip6_in_sk_msg(void)
96 {
97 	asm volatile ("					\
98 	r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_0]);	\
99 	r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_1]);	\
100 	r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_2]);	\
101 	r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_3]);	\
102 	exit;						\
103 "	:
104 	: __imm_const(sk_msg_md_local_ip6_0, offsetof(struct sk_msg_md, local_ip6[0])),
105 	  __imm_const(sk_msg_md_local_ip6_1, offsetof(struct sk_msg_md, local_ip6[1])),
106 	  __imm_const(sk_msg_md_local_ip6_2, offsetof(struct sk_msg_md, local_ip6[2])),
107 	  __imm_const(sk_msg_md_local_ip6_3, offsetof(struct sk_msg_md, local_ip6[3]))
108 	: __clobber_all);
109 }
110 
111 SEC("sk_msg")
112 __description("valid access size in SK_MSG")
113 __success
access_size_in_sk_msg(void)114 __naked void access_size_in_sk_msg(void)
115 {
116 	asm volatile ("					\
117 	r0 = *(u32*)(r1 + %[sk_msg_md_size]);		\
118 	exit;						\
119 "	:
120 	: __imm_const(sk_msg_md_size, offsetof(struct sk_msg_md, size))
121 	: __clobber_all);
122 }
123 
124 SEC("sk_msg")
125 __description("invalid 64B read of size in SK_MSG")
126 __failure __msg("invalid bpf_context access")
__flag(BPF_F_ANY_ALIGNMENT)127 __flag(BPF_F_ANY_ALIGNMENT)
128 __naked void of_size_in_sk_msg(void)
129 {
130 	asm volatile ("					\
131 	r2 = *(u64*)(r1 + %[sk_msg_md_size]);		\
132 	exit;						\
133 "	:
134 	: __imm_const(sk_msg_md_size, offsetof(struct sk_msg_md, size))
135 	: __clobber_all);
136 }
137 
138 SEC("sk_msg")
139 __description("invalid read past end of SK_MSG")
140 __failure __msg("invalid bpf_context access")
past_end_of_sk_msg(void)141 __naked void past_end_of_sk_msg(void)
142 {
143 	asm volatile ("					\
144 	r2 = *(u32*)(r1 + %[__imm_0]);			\
145 	exit;						\
146 "	:
147 	: __imm_const(__imm_0, offsetof(struct sk_msg_md, size) + 4)
148 	: __clobber_all);
149 }
150 
151 SEC("sk_msg")
152 __description("invalid read offset in SK_MSG")
153 __failure __msg("invalid bpf_context access")
__flag(BPF_F_ANY_ALIGNMENT)154 __flag(BPF_F_ANY_ALIGNMENT)
155 __naked void read_offset_in_sk_msg(void)
156 {
157 	asm volatile ("					\
158 	r2 = *(u32*)(r1 + %[__imm_0]);			\
159 	exit;						\
160 "	:
161 	: __imm_const(__imm_0, offsetof(struct sk_msg_md, family) + 1)
162 	: __clobber_all);
163 }
164 
165 SEC("sk_msg")
166 __description("direct packet read for SK_MSG")
167 __success
packet_read_for_sk_msg(void)168 __naked void packet_read_for_sk_msg(void)
169 {
170 	asm volatile ("					\
171 	r2 = *(u64*)(r1 + %[sk_msg_md_data]);		\
172 	r3 = *(u64*)(r1 + %[sk_msg_md_data_end]);	\
173 	r0 = r2;					\
174 	r0 += 8;					\
175 	if r0 > r3 goto l0_%=;				\
176 	r0 = *(u8*)(r2 + 0);				\
177 l0_%=:	r0 = 0;						\
178 	exit;						\
179 "	:
180 	: __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)),
181 	  __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end))
182 	: __clobber_all);
183 }
184 
185 SEC("sk_msg")
186 __description("direct packet write for SK_MSG")
187 __success
packet_write_for_sk_msg(void)188 __naked void packet_write_for_sk_msg(void)
189 {
190 	asm volatile ("					\
191 	r2 = *(u64*)(r1 + %[sk_msg_md_data]);		\
192 	r3 = *(u64*)(r1 + %[sk_msg_md_data_end]);	\
193 	r0 = r2;					\
194 	r0 += 8;					\
195 	if r0 > r3 goto l0_%=;				\
196 	*(u8*)(r2 + 0) = r2;				\
197 l0_%=:	r0 = 0;						\
198 	exit;						\
199 "	:
200 	: __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)),
201 	  __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end))
202 	: __clobber_all);
203 }
204 
205 SEC("sk_msg")
206 __description("overlapping checks for direct packet access SK_MSG")
207 __success
direct_packet_access_sk_msg(void)208 __naked void direct_packet_access_sk_msg(void)
209 {
210 	asm volatile ("					\
211 	r2 = *(u64*)(r1 + %[sk_msg_md_data]);		\
212 	r3 = *(u64*)(r1 + %[sk_msg_md_data_end]);	\
213 	r0 = r2;					\
214 	r0 += 8;					\
215 	if r0 > r3 goto l0_%=;				\
216 	r1 = r2;					\
217 	r1 += 6;					\
218 	if r1 > r3 goto l0_%=;				\
219 	r0 = *(u16*)(r2 + 6);				\
220 l0_%=:	r0 = 0;						\
221 	exit;						\
222 "	:
223 	: __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)),
224 	  __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end))
225 	: __clobber_all);
226 }
227 
228 char _license[] SEC("license") = "GPL";
229