• Arthur Fabre's avatar
    bpf: verifier: MOV64 don't mark dst reg unbounded · fbeb1603
    Arthur Fabre authored
    When check_alu_op() handles a BPF_MOV64 between two registers,
    it calls check_reg_arg(DST_OP) on the dst register, marking it
    as unbounded. If the src and dst register are the same, this
    marks the src as unbounded, which can lead to unexpected errors
    for further checks that rely on bounds info. For example:
    
    	BPF_MOV64_IMM(BPF_REG_2, 0),
    	BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
    	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
    	BPF_MOV64_IMM(BPF_REG_0, 0),
    	BPF_EXIT_INSN(),
    
    Results in:
    
    	"math between ctx pointer and register with unbounded
    	min value is not allowed"
    
    check_alu_op() now uses check_reg_arg(DST_OP_NO_MARK), and MOVs
    that need to mark the dst register (MOVIMM, MOV32) do so.
    
    Added a test case for MOV64 dst == src, and dst != src.
    Signed-off-by: default avatarArthur Fabre <afabre@cloudflare.com>
    Acked-by: default avatarEdward Cree <ecree@solarflare.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    fbeb1603
verifier.c 175 KB