Re: [PATCH] arm64: bpf: Fix UBSAN misaligned access in BPF JIT

Fuad Tabba
2026-02-25T17:53:56Z

Hi Will,

On Wed, 25 Feb 2026 at 17:48, Will Deacon <will@kernel.org> wrote:
>
> On Wed, Feb 25, 2026 at 05:46:52PM +0800, Xu Kuohai wrote:
> > Interesting, I think the plt target should be 64-bit aligned to ensure
> > atomic reading on arm64. It can be updated concurrently by WRITE_ONCE
> > in the bpf_arch_text_poke function while the ldr instruction in the plt is
> > executed. If it is not aligned correctly, the ldr may read a half-old
> > half-new value, causing the plt to jump to an invalid destination.
>
> Thanks for pointing that out; I hadn't realised that we patched live
> PLTs!
>
> > To avoid over-aligning the entire buffer, how about fixing the padding
> > method in build_plt to just make the plt target aligned correctly?
>
> Makes sense to me.

As I noted in my reply to Xu, and keeping in mind that this is very
new to me (so take it with a huge pinch of salt), I don't think this
is correct, but that my original patch is probably the best fix:

> I'm not sure about this. If my reading of the code is correct, during
> the first JIT pass, ctx->image is NULL. The current padding logic in
> build_plt() looks like this:
>
> /* make sure target is 64-bit aligned */
> if ((ctx->idx + PLT_TARGET_OFFSET / AARCH64_INSN_SIZE) % 2)
> emit(A64_NOP, ctx);
>
> This forces the relative offset of the PLT to be a multiple of 8
> bytes. Therefore, it assumes that the base pointer (ctx->image) is
> also 8-byte aligned. If the allocator gives us a base pointer that is
> only 4-byte aligned, target will end up misaligned.
>
> If we try to make the padding dynamic based on the actual address of
> ctx->image, pass 1 (where ctx->image is NULL) and pass 2 (where
> ctx->image is allocated) might disagree on the number of NOPs
> required. This would cause ctx->idx to diverge between passes,
> breaking the size calculations and offset tables.

Cheers,
/fuad

>
> Will