bpf: mark a NULL memory argument of a call precise

check_mem_reg() allows bpf_register_is_null() for nullable arguments
w/o marking the underlying scalar register precise. Hence a checkpoint
created on such a path would prune against arbitrary scalar value.

The argument may live on the stack rather than in a register when a
call has more than MAX_BPF_FUNC_REG_ARGS arguments, hence the new
mark_arg_precision() helper.

Fixes: e5069b9c23 ("bpf: Support pointers in global func args")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260904-register-is-null-precise-fixes-v1-3-0f5a360ff15d@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Eduard Zingerman
2026-09-04 17:05:54 -07:00
committed by Alexei Starovoitov
parent 593c8eb0fb
commit f1e418129f

View File

@@ -4246,6 +4246,15 @@ static int mark_stack_arg_precision(struct bpf_verifier_env *env, int arg_idx)
return mark_chain_precision_batch(env, env->cur_state);
}
static int mark_arg_precision(struct bpf_verifier_env *env, argno_t argno)
{
int regno = reg_from_argno(argno);
if (regno >= 0)
return mark_chain_precision(env, regno);
return mark_stack_arg_precision(env, arg_idx_from_argno(argno));
}
static int check_outgoing_stack_args(struct bpf_verifier_env *env, struct bpf_func_state *caller,
int nargs, const char *callee_name, const struct btf *btf,
const struct btf_param *args)
@@ -7175,7 +7184,7 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg
int size, err = 0;
if (bpf_register_is_null(reg))
return 0;
return mark_arg_precision(env, argno);
if (known_memory)
*known_memory = true;