]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf/arm64: Fix BPF_ST into arena memory
authorPuranjay Mohan <puranjay@kernel.org>
Thu, 30 Oct 2025 12:17:14 +0000 (12:17 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 31 Oct 2025 18:20:53 +0000 (11:20 -0700)
The arm64 JIT supports BPF_ST with BPF_PROBE_MEM32 (arena) by using the
tmp2 register to hold the dst + arena_vm_base value and using tmp2 as the
new dst register. But this is broken because in case is_lsi_offset()
returns false the tmp2 will be clobbered by emit_a64_mov_i(1, tmp2, off,
ctx); and hence the emitted store instruction will be of the form:
strb    w10, [x11, x11]
Fix this by using the third temporary register to hold the dst +
arena_vm_base.

Fixes: 339af577ec05 ("bpf: Add arm64 JIT support for PROBE_MEM32 pseudo instructions.")
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/r/20251030121715.55214-1-puranjay@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/arm64/net/bpf_jit_comp.c

index ab83089c3d8fe0a5e4bc3094abf3f75ba52d14eb..0c9a50a1e73e7dc12f4e18377f449d9ef918996b 100644 (file)
@@ -1213,6 +1213,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
        u8 src = bpf2a64[insn->src_reg];
        const u8 tmp = bpf2a64[TMP_REG_1];
        const u8 tmp2 = bpf2a64[TMP_REG_2];
+       const u8 tmp3 = bpf2a64[TMP_REG_3];
        const u8 fp = bpf2a64[BPF_REG_FP];
        const u8 arena_vm_base = bpf2a64[ARENA_VM_START];
        const u8 priv_sp = bpf2a64[PRIVATE_SP];
@@ -1757,8 +1758,8 @@ emit_cond_jmp:
        case BPF_ST | BPF_PROBE_MEM32 | BPF_W:
        case BPF_ST | BPF_PROBE_MEM32 | BPF_DW:
                if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
-                       emit(A64_ADD(1, tmp2, dst, arena_vm_base), ctx);
-                       dst = tmp2;
+                       emit(A64_ADD(1, tmp3, dst, arena_vm_base), ctx);
+                       dst = tmp3;
                }
                if (dst == fp) {
                        dst_adj = ctx->priv_sp_used ? priv_sp : A64_SP;