mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 15:11:50 +00:00
bpf: improve verifier state equivalence
since UNKNOWN_VALUE type is weaker than CONST_IMM we can un-teach verifier its recognition of constants in conditional branches without affecting safety. Ex: if (reg == 123) { .. here verifier was marking reg->type as CONST_IMM instead keep reg as UNKNOWN_VALUE } Two verifier states with UNKNOWN_VALUE are equivalent, whereas CONST_IMM_X != CONST_IMM_Y, since CONST_IMM is used for stack range verification and other cases. So help search pruning by marking registers as UNKNOWN_VALUE where possible instead of CONST_IMM. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
969bf05eb3
commit
735b433397
@ -1704,12 +1704,11 @@ static int check_cond_jmp_op(struct verifier_env *env,
|
||||
*/
|
||||
regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
|
||||
/* branch targer cannot access it, since reg == 0 */
|
||||
other_branch->regs[insn->dst_reg].type = CONST_IMM;
|
||||
other_branch->regs[insn->dst_reg].imm = 0;
|
||||
mark_reg_unknown_value(other_branch->regs,
|
||||
insn->dst_reg);
|
||||
} else {
|
||||
other_branch->regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
|
||||
regs[insn->dst_reg].type = CONST_IMM;
|
||||
regs[insn->dst_reg].imm = 0;
|
||||
mark_reg_unknown_value(regs, insn->dst_reg);
|
||||
}
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT &&
|
||||
dst_reg->type == PTR_TO_PACKET &&
|
||||
@ -1718,22 +1717,6 @@ static int check_cond_jmp_op(struct verifier_env *env,
|
||||
} else if (is_pointer_value(env, insn->dst_reg)) {
|
||||
verbose("R%d pointer comparison prohibited\n", insn->dst_reg);
|
||||
return -EACCES;
|
||||
} else if (BPF_SRC(insn->code) == BPF_K &&
|
||||
(opcode == BPF_JEQ || opcode == BPF_JNE)) {
|
||||
|
||||
if (opcode == BPF_JEQ) {
|
||||
/* detect if (R == imm) goto
|
||||
* and in the target state recognize that R = imm
|
||||
*/
|
||||
other_branch->regs[insn->dst_reg].type = CONST_IMM;
|
||||
other_branch->regs[insn->dst_reg].imm = insn->imm;
|
||||
} else {
|
||||
/* detect if (R != imm) goto
|
||||
* and in the fall-through state recognize that R = imm
|
||||
*/
|
||||
regs[insn->dst_reg].type = CONST_IMM;
|
||||
regs[insn->dst_reg].imm = insn->imm;
|
||||
}
|
||||
}
|
||||
if (log_level)
|
||||
print_verifier_state(&env->cur_state);
|
||||
|
Loading…
Reference in New Issue
Block a user