1*81d1d6ddSEduard Zingerman // SPDX-License-Identifier: GPL-2.0 2*81d1d6ddSEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/subreg.c */ 3*81d1d6ddSEduard Zingerman 4*81d1d6ddSEduard Zingerman #include <linux/bpf.h> 5*81d1d6ddSEduard Zingerman #include <bpf/bpf_helpers.h> 6*81d1d6ddSEduard Zingerman #include "bpf_misc.h" 7*81d1d6ddSEduard Zingerman 8*81d1d6ddSEduard Zingerman /* This file contains sub-register zero extension checks for insns defining 9*81d1d6ddSEduard Zingerman * sub-registers, meaning: 10*81d1d6ddSEduard Zingerman * - All insns under BPF_ALU class. Their BPF_ALU32 variants or narrow width 11*81d1d6ddSEduard Zingerman * forms (BPF_END) could define sub-registers. 12*81d1d6ddSEduard Zingerman * - Narrow direct loads, BPF_B/H/W | BPF_LDX. 13*81d1d6ddSEduard Zingerman * - BPF_LD is not exposed to JIT back-ends, so no need for testing. 14*81d1d6ddSEduard Zingerman * 15*81d1d6ddSEduard Zingerman * "get_prandom_u32" is used to initialize low 32-bit of some registers to 16*81d1d6ddSEduard Zingerman * prevent potential optimizations done by verifier or JIT back-ends which could 17*81d1d6ddSEduard Zingerman * optimize register back into constant when range info shows one register is a 18*81d1d6ddSEduard Zingerman * constant. 19*81d1d6ddSEduard Zingerman */ 20*81d1d6ddSEduard Zingerman 21*81d1d6ddSEduard Zingerman SEC("socket") 22*81d1d6ddSEduard Zingerman __description("add32 reg zero extend check") 23*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) add32_reg_zero_extend_check(void)24*81d1d6ddSEduard Zingerman__naked void add32_reg_zero_extend_check(void) 25*81d1d6ddSEduard Zingerman { 26*81d1d6ddSEduard Zingerman asm volatile (" \ 27*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 28*81d1d6ddSEduard Zingerman r1 = r0; \ 29*81d1d6ddSEduard Zingerman r0 = 0x100000000 ll; \ 30*81d1d6ddSEduard Zingerman w0 += w1; \ 31*81d1d6ddSEduard Zingerman r0 >>= 32; \ 32*81d1d6ddSEduard Zingerman exit; \ 33*81d1d6ddSEduard Zingerman " : 34*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 35*81d1d6ddSEduard Zingerman : __clobber_all); 36*81d1d6ddSEduard Zingerman } 37*81d1d6ddSEduard Zingerman 38*81d1d6ddSEduard Zingerman SEC("socket") 39*81d1d6ddSEduard Zingerman __description("add32 imm zero extend check") 40*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) add32_imm_zero_extend_check(void)41*81d1d6ddSEduard Zingerman__naked void add32_imm_zero_extend_check(void) 42*81d1d6ddSEduard Zingerman { 43*81d1d6ddSEduard Zingerman asm volatile (" \ 44*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 45*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 46*81d1d6ddSEduard Zingerman r0 |= r1; \ 47*81d1d6ddSEduard Zingerman /* An insn could have no effect on the low 32-bit, for example:\ 48*81d1d6ddSEduard Zingerman * a = a + 0 \ 49*81d1d6ddSEduard Zingerman * a = a | 0 \ 50*81d1d6ddSEduard Zingerman * a = a & -1 \ 51*81d1d6ddSEduard Zingerman * But, they should still zero high 32-bit. \ 52*81d1d6ddSEduard Zingerman */ \ 53*81d1d6ddSEduard Zingerman w0 += 0; \ 54*81d1d6ddSEduard Zingerman r0 >>= 32; \ 55*81d1d6ddSEduard Zingerman r6 = r0; \ 56*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 57*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 58*81d1d6ddSEduard Zingerman r0 |= r1; \ 59*81d1d6ddSEduard Zingerman w0 += -2; \ 60*81d1d6ddSEduard Zingerman r0 >>= 32; \ 61*81d1d6ddSEduard Zingerman r0 |= r6; \ 62*81d1d6ddSEduard Zingerman exit; \ 63*81d1d6ddSEduard Zingerman " : 64*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 65*81d1d6ddSEduard Zingerman : __clobber_all); 66*81d1d6ddSEduard Zingerman } 67*81d1d6ddSEduard Zingerman 68*81d1d6ddSEduard Zingerman SEC("socket") 69*81d1d6ddSEduard Zingerman __description("sub32 reg zero extend check") 70*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) sub32_reg_zero_extend_check(void)71*81d1d6ddSEduard Zingerman__naked void sub32_reg_zero_extend_check(void) 72*81d1d6ddSEduard Zingerman { 73*81d1d6ddSEduard Zingerman asm volatile (" \ 74*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 75*81d1d6ddSEduard Zingerman r1 = r0; \ 76*81d1d6ddSEduard Zingerman r0 = 0x1ffffffff ll; \ 77*81d1d6ddSEduard Zingerman w0 -= w1; \ 78*81d1d6ddSEduard Zingerman r0 >>= 32; \ 79*81d1d6ddSEduard Zingerman exit; \ 80*81d1d6ddSEduard Zingerman " : 81*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 82*81d1d6ddSEduard Zingerman : __clobber_all); 83*81d1d6ddSEduard Zingerman } 84*81d1d6ddSEduard Zingerman 85*81d1d6ddSEduard Zingerman SEC("socket") 86*81d1d6ddSEduard Zingerman __description("sub32 imm zero extend check") 87*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) sub32_imm_zero_extend_check(void)88*81d1d6ddSEduard Zingerman__naked void sub32_imm_zero_extend_check(void) 89*81d1d6ddSEduard Zingerman { 90*81d1d6ddSEduard Zingerman asm volatile (" \ 91*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 92*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 93*81d1d6ddSEduard Zingerman r0 |= r1; \ 94*81d1d6ddSEduard Zingerman w0 -= 0; \ 95*81d1d6ddSEduard Zingerman r0 >>= 32; \ 96*81d1d6ddSEduard Zingerman r6 = r0; \ 97*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 98*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 99*81d1d6ddSEduard Zingerman r0 |= r1; \ 100*81d1d6ddSEduard Zingerman w0 -= 1; \ 101*81d1d6ddSEduard Zingerman r0 >>= 32; \ 102*81d1d6ddSEduard Zingerman r0 |= r6; \ 103*81d1d6ddSEduard Zingerman exit; \ 104*81d1d6ddSEduard Zingerman " : 105*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 106*81d1d6ddSEduard Zingerman : __clobber_all); 107*81d1d6ddSEduard Zingerman } 108*81d1d6ddSEduard Zingerman 109*81d1d6ddSEduard Zingerman SEC("socket") 110*81d1d6ddSEduard Zingerman __description("mul32 reg zero extend check") 111*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mul32_reg_zero_extend_check(void)112*81d1d6ddSEduard Zingerman__naked void mul32_reg_zero_extend_check(void) 113*81d1d6ddSEduard Zingerman { 114*81d1d6ddSEduard Zingerman asm volatile (" \ 115*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 116*81d1d6ddSEduard Zingerman r1 = r0; \ 117*81d1d6ddSEduard Zingerman r0 = 0x100000001 ll; \ 118*81d1d6ddSEduard Zingerman w0 *= w1; \ 119*81d1d6ddSEduard Zingerman r0 >>= 32; \ 120*81d1d6ddSEduard Zingerman exit; \ 121*81d1d6ddSEduard Zingerman " : 122*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 123*81d1d6ddSEduard Zingerman : __clobber_all); 124*81d1d6ddSEduard Zingerman } 125*81d1d6ddSEduard Zingerman 126*81d1d6ddSEduard Zingerman SEC("socket") 127*81d1d6ddSEduard Zingerman __description("mul32 imm zero extend check") 128*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mul32_imm_zero_extend_check(void)129*81d1d6ddSEduard Zingerman__naked void mul32_imm_zero_extend_check(void) 130*81d1d6ddSEduard Zingerman { 131*81d1d6ddSEduard Zingerman asm volatile (" \ 132*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 133*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 134*81d1d6ddSEduard Zingerman r0 |= r1; \ 135*81d1d6ddSEduard Zingerman w0 *= 1; \ 136*81d1d6ddSEduard Zingerman r0 >>= 32; \ 137*81d1d6ddSEduard Zingerman r6 = r0; \ 138*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 139*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 140*81d1d6ddSEduard Zingerman r0 |= r1; \ 141*81d1d6ddSEduard Zingerman w0 *= -1; \ 142*81d1d6ddSEduard Zingerman r0 >>= 32; \ 143*81d1d6ddSEduard Zingerman r0 |= r6; \ 144*81d1d6ddSEduard Zingerman exit; \ 145*81d1d6ddSEduard Zingerman " : 146*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 147*81d1d6ddSEduard Zingerman : __clobber_all); 148*81d1d6ddSEduard Zingerman } 149*81d1d6ddSEduard Zingerman 150*81d1d6ddSEduard Zingerman SEC("socket") 151*81d1d6ddSEduard Zingerman __description("div32 reg zero extend check") 152*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) div32_reg_zero_extend_check(void)153*81d1d6ddSEduard Zingerman__naked void div32_reg_zero_extend_check(void) 154*81d1d6ddSEduard Zingerman { 155*81d1d6ddSEduard Zingerman asm volatile (" \ 156*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 157*81d1d6ddSEduard Zingerman r1 = r0; \ 158*81d1d6ddSEduard Zingerman r0 = -1; \ 159*81d1d6ddSEduard Zingerman w0 /= w1; \ 160*81d1d6ddSEduard Zingerman r0 >>= 32; \ 161*81d1d6ddSEduard Zingerman exit; \ 162*81d1d6ddSEduard Zingerman " : 163*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 164*81d1d6ddSEduard Zingerman : __clobber_all); 165*81d1d6ddSEduard Zingerman } 166*81d1d6ddSEduard Zingerman 167*81d1d6ddSEduard Zingerman SEC("socket") 168*81d1d6ddSEduard Zingerman __description("div32 imm zero extend check") 169*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) div32_imm_zero_extend_check(void)170*81d1d6ddSEduard Zingerman__naked void div32_imm_zero_extend_check(void) 171*81d1d6ddSEduard Zingerman { 172*81d1d6ddSEduard Zingerman asm volatile (" \ 173*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 174*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 175*81d1d6ddSEduard Zingerman r0 |= r1; \ 176*81d1d6ddSEduard Zingerman w0 /= 1; \ 177*81d1d6ddSEduard Zingerman r0 >>= 32; \ 178*81d1d6ddSEduard Zingerman r6 = r0; \ 179*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 180*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 181*81d1d6ddSEduard Zingerman r0 |= r1; \ 182*81d1d6ddSEduard Zingerman w0 /= 2; \ 183*81d1d6ddSEduard Zingerman r0 >>= 32; \ 184*81d1d6ddSEduard Zingerman r0 |= r6; \ 185*81d1d6ddSEduard Zingerman exit; \ 186*81d1d6ddSEduard Zingerman " : 187*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 188*81d1d6ddSEduard Zingerman : __clobber_all); 189*81d1d6ddSEduard Zingerman } 190*81d1d6ddSEduard Zingerman 191*81d1d6ddSEduard Zingerman SEC("socket") 192*81d1d6ddSEduard Zingerman __description("or32 reg zero extend check") 193*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) or32_reg_zero_extend_check(void)194*81d1d6ddSEduard Zingerman__naked void or32_reg_zero_extend_check(void) 195*81d1d6ddSEduard Zingerman { 196*81d1d6ddSEduard Zingerman asm volatile (" \ 197*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 198*81d1d6ddSEduard Zingerman r1 = r0; \ 199*81d1d6ddSEduard Zingerman r0 = 0x100000001 ll; \ 200*81d1d6ddSEduard Zingerman w0 |= w1; \ 201*81d1d6ddSEduard Zingerman r0 >>= 32; \ 202*81d1d6ddSEduard Zingerman exit; \ 203*81d1d6ddSEduard Zingerman " : 204*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 205*81d1d6ddSEduard Zingerman : __clobber_all); 206*81d1d6ddSEduard Zingerman } 207*81d1d6ddSEduard Zingerman 208*81d1d6ddSEduard Zingerman SEC("socket") 209*81d1d6ddSEduard Zingerman __description("or32 imm zero extend check") 210*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) or32_imm_zero_extend_check(void)211*81d1d6ddSEduard Zingerman__naked void or32_imm_zero_extend_check(void) 212*81d1d6ddSEduard Zingerman { 213*81d1d6ddSEduard Zingerman asm volatile (" \ 214*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 215*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 216*81d1d6ddSEduard Zingerman r0 |= r1; \ 217*81d1d6ddSEduard Zingerman w0 |= 0; \ 218*81d1d6ddSEduard Zingerman r0 >>= 32; \ 219*81d1d6ddSEduard Zingerman r6 = r0; \ 220*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 221*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 222*81d1d6ddSEduard Zingerman r0 |= r1; \ 223*81d1d6ddSEduard Zingerman w0 |= 1; \ 224*81d1d6ddSEduard Zingerman r0 >>= 32; \ 225*81d1d6ddSEduard Zingerman r0 |= r6; \ 226*81d1d6ddSEduard Zingerman exit; \ 227*81d1d6ddSEduard Zingerman " : 228*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 229*81d1d6ddSEduard Zingerman : __clobber_all); 230*81d1d6ddSEduard Zingerman } 231*81d1d6ddSEduard Zingerman 232*81d1d6ddSEduard Zingerman SEC("socket") 233*81d1d6ddSEduard Zingerman __description("and32 reg zero extend check") 234*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) and32_reg_zero_extend_check(void)235*81d1d6ddSEduard Zingerman__naked void and32_reg_zero_extend_check(void) 236*81d1d6ddSEduard Zingerman { 237*81d1d6ddSEduard Zingerman asm volatile (" \ 238*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 239*81d1d6ddSEduard Zingerman r1 = 0x100000000 ll; \ 240*81d1d6ddSEduard Zingerman r1 |= r0; \ 241*81d1d6ddSEduard Zingerman r0 = 0x1ffffffff ll; \ 242*81d1d6ddSEduard Zingerman w0 &= w1; \ 243*81d1d6ddSEduard Zingerman r0 >>= 32; \ 244*81d1d6ddSEduard Zingerman exit; \ 245*81d1d6ddSEduard Zingerman " : 246*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 247*81d1d6ddSEduard Zingerman : __clobber_all); 248*81d1d6ddSEduard Zingerman } 249*81d1d6ddSEduard Zingerman 250*81d1d6ddSEduard Zingerman SEC("socket") 251*81d1d6ddSEduard Zingerman __description("and32 imm zero extend check") 252*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) and32_imm_zero_extend_check(void)253*81d1d6ddSEduard Zingerman__naked void and32_imm_zero_extend_check(void) 254*81d1d6ddSEduard Zingerman { 255*81d1d6ddSEduard Zingerman asm volatile (" \ 256*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 257*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 258*81d1d6ddSEduard Zingerman r0 |= r1; \ 259*81d1d6ddSEduard Zingerman w0 &= -1; \ 260*81d1d6ddSEduard Zingerman r0 >>= 32; \ 261*81d1d6ddSEduard Zingerman r6 = r0; \ 262*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 263*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 264*81d1d6ddSEduard Zingerman r0 |= r1; \ 265*81d1d6ddSEduard Zingerman w0 &= -2; \ 266*81d1d6ddSEduard Zingerman r0 >>= 32; \ 267*81d1d6ddSEduard Zingerman r0 |= r6; \ 268*81d1d6ddSEduard Zingerman exit; \ 269*81d1d6ddSEduard Zingerman " : 270*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 271*81d1d6ddSEduard Zingerman : __clobber_all); 272*81d1d6ddSEduard Zingerman } 273*81d1d6ddSEduard Zingerman 274*81d1d6ddSEduard Zingerman SEC("socket") 275*81d1d6ddSEduard Zingerman __description("lsh32 reg zero extend check") 276*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) lsh32_reg_zero_extend_check(void)277*81d1d6ddSEduard Zingerman__naked void lsh32_reg_zero_extend_check(void) 278*81d1d6ddSEduard Zingerman { 279*81d1d6ddSEduard Zingerman asm volatile (" \ 280*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 281*81d1d6ddSEduard Zingerman r1 = 0x100000000 ll; \ 282*81d1d6ddSEduard Zingerman r0 |= r1; \ 283*81d1d6ddSEduard Zingerman r1 = 1; \ 284*81d1d6ddSEduard Zingerman w0 <<= w1; \ 285*81d1d6ddSEduard Zingerman r0 >>= 32; \ 286*81d1d6ddSEduard Zingerman exit; \ 287*81d1d6ddSEduard Zingerman " : 288*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 289*81d1d6ddSEduard Zingerman : __clobber_all); 290*81d1d6ddSEduard Zingerman } 291*81d1d6ddSEduard Zingerman 292*81d1d6ddSEduard Zingerman SEC("socket") 293*81d1d6ddSEduard Zingerman __description("lsh32 imm zero extend check") 294*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) lsh32_imm_zero_extend_check(void)295*81d1d6ddSEduard Zingerman__naked void lsh32_imm_zero_extend_check(void) 296*81d1d6ddSEduard Zingerman { 297*81d1d6ddSEduard Zingerman asm volatile (" \ 298*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 299*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 300*81d1d6ddSEduard Zingerman r0 |= r1; \ 301*81d1d6ddSEduard Zingerman w0 <<= 0; \ 302*81d1d6ddSEduard Zingerman r0 >>= 32; \ 303*81d1d6ddSEduard Zingerman r6 = r0; \ 304*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 305*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 306*81d1d6ddSEduard Zingerman r0 |= r1; \ 307*81d1d6ddSEduard Zingerman w0 <<= 1; \ 308*81d1d6ddSEduard Zingerman r0 >>= 32; \ 309*81d1d6ddSEduard Zingerman r0 |= r6; \ 310*81d1d6ddSEduard Zingerman exit; \ 311*81d1d6ddSEduard Zingerman " : 312*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 313*81d1d6ddSEduard Zingerman : __clobber_all); 314*81d1d6ddSEduard Zingerman } 315*81d1d6ddSEduard Zingerman 316*81d1d6ddSEduard Zingerman SEC("socket") 317*81d1d6ddSEduard Zingerman __description("rsh32 reg zero extend check") 318*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) rsh32_reg_zero_extend_check(void)319*81d1d6ddSEduard Zingerman__naked void rsh32_reg_zero_extend_check(void) 320*81d1d6ddSEduard Zingerman { 321*81d1d6ddSEduard Zingerman asm volatile (" \ 322*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 323*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 324*81d1d6ddSEduard Zingerman r0 |= r1; \ 325*81d1d6ddSEduard Zingerman r1 = 1; \ 326*81d1d6ddSEduard Zingerman w0 >>= w1; \ 327*81d1d6ddSEduard Zingerman r0 >>= 32; \ 328*81d1d6ddSEduard Zingerman exit; \ 329*81d1d6ddSEduard Zingerman " : 330*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 331*81d1d6ddSEduard Zingerman : __clobber_all); 332*81d1d6ddSEduard Zingerman } 333*81d1d6ddSEduard Zingerman 334*81d1d6ddSEduard Zingerman SEC("socket") 335*81d1d6ddSEduard Zingerman __description("rsh32 imm zero extend check") 336*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) rsh32_imm_zero_extend_check(void)337*81d1d6ddSEduard Zingerman__naked void rsh32_imm_zero_extend_check(void) 338*81d1d6ddSEduard Zingerman { 339*81d1d6ddSEduard Zingerman asm volatile (" \ 340*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 341*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 342*81d1d6ddSEduard Zingerman r0 |= r1; \ 343*81d1d6ddSEduard Zingerman w0 >>= 0; \ 344*81d1d6ddSEduard Zingerman r0 >>= 32; \ 345*81d1d6ddSEduard Zingerman r6 = r0; \ 346*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 347*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 348*81d1d6ddSEduard Zingerman r0 |= r1; \ 349*81d1d6ddSEduard Zingerman w0 >>= 1; \ 350*81d1d6ddSEduard Zingerman r0 >>= 32; \ 351*81d1d6ddSEduard Zingerman r0 |= r6; \ 352*81d1d6ddSEduard Zingerman exit; \ 353*81d1d6ddSEduard Zingerman " : 354*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 355*81d1d6ddSEduard Zingerman : __clobber_all); 356*81d1d6ddSEduard Zingerman } 357*81d1d6ddSEduard Zingerman 358*81d1d6ddSEduard Zingerman SEC("socket") 359*81d1d6ddSEduard Zingerman __description("neg32 reg zero extend check") 360*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) neg32_reg_zero_extend_check(void)361*81d1d6ddSEduard Zingerman__naked void neg32_reg_zero_extend_check(void) 362*81d1d6ddSEduard Zingerman { 363*81d1d6ddSEduard Zingerman asm volatile (" \ 364*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 365*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 366*81d1d6ddSEduard Zingerman r0 |= r1; \ 367*81d1d6ddSEduard Zingerman w0 = -w0; \ 368*81d1d6ddSEduard Zingerman r0 >>= 32; \ 369*81d1d6ddSEduard Zingerman exit; \ 370*81d1d6ddSEduard Zingerman " : 371*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 372*81d1d6ddSEduard Zingerman : __clobber_all); 373*81d1d6ddSEduard Zingerman } 374*81d1d6ddSEduard Zingerman 375*81d1d6ddSEduard Zingerman SEC("socket") 376*81d1d6ddSEduard Zingerman __description("mod32 reg zero extend check") 377*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mod32_reg_zero_extend_check(void)378*81d1d6ddSEduard Zingerman__naked void mod32_reg_zero_extend_check(void) 379*81d1d6ddSEduard Zingerman { 380*81d1d6ddSEduard Zingerman asm volatile (" \ 381*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 382*81d1d6ddSEduard Zingerman r1 = r0; \ 383*81d1d6ddSEduard Zingerman r0 = -1; \ 384*81d1d6ddSEduard Zingerman w0 %%= w1; \ 385*81d1d6ddSEduard Zingerman r0 >>= 32; \ 386*81d1d6ddSEduard Zingerman exit; \ 387*81d1d6ddSEduard Zingerman " : 388*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 389*81d1d6ddSEduard Zingerman : __clobber_all); 390*81d1d6ddSEduard Zingerman } 391*81d1d6ddSEduard Zingerman 392*81d1d6ddSEduard Zingerman SEC("socket") 393*81d1d6ddSEduard Zingerman __description("mod32 imm zero extend check") 394*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mod32_imm_zero_extend_check(void)395*81d1d6ddSEduard Zingerman__naked void mod32_imm_zero_extend_check(void) 396*81d1d6ddSEduard Zingerman { 397*81d1d6ddSEduard Zingerman asm volatile (" \ 398*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 399*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 400*81d1d6ddSEduard Zingerman r0 |= r1; \ 401*81d1d6ddSEduard Zingerman w0 %%= 1; \ 402*81d1d6ddSEduard Zingerman r0 >>= 32; \ 403*81d1d6ddSEduard Zingerman r6 = r0; \ 404*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 405*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 406*81d1d6ddSEduard Zingerman r0 |= r1; \ 407*81d1d6ddSEduard Zingerman w0 %%= 2; \ 408*81d1d6ddSEduard Zingerman r0 >>= 32; \ 409*81d1d6ddSEduard Zingerman r0 |= r6; \ 410*81d1d6ddSEduard Zingerman exit; \ 411*81d1d6ddSEduard Zingerman " : 412*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 413*81d1d6ddSEduard Zingerman : __clobber_all); 414*81d1d6ddSEduard Zingerman } 415*81d1d6ddSEduard Zingerman 416*81d1d6ddSEduard Zingerman SEC("socket") 417*81d1d6ddSEduard Zingerman __description("xor32 reg zero extend check") 418*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) xor32_reg_zero_extend_check(void)419*81d1d6ddSEduard Zingerman__naked void xor32_reg_zero_extend_check(void) 420*81d1d6ddSEduard Zingerman { 421*81d1d6ddSEduard Zingerman asm volatile (" \ 422*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 423*81d1d6ddSEduard Zingerman r1 = r0; \ 424*81d1d6ddSEduard Zingerman r0 = 0x100000000 ll; \ 425*81d1d6ddSEduard Zingerman w0 ^= w1; \ 426*81d1d6ddSEduard Zingerman r0 >>= 32; \ 427*81d1d6ddSEduard Zingerman exit; \ 428*81d1d6ddSEduard Zingerman " : 429*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 430*81d1d6ddSEduard Zingerman : __clobber_all); 431*81d1d6ddSEduard Zingerman } 432*81d1d6ddSEduard Zingerman 433*81d1d6ddSEduard Zingerman SEC("socket") 434*81d1d6ddSEduard Zingerman __description("xor32 imm zero extend check") 435*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) xor32_imm_zero_extend_check(void)436*81d1d6ddSEduard Zingerman__naked void xor32_imm_zero_extend_check(void) 437*81d1d6ddSEduard Zingerman { 438*81d1d6ddSEduard Zingerman asm volatile (" \ 439*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 440*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 441*81d1d6ddSEduard Zingerman r0 |= r1; \ 442*81d1d6ddSEduard Zingerman w0 ^= 1; \ 443*81d1d6ddSEduard Zingerman r0 >>= 32; \ 444*81d1d6ddSEduard Zingerman exit; \ 445*81d1d6ddSEduard Zingerman " : 446*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 447*81d1d6ddSEduard Zingerman : __clobber_all); 448*81d1d6ddSEduard Zingerman } 449*81d1d6ddSEduard Zingerman 450*81d1d6ddSEduard Zingerman SEC("socket") 451*81d1d6ddSEduard Zingerman __description("mov32 reg zero extend check") 452*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mov32_reg_zero_extend_check(void)453*81d1d6ddSEduard Zingerman__naked void mov32_reg_zero_extend_check(void) 454*81d1d6ddSEduard Zingerman { 455*81d1d6ddSEduard Zingerman asm volatile (" \ 456*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 457*81d1d6ddSEduard Zingerman r1 = 0x100000000 ll; \ 458*81d1d6ddSEduard Zingerman r1 |= r0; \ 459*81d1d6ddSEduard Zingerman r0 = 0x100000000 ll; \ 460*81d1d6ddSEduard Zingerman w0 = w1; \ 461*81d1d6ddSEduard Zingerman r0 >>= 32; \ 462*81d1d6ddSEduard Zingerman exit; \ 463*81d1d6ddSEduard Zingerman " : 464*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 465*81d1d6ddSEduard Zingerman : __clobber_all); 466*81d1d6ddSEduard Zingerman } 467*81d1d6ddSEduard Zingerman 468*81d1d6ddSEduard Zingerman SEC("socket") 469*81d1d6ddSEduard Zingerman __description("mov32 imm zero extend check") 470*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) mov32_imm_zero_extend_check(void)471*81d1d6ddSEduard Zingerman__naked void mov32_imm_zero_extend_check(void) 472*81d1d6ddSEduard Zingerman { 473*81d1d6ddSEduard Zingerman asm volatile (" \ 474*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 475*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 476*81d1d6ddSEduard Zingerman r0 |= r1; \ 477*81d1d6ddSEduard Zingerman w0 = 0; \ 478*81d1d6ddSEduard Zingerman r0 >>= 32; \ 479*81d1d6ddSEduard Zingerman r6 = r0; \ 480*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 481*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 482*81d1d6ddSEduard Zingerman r0 |= r1; \ 483*81d1d6ddSEduard Zingerman w0 = 1; \ 484*81d1d6ddSEduard Zingerman r0 >>= 32; \ 485*81d1d6ddSEduard Zingerman r0 |= r6; \ 486*81d1d6ddSEduard Zingerman exit; \ 487*81d1d6ddSEduard Zingerman " : 488*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 489*81d1d6ddSEduard Zingerman : __clobber_all); 490*81d1d6ddSEduard Zingerman } 491*81d1d6ddSEduard Zingerman 492*81d1d6ddSEduard Zingerman SEC("socket") 493*81d1d6ddSEduard Zingerman __description("arsh32 reg zero extend check") 494*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) arsh32_reg_zero_extend_check(void)495*81d1d6ddSEduard Zingerman__naked void arsh32_reg_zero_extend_check(void) 496*81d1d6ddSEduard Zingerman { 497*81d1d6ddSEduard Zingerman asm volatile (" \ 498*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 499*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 500*81d1d6ddSEduard Zingerman r0 |= r1; \ 501*81d1d6ddSEduard Zingerman r1 = 1; \ 502*81d1d6ddSEduard Zingerman w0 s>>= w1; \ 503*81d1d6ddSEduard Zingerman r0 >>= 32; \ 504*81d1d6ddSEduard Zingerman exit; \ 505*81d1d6ddSEduard Zingerman " : 506*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 507*81d1d6ddSEduard Zingerman : __clobber_all); 508*81d1d6ddSEduard Zingerman } 509*81d1d6ddSEduard Zingerman 510*81d1d6ddSEduard Zingerman SEC("socket") 511*81d1d6ddSEduard Zingerman __description("arsh32 imm zero extend check") 512*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) arsh32_imm_zero_extend_check(void)513*81d1d6ddSEduard Zingerman__naked void arsh32_imm_zero_extend_check(void) 514*81d1d6ddSEduard Zingerman { 515*81d1d6ddSEduard Zingerman asm volatile (" \ 516*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 517*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 518*81d1d6ddSEduard Zingerman r0 |= r1; \ 519*81d1d6ddSEduard Zingerman w0 s>>= 0; \ 520*81d1d6ddSEduard Zingerman r0 >>= 32; \ 521*81d1d6ddSEduard Zingerman r6 = r0; \ 522*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 523*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 524*81d1d6ddSEduard Zingerman r0 |= r1; \ 525*81d1d6ddSEduard Zingerman w0 s>>= 1; \ 526*81d1d6ddSEduard Zingerman r0 >>= 32; \ 527*81d1d6ddSEduard Zingerman r0 |= r6; \ 528*81d1d6ddSEduard Zingerman exit; \ 529*81d1d6ddSEduard Zingerman " : 530*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 531*81d1d6ddSEduard Zingerman : __clobber_all); 532*81d1d6ddSEduard Zingerman } 533*81d1d6ddSEduard Zingerman 534*81d1d6ddSEduard Zingerman SEC("socket") 535*81d1d6ddSEduard Zingerman __description("end16 (to_le) reg zero extend check") 536*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) le_reg_zero_extend_check_1(void)537*81d1d6ddSEduard Zingerman__naked void le_reg_zero_extend_check_1(void) 538*81d1d6ddSEduard Zingerman { 539*81d1d6ddSEduard Zingerman asm volatile (" \ 540*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 541*81d1d6ddSEduard Zingerman r6 = r0; \ 542*81d1d6ddSEduard Zingerman r6 <<= 32; \ 543*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 544*81d1d6ddSEduard Zingerman r0 |= r6; \ 545*81d1d6ddSEduard Zingerman r0 = le16 r0; \ 546*81d1d6ddSEduard Zingerman r0 >>= 32; \ 547*81d1d6ddSEduard Zingerman exit; \ 548*81d1d6ddSEduard Zingerman " : 549*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 550*81d1d6ddSEduard Zingerman : __clobber_all); 551*81d1d6ddSEduard Zingerman } 552*81d1d6ddSEduard Zingerman 553*81d1d6ddSEduard Zingerman SEC("socket") 554*81d1d6ddSEduard Zingerman __description("end32 (to_le) reg zero extend check") 555*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) le_reg_zero_extend_check_2(void)556*81d1d6ddSEduard Zingerman__naked void le_reg_zero_extend_check_2(void) 557*81d1d6ddSEduard Zingerman { 558*81d1d6ddSEduard Zingerman asm volatile (" \ 559*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 560*81d1d6ddSEduard Zingerman r6 = r0; \ 561*81d1d6ddSEduard Zingerman r6 <<= 32; \ 562*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 563*81d1d6ddSEduard Zingerman r0 |= r6; \ 564*81d1d6ddSEduard Zingerman r0 = le32 r0; \ 565*81d1d6ddSEduard Zingerman r0 >>= 32; \ 566*81d1d6ddSEduard Zingerman exit; \ 567*81d1d6ddSEduard Zingerman " : 568*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 569*81d1d6ddSEduard Zingerman : __clobber_all); 570*81d1d6ddSEduard Zingerman } 571*81d1d6ddSEduard Zingerman 572*81d1d6ddSEduard Zingerman SEC("socket") 573*81d1d6ddSEduard Zingerman __description("end16 (to_be) reg zero extend check") 574*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) be_reg_zero_extend_check_1(void)575*81d1d6ddSEduard Zingerman__naked void be_reg_zero_extend_check_1(void) 576*81d1d6ddSEduard Zingerman { 577*81d1d6ddSEduard Zingerman asm volatile (" \ 578*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 579*81d1d6ddSEduard Zingerman r6 = r0; \ 580*81d1d6ddSEduard Zingerman r6 <<= 32; \ 581*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 582*81d1d6ddSEduard Zingerman r0 |= r6; \ 583*81d1d6ddSEduard Zingerman r0 = be16 r0; \ 584*81d1d6ddSEduard Zingerman r0 >>= 32; \ 585*81d1d6ddSEduard Zingerman exit; \ 586*81d1d6ddSEduard Zingerman " : 587*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 588*81d1d6ddSEduard Zingerman : __clobber_all); 589*81d1d6ddSEduard Zingerman } 590*81d1d6ddSEduard Zingerman 591*81d1d6ddSEduard Zingerman SEC("socket") 592*81d1d6ddSEduard Zingerman __description("end32 (to_be) reg zero extend check") 593*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) be_reg_zero_extend_check_2(void)594*81d1d6ddSEduard Zingerman__naked void be_reg_zero_extend_check_2(void) 595*81d1d6ddSEduard Zingerman { 596*81d1d6ddSEduard Zingerman asm volatile (" \ 597*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 598*81d1d6ddSEduard Zingerman r6 = r0; \ 599*81d1d6ddSEduard Zingerman r6 <<= 32; \ 600*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 601*81d1d6ddSEduard Zingerman r0 |= r6; \ 602*81d1d6ddSEduard Zingerman r0 = be32 r0; \ 603*81d1d6ddSEduard Zingerman r0 >>= 32; \ 604*81d1d6ddSEduard Zingerman exit; \ 605*81d1d6ddSEduard Zingerman " : 606*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 607*81d1d6ddSEduard Zingerman : __clobber_all); 608*81d1d6ddSEduard Zingerman } 609*81d1d6ddSEduard Zingerman 610*81d1d6ddSEduard Zingerman SEC("socket") 611*81d1d6ddSEduard Zingerman __description("ldx_b zero extend check") 612*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) ldx_b_zero_extend_check(void)613*81d1d6ddSEduard Zingerman__naked void ldx_b_zero_extend_check(void) 614*81d1d6ddSEduard Zingerman { 615*81d1d6ddSEduard Zingerman asm volatile (" \ 616*81d1d6ddSEduard Zingerman r6 = r10; \ 617*81d1d6ddSEduard Zingerman r6 += -4; \ 618*81d1d6ddSEduard Zingerman r7 = 0xfaceb00c; \ 619*81d1d6ddSEduard Zingerman *(u32*)(r6 + 0) = r7; \ 620*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 621*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 622*81d1d6ddSEduard Zingerman r0 |= r1; \ 623*81d1d6ddSEduard Zingerman r0 = *(u8*)(r6 + 0); \ 624*81d1d6ddSEduard Zingerman r0 >>= 32; \ 625*81d1d6ddSEduard Zingerman exit; \ 626*81d1d6ddSEduard Zingerman " : 627*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 628*81d1d6ddSEduard Zingerman : __clobber_all); 629*81d1d6ddSEduard Zingerman } 630*81d1d6ddSEduard Zingerman 631*81d1d6ddSEduard Zingerman SEC("socket") 632*81d1d6ddSEduard Zingerman __description("ldx_h zero extend check") 633*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) ldx_h_zero_extend_check(void)634*81d1d6ddSEduard Zingerman__naked void ldx_h_zero_extend_check(void) 635*81d1d6ddSEduard Zingerman { 636*81d1d6ddSEduard Zingerman asm volatile (" \ 637*81d1d6ddSEduard Zingerman r6 = r10; \ 638*81d1d6ddSEduard Zingerman r6 += -4; \ 639*81d1d6ddSEduard Zingerman r7 = 0xfaceb00c; \ 640*81d1d6ddSEduard Zingerman *(u32*)(r6 + 0) = r7; \ 641*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 642*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 643*81d1d6ddSEduard Zingerman r0 |= r1; \ 644*81d1d6ddSEduard Zingerman r0 = *(u16*)(r6 + 0); \ 645*81d1d6ddSEduard Zingerman r0 >>= 32; \ 646*81d1d6ddSEduard Zingerman exit; \ 647*81d1d6ddSEduard Zingerman " : 648*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 649*81d1d6ddSEduard Zingerman : __clobber_all); 650*81d1d6ddSEduard Zingerman } 651*81d1d6ddSEduard Zingerman 652*81d1d6ddSEduard Zingerman SEC("socket") 653*81d1d6ddSEduard Zingerman __description("ldx_w zero extend check") 654*81d1d6ddSEduard Zingerman __success __success_unpriv __retval(0) ldx_w_zero_extend_check(void)655*81d1d6ddSEduard Zingerman__naked void ldx_w_zero_extend_check(void) 656*81d1d6ddSEduard Zingerman { 657*81d1d6ddSEduard Zingerman asm volatile (" \ 658*81d1d6ddSEduard Zingerman r6 = r10; \ 659*81d1d6ddSEduard Zingerman r6 += -4; \ 660*81d1d6ddSEduard Zingerman r7 = 0xfaceb00c; \ 661*81d1d6ddSEduard Zingerman *(u32*)(r6 + 0) = r7; \ 662*81d1d6ddSEduard Zingerman call %[bpf_get_prandom_u32]; \ 663*81d1d6ddSEduard Zingerman r1 = 0x1000000000 ll; \ 664*81d1d6ddSEduard Zingerman r0 |= r1; \ 665*81d1d6ddSEduard Zingerman r0 = *(u32*)(r6 + 0); \ 666*81d1d6ddSEduard Zingerman r0 >>= 32; \ 667*81d1d6ddSEduard Zingerman exit; \ 668*81d1d6ddSEduard Zingerman " : 669*81d1d6ddSEduard Zingerman : __imm(bpf_get_prandom_u32) 670*81d1d6ddSEduard Zingerman : __clobber_all); 671*81d1d6ddSEduard Zingerman } 672*81d1d6ddSEduard Zingerman 673*81d1d6ddSEduard Zingerman char _license[] SEC("license") = "GPL"; 674