11a24af65SEduard Zingerman { 21a24af65SEduard Zingerman "BPF_ST_MEM stack imm non-zero", 31a24af65SEduard Zingerman .insns = { 41a24af65SEduard Zingerman BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 42), 51a24af65SEduard Zingerman BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 61a24af65SEduard Zingerman BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -42), 71a24af65SEduard Zingerman /* if value is tracked correctly R0 is zero */ 81a24af65SEduard Zingerman BPF_EXIT_INSN(), 91a24af65SEduard Zingerman }, 101a24af65SEduard Zingerman .result = ACCEPT, 111a24af65SEduard Zingerman /* Use prog type that requires return value in range [0, 1] */ 121a24af65SEduard Zingerman .prog_type = BPF_PROG_TYPE_SK_LOOKUP, 131a24af65SEduard Zingerman .expected_attach_type = BPF_SK_LOOKUP, 141a24af65SEduard Zingerman .runs = -1, 151a24af65SEduard Zingerman }, 161a24af65SEduard Zingerman { 171a24af65SEduard Zingerman "BPF_ST_MEM stack imm zero", 181a24af65SEduard Zingerman .insns = { 191a24af65SEduard Zingerman /* mark stack 0000 0000 */ 201a24af65SEduard Zingerman BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 211a24af65SEduard Zingerman /* read and sum a few bytes */ 221a24af65SEduard Zingerman BPF_MOV64_IMM(BPF_REG_0, 0), 231a24af65SEduard Zingerman BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, -8), 241a24af65SEduard Zingerman BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 251a24af65SEduard Zingerman BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, -4), 261a24af65SEduard Zingerman BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 271a24af65SEduard Zingerman BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, -1), 281a24af65SEduard Zingerman BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 291a24af65SEduard Zingerman /* if value is tracked correctly R0 is zero */ 301a24af65SEduard Zingerman BPF_EXIT_INSN(), 311a24af65SEduard Zingerman }, 321a24af65SEduard Zingerman .result = ACCEPT, 331a24af65SEduard Zingerman /* Use prog type that requires return value in range [0, 1] */ 341a24af65SEduard Zingerman .prog_type = BPF_PROG_TYPE_SK_LOOKUP, 351a24af65SEduard Zingerman .expected_attach_type = BPF_SK_LOOKUP, 361a24af65SEduard Zingerman .runs = -1, 371a24af65SEduard Zingerman }, 382a33c5a2SEduard Zingerman { 392a33c5a2SEduard Zingerman "BPF_ST_MEM stack imm zero, variable offset", 402a33c5a2SEduard Zingerman .insns = { 412a33c5a2SEduard Zingerman /* set fp[-16], fp[-24] to zeros */ 422a33c5a2SEduard Zingerman BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 432a33c5a2SEduard Zingerman BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0), 442a33c5a2SEduard Zingerman /* r0 = random value in range [-32, -15] */ 452a33c5a2SEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), 462a33c5a2SEduard Zingerman BPF_JMP_IMM(BPF_JLE, BPF_REG_0, 16, 2), 472a33c5a2SEduard Zingerman BPF_MOV64_IMM(BPF_REG_0, 0), 482a33c5a2SEduard Zingerman BPF_EXIT_INSN(), 492a33c5a2SEduard Zingerman BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 32), 502a33c5a2SEduard Zingerman /* fp[r0] = 0, make a variable offset write of zero, 512a33c5a2SEduard Zingerman * this should preserve zero marks on stack. 522a33c5a2SEduard Zingerman */ 532a33c5a2SEduard Zingerman BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_10), 542a33c5a2SEduard Zingerman BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), 552a33c5a2SEduard Zingerman /* r0 = fp[-20], if variable offset write was tracked correctly 562a33c5a2SEduard Zingerman * r0 would be a known zero. 572a33c5a2SEduard Zingerman */ 582a33c5a2SEduard Zingerman BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_10, -20), 592a33c5a2SEduard Zingerman /* Would fail return code verification if r0 range is not tracked correctly. */ 602a33c5a2SEduard Zingerman BPF_EXIT_INSN(), 612a33c5a2SEduard Zingerman }, 622a33c5a2SEduard Zingerman .result = ACCEPT, 632a33c5a2SEduard Zingerman /* Use prog type that requires return value in range [0, 1] */ 642a33c5a2SEduard Zingerman .prog_type = BPF_PROG_TYPE_SK_LOOKUP, 652a33c5a2SEduard Zingerman .expected_attach_type = BPF_SK_LOOKUP, 662a33c5a2SEduard Zingerman .runs = -1, 672a33c5a2SEduard Zingerman }, 6885eb035eSHao Sun { 6985eb035eSHao Sun "BPF_ST_MEM stack imm sign", 7085eb035eSHao Sun /* Check if verifier correctly reasons about sign of an 7185eb035eSHao Sun * immediate spilled to stack by BPF_ST instruction. 7285eb035eSHao Sun * 7385eb035eSHao Sun * fp[-8] = -44; 7485eb035eSHao Sun * r0 = fp[-8]; 7585eb035eSHao Sun * if r0 s< 0 goto ret0; 7685eb035eSHao Sun * r0 = -1; 7785eb035eSHao Sun * exit; 7885eb035eSHao Sun * ret0: 7985eb035eSHao Sun * r0 = 0; 8085eb035eSHao Sun * exit; 8185eb035eSHao Sun */ 8285eb035eSHao Sun .insns = { 8385eb035eSHao Sun BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, -44), 8485eb035eSHao Sun BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 8585eb035eSHao Sun BPF_JMP_IMM(BPF_JSLT, BPF_REG_0, 0, 2), 8685eb035eSHao Sun BPF_MOV64_IMM(BPF_REG_0, -1), 8785eb035eSHao Sun BPF_EXIT_INSN(), 8885eb035eSHao Sun BPF_MOV64_IMM(BPF_REG_0, 0), 8985eb035eSHao Sun BPF_EXIT_INSN(), 9085eb035eSHao Sun }, 9185eb035eSHao Sun /* Use prog type that requires return value in range [0, 1] */ 9285eb035eSHao Sun .prog_type = BPF_PROG_TYPE_SK_LOOKUP, 9385eb035eSHao Sun .expected_attach_type = BPF_SK_LOOKUP, 9485eb035eSHao Sun .result = VERBOSE_ACCEPT, 9585eb035eSHao Sun .runs = -1, 9685eb035eSHao Sun .errstr = "0: (7a) *(u64 *)(r10 -8) = -44 ; R10=fp0 fp-8_w=-44\ 9785eb035eSHao Sun 2: (c5) if r0 s< 0x0 goto pc+2\ 9885eb035eSHao Sun R0_w=-44", 9985eb035eSHao Sun }, 100