1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #include <linux/bpf.h> |
4 | #include <bpf/bpf_helpers.h> |
5 | #include "bpf_misc.h" |
6 | |
7 | #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \ |
8 | (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \ |
9 | defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390) || \ |
10 | defined(__TARGET_ARCH_loongarch)) && \ |
11 | __clang_major__ >= 18 |
12 | |
13 | SEC("socket" ) |
14 | __description("MOV32SX, S8" ) |
15 | __success __success_unpriv __retval(0x23) |
16 | __naked void mov32sx_s8(void) |
17 | { |
18 | asm volatile (" \ |
19 | w0 = 0xff23; \ |
20 | w0 = (s8)w0; \ |
21 | exit; \ |
22 | " ::: __clobber_all); |
23 | } |
24 | |
25 | SEC("socket" ) |
26 | __description("MOV32SX, S16" ) |
27 | __success __success_unpriv __retval(0xFFFFff23) |
28 | __naked void mov32sx_s16(void) |
29 | { |
30 | asm volatile (" \ |
31 | w0 = 0xff23; \ |
32 | w0 = (s16)w0; \ |
33 | exit; \ |
34 | " ::: __clobber_all); |
35 | } |
36 | |
37 | SEC("socket" ) |
38 | __description("MOV64SX, S8" ) |
39 | __success __success_unpriv __retval(-2) |
40 | __naked void mov64sx_s8(void) |
41 | { |
42 | asm volatile (" \ |
43 | r0 = 0x1fe; \ |
44 | r0 = (s8)r0; \ |
45 | exit; \ |
46 | " ::: __clobber_all); |
47 | } |
48 | |
49 | SEC("socket" ) |
50 | __description("MOV64SX, S16" ) |
51 | __success __success_unpriv __retval(0xf23) |
52 | __naked void mov64sx_s16(void) |
53 | { |
54 | asm volatile (" \ |
55 | r0 = 0xf0f23; \ |
56 | r0 = (s16)r0; \ |
57 | exit; \ |
58 | " ::: __clobber_all); |
59 | } |
60 | |
61 | SEC("socket" ) |
62 | __description("MOV64SX, S32" ) |
63 | __success __success_unpriv __retval(-1) |
64 | __naked void mov64sx_s32(void) |
65 | { |
66 | asm volatile (" \ |
67 | r0 = 0xfffffffe; \ |
68 | r0 = (s32)r0; \ |
69 | r0 >>= 1; \ |
70 | exit; \ |
71 | " ::: __clobber_all); |
72 | } |
73 | |
74 | SEC("socket" ) |
75 | __description("MOV32SX, S8, range_check" ) |
76 | __success __success_unpriv __retval(1) |
77 | __naked void mov32sx_s8_range(void) |
78 | { |
79 | asm volatile (" \ |
80 | call %[bpf_get_prandom_u32]; \ |
81 | w1 = (s8)w0; \ |
82 | /* w1 with s8 range */ \ |
83 | if w1 s> 0x7f goto l0_%=; \ |
84 | if w1 s< -0x80 goto l0_%=; \ |
85 | r0 = 1; \ |
86 | l1_%=: \ |
87 | exit; \ |
88 | l0_%=: \ |
89 | r0 = 2; \ |
90 | goto l1_%=; \ |
91 | " : |
92 | : __imm(bpf_get_prandom_u32) |
93 | : __clobber_all); |
94 | } |
95 | |
96 | SEC("socket" ) |
97 | __description("MOV32SX, S16, range_check" ) |
98 | __success __success_unpriv __retval(1) |
99 | __naked void mov32sx_s16_range(void) |
100 | { |
101 | asm volatile (" \ |
102 | call %[bpf_get_prandom_u32]; \ |
103 | w1 = (s16)w0; \ |
104 | /* w1 with s16 range */ \ |
105 | if w1 s> 0x7fff goto l0_%=; \ |
106 | if w1 s< -0x80ff goto l0_%=; \ |
107 | r0 = 1; \ |
108 | l1_%=: \ |
109 | exit; \ |
110 | l0_%=: \ |
111 | r0 = 2; \ |
112 | goto l1_%=; \ |
113 | " : |
114 | : __imm(bpf_get_prandom_u32) |
115 | : __clobber_all); |
116 | } |
117 | |
118 | SEC("socket" ) |
119 | __description("MOV32SX, S16, range_check 2" ) |
120 | __success __success_unpriv __retval(1) |
121 | __naked void mov32sx_s16_range_2(void) |
122 | { |
123 | asm volatile (" \ |
124 | r1 = 65535; \ |
125 | w2 = (s16)w1; \ |
126 | r2 >>= 1; \ |
127 | if r2 != 0x7fffFFFF goto l0_%=; \ |
128 | r0 = 1; \ |
129 | l1_%=: \ |
130 | exit; \ |
131 | l0_%=: \ |
132 | r0 = 0; \ |
133 | goto l1_%=; \ |
134 | " : |
135 | : __imm(bpf_get_prandom_u32) |
136 | : __clobber_all); |
137 | } |
138 | |
139 | SEC("socket" ) |
140 | __description("MOV64SX, S8, range_check" ) |
141 | __success __success_unpriv __retval(1) |
142 | __naked void mov64sx_s8_range(void) |
143 | { |
144 | asm volatile (" \ |
145 | call %[bpf_get_prandom_u32]; \ |
146 | r1 = (s8)r0; \ |
147 | /* r1 with s8 range */ \ |
148 | if r1 s> 0x7f goto l0_%=; \ |
149 | if r1 s< -0x80 goto l0_%=; \ |
150 | r0 = 1; \ |
151 | l1_%=: \ |
152 | exit; \ |
153 | l0_%=: \ |
154 | r0 = 2; \ |
155 | goto l1_%=; \ |
156 | " : |
157 | : __imm(bpf_get_prandom_u32) |
158 | : __clobber_all); |
159 | } |
160 | |
161 | SEC("socket" ) |
162 | __description("MOV64SX, S16, range_check" ) |
163 | __success __success_unpriv __retval(1) |
164 | __naked void mov64sx_s16_range(void) |
165 | { |
166 | asm volatile (" \ |
167 | call %[bpf_get_prandom_u32]; \ |
168 | r1 = (s16)r0; \ |
169 | /* r1 with s16 range */ \ |
170 | if r1 s> 0x7fff goto l0_%=; \ |
171 | if r1 s< -0x8000 goto l0_%=; \ |
172 | r0 = 1; \ |
173 | l1_%=: \ |
174 | exit; \ |
175 | l0_%=: \ |
176 | r0 = 2; \ |
177 | goto l1_%=; \ |
178 | " : |
179 | : __imm(bpf_get_prandom_u32) |
180 | : __clobber_all); |
181 | } |
182 | |
183 | SEC("socket" ) |
184 | __description("MOV64SX, S32, range_check" ) |
185 | __success __success_unpriv __retval(1) |
186 | __naked void mov64sx_s32_range(void) |
187 | { |
188 | asm volatile (" \ |
189 | call %[bpf_get_prandom_u32]; \ |
190 | r1 = (s32)r0; \ |
191 | /* r1 with s32 range */ \ |
192 | if r1 s> 0x7fffffff goto l0_%=; \ |
193 | if r1 s< -0x80000000 goto l0_%=; \ |
194 | r0 = 1; \ |
195 | l1_%=: \ |
196 | exit; \ |
197 | l0_%=: \ |
198 | r0 = 2; \ |
199 | goto l1_%=; \ |
200 | " : |
201 | : __imm(bpf_get_prandom_u32) |
202 | : __clobber_all); |
203 | } |
204 | |
205 | SEC("socket" ) |
206 | __description("MOV64SX, S16, R10 Sign Extension" ) |
207 | __failure __msg("R1 type=scalar expected=fp, pkt, pkt_meta, map_key, map_value, mem, ringbuf_mem, buf, trusted_ptr_" ) |
208 | __failure_unpriv __msg_unpriv("R10 sign-extension part of pointer" ) |
209 | __naked void mov64sx_s16_r10(void) |
210 | { |
211 | asm volatile (" \ |
212 | r1 = 553656332; \ |
213 | *(u32 *)(r10 - 8) = r1; \ |
214 | r1 = (s16)r10; \ |
215 | r1 += -8; \ |
216 | r2 = 3; \ |
217 | if r2 <= r1 goto l0_%=; \ |
218 | l0_%=: \ |
219 | call %[bpf_trace_printk]; \ |
220 | r0 = 0; \ |
221 | exit; \ |
222 | " : |
223 | : __imm(bpf_trace_printk) |
224 | : __clobber_all); |
225 | } |
226 | |
227 | #else |
228 | |
229 | SEC("socket" ) |
230 | __description("cpuv4 is not supported by compiler or jit, use a dummy test" ) |
231 | __success |
232 | int dummy_test(void) |
233 | { |
234 | return 0; |
235 | } |
236 | |
237 | #endif |
238 | |
239 | char _license[] SEC("license" ) = "GPL" ; |
240 | |