Patch "bpf: Fix verifier id tracking of scalars on spill" has been added to the 6.3-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bpf: Fix verifier id tracking of scalars on spill

to the 6.3-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bpf-fix-verifier-id-tracking-of-scalars-on-spill.patch
and it can be found in the queue-6.3 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 76c406594b0e4080b2ddd94aff6c8ea1522dfd60
Author: Maxim Mikityanskiy <maxim@xxxxxxxxxxxxx>
Date:   Wed Jun 7 15:39:50 2023 +0300

    bpf: Fix verifier id tracking of scalars on spill
    
    [ Upstream commit 713274f1f2c896d37017efee333fd44149710119 ]
    
    The following scenario describes a bug in the verifier where it
    incorrectly concludes about equivalent scalar IDs which could lead to
    verifier bypass in privileged mode:
    
    1. Prepare a 32-bit rogue number.
    2. Put the rogue number into the upper half of a 64-bit register, and
       roll a random (unknown to the verifier) bit in the lower half. The
       rest of the bits should be zero (although variations are possible).
    3. Assign an ID to the register by MOVing it to another arbitrary
       register.
    4. Perform a 32-bit spill of the register, then perform a 32-bit fill to
       another register. Due to a bug in the verifier, the ID will be
       preserved, although the new register will contain only the lower 32
       bits, i.e. all zeros except one random bit.
    
    At this point there are two registers with different values but the same
    ID, which means the integrity of the verifier state has been corrupted.
    
    5. Compare the new 32-bit register with 0. In the branch where it's
       equal to 0, the verifier will believe that the original 64-bit
       register is also 0, because it has the same ID, but its actual value
       still contains the rogue number in the upper half.
       Some optimizations of the verifier prevent the actual bypass, so
       extra care is needed: the comparison must be between two registers,
       and both branches must be reachable (this is why one random bit is
       needed). Both branches are still suitable for the bypass.
    6. Right shift the original register by 32 bits to pop the rogue number.
    7. Use the rogue number as an offset with any pointer. The verifier will
       believe that the offset is 0, while in reality it's the given number.
    
    The fix is similar to the 32-bit BPF_MOV handling in check_alu_op for
    SCALAR_VALUE. If the spill is narrowing the actual register value, don't
    keep the ID, make sure it's reset to 0.
    
    Fixes: 354e8f1970f8 ("bpf: Support <8-byte scalar spill and refill")
    Signed-off-by: Maxim Mikityanskiy <maxim@xxxxxxxxxxxxx>
    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Tested-by: Andrii Nakryiko <andrii@xxxxxxxxxx> # Checked veristat delta
    Acked-by: Yonghong Song <yhs@xxxxxx>
    Link: https://lore.kernel.org/bpf/20230607123951.558971-2-maxtram95@xxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1f6c0c5a1741d..b039990137444 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3559,6 +3559,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
 				return err;
 		}
 		save_register_state(state, spi, reg, size);
+		/* Break the relation on a narrowing spill. */
+		if (fls64(reg->umax_value) > BITS_PER_BYTE * size)
+			state->stack[spi].spilled_ptr.id = 0;
 	} else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) &&
 		   insn->imm != 0 && env->bpf_capable) {
 		struct bpf_reg_state fake_reg = {};



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux