Re: [PATCH bpf-next] bpf, arm32: Reject BPF_PSEUDO_CALL in the JIT

Daniel Borkmann
2026-04-17T11:22:24Z

On 4/17/26 12:30 PM, Puranjay Mohan wrote:
> The ARM32 BPF JIT does not support BPF-to-BPF function calls
> (subprogram calls). When insn->src_reg == BPF_PSEUDO_CALL, the
> imm field contains a pc-relative offset to another BPF function,
> not a helper function index.
>
> When a program containing BPF-to-BPF calls is loaded, the verifier
> invokes bpf_jit_subprogs() which calls bpf_int_jit_compile() for each
> subprogram. Since ARM32 does not reject BPF_PSEUDO_CALL, the JIT
> silently emits code for the call using the wrong address computation:
>
> func = __bpf_call_base + imm
>
> where imm is actually a pc-relative subprogram offset, producing
> a bogus function pointer. Because build_body() reports success,
> bpf_jit_binary_alloc() is reached and a JIT image is allocated.
>
> ARM32 also lacks the jit_data/extra_pass mechanism needed for
> the second JIT pass in bpf_jit_subprogs(). On the second pass,
> bpf_int_jit_compile() performs a full fresh compilation,
> allocating a new JIT binary and overwriting prog->bpf_func. The
> first allocation is never freed. bpf_jit_subprogs() then detects
> the function pointer changed and aborts with -ENOTSUPP, but the
> original JIT binary has already been leaked. Each program
> load/unload cycle leaks one JIT binary allocation, as reported
> by kmemleak:
>
> unreferenced object 0xbf0a1000 (size 4096):
> backtrace:
> bpf_jit_binary_alloc+0x64/0xfc
> bpf_int_jit_compile+0x14c/0x348
> bpf_jit_subprogs+0x4fc/0xa60
>
> Fix this by rejecting BPF_PSEUDO_CALL early in build_insn(),
> falling through to the existing 'notyet' path. This causes
> build_body() to fail before any JIT binary is allocated, so
> bpf_int_jit_compile() returns the original program unjitted.
> bpf_jit_subprogs() then sees !prog->jited and cleanly falls
> back to the interpreter.
>
> Fixes: 1c2a088a6626 ("bpf: x64: add JIT support for multi-function programs")
> Reported-by: Jonas Rebmann <jre@pengutronix.de>
> Closes: https://lore.kernel.org/bpf/b63e9174-7a3d-4e22-8294-16df07a4af89@pengutronix.de
> Tested-by: Jonas Rebmann <jre@pengutronix.de>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>