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

x86/bhi: Add BHI stubs

Add an array of code thunks, to be called from the FineIBT preamble,
clobbering the first 'n' argument registers for speculative execution.

Notably the 0th entry will clobber no argument registers and will never
be used, it exists so the array can be naturally indexed, while the 7th
entry will clobber all the 6 argument registers and also RSP in order to
mess up stack based arguments.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Link: https://lore.kernel.org/r/20250224124200.717378681@infradead.org

authored by

Peter Zijlstra and committed by
Ingo Molnar
b815f687 97e59672

+153 -1
+4
arch/x86/include/asm/cfi.h
··· 101 101 102 102 extern enum cfi_mode cfi_mode; 103 103 104 + typedef u8 bhi_thunk[32]; 105 + extern bhi_thunk __bhi_args[]; 106 + extern bhi_thunk __bhi_args_end[]; 107 + 104 108 struct pt_regs; 105 109 106 110 #ifdef CONFIG_CFI_CLANG
+2 -1
arch/x86/lib/Makefile
··· 66 66 lib-y += clear_page_64.o copy_page_64.o 67 67 lib-y += memmove_64.o memset_64.o 68 68 lib-y += copy_user_64.o copy_user_uncached_64.o 69 - lib-y += cmpxchg16b_emu.o 69 + lib-y += cmpxchg16b_emu.o 70 + lib-y += bhi.o 70 71 endif
+147
arch/x86/lib/bhi.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #include <linux/linkage.h> 4 + #include <asm/unwind_hints.h> 5 + #include <asm/nospec-branch.h> 6 + 7 + /* 8 + * Notably, the FineIBT preamble calling these will have ZF set and r10 zero. 9 + * 10 + * The very last element is in fact larger than 32 bytes, but since its the 11 + * last element, this does not matter, 12 + * 13 + * There are 2 #UD sites, located between 0,1-2,3 and 4,5-6,7 such that they 14 + * can be reached using Jcc.d8, these elements (1 and 5) have sufficiently 15 + * big alignment holes for this to not stagger the array. 16 + */ 17 + 18 + .pushsection .noinstr.text, "ax" 19 + 20 + .align 32 21 + SYM_CODE_START(__bhi_args) 22 + 23 + #ifdef CONFIG_FINEIBT_BHI 24 + 25 + .align 32 26 + SYM_INNER_LABEL(__bhi_args_0, SYM_L_LOCAL) 27 + ANNOTATE_NOENDBR 28 + UNWIND_HINT_FUNC 29 + jne .Lud_1 30 + ANNOTATE_UNRET_SAFE 31 + ret 32 + int3 33 + 34 + .align 32 35 + SYM_INNER_LABEL(__bhi_args_1, SYM_L_LOCAL) 36 + ANNOTATE_NOENDBR 37 + UNWIND_HINT_FUNC 38 + jne .Lud_1 39 + cmovne %r10, %rdi 40 + ANNOTATE_UNRET_SAFE 41 + ret 42 + int3 43 + 44 + .align 8 45 + ANNOTATE_REACHABLE 46 + .Lud_1: ud2 47 + ANNOTATE_UNRET_SAFE 48 + ret 49 + int3 50 + 51 + .align 32 52 + SYM_INNER_LABEL(__bhi_args_2, SYM_L_LOCAL) 53 + ANNOTATE_NOENDBR 54 + UNWIND_HINT_FUNC 55 + jne .Lud_1 56 + cmovne %r10, %rdi 57 + cmovne %r10, %rsi 58 + ANNOTATE_UNRET_SAFE 59 + ret 60 + int3 61 + 62 + .align 32 63 + SYM_INNER_LABEL(__bhi_args_3, SYM_L_LOCAL) 64 + ANNOTATE_NOENDBR 65 + UNWIND_HINT_FUNC 66 + jne .Lud_1 67 + cmovne %r10, %rdi 68 + cmovne %r10, %rsi 69 + cmovne %r10, %rdx 70 + ANNOTATE_UNRET_SAFE 71 + ret 72 + int3 73 + 74 + .align 32 75 + SYM_INNER_LABEL(__bhi_args_4, SYM_L_LOCAL) 76 + ANNOTATE_NOENDBR 77 + UNWIND_HINT_FUNC 78 + jne .Lud_2 79 + cmovne %r10, %rdi 80 + cmovne %r10, %rsi 81 + cmovne %r10, %rdx 82 + cmovne %r10, %rcx 83 + ANNOTATE_UNRET_SAFE 84 + ret 85 + int3 86 + 87 + .align 32 88 + SYM_INNER_LABEL(__bhi_args_5, SYM_L_LOCAL) 89 + ANNOTATE_NOENDBR 90 + UNWIND_HINT_FUNC 91 + jne .Lud_2 92 + cmovne %r10, %rdi 93 + cmovne %r10, %rsi 94 + cmovne %r10, %rdx 95 + cmovne %r10, %rcx 96 + cmovne %r10, %r8 97 + ANNOTATE_UNRET_SAFE 98 + ret 99 + int3 100 + 101 + .align 8 102 + ANNOTATE_REACHABLE 103 + .Lud_2: ud2 104 + ANNOTATE_UNRET_SAFE 105 + ret 106 + int3 107 + 108 + .align 32 109 + SYM_INNER_LABEL(__bhi_args_6, SYM_L_LOCAL) 110 + ANNOTATE_NOENDBR 111 + UNWIND_HINT_FUNC 112 + jne .Lud_2 113 + cmovne %r10, %rdi 114 + cmovne %r10, %rsi 115 + cmovne %r10, %rdx 116 + cmovne %r10, %rcx 117 + cmovne %r10, %r8 118 + cmovne %r10, %r9 119 + ANNOTATE_UNRET_SAFE 120 + ret 121 + int3 122 + 123 + .align 32 124 + SYM_INNER_LABEL(__bhi_args_7, SYM_L_LOCAL) 125 + ANNOTATE_NOENDBR 126 + UNWIND_HINT_FUNC 127 + jne .Lud_2 128 + cmovne %r10, %rdi 129 + cmovne %r10, %rsi 130 + cmovne %r10, %rdx 131 + cmovne %r10, %rcx 132 + cmovne %r10, %r8 133 + cmovne %r10, %r9 134 + cmovne %r10, %rsp 135 + ANNOTATE_UNRET_SAFE 136 + ret 137 + int3 138 + 139 + #endif /* CONFIG_FINEIBT_BHI */ 140 + 141 + .align 32 142 + SYM_INNER_LABEL(__bhi_args_end, SYM_L_GLOBAL) 143 + ANNOTATE_NOENDBR 144 + nop /* Work around toolchain+objtool quirk */ 145 + SYM_CODE_END(__bhi_args) 146 + 147 + .popsection