On Sat, 2026-06-20 at 00:04 +0800, Nuoqi Gui wrote:
> BPF_PSEUDO_BTF_ID is resolved before the main verifier pass. The resolver
> looks up the referenced kernel symbol through kallsyms and rewrites the
> ldimm64 immediate to the concrete address that later becomes verifier
> state.
> 
> Require CAP_BPF before doing that materialization. This keeps typed ksym
> address resolution on the privileged side and prevents loaders without
> CAP_BPF from receiving a verifier log that contains the resolved address.
> 
> Fixes: 4976b718c3551 ("bpf: Introduce pseudo_btf_id")
> Signed-off-by: Nuoqi Gui <[email protected]>
> ---
>  kernel/bpf/verifier.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index ed7ba0e6a9ce..dbf5df995fc2 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -17639,6 +17639,11 @@ static int check_pseudo_btf_id(struct 
> bpf_verifier_env *env,
>       int btf_fd;
>       int err;
>  
> +     if (!env->bpf_capable) {
> +             verbose(env, "BPF_PSEUDO_BTF_ID loads require CAP_BPF\n");
> +             return -EACCES;
> +     }
> +

Thank you for identifying this issue.
I think the correct way to fix it is to extend the `is_ptr && !allow_ptr_leaks`
logic in kernel/bpf/disasm.c:print_bpf_insn().
Note that it seems there are additional cases that are not covered,
something like below seem warranted:


  bool is_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD    ||
                insn->src_reg == BPF_PSEUDO_MAP_VALUE  ||
                insn->src_reg == BPF_PSEUDO_MAP_IDX    ||
                insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE ||
                insn->src_reg == BPF_PSEUDO_BTF_ID;

Could you please double check?

>       btf_fd = insn[1].imm;
>       if (btf_fd) {
>               btf = btf_get_by_fd(btf_fd);

Reply via email to