Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cfi: Move BPF CFI types and helpers to generic code

Instead of duplicating the same code for each architecture, move
the CFI type hash variables for BPF function types and related
helper functions to generic CFI code, and allow architectures to
override the function definitions if needed.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://lore.kernel.org/r/20250801001004.1859976-7-samitolvanen@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Sami Tolvanen and committed by
Alexei Starovoitov
f1befc82 5ccaeedb

+56 -68
-16
arch/riscv/include/asm/cfi.h
··· 14 14 #ifdef CONFIG_CFI_CLANG 15 15 enum bug_trap_type handle_cfi_failure(struct pt_regs *regs); 16 16 #define __bpfcall 17 - static inline int cfi_get_offset(void) 18 - { 19 - return 4; 20 - } 21 - 22 - #define cfi_get_offset cfi_get_offset 23 - extern u32 cfi_bpf_hash; 24 - extern u32 cfi_bpf_subprog_hash; 25 - extern u32 cfi_get_func_hash(void *func); 26 17 #else 27 18 static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) 28 19 { 29 20 return BUG_TRAP_TYPE_NONE; 30 - } 31 - 32 - #define cfi_bpf_hash 0U 33 - #define cfi_bpf_subprog_hash 0U 34 - static inline u32 cfi_get_func_hash(void *func) 35 - { 36 - return 0; 37 21 } 38 22 #endif /* CONFIG_CFI_CLANG */ 39 23
-24
arch/riscv/kernel/cfi.c
··· 4 4 * 5 5 * Copyright (C) 2023 Google LLC 6 6 */ 7 - #include <linux/cfi_types.h> 8 7 #include <linux/cfi.h> 9 8 #include <asm/insn.h> 10 9 ··· 75 76 76 77 return report_cfi_failure(regs, regs->epc, &target, type); 77 78 } 78 - 79 - #ifdef CONFIG_CFI_CLANG 80 - struct bpf_insn; 81 - 82 - /* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */ 83 - extern unsigned int __bpf_prog_runX(const void *ctx, 84 - const struct bpf_insn *insn); 85 - DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX); 86 - 87 - /* Must match bpf_callback_t */ 88 - extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64); 89 - DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn); 90 - 91 - u32 cfi_get_func_hash(void *func) 92 - { 93 - u32 hash; 94 - 95 - if (get_kernel_nofault(hash, func - cfi_get_offset())) 96 - return 0; 97 - 98 - return hash; 99 - } 100 - #endif
+2 -8
arch/x86/include/asm/cfi.h
··· 116 116 #ifdef CONFIG_CFI_CLANG 117 117 enum bug_trap_type handle_cfi_failure(struct pt_regs *regs); 118 118 #define __bpfcall 119 - extern u32 cfi_bpf_hash; 120 - extern u32 cfi_bpf_subprog_hash; 121 119 122 120 static inline int cfi_get_offset(void) 123 121 { ··· 133 135 #define cfi_get_offset cfi_get_offset 134 136 135 137 extern u32 cfi_get_func_hash(void *func); 138 + #define cfi_get_func_hash cfi_get_func_hash 139 + 136 140 extern int cfi_get_func_arity(void *func); 137 141 138 142 #ifdef CONFIG_FINEIBT ··· 152 152 static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) 153 153 { 154 154 return BUG_TRAP_TYPE_NONE; 155 - } 156 - #define cfi_bpf_hash 0U 157 - #define cfi_bpf_subprog_hash 0U 158 - static inline u32 cfi_get_func_hash(void *func) 159 - { 160 - return 0; 161 155 } 162 156 static inline int cfi_get_func_arity(void *func) 163 157 {
-12
arch/x86/kernel/alternative.c
··· 2 2 #define pr_fmt(fmt) "SMP alternatives: " fmt 3 3 4 4 #include <linux/mmu_context.h> 5 - #include <linux/cfi_types.h> 6 5 #include <linux/perf_event.h> 7 6 #include <linux/vmalloc.h> 8 7 #include <linux/memory.h> ··· 1184 1185 #endif 1185 1186 1186 1187 #ifdef CONFIG_CFI_CLANG 1187 - struct bpf_insn; 1188 - 1189 - /* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */ 1190 - extern unsigned int __bpf_prog_runX(const void *ctx, 1191 - const struct bpf_insn *insn); 1192 - DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX); 1193 - 1194 - /* Must match bpf_callback_t */ 1195 - extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64); 1196 - DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn); 1197 - 1198 1188 u32 cfi_get_func_hash(void *func) 1199 1189 { 1200 1190 u32 hash;
+39 -8
include/linux/cfi.h
··· 11 11 #include <linux/module.h> 12 12 #include <asm/cfi.h> 13 13 14 + #ifdef CONFIG_CFI_CLANG 14 15 extern bool cfi_warn; 15 16 16 - #ifndef cfi_get_offset 17 - static inline int cfi_get_offset(void) 18 - { 19 - return 0; 20 - } 21 - #endif 22 - 23 - #ifdef CONFIG_CFI_CLANG 24 17 enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr, 25 18 unsigned long *target, u32 type); 26 19 ··· 22 29 { 23 30 return report_cfi_failure(regs, addr, NULL, 0); 24 31 } 32 + 33 + #ifndef cfi_get_offset 34 + /* 35 + * Returns the CFI prefix offset. By default, the compiler emits only 36 + * a 4-byte CFI type hash before the function. If an architecture 37 + * uses -fpatchable-function-entry=N,M where M>0 to change the prefix 38 + * offset, they must override this function. 39 + */ 40 + static inline int cfi_get_offset(void) 41 + { 42 + return 4; 43 + } 44 + #endif 45 + 46 + #ifndef cfi_get_func_hash 47 + static inline u32 cfi_get_func_hash(void *func) 48 + { 49 + u32 hash; 50 + 51 + if (get_kernel_nofault(hash, func - cfi_get_offset())) 52 + return 0; 53 + 54 + return hash; 55 + } 56 + #endif 57 + 58 + /* CFI type hashes for BPF function types */ 59 + extern u32 cfi_bpf_hash; 60 + extern u32 cfi_bpf_subprog_hash; 61 + 62 + #else /* CONFIG_CFI_CLANG */ 63 + 64 + static inline int cfi_get_offset(void) { return 0; } 65 + static inline u32 cfi_get_func_hash(void *func) { return 0; } 66 + 67 + #define cfi_bpf_hash 0U 68 + #define cfi_bpf_subprog_hash 0U 69 + 25 70 #endif /* CONFIG_CFI_CLANG */ 26 71 27 72 #ifdef CONFIG_ARCH_USES_CFI_TRAPS
+15
kernel/cfi.c
··· 5 5 * Copyright (C) 2022 Google LLC 6 6 */ 7 7 8 + #include <linux/bpf.h> 9 + #include <linux/cfi_types.h> 8 10 #include <linux/cfi.h> 9 11 10 12 bool cfi_warn __ro_after_init = IS_ENABLED(CONFIG_CFI_PERMISSIVE); ··· 28 26 29 27 return BUG_TRAP_TYPE_BUG; 30 28 } 29 + 30 + /* 31 + * Declare two non-existent functions with types that match bpf_func_t and 32 + * bpf_callback_t pointers, and use DEFINE_CFI_TYPE to define type hash 33 + * variables for each function type. The cfi_bpf_* variables are used by 34 + * arch-specific BPF JIT implementations to ensure indirectly callable JIT 35 + * code has matching CFI type hashes. 36 + */ 37 + extern typeof(*(bpf_func_t)0) __bpf_prog_runX; 38 + DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX); 39 + 40 + extern typeof(*(bpf_callback_t)0) __bpf_callback_fn; 41 + DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn); 31 42 32 43 #ifdef CONFIG_ARCH_USES_CFI_TRAPS 33 44 static inline unsigned long trap_address(s32 *p)