Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] bpf: NULL pointer dereference in process_arg_ptr_to_btf_id due to 
missing ARG_PTR_TO_BTF_ID_SOCK_COMMON
--

commit 84d2361be82e8cb989ae15ca8d3347130aa3ce1b
Author: Jay Wang <[email protected]>

bpf: fetch the vmlinux BTF where kernel types enter a program

This commit defers fetching the vmlinux BTF in the BPF verifier until
kernel types are actually needed by a program. This optimization avoids
loading and parsing BTF data for programs that do not use kernel types,
such as simple socket filters.

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a7c9e2d8965d5..f02ecb0dae75c 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -11568,6 +11570,24 @@ static int release_reg(struct bpf_verifier_env *env, 
> struct bpf_reg_state *reg,
>       return err;
>  }
>  
> +/* Does calling helper @func_id bring kernel BTF types into the program? */
> +static bool helper_uses_vmlinux_btf(enum bpf_func_id func_id,
> +                                 const struct bpf_func_proto *fn)
> +{
> +     int i;
> +
> +     /* these take the kernel type id in a struct btf_ptr, not in a register 
> */
> +     if (func_id == BPF_FUNC_snprintf_btf || func_id == 
> BPF_FUNC_seq_printf_btf)
> +             return true;
> +     if (base_type(fn->ret_type) == RET_PTR_TO_BTF_ID)
> +             return true;
> +     for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) {
> +             if (base_type(fn->arg_type[i]) == ARG_PTR_TO_BTF_ID)
> +                     return true;

[Severity: High]
Does this logic also need to check for ARG_PTR_TO_BTF_ID_SOCK_COMMON?

If ARG_PTR_TO_BTF_ID_SOCK_COMMON is omitted here, helpers like
bpf_sk_release() that accept this argument type will skip loading
btf_vmlinux.

If a program synthesizes a PTR_TO_BTF_ID pointing to a module's BTF using
ldimm64, btf_vmlinux could remain NULL. Later, in check_func_args(),
arg_btf is assigned from btf_vmlinux:

check_func_args() {
    ...
    case ARG_PTR_TO_BTF_ID:
    case ARG_PTR_TO_BTF_ID_SOCK_COMMON:
    {
        const u32 *arg_btf_id = fn->arg_btf_id[arg];
        const struct btf *arg_btf = meta->btf ?: btf_vmlinux;
    ...
}

Because btf_vmlinux is NULL, arg_btf becomes NULL. Could this lead to a
NULL pointer dereference when process_arg_ptr_to_btf_id() unconditionally
dereferences it?

process_arg_ptr_to_btf_id() {
    ...
    arg_t = btf_type_skip_modifiers(arg_btf, arg_btf_id, &arg_btf_id);
    ...
}

> +     }
> +     return false;
> +}
> +

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=3

Reply via email to