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
8SEC("sk_msg")
9__description("valid access family in SK_MSG")
10__success
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
21SEC("sk_msg")
22__description("valid access remote_ip4 in SK_MSG")
23__success
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
34SEC("sk_msg")
35__description("valid access local_ip4 in SK_MSG")
36__success
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
47SEC("sk_msg")
48__description("valid access remote_port in SK_MSG")
49__success
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
60SEC("sk_msg")
61__description("valid access local_port in SK_MSG")
62__success
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
73SEC("sk_skb")
74__description("valid access remote_ip6 in SK_MSG")
75__success
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
92SEC("sk_skb")
93__description("valid access local_ip6 in SK_MSG")
94__success
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
111SEC("sk_msg")
112__description("valid access size in SK_MSG")
113__success
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
124SEC("sk_msg")
125__description("invalid 64B read of size in SK_MSG")
126__failure __msg("invalid bpf_context access")
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
138SEC("sk_msg")
139__description("invalid read past end of SK_MSG")
140__failure __msg("invalid bpf_context access")
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
151SEC("sk_msg")
152__description("invalid read offset in SK_MSG")
153__failure __msg("invalid bpf_context access")
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
165SEC("sk_msg")
166__description("direct packet read for SK_MSG")
167__success
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);				\
177l0_%=:	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
185SEC("sk_msg")
186__description("direct packet write for SK_MSG")
187__success
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;				\
197l0_%=:	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
205SEC("sk_msg")
206__description("overlapping checks for direct packet access SK_MSG")
207__success
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);				\
220l0_%=:	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
228char _license[] SEC("license") = "GPL";
229