• Xu Kuohai's avatar
    bpf, arm64: Fixed a BTI error on returning to patched function · 738a96c4
    Xu Kuohai authored
    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: efc9909f ("bpf, arm64: Add bpf trampoline for arm64")
    Reported-by: default avatarFlorent Revest <revest@chromium.org>
    Signed-off-by: default avatarXu Kuohai <xukuohai@huawei.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Tested-by: default avatarFlorent Revest <revest@chromium.org>
    Acked-by: default avatarFlorent Revest <revest@chromium.org>
    Link: https://lore.kernel.org/bpf/20230401234144.3719742-1-xukuohai@huaweicloud.com
    738a96c4
bpf_jit_comp.c 58 KB