]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Set sub->arg_cnt earlier in btf_prepare_func_args()
authorYonghong Song <yonghong.song@linux.dev>
Wed, 13 May 2026 04:50:10 +0000 (21:50 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 13 May 2026 16:27:30 +0000 (09:27 -0700)
Move the "sub->arg_cnt = nargs" assignment to immediately after
nargs is computed from btf_type_vlen(), instead of at the end of
btf_prepare_func_args().

btf_prepare_func_args() can return -EINVAL early in several cases,
e.g. when a static function has some non-int/enum arguments.
Since -EINVAL from btf_prepare_func_args() does not immediately
reject verification, arg_cnt remains zero after the early return.
This causes later stack argument based load/store insns to
incorrectly assume the function has no arguments.

Setting arg_cnt right after nargs ensures it is available regardless
of which path btf_prepare_func_args() takes.

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20260513045010.2384635-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/btf.c

index a6bf4781943cf8b048b692df273d76d86c4b9142..099d7ca5a980001c365e9a21dc6fa138222f0f37 100644 (file)
@@ -7864,6 +7864,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
        }
        args = (const struct btf_param *)(t + 1);
        nargs = btf_type_vlen(t);
+       sub->arg_cnt = nargs;
        if (nargs > MAX_BPF_FUNC_REG_ARGS) {
                if (!is_global)
                        return -EINVAL;
@@ -8051,7 +8052,6 @@ skip_pointer:
                return -EINVAL;
        }
 
-       sub->arg_cnt = nargs;
        sub->args_cached = true;
 
        return 0;