Patch "bpf, arm64: Fixed a BTI error on returning to patched function" has been added to the 6.2-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bpf, arm64: Fixed a BTI error on returning to patched function

to the 6.2-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bpf-arm64-fixed-a-bti-error-on-returning-to-patched-.patch
and it can be found in the queue-6.2 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 9aa3ef33350c5e03d4f44e23889a91fbb3359c34
Author: Xu Kuohai <xukuohai@xxxxxxxxxx>
Date:   Sat Apr 1 19:41:44 2023 -0400

    bpf, arm64: Fixed a BTI error on returning to patched function
    
    [ Upstream commit 738a96c4a8c36950803fdd27e7c30aca92dccefd ]
    
    When BPF_TRAMP_F_CALL_ORIG is set, BPF trampoline uses BLR to jump
    back to the instruction next to call site to call the patched function.
    For BTI-enabled kernel, the instruction next to call site is usually
    PACIASP, in this case, it's safe to jump back with BLR. But when
    the call site is not followed by a PACIASP or bti, a BTI exception
    is triggered.
    
    Here is a fault log:
    
     Unhandled 64-bit el1h sync exception on CPU0, ESR 0x0000000034000002 -- BTI
     CPU: 0 PID: 263 Comm: test_progs Tainted: GF
     Hardware name: linux,dummy-virt (DT)
     pstate: 40400805 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=-c)
     pc : bpf_fentry_test1+0xc/0x30
     lr : bpf_trampoline_6442573892_0+0x48/0x1000
     sp : ffff80000c0c3a50
     x29: ffff80000c0c3a90 x28: ffff0000c2e6c080 x27: 0000000000000000
     x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000050
     x23: 0000000000000000 x22: 0000ffffcfd2a7f0 x21: 000000000000000a
     x20: 0000ffffcfd2a7f0 x19: 0000000000000000 x18: 0000000000000000
     x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffcfd2a7f0
     x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
     x11: 0000000000000000 x10: ffff80000914f5e4 x9 : ffff8000082a1528
     x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0101010101010101
     x5 : 0000000000000000 x4 : 00000000fffffff2 x3 : 0000000000000001
     x2 : ffff8001f4b82000 x1 : 0000000000000000 x0 : 0000000000000001
     Kernel panic - not syncing: Unhandled exception
     CPU: 0 PID: 263 Comm: test_progs Tainted: GF
     Hardware name: linux,dummy-virt (DT)
     Call trace:
      dump_backtrace+0xec/0x144
      show_stack+0x24/0x7c
      dump_stack_lvl+0x8c/0xb8
      dump_stack+0x18/0x34
      panic+0x1cc/0x3ec
      __el0_error_handler_common+0x0/0x130
      el1h_64_sync_handler+0x60/0xd0
      el1h_64_sync+0x78/0x7c
      bpf_fentry_test1+0xc/0x30
      bpf_fentry_test1+0xc/0x30
      bpf_prog_test_run_tracing+0xdc/0x2a0
      __sys_bpf+0x438/0x22a0
      __arm64_sys_bpf+0x30/0x54
      invoke_syscall+0x78/0x110
      el0_svc_common.constprop.0+0x6c/0x1d0
      do_el0_svc+0x38/0xe0
      el0_svc+0x30/0xd0
      el0t_64_sync_handler+0x1ac/0x1b0
      el0t_64_sync+0x1a0/0x1a4
     Kernel Offset: disabled
     CPU features: 0x0000,00034c24,f994fdab
     Memory Limit: none
    
    And the instruction next to call site of bpf_fentry_test1 is ADD,
    not PACIASP:
    
    <bpf_fentry_test1>:
            bti     c
            nop
            nop
            add     w0, w0, #0x1
            paciasp
    
    For BPF prog, JIT always puts a PACIASP after call site for BTI-enabled
    kernel, so there is no problem. To fix it, replace BLR with RET to bypass
    the branch target check.
    
    Fixes: efc9909fdce0 ("bpf, arm64: Add bpf trampoline for arm64")
    Reported-by: Florent Revest <revest@xxxxxxxxxxxx>
    Signed-off-by: Xu Kuohai <xukuohai@xxxxxxxxxx>
    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Tested-by: Florent Revest <revest@xxxxxxxxxxxx>
    Acked-by: Florent Revest <revest@xxxxxxxxxxxx>
    Link: https://lore.kernel.org/bpf/20230401234144.3719742-1-xukuohai@xxxxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index a6acb94ea3d63..c2edadb8ec6a3 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -281,4 +281,8 @@
 /* DMB */
 #define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
 
+/* ADR */
+#define A64_ADR(Rd, offset) \
+	aarch64_insn_gen_adr(0, offset, Rd, AARCH64_INSN_ADR_TYPE_ADR)
+
 #endif /* _BPF_JIT_H */
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 62f805f427b79..b26da8efa616e 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1900,7 +1900,8 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 		restore_args(ctx, args_off, nargs);
 		/* call original func */
 		emit(A64_LDR64I(A64_R(10), A64_SP, retaddr_off), ctx);
-		emit(A64_BLR(A64_R(10)), ctx);
+		emit(A64_ADR(A64_LR, AARCH64_INSN_SIZE * 2), ctx);
+		emit(A64_RET(A64_R(10)), ctx);
 		/* store return value */
 		emit(A64_STR64I(A64_R(0), A64_SP, retval_off), ctx);
 		/* reserve a nop for bpf_tramp_image_put */



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux