• Yonghong Song's avatar
    bpf: Add missed var_off setting in coerce_subreg_to_size_sx() · 44b7f715
    Yonghong Song authored
    In coerce_subreg_to_size_sx(), for the case where upper
    sign extension bits are the same for smax32 and smin32
    values, we missed to setup properly. This is especially
    problematic if both smax32 and smin32's sign extension
    bits are 1.
    
    The following is a simple example illustrating the inconsistent
    verifier states due to missed var_off:
    
      0: (85) call bpf_get_prandom_u32#7    ; R0_w=scalar()
      1: (bf) r3 = r0                       ; R0_w=scalar(id=1) R3_w=scalar(id=1)
      2: (57) r3 &= 15                      ; R3_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=15,var_off=(0x0; 0xf))
      3: (47) r3 |= 128                     ; R3_w=scalar(smin=umin=smin32=umin32=128,smax=umax=smax32=umax32=143,var_off=(0x80; 0xf))
      4: (bc) w7 = (s8)w3
      REG INVARIANTS VIOLATION (alu): range bounds violation u64=[0xffffff80, 0x8f] s64=[0xffffff80, 0x8f]
        u32=[0xffffff80, 0x8f] s32=[0x80, 0xffffff8f] var_off=(0x80, 0xf)
    
    The var_off=(0x80, 0xf) is not correct, and the correct one should
    be var_off=(0xffffff80; 0xf) since from insn 3, we know that at
    insn 4, the sign extension bits will be 1. This patch fixed this
    issue by setting var_off properly.
    
    Fixes: 8100928c ("bpf: Support new sign-extension mov insns")
    Signed-off-by: default avatarYonghong Song <yonghong.song@linux.dev>
    Link: https://lore.kernel.org/r/20240615174632.3995278-1-yonghong.song@linux.devSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    44b7f715
verifier.c 649 KB