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