Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[linux-block.git] / kernel / bpf / verifier.c
index 068b20ed34d2c9894fb378a23b24d5661b80329e..003f7ba195581de4ad90a77625adbdbc00673d2c 100644 (file)
@@ -6076,6 +6076,9 @@ skip_type_check:
                        return -EACCES;
                }
                meta->mem_size = reg->var_off.value;
+               err = mark_chain_precision(env, regno);
+               if (err)
+                       return err;
                break;
        case ARG_PTR_TO_INT:
        case ARG_PTR_TO_LONG:
@@ -7018,8 +7021,7 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
        struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
        struct bpf_reg_state *regs = cur_regs(env), *reg;
        struct bpf_map *map = meta->map_ptr;
-       struct tnum range;
-       u64 val;
+       u64 val, max;
        int err;
 
        if (func_id != BPF_FUNC_tail_call)
@@ -7029,10 +7031,11 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
                return -EINVAL;
        }
 
-       range = tnum_range(0, map->max_entries - 1);
        reg = &regs[BPF_REG_3];
+       val = reg->var_off.value;
+       max = map->max_entries;
 
-       if (!register_is_const(reg) || !tnum_in(range, reg->var_off)) {
+       if (!(register_is_const(reg) && val < max)) {
                bpf_map_key_store(aux, BPF_MAP_KEY_POISON);
                return 0;
        }
@@ -7040,8 +7043,6 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
        err = mark_chain_precision(env, BPF_REG_3);
        if (err)
                return err;
-
-       val = reg->var_off.value;
        if (bpf_map_key_unseen(aux))
                bpf_map_key_store(aux, val);
        else if (!bpf_map_key_poisoned(aux) &&