1b14a702aSEduard Zingerman // SPDX-License-Identifier: GPL-2.0
2b14a702aSEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c */
3b14a702aSEduard Zingerman 
4b14a702aSEduard Zingerman #include <linux/bpf.h>
5b14a702aSEduard Zingerman #include <bpf/bpf_helpers.h>
6b14a702aSEduard Zingerman #include "bpf_misc.h"
7b14a702aSEduard Zingerman 
8b14a702aSEduard Zingerman struct {
9b14a702aSEduard Zingerman 	__uint(type, BPF_MAP_TYPE_HASH);
10b14a702aSEduard Zingerman 	__uint(max_entries, 1);
11b14a702aSEduard Zingerman 	__type(key, long long);
12b14a702aSEduard Zingerman 	__type(value, long long);
13b14a702aSEduard Zingerman } map_hash_8b SEC(".maps");
14b14a702aSEduard Zingerman 
15b14a702aSEduard Zingerman SEC("socket")
16b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, positive bounds")
17b14a702aSEduard Zingerman __failure __msg("unbounded min value")
18b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_positive_bounds(void)19b14a702aSEduard Zingerman __naked void signed_and_unsigned_positive_bounds(void)
20b14a702aSEduard Zingerman {
21b14a702aSEduard Zingerman 	asm volatile ("					\
22b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
23b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
24b14a702aSEduard Zingerman 	r1 = 0;						\
25b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
26b14a702aSEduard Zingerman 	r2 = r10;					\
27b14a702aSEduard Zingerman 	r2 += -8;					\
28b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
29b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
30b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
31b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
32b14a702aSEduard Zingerman 	r2 = 2;						\
33b14a702aSEduard Zingerman 	if r2 >= r1 goto l0_%=;				\
34b14a702aSEduard Zingerman 	if r1 s> 4 goto l0_%=;				\
35b14a702aSEduard Zingerman 	r0 += r1;					\
36b14a702aSEduard Zingerman 	r1 = 0;						\
37b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
38b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
39b14a702aSEduard Zingerman 	exit;						\
40b14a702aSEduard Zingerman "	:
41b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
42b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
43b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
44b14a702aSEduard Zingerman 	: __clobber_all);
45b14a702aSEduard Zingerman }
46b14a702aSEduard Zingerman 
47b14a702aSEduard Zingerman SEC("socket")
48b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned")
49b14a702aSEduard Zingerman __failure __msg("unbounded min value")
50b14a702aSEduard Zingerman __failure_unpriv
checks_mixing_signed_and_unsigned(void)51b14a702aSEduard Zingerman __naked void checks_mixing_signed_and_unsigned(void)
52b14a702aSEduard Zingerman {
53b14a702aSEduard Zingerman 	asm volatile ("					\
54b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
55b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
56b14a702aSEduard Zingerman 	r1 = 0;						\
57b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
58b14a702aSEduard Zingerman 	r2 = r10;					\
59b14a702aSEduard Zingerman 	r2 += -8;					\
60b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
61b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
62b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
63b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
64b14a702aSEduard Zingerman 	r2 = -1;					\
65b14a702aSEduard Zingerman 	if r1 > r2 goto l0_%=;				\
66b14a702aSEduard Zingerman 	if r1 s> 1 goto l0_%=;				\
67b14a702aSEduard Zingerman 	r0 += r1;					\
68b14a702aSEduard Zingerman 	r1 = 0;						\
69b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
70b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
71b14a702aSEduard Zingerman 	exit;						\
72b14a702aSEduard Zingerman "	:
73b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
74b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
75b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
76b14a702aSEduard Zingerman 	: __clobber_all);
77b14a702aSEduard Zingerman }
78b14a702aSEduard Zingerman 
79b14a702aSEduard Zingerman SEC("socket")
80b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 2")
81b14a702aSEduard Zingerman __failure __msg("unbounded min value")
82b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_2(void)83b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_2(void)
84b14a702aSEduard Zingerman {
85b14a702aSEduard Zingerman 	asm volatile ("					\
86b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
87b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
88b14a702aSEduard Zingerman 	r1 = 0;						\
89b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
90b14a702aSEduard Zingerman 	r2 = r10;					\
91b14a702aSEduard Zingerman 	r2 += -8;					\
92b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
93b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
94b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
95b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
96b14a702aSEduard Zingerman 	r2 = -1;					\
97b14a702aSEduard Zingerman 	if r1 > r2 goto l0_%=;				\
98b14a702aSEduard Zingerman 	r8 = 0;						\
99b14a702aSEduard Zingerman 	r8 += r1;					\
100b14a702aSEduard Zingerman 	if r8 s> 1 goto l0_%=;				\
101b14a702aSEduard Zingerman 	r0 += r8;					\
102b14a702aSEduard Zingerman 	r0 = 0;						\
103b14a702aSEduard Zingerman 	*(u8*)(r8 + 0) = r0;				\
104b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
105b14a702aSEduard Zingerman 	exit;						\
106b14a702aSEduard Zingerman "	:
107b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
108b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
109b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
110b14a702aSEduard Zingerman 	: __clobber_all);
111b14a702aSEduard Zingerman }
112b14a702aSEduard Zingerman 
113b14a702aSEduard Zingerman SEC("socket")
114b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 3")
115b14a702aSEduard Zingerman __failure __msg("unbounded min value")
116b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_3(void)117b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_3(void)
118b14a702aSEduard Zingerman {
119b14a702aSEduard Zingerman 	asm volatile ("					\
120b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
121b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
122b14a702aSEduard Zingerman 	r1 = 0;						\
123b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
124b14a702aSEduard Zingerman 	r2 = r10;					\
125b14a702aSEduard Zingerman 	r2 += -8;					\
126b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
127b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
128b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
129b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
130b14a702aSEduard Zingerman 	r2 = -1;					\
131b14a702aSEduard Zingerman 	if r1 > r2 goto l0_%=;				\
132b14a702aSEduard Zingerman 	r8 = r1;					\
133b14a702aSEduard Zingerman 	if r8 s> 1 goto l0_%=;				\
134b14a702aSEduard Zingerman 	r0 += r8;					\
135b14a702aSEduard Zingerman 	r0 = 0;						\
136b14a702aSEduard Zingerman 	*(u8*)(r8 + 0) = r0;				\
137b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
138b14a702aSEduard Zingerman 	exit;						\
139b14a702aSEduard Zingerman "	:
140b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
141b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
142b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
143b14a702aSEduard Zingerman 	: __clobber_all);
144b14a702aSEduard Zingerman }
145b14a702aSEduard Zingerman 
146b14a702aSEduard Zingerman SEC("socket")
147b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 4")
148b14a702aSEduard Zingerman __success __success_unpriv __retval(0)
signed_and_unsigned_variant_4(void)149b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_4(void)
150b14a702aSEduard Zingerman {
151b14a702aSEduard Zingerman 	asm volatile ("					\
152b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
153b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
154b14a702aSEduard Zingerman 	r1 = 0;						\
155b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
156b14a702aSEduard Zingerman 	r2 = r10;					\
157b14a702aSEduard Zingerman 	r2 += -8;					\
158b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
159b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
160b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
161b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
162b14a702aSEduard Zingerman 	r2 = 1;						\
163b14a702aSEduard Zingerman 	r1 &= r2;					\
164b14a702aSEduard Zingerman 	if r1 s> 1 goto l0_%=;				\
165b14a702aSEduard Zingerman 	r0 += r1;					\
166b14a702aSEduard Zingerman 	r1 = 0;						\
167b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
168b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
169b14a702aSEduard Zingerman 	exit;						\
170b14a702aSEduard Zingerman "	:
171b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
172b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
173b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
174b14a702aSEduard Zingerman 	: __clobber_all);
175b14a702aSEduard Zingerman }
176b14a702aSEduard Zingerman 
177b14a702aSEduard Zingerman SEC("socket")
178b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 5")
179b14a702aSEduard Zingerman __failure __msg("unbounded min value")
180b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_5(void)181b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_5(void)
182b14a702aSEduard Zingerman {
183b14a702aSEduard Zingerman 	asm volatile ("					\
184b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
185b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
186b14a702aSEduard Zingerman 	r1 = 0;						\
187b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
188b14a702aSEduard Zingerman 	r2 = r10;					\
189b14a702aSEduard Zingerman 	r2 += -8;					\
190b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
191b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
192b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
193b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
194b14a702aSEduard Zingerman 	r2 = -1;					\
195b14a702aSEduard Zingerman 	if r1 > r2 goto l0_%=;				\
196b14a702aSEduard Zingerman 	if r1 s> 1 goto l0_%=;				\
197b14a702aSEduard Zingerman 	r0 += 4;					\
198b14a702aSEduard Zingerman 	r0 -= r1;					\
199b14a702aSEduard Zingerman 	r1 = 0;						\
200b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
201b14a702aSEduard Zingerman 	r0 = 0;						\
202b14a702aSEduard Zingerman l0_%=:	exit;						\
203b14a702aSEduard Zingerman "	:
204b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
205b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
206b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
207b14a702aSEduard Zingerman 	: __clobber_all);
208b14a702aSEduard Zingerman }
209b14a702aSEduard Zingerman 
210b14a702aSEduard Zingerman SEC("socket")
211b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 6")
212b14a702aSEduard Zingerman __failure __msg("R4 min value is negative, either use unsigned")
213b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_6(void)214b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_6(void)
215b14a702aSEduard Zingerman {
216b14a702aSEduard Zingerman 	asm volatile ("					\
217b14a702aSEduard Zingerman 	r9 = r1;					\
218b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
219b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
220b14a702aSEduard Zingerman 	r1 = r9;					\
221b14a702aSEduard Zingerman 	r2 = 0;						\
222b14a702aSEduard Zingerman 	r3 = r10;					\
223b14a702aSEduard Zingerman 	r3 += -512;					\
224b14a702aSEduard Zingerman 	r4 = *(u64*)(r10 - 16);				\
225b14a702aSEduard Zingerman 	r6 = -1;					\
226b14a702aSEduard Zingerman 	if r4 > r6 goto l0_%=;				\
227b14a702aSEduard Zingerman 	if r4 s> 1 goto l0_%=;				\
228b14a702aSEduard Zingerman 	r4 += 1;					\
229b14a702aSEduard Zingerman 	r5 = 0;						\
230b14a702aSEduard Zingerman 	r6 = 0;						\
231b14a702aSEduard Zingerman 	*(u16*)(r10 - 512) = r6;			\
232b14a702aSEduard Zingerman 	call %[bpf_skb_load_bytes];			\
233b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
234b14a702aSEduard Zingerman 	exit;						\
235b14a702aSEduard Zingerman "	:
236b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
237b14a702aSEduard Zingerman 	  __imm(bpf_skb_load_bytes)
238b14a702aSEduard Zingerman 	: __clobber_all);
239b14a702aSEduard Zingerman }
240b14a702aSEduard Zingerman 
241b14a702aSEduard Zingerman SEC("socket")
242b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 7")
243b14a702aSEduard Zingerman __success __success_unpriv __retval(0)
signed_and_unsigned_variant_7(void)244b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_7(void)
245b14a702aSEduard Zingerman {
246b14a702aSEduard Zingerman 	asm volatile ("					\
247b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
248b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
249b14a702aSEduard Zingerman 	r1 = 0;						\
250b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
251b14a702aSEduard Zingerman 	r2 = r10;					\
252b14a702aSEduard Zingerman 	r2 += -8;					\
253b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
254b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
255b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
256b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
257b14a702aSEduard Zingerman 	r2 = %[__imm_0];				\
258b14a702aSEduard Zingerman 	if r1 > r2 goto l0_%=;				\
259b14a702aSEduard Zingerman 	if r1 s> 1 goto l0_%=;				\
260b14a702aSEduard Zingerman 	r0 += r1;					\
261b14a702aSEduard Zingerman 	r1 = 0;						\
262b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
263b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
264b14a702aSEduard Zingerman 	exit;						\
265b14a702aSEduard Zingerman "	:
266b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
267b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
268b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b),
269b14a702aSEduard Zingerman 	  __imm_const(__imm_0, 1024 * 1024 * 1024)
270b14a702aSEduard Zingerman 	: __clobber_all);
271b14a702aSEduard Zingerman }
272b14a702aSEduard Zingerman 
273b14a702aSEduard Zingerman SEC("socket")
274b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 8")
275b14a702aSEduard Zingerman __failure __msg("unbounded min value")
276b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_8(void)277b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_8(void)
278b14a702aSEduard Zingerman {
279b14a702aSEduard Zingerman 	asm volatile ("					\
280b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
281b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
282b14a702aSEduard Zingerman 	r1 = 0;						\
283b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
284b14a702aSEduard Zingerman 	r2 = r10;					\
285b14a702aSEduard Zingerman 	r2 += -8;					\
286b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
287b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
288b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
289b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
290b14a702aSEduard Zingerman 	r2 = -1;					\
291b14a702aSEduard Zingerman 	if r2 > r1 goto l1_%=;				\
292b14a702aSEduard Zingerman 	r0 = 0;						\
293b14a702aSEduard Zingerman 	exit;						\
294b14a702aSEduard Zingerman l1_%=:	if r1 s> 1 goto l0_%=;				\
295b14a702aSEduard Zingerman 	r0 += r1;					\
296b14a702aSEduard Zingerman 	r1 = 0;						\
297b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
298b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
299b14a702aSEduard Zingerman 	exit;						\
300b14a702aSEduard Zingerman "	:
301b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
302b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
303b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
304b14a702aSEduard Zingerman 	: __clobber_all);
305b14a702aSEduard Zingerman }
306b14a702aSEduard Zingerman 
307b14a702aSEduard Zingerman SEC("socket")
308b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 9")
309b14a702aSEduard Zingerman __success __success_unpriv __retval(0)
signed_and_unsigned_variant_9(void)310b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_9(void)
311b14a702aSEduard Zingerman {
312b14a702aSEduard Zingerman 	asm volatile ("					\
313b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
314b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
315b14a702aSEduard Zingerman 	r1 = 0;						\
316b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
317b14a702aSEduard Zingerman 	r2 = r10;					\
318b14a702aSEduard Zingerman 	r2 += -8;					\
319b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
320b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
321b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
322b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
323b14a702aSEduard Zingerman 	r2 = -9223372036854775808ULL ll;		\
324b14a702aSEduard Zingerman 	if r2 > r1 goto l1_%=;				\
325b14a702aSEduard Zingerman 	r0 = 0;						\
326b14a702aSEduard Zingerman 	exit;						\
327b14a702aSEduard Zingerman l1_%=:	if r1 s> 1 goto l0_%=;				\
328b14a702aSEduard Zingerman 	r0 += r1;					\
329b14a702aSEduard Zingerman 	r1 = 0;						\
330b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
331b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
332b14a702aSEduard Zingerman 	exit;						\
333b14a702aSEduard Zingerman "	:
334b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
335b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
336b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
337b14a702aSEduard Zingerman 	: __clobber_all);
338b14a702aSEduard Zingerman }
339b14a702aSEduard Zingerman 
340b14a702aSEduard Zingerman SEC("socket")
341b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 10")
342b14a702aSEduard Zingerman __failure __msg("unbounded min value")
343b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_10(void)344b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_10(void)
345b14a702aSEduard Zingerman {
346b14a702aSEduard Zingerman 	asm volatile ("					\
347b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
348b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
349b14a702aSEduard Zingerman 	r1 = 0;						\
350b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
351b14a702aSEduard Zingerman 	r2 = r10;					\
352b14a702aSEduard Zingerman 	r2 += -8;					\
353b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
354b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
355b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
356b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
357*953d9f5bSYonghong Song 	r2 = -1;						\
358b14a702aSEduard Zingerman 	if r2 > r1 goto l1_%=;				\
359b14a702aSEduard Zingerman 	r0 = 0;						\
360b14a702aSEduard Zingerman 	exit;						\
361b14a702aSEduard Zingerman l1_%=:	if r1 s> 1 goto l0_%=;				\
362b14a702aSEduard Zingerman 	r0 += r1;					\
363b14a702aSEduard Zingerman 	r1 = 0;						\
364b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
365b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
366b14a702aSEduard Zingerman 	exit;						\
367b14a702aSEduard Zingerman "	:
368b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
369b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
370b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
371b14a702aSEduard Zingerman 	: __clobber_all);
372b14a702aSEduard Zingerman }
373b14a702aSEduard Zingerman 
374b14a702aSEduard Zingerman SEC("socket")
375b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 11")
376b14a702aSEduard Zingerman __failure __msg("unbounded min value")
377b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_11(void)378b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_11(void)
379b14a702aSEduard Zingerman {
380b14a702aSEduard Zingerman 	asm volatile ("					\
381b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
382b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
383b14a702aSEduard Zingerman 	r1 = 0;						\
384b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
385b14a702aSEduard Zingerman 	r2 = r10;					\
386b14a702aSEduard Zingerman 	r2 += -8;					\
387b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
388b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
389b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
390b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
391b14a702aSEduard Zingerman 	r2 = -1;					\
392b14a702aSEduard Zingerman 	if r2 >= r1 goto l1_%=;				\
393b14a702aSEduard Zingerman 	/* Dead branch. */				\
394b14a702aSEduard Zingerman 	r0 = 0;						\
395b14a702aSEduard Zingerman 	exit;						\
396b14a702aSEduard Zingerman l1_%=:	if r1 s> 1 goto l0_%=;				\
397b14a702aSEduard Zingerman 	r0 += r1;					\
398b14a702aSEduard Zingerman 	r1 = 0;						\
399b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
400b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
401b14a702aSEduard Zingerman 	exit;						\
402b14a702aSEduard Zingerman "	:
403b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
404b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
405b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
406b14a702aSEduard Zingerman 	: __clobber_all);
407b14a702aSEduard Zingerman }
408b14a702aSEduard Zingerman 
409b14a702aSEduard Zingerman SEC("socket")
410b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 12")
411b14a702aSEduard Zingerman __failure __msg("unbounded min value")
412b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_12(void)413b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_12(void)
414b14a702aSEduard Zingerman {
415b14a702aSEduard Zingerman 	asm volatile ("					\
416b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
417b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
418b14a702aSEduard Zingerman 	r1 = 0;						\
419b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
420b14a702aSEduard Zingerman 	r2 = r10;					\
421b14a702aSEduard Zingerman 	r2 += -8;					\
422b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
423b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
424b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
425b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
426b14a702aSEduard Zingerman 	r2 = -6;					\
427b14a702aSEduard Zingerman 	if r2 >= r1 goto l1_%=;				\
428b14a702aSEduard Zingerman 	r0 = 0;						\
429b14a702aSEduard Zingerman 	exit;						\
430b14a702aSEduard Zingerman l1_%=:	if r1 s> 1 goto l0_%=;				\
431b14a702aSEduard Zingerman 	r0 += r1;					\
432b14a702aSEduard Zingerman 	r1 = 0;						\
433b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
434b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
435b14a702aSEduard Zingerman 	exit;						\
436b14a702aSEduard Zingerman "	:
437b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
438b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
439b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
440b14a702aSEduard Zingerman 	: __clobber_all);
441b14a702aSEduard Zingerman }
442b14a702aSEduard Zingerman 
443b14a702aSEduard Zingerman SEC("socket")
444b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 13")
445b14a702aSEduard Zingerman __failure __msg("unbounded min value")
446b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_13(void)447b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_13(void)
448b14a702aSEduard Zingerman {
449b14a702aSEduard Zingerman 	asm volatile ("					\
450b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
451b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
452b14a702aSEduard Zingerman 	r1 = 0;						\
453b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
454b14a702aSEduard Zingerman 	r2 = r10;					\
455b14a702aSEduard Zingerman 	r2 += -8;					\
456b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
457b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
458b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
459b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
460b14a702aSEduard Zingerman 	r2 = 2;						\
461b14a702aSEduard Zingerman 	if r2 >= r1 goto l0_%=;				\
462b14a702aSEduard Zingerman 	r7 = 1;						\
463b14a702aSEduard Zingerman 	if r7 s> 0 goto l1_%=;				\
464b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
465b14a702aSEduard Zingerman 	exit;						\
466b14a702aSEduard Zingerman l1_%=:	r7 += r1;					\
467b14a702aSEduard Zingerman 	if r7 s> 4 goto l2_%=;				\
468b14a702aSEduard Zingerman 	r0 += r7;					\
469b14a702aSEduard Zingerman 	r1 = 0;						\
470b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
471b14a702aSEduard Zingerman l2_%=:	r0 = 0;						\
472b14a702aSEduard Zingerman 	exit;						\
473b14a702aSEduard Zingerman "	:
474b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
475b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
476b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
477b14a702aSEduard Zingerman 	: __clobber_all);
478b14a702aSEduard Zingerman }
479b14a702aSEduard Zingerman 
480b14a702aSEduard Zingerman SEC("socket")
481b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 14")
482b14a702aSEduard Zingerman __failure __msg("unbounded min value")
483b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_14(void)484b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_14(void)
485b14a702aSEduard Zingerman {
486b14a702aSEduard Zingerman 	asm volatile ("					\
487b14a702aSEduard Zingerman 	r9 = *(u32*)(r1 + %[__sk_buff_mark]);		\
488b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
489b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
490b14a702aSEduard Zingerman 	r1 = 0;						\
491b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
492b14a702aSEduard Zingerman 	r2 = r10;					\
493b14a702aSEduard Zingerman 	r2 += -8;					\
494b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
495b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
496b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
497b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
498b14a702aSEduard Zingerman 	r2 = -1;					\
499b14a702aSEduard Zingerman 	r8 = 2;						\
500b14a702aSEduard Zingerman 	if r9 == 42 goto l1_%=;				\
501b14a702aSEduard Zingerman 	if r8 s> r1 goto l2_%=;				\
502b14a702aSEduard Zingerman l3_%=:	if r1 s> 1 goto l2_%=;				\
503b14a702aSEduard Zingerman 	r0 += r1;					\
504b14a702aSEduard Zingerman l0_%=:	r1 = 0;						\
505b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
506b14a702aSEduard Zingerman l2_%=:	r0 = 0;						\
507b14a702aSEduard Zingerman 	exit;						\
508b14a702aSEduard Zingerman l1_%=:	if r1 > r2 goto l2_%=;				\
509b14a702aSEduard Zingerman 	goto l3_%=;					\
510b14a702aSEduard Zingerman "	:
511b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
512b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
513b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b),
514b14a702aSEduard Zingerman 	  __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))
515b14a702aSEduard Zingerman 	: __clobber_all);
516b14a702aSEduard Zingerman }
517b14a702aSEduard Zingerman 
518b14a702aSEduard Zingerman SEC("socket")
519b14a702aSEduard Zingerman __description("bounds checks mixing signed and unsigned, variant 15")
520b14a702aSEduard Zingerman __failure __msg("unbounded min value")
521b14a702aSEduard Zingerman __failure_unpriv
signed_and_unsigned_variant_15(void)522b14a702aSEduard Zingerman __naked void signed_and_unsigned_variant_15(void)
523b14a702aSEduard Zingerman {
524b14a702aSEduard Zingerman 	asm volatile ("					\
525b14a702aSEduard Zingerman 	call %[bpf_ktime_get_ns];			\
526b14a702aSEduard Zingerman 	*(u64*)(r10 - 16) = r0;				\
527b14a702aSEduard Zingerman 	r1 = 0;						\
528b14a702aSEduard Zingerman 	*(u64*)(r10 - 8) = r1;				\
529b14a702aSEduard Zingerman 	r2 = r10;					\
530b14a702aSEduard Zingerman 	r2 += -8;					\
531b14a702aSEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
532b14a702aSEduard Zingerman 	call %[bpf_map_lookup_elem];			\
533b14a702aSEduard Zingerman 	if r0 == 0 goto l0_%=;				\
534b14a702aSEduard Zingerman 	r1 = *(u64*)(r10 - 16);				\
535b14a702aSEduard Zingerman 	r2 = -6;					\
536b14a702aSEduard Zingerman 	if r2 >= r1 goto l1_%=;				\
537b14a702aSEduard Zingerman l0_%=:	r0 = 0;						\
538b14a702aSEduard Zingerman 	exit;						\
539b14a702aSEduard Zingerman l1_%=:	r0 += r1;					\
540b14a702aSEduard Zingerman 	if r0 > 1 goto l2_%=;				\
541b14a702aSEduard Zingerman 	r0 = 0;						\
542b14a702aSEduard Zingerman 	exit;						\
543b14a702aSEduard Zingerman l2_%=:	r1 = 0;						\
544b14a702aSEduard Zingerman 	*(u8*)(r0 + 0) = r1;				\
545b14a702aSEduard Zingerman 	r0 = 0;						\
546b14a702aSEduard Zingerman 	exit;						\
547b14a702aSEduard Zingerman "	:
548b14a702aSEduard Zingerman 	: __imm(bpf_ktime_get_ns),
549b14a702aSEduard Zingerman 	  __imm(bpf_map_lookup_elem),
550b14a702aSEduard Zingerman 	  __imm_addr(map_hash_8b)
551b14a702aSEduard Zingerman 	: __clobber_all);
552b14a702aSEduard Zingerman }
553b14a702aSEduard Zingerman 
554b14a702aSEduard Zingerman char _license[] SEC("license") = "GPL";
555