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"; 237