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);