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