History

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.

Eduard Zingerman committed 2 months ago

Commit f1e41811 parent 593c8eb1 file · +10 −1Browse files

Unified · Split

kernel/bpf/verifier.c+10−1
@@ -4246,6 +4246,15 @@ static int mark_stack_arg_precision(struct bpf_verifier_env *env, int arg_idx) · 4245 unmodified lines
4246 return mark_chain_precision_batch(env, env->cur_state);4246 return mark_chain_precision_batch(env, env->cur_state);
4247}4247}
4248 4248
4249static int mark_arg_precision(struct bpf_verifier_env *env, argno_t argno)
4250{
4251 int regno = reg_from_argno(argno);
4252
4253 if (regno >= 0)
4254 return mark_chain_precision(env, regno);
4255 return mark_stack_arg_precision(env, arg_idx_from_argno(argno));
4256}
4257
4249static int check_outgoing_stack_args(struct bpf_verifier_env *env, struct bpf_func_state *caller,4258static int check_outgoing_stack_args(struct bpf_verifier_env *env, struct bpf_func_state *caller,
4250 int nargs, const char *callee_name, const struct btf *btf,4259 int nargs, const char *callee_name, const struct btf *btf,
4251 const struct btf_param *args)4260 const struct btf_param *args)
@@ -7175,7 +7184,7 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg · 2923 unmodified lines
7175 int size, err = 0;7184 int size, err = 0;
7176 7185
7177 if (bpf_register_is_null(reg))7186 if (bpf_register_is_null(reg))
7178 return 0;7187 return mark_arg_precision(env, argno);
7179 if (known_memory)7188 if (known_memory)
7180 *known_memory = true;7189 *known_memory = true;
7181 7190