The riscv BPF JIT doesn't emit proper kCFI prologues for BPF programs and struct_ops trampolines when CONFIG_CFI_CLANG is enabled. This causes CFI failures when calling BPF programs and can even crash the kernel due to invalid memory accesses. Example crash: root@rv-selftester:~/bpf# ./test_progs -a dummy_st_ops Unable to handle kernel paging request at virtual address ffffffff78204ffc Oops [#1] Modules linked in: bpf_testmod(OE) [....] CPU: 3 PID: 356 Comm: test_progs Tainted: P OE 6.8.0-rc1 #1 Hardware name: riscv-virtio,qemu (DT) epc : bpf_struct_ops_test_run+0x28c/0x5fc ra : bpf_struct_ops_test_run+0x26c/0x5fc epc : ffffffff82958010 ra : ffffffff82957ff0 sp : ff200000007abc80 gp : ffffffff868d6218 tp : ff6000008d87b840 t0 : 000000000000000f t1 : 0000000000000000 t2 : 000000002005793e s0 : ff200000007abcf0 s1 : ff6000008a90fee0 a0 : 0000000000000000 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000000 a4 : 0000000000000000 a5 : ffffffff868dba26 a6 : 0000000000000001 a7 : 0000000052464e43 s2 : 00007ffffc0a95f0 s3 : ff6000008a90fe80 s4 : ff60000084c24c00 s5 : ffffffff78205000 s6 : ff60000088750648 s7 : ff20000000035008 s8 : fffffffffffffff4 s9 : ffffffff86200610 s10: 0000000000000000 s11: 0000000000000000 t3 : ffffffff8483dc30 t4 : ffffffff8483dc10 t5 : ffffffff8483dbf0 t6 : ffffffff8483dbd0 status: 0000000200000120 badaddr: ffffffff78204ffc cause: 000000000000000d [<ffffffff82958010>] bpf_struct_ops_test_run+0x28c/0x5fc [<ffffffff805083ee>] bpf_prog_test_run+0x170/0x548 [<ffffffff805029c8>] __sys_bpf+0x2d2/0x378 [<ffffffff804ff570>] __riscv_sys_bpf+0x5c/0x120 [<ffffffff8000e8fe>] syscall_handler+0x62/0xe4 [<ffffffff83362df6>] do_trap_ecall_u+0xc6/0x27c [<ffffffff833822c4>] ret_from_exception+0x0/0x64 Code: b603 0109 b683 0189 b703 0209 8493 0609 157d 8d65 (a303) ffca ---[ end trace 0000000000000000 ]--- Kernel panic - not syncing: Fatal exception SMP: stopping secondary CPUs Implement proper kCFI prologues for the BPF programs and callbacks and drop __nocfi for riscv64. Fix the trampoline generation code to emit kCFI prologue when a struct_ops trampoline is being prepared. Signed-off-by: Puranjay Mohan <puranjay12@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20240303170207.82201-2-puranjay12@gmail.com
40 lines
810 B
C
40 lines
810 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_RISCV_CFI_H
|
|
#define _ASM_RISCV_CFI_H
|
|
|
|
/*
|
|
* Clang Control Flow Integrity (CFI) support.
|
|
*
|
|
* Copyright (C) 2023 Google LLC
|
|
*/
|
|
#include <linux/bug.h>
|
|
|
|
struct pt_regs;
|
|
|
|
#ifdef CONFIG_CFI_CLANG
|
|
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
|
|
#define __bpfcall
|
|
static inline int cfi_get_offset(void)
|
|
{
|
|
return 4;
|
|
}
|
|
|
|
#define cfi_get_offset cfi_get_offset
|
|
extern u32 cfi_bpf_hash;
|
|
extern u32 cfi_bpf_subprog_hash;
|
|
extern u32 cfi_get_func_hash(void *func);
|
|
#else
|
|
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
|
|
{
|
|
return BUG_TRAP_TYPE_NONE;
|
|
}
|
|
|
|
#define cfi_bpf_hash 0U
|
|
#define cfi_bpf_subprog_hash 0U
|
|
static inline u32 cfi_get_func_hash(void *func)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_CFI_CLANG */
|
|
|
|
#endif /* _ASM_RISCV_CFI_H */
|