diff options
| author | Amery Hung <ameryhung@gmail.com> | 2026-08-01 00:46:19 -0700 |
|---|---|---|
| committer | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-08-03 00:29:12 +0200 |
| commit | 9f52714dd89b489f7de5de2b60736edde07ddf5f (patch) | |
| tree | d8c0cd61244758c6a8a615232936df085692595c | |
| parent | c82b998777b7102f3617a46201805b7e7b899524 (diff) | |
bpf: Pass kfunc meta to mem and mem_size check
kfunc now shares the same bpf_call_arg_meta with helpers. Pass kfunc's
own meta to check_mem_reg() and check_kfunc_mem_size() instead of NULL
or a temporary meta on the stack.
Signed-off-by: Amery Hung <ameryhung@gmail.com>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260801074633.1595644-5-ameryhung@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
| -rw-r--r-- | kernel/bpf/verifier.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 4f39e439973c..3fec0afacb3f 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6924,7 +6924,7 @@ static int check_mem_size_reg(struct bpf_verifier_env *env, } static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg, - argno_t argno, u32 mem_size) + argno_t argno, u32 mem_size, struct bpf_call_arg_meta *meta) { bool may_be_null = type_may_be_null(reg->type); struct bpf_reg_state saved_reg; @@ -6950,8 +6950,8 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg int size = base_type(reg->type) == PTR_TO_STACK ? -(int)mem_size : mem_size; - err = check_helper_mem_access(env, reg, argno, size, BPF_READ, true, NULL); - err = err ?: check_helper_mem_access(env, reg, argno, size, BPF_WRITE, true, NULL); + err = check_helper_mem_access(env, reg, argno, size, BPF_READ, true, meta); + err = err ?: check_helper_mem_access(env, reg, argno, size, BPF_WRITE, true, meta); if (may_be_null) *reg = saved_reg; @@ -6994,22 +6994,20 @@ static int process_const_alloc_mem_size(struct bpf_verifier_env *env, struct bpf } static int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg_state *mem_reg, - struct bpf_reg_state *size_reg, argno_t mem_argno, argno_t size_argno) + struct bpf_reg_state *size_reg, argno_t mem_argno, + argno_t size_argno, struct bpf_call_arg_meta *meta) { bool may_be_null = type_may_be_null(mem_reg->type); struct bpf_reg_state saved_reg; - struct bpf_call_arg_meta meta; int err; - memset(&meta, 0, sizeof(meta)); - if (may_be_null) { saved_reg = *mem_reg; mark_ptr_not_null_reg(mem_reg); } - err = check_mem_size_reg(env, mem_reg, size_reg, mem_argno, size_argno, BPF_READ, true, &meta); - err = err ?: check_mem_size_reg(env, mem_reg, size_reg, mem_argno, size_argno, BPF_WRITE, true, &meta); + err = check_mem_size_reg(env, mem_reg, size_reg, mem_argno, size_argno, BPF_READ, true, meta); + err = err ?: check_mem_size_reg(env, mem_reg, size_reg, mem_argno, size_argno, BPF_WRITE, true, meta); if (may_be_null) *mem_reg = saved_reg; @@ -9258,7 +9256,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog, ret = check_func_arg_reg_off(env, reg, argno, ARG_DONTCARE); if (ret < 0) return ret; - if (check_mem_reg(env, reg, argno, arg->mem_size)) + if (check_mem_reg(env, reg, argno, arg->mem_size, NULL)) return -EINVAL; if (!(arg->arg_type & PTR_MAYBE_NULL) && (type_may_be_null(reg->type) || bpf_register_is_null(reg))) { @@ -12405,7 +12403,7 @@ check_ok: ref_tname, PTR_ERR(resolve_ret)); return -EINVAL; } - ret = check_mem_reg(env, reg, argno, type_size); + ret = check_mem_reg(env, reg, argno, type_size, meta); if (ret < 0) return ret; break; @@ -12419,7 +12417,7 @@ check_ok: if (!bpf_register_is_null(buff_reg) || !is_kfunc_arg_nullable(meta->btf, buff_arg)) { ret = check_kfunc_mem_size_reg(env, buff_reg, size_reg, - argno, next_argno); + argno, next_argno, meta); if (ret < 0) { verbose(env, "%s and ", reg_arg_name(env, argno)); verbose(env, "%s memory, len pair leads to invalid memory access\n", |
