Unifies adjusted and unadjusted register value types (e.g. FRAME_POINTER is[...]
now just a PTR_TO_STACK with zero offset).
Tracks value alignment by means of tracking known & unknown bits. This
also replaces the 'reg->imm' (leading zero bits) calculations for (what
were) UNKNOWN_VALUEs.
If pointer leaks are allowed, and adjust_ptr_min_max_vals returns -EACCES,
treat the pointer as an unknown scalar and try again, because we might be
able to conclude something about the result (e.g. pointer & 0x40 is either
0 or 0x40).
Signed-off-by: Edward Cree <ecree@xxxxxxxxxxxxxx>
+static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,[...]
+ struct bpf_insn *insn,
+ struct bpf_reg_state *dst_reg,
+ struct bpf_reg_state *src_reg)
{
struct bpf_reg_state *regs = env->cur_state.regs;
- } else if (insn->imm < BPF_REGISTER_MAX_RANGE &&[...]
- (s64)insn->imm > BPF_REGISTER_MIN_RANGE) {
- min_val = max_val = insn->imm;
- src_align = calc_align(insn->imm);
+ if (BPF_CLASS(insn->code) != BPF_ALU64) {
+ /* 32-bit ALU ops are (32,32)->64 */
+ coerce_reg_to_32(dst_reg);
+ coerce_reg_to_32(src_reg);
}
-
- dst_reg->max_value = BPF_REGISTER_MAX_RANGE;
+ if (BPF_CLASS(insn->code) != BPF_ALU64) {
+ /* 32-bit ALU ops are (32,32)->64 */
+ coerce_reg_to_32(dst_reg);
+ coerce_reg_to_32(src_reg);
}
+ min_val = src_reg->min_value;
+ max_val = src_reg->max_value;
+ src_known = tnum_is_const(src_reg->var_off);
+ dst_known = tnum_is_const(dst_reg->var_off);
switch (opcode) {