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 227#else 228 229SEC("socket") 230__description("cpuv4 is not supported by compiler or jit, use a dummy test") 231__success 232int dummy_test(void) 233{ 234 return 0; 235} 236 237#endif 238 239char _license[] SEC("license") = "GPL"; 240