Re: [PATCH bpf-next 4/6] bpf, arm64: Fix exception table metadata for arena load-acquire

Puranjay Mohan <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <CANk7y0hVZoGJRt=v=3499ALtJ5DnPA16OZYyEzBik=H-4G8+2g@mail.gmail.com>
On Thu, Aug 6, 2026 at 3:39 PM Daniel Borkmann <[email protected]> wrote:
>
> Same problem as on x86-64: add_exception_handler() decides whether an
> instruction is a load by its class, and a load-acquire is of BPF_STX
> class even though it reads from src_reg into dst_reg. As a result ...
>
>   if (BPF_CLASS(insn->code) != BPF_LDX)
>           dst_reg = DONT_CLEAR;
>
> ... drops the register to clear, and ...
>
>   if (BPF_CLASS(insn->code) == BPF_LDX)
>           arena_reg = bpf2a64[insn->src_reg];
>   else
>           arena_reg = bpf2a64[insn->dst_reg];
>
> ... hands ex_handler_bpf() the value register instead of the address
> register. A load-acquire from an arena pointer that faults on an
> unmapped page is therefore reported as a WRITE at a bogus address,
> and dst_reg keeps its previous value instead of being cleared to 0.
>
> Note that emit_atomic_ld_st() already picks src_reg as the address
> for BPF_LOAD_ACQ, so only the exception table metadata was out of sync
> with the emitted access.
>
> Same as on x86-64, use bpf_atomic_is_load_acq() so a load-acquire takes
> the load path.
>
> Fixes: 9bb12368d539 ("bpf, arm64: Support load-acquire and store-release instructions")
> Signed-off-by: Daniel Borkmann <[email protected]>
> Cc: Peilin Ye <[email protected]>
> ---
>  arch/arm64/net/bpf_jit_comp.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index 4cdc7dfb05ba..d14d297ebb96 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -1178,7 +1178,12 @@ static int add_exception_handler(const struct bpf_insn *insn,
>
>         ex->insn = ins_offset;
>
> -       if (BPF_CLASS(insn->code) != BPF_LDX)
> +       /*
> +        * A load-acquire is of BPF_STX class, but reads from src_reg into
> +        * dst_reg like a BPF_LDX does, hence it must not be treated as a store
> +        * here.
> +        */
> +       if (BPF_CLASS(insn->code) != BPF_LDX && !bpf_atomic_is_load_acq(insn))
>                 dst_reg = DONT_CLEAR;
>
>         ex->fixup = FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
> @@ -1193,7 +1198,7 @@ static int add_exception_handler(const struct bpf_insn *insn,
>                  * memory access. Pass the reg holding the unmodified 32-bit address to
>                  * ex_handler_bpf.
>                  */
> -               if (BPF_CLASS(insn->code) == BPF_LDX)
> +               if (BPF_CLASS(insn->code) == BPF_LDX || bpf_atomic_is_load_acq(insn))
>                         arena_reg = bpf2a64[insn->src_reg];
>                 else
>                         arena_reg = bpf2a64[insn->dst_reg];
> --
> 2.43.0
>

Thanks for fixing this.

Reviewed-by: Puranjay Mohan <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.