|
@@ -143,6 +143,8 @@ struct bpf_verifier_stack_elem {
|
|
|
#define BPF_COMPLEXITY_LIMIT_INSNS 65536
|
|
|
#define BPF_COMPLEXITY_LIMIT_STACK 1024
|
|
|
|
|
|
+#define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA)
|
|
|
+
|
|
|
struct bpf_call_arg_meta {
|
|
|
struct bpf_map *map_ptr;
|
|
|
bool raw_mode;
|
|
@@ -1357,6 +1359,8 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
|
|
|
} else if (fn->ret_type == RET_VOID) {
|
|
|
regs[BPF_REG_0].type = NOT_INIT;
|
|
|
} else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) {
|
|
|
+ struct bpf_insn_aux_data *insn_aux;
|
|
|
+
|
|
|
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
|
|
|
regs[BPF_REG_0].max_value = regs[BPF_REG_0].min_value = 0;
|
|
|
/* remember map_ptr, so that check_map_access()
|
|
@@ -1369,7 +1373,11 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
|
|
|
}
|
|
|
regs[BPF_REG_0].map_ptr = meta.map_ptr;
|
|
|
regs[BPF_REG_0].id = ++env->id_gen;
|
|
|
- env->insn_aux_data[insn_idx].map_ptr = meta.map_ptr;
|
|
|
+ insn_aux = &env->insn_aux_data[insn_idx];
|
|
|
+ if (!insn_aux->map_ptr)
|
|
|
+ insn_aux->map_ptr = meta.map_ptr;
|
|
|
+ else if (insn_aux->map_ptr != meta.map_ptr)
|
|
|
+ insn_aux->map_ptr = BPF_MAP_PTR_POISON;
|
|
|
} else {
|
|
|
verbose("unknown return type %d of func %s#%d\n",
|
|
|
fn->ret_type, func_id_name(func_id), func_id);
|
|
@@ -3307,7 +3315,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
|
|
|
|
|
|
if (ebpf_jit_enabled() && insn->imm == BPF_FUNC_map_lookup_elem) {
|
|
|
map_ptr = env->insn_aux_data[i + delta].map_ptr;
|
|
|
- if (!map_ptr->ops->map_gen_lookup)
|
|
|
+ if (map_ptr == BPF_MAP_PTR_POISON ||
|
|
|
+ !map_ptr->ops->map_gen_lookup)
|
|
|
goto patch_call_imm;
|
|
|
|
|
|
cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf);
|