FILE
verifier_movsx.c
File preview with syntax highlighting.
linux-6.19.14/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) || \ 9 defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390) || \ 10 defined(__TARGET_ARCH_loongarch)) && \ 11 __clang_major__ >= 18 12 13SEC("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 25SEC("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 37SEC("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 49SEC("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 61SEC("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 74SEC("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; \ 86l1_%=: \ 87 exit; \ 88l0_%=: \ 89 r0 = 2; \ 90 goto l1_%=; \ 91" : 92 : __imm(bpf_get_prandom_u32) 93 : __clobber_all); 94} 95 96SEC("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; \ 108l1_%=: \ 109 exit; \ 110l0_%=: \ 111 r0 = 2; \ 112 goto l1_%=; \ 113" : 114 : __imm(bpf_get_prandom_u32) 115 : __clobber_all); 116} 117 118SEC("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; \ 129l1_%=: \ 130 exit; \ 131l0_%=: \ 132 r0 = 0; \ 133 goto l1_%=; \ 134" : 135 : __imm(bpf_get_prandom_u32) 136 : __clobber_all); 137} 138 139SEC("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; \ 151l1_%=: \ 152 exit; \ 153l0_%=: \ 154 r0 = 2; \ 155 goto l1_%=; \ 156" : 157 : __imm(bpf_get_prandom_u32) 158 : __clobber_all); 159} 160 161SEC("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; \ 173l1_%=: \ 174 exit; \ 175l0_%=: \ 176 r0 = 2; \ 177 goto l1_%=; \ 178" : 179 : __imm(bpf_get_prandom_u32) 180 : __clobber_all); 181} 182 183SEC("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; \ 195l1_%=: \ 196 exit; \ 197l0_%=: \ 198 r0 = 2; \ 199 goto l1_%=; \ 200" : 201 : __imm(bpf_get_prandom_u32) 202 : __clobber_all); 203} 204 205SEC("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_%=; \ 218l0_%=: \ 219 call %[bpf_trace_printk]; \ 220 r0 = 0; \ 221 exit; \ 222" : 223 : __imm(bpf_trace_printk) 224 : __clobber_all); 225} 226 227SEC("socket") 228__description("MOV32SX, S8, var_off u32_max") 229__failure __msg("infinite loop detected") 230__failure_unpriv __msg_unpriv("back-edge from insn 2 to 0") 231__naked void mov64sx_s32_varoff_1(void) 232{ 233 asm volatile (" \ 234l0_%=: \ 235 r3 = *(u8 *)(r10 -387); \ 236 w7 = (s8)w3; \ 237 if w7 >= 0x2533823b goto l0_%=; \ 238 w0 = 0; \ 239 exit; \ 240" : 241 : 242 : __clobber_all); 243} 244 245SEC("socket") 246__description("MOV32SX, S8, var_off not u32_max, positive after s8 extension") 247__success __retval(0) 248__success_unpriv 249#ifdef SPEC_V1 250__xlated_unpriv("w0 = 0") 251__xlated_unpriv("exit") 252__xlated_unpriv("nospec") /* inserted to prevent `frame pointer is read only` */ 253__xlated_unpriv("goto pc-1") 254#endif 255__naked void mov64sx_s32_varoff_2(void) 256{ 257 asm volatile (" \ 258 call %[bpf_get_prandom_u32]; \ 259 r3 = r0; \ 260 r3 &= 0xf; \ 261 w7 = (s8)w3; \ 262 if w7 s>= 16 goto l0_%=; \ 263 w0 = 0; \ 264 exit; \ 265l0_%=: \ 266 r10 = 1; \ 267 exit; \ 268" : 269 : __imm(bpf_get_prandom_u32) 270 : __clobber_all); 271} 272 273SEC("socket") 274__description("MOV32SX, S8, var_off not u32_max, negative after s8 extension") 275__success __retval(0) 276__success_unpriv 277#ifdef SPEC_V1 278__xlated_unpriv("w0 = 0") 279__xlated_unpriv("exit") 280__xlated_unpriv("nospec") /* inserted to prevent `frame pointer is read only` */ 281__xlated_unpriv("goto pc-1") 282#endif 283__naked void mov64sx_s32_varoff_3(void) 284{ 285 asm volatile (" \ 286 call %[bpf_get_prandom_u32]; \ 287 r3 = r0; \ 288 r3 &= 0xf; \ 289 r3 |= 0x80; \ 290 w7 = (s8)w3; \ 291 if w7 s>= -5 goto l0_%=; \ 292 w0 = 0; \ 293 exit; \ 294l0_%=: \ 295 r10 = 1; \ 296 exit; \ 297" : 298 : __imm(bpf_get_prandom_u32) 299 : __clobber_all); 300} 301 302SEC("socket") 303__description("MOV64SX, S8, unsigned range_check") 304__success __retval(0) 305__naked void mov64sx_s8_range_check(void) 306{ 307 asm volatile (" \ 308 call %[bpf_get_prandom_u32]; \ 309 r0 &= 0x1; \ 310 r0 += 0xfe; \ 311 r0 = (s8)r0; \ 312 if r0 < 0xfffffffffffffffe goto label_%=; \ 313 r0 = 0; \ 314 exit; \ 315label_%=: \ 316 exit; \ 317" : 318 : __imm(bpf_get_prandom_u32) 319 : __clobber_all); 320} 321 322SEC("socket") 323__description("MOV32SX, S8, unsigned range_check") 324__success __retval(0) 325__naked void mov32sx_s8_range_check(void) 326{ 327 asm volatile (" \ 328 call %[bpf_get_prandom_u32]; \ 329 w0 &= 0x1; \ 330 w0 += 0xfe; \ 331 w0 = (s8)w0; \ 332 if w0 < 0xfffffffe goto label_%=; \ 333 r0 = 0; \ 334 exit; \ 335label_%=: \ 336 exit; \ 337 " : 338 : __imm(bpf_get_prandom_u32) 339 : __clobber_all); 340} 341 342#else 343 344SEC("socket") 345__description("cpuv4 is not supported by compiler or jit, use a dummy test") 346__success 347int dummy_test(void) 348{ 349 return 0; 350} 351 352#endif 353 354char _license[] SEC("license") = "GPL";
~/
Read-only file preview.