bpf: track references based on is_acquire_func
So far, the verifier only acquires reference tracking state for RET_PTR_TO_SOCKET_OR_NULL. Instead of extending this for every new return type which desires these semantics, acquire reference tracking state iff the called helper is an acquire function. Signed-off-by: Lorenz Bauer <lmb@cloudflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:

committed by
Alexei Starovoitov

parent
48e5d98a0e
commit
0f3adc288d
@@ -3147,19 +3147,7 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
|
|||||||
} else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) {
|
} else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) {
|
||||||
mark_reg_known_zero(env, regs, BPF_REG_0);
|
mark_reg_known_zero(env, regs, BPF_REG_0);
|
||||||
regs[BPF_REG_0].type = PTR_TO_SOCKET_OR_NULL;
|
regs[BPF_REG_0].type = PTR_TO_SOCKET_OR_NULL;
|
||||||
if (is_acquire_function(func_id)) {
|
regs[BPF_REG_0].id = ++env->id_gen;
|
||||||
int id = acquire_reference_state(env, insn_idx);
|
|
||||||
|
|
||||||
if (id < 0)
|
|
||||||
return id;
|
|
||||||
/* For mark_ptr_or_null_reg() */
|
|
||||||
regs[BPF_REG_0].id = id;
|
|
||||||
/* For release_reference() */
|
|
||||||
regs[BPF_REG_0].ref_obj_id = id;
|
|
||||||
} else {
|
|
||||||
/* For mark_ptr_or_null_reg() */
|
|
||||||
regs[BPF_REG_0].id = ++env->id_gen;
|
|
||||||
}
|
|
||||||
} else if (fn->ret_type == RET_PTR_TO_TCP_SOCK_OR_NULL) {
|
} else if (fn->ret_type == RET_PTR_TO_TCP_SOCK_OR_NULL) {
|
||||||
mark_reg_known_zero(env, regs, BPF_REG_0);
|
mark_reg_known_zero(env, regs, BPF_REG_0);
|
||||||
regs[BPF_REG_0].type = PTR_TO_TCP_SOCK_OR_NULL;
|
regs[BPF_REG_0].type = PTR_TO_TCP_SOCK_OR_NULL;
|
||||||
@@ -3170,9 +3158,19 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_ptr_cast_function(func_id))
|
if (is_ptr_cast_function(func_id)) {
|
||||||
/* For release_reference() */
|
/* For release_reference() */
|
||||||
regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
|
regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
|
||||||
|
} else if (is_acquire_function(func_id)) {
|
||||||
|
int id = acquire_reference_state(env, insn_idx);
|
||||||
|
|
||||||
|
if (id < 0)
|
||||||
|
return id;
|
||||||
|
/* For mark_ptr_or_null_reg() */
|
||||||
|
regs[BPF_REG_0].id = id;
|
||||||
|
/* For release_reference() */
|
||||||
|
regs[BPF_REG_0].ref_obj_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
do_refine_retval_range(regs, fn->ret_type, func_id, &meta);
|
do_refine_retval_range(regs, fn->ret_type, func_id, &meta);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user