mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] x86/kexec: Type relocate_kernel() to drop __nocfi
@ 2026-11-11 23:26 Ben Cressey
  2026-11-12  5:59 ` Josh Poimboeuf
  2026-11-12  8:00 ` Peter Zijlstra
  0 siblings, 2 replies; 3+ messages in thread
From: Ben Cressey @ 2026-11-11 23:26 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	H. Peter Anvin
  Cc: x86, linux-kernel, Sami Tolvanen, Kees Cook, Nathan Chancellor,
	llvm, Josh Poimboeuf, Peter Zijlstra, kexec, David Woodhouse

machine_kexec() calls the control page's copy of relocate_kernel()
indirectly. The routine has no kCFI type, so all of machine_kexec() is
exempt since commit 2114796ca041 ("x86/kexec: Mark machine_kexec() with
__nocfi"), and ANNOTATE_NOCFI_SYM() silences objtool.

No other call there loses its check today, but one added later would.
Review of that mark on arm64 preferred a typed entry, and objected to
covering a whole function, on x86 too [1].

Typing the routine was set aside in 2025 as not worth it [2]: a type
from the caller cannot catch a prototype that drifts, and
machine_kexec() seemed unlikely to follow a stray pointer.

Type the routine with SYM_TYPED_START(), emit an ENDBR only under
CONFIG_FINEIBT, whose boot-time rewrite skips a function without one,
and drop both exemptions, along with kexec as a valid use in annotate.h.

The check guards only the pointer, and not reliably under plain FineIBT,
which checks in the callee with IBT off. A failed check panics or hangs
with no CFI report, since load_segments() has reset GS.

Link: https://lore.kernel.org/202609241804.BB23BF10@keescook # [1]
Link: https://lore.kernel.org/9c41ab61efc573e3ab5a75b6e4031f81db84a846.camel@infradead.org # [2]
Signed-off-by: Ben Cressey <ben@cressey.dev>
---
This follows Kees Cook's review [1] of the arm64 kexec fix, which goes
separately. It is not a security fix, and nothing faults here today.
The copy gains a type hash and, with CONFIG_FINEIBT=y, an ENDBR, bare
under cfi=kcfi or cfi=off. SYM_TYPED_FUNC_START() is not used, since it
would put an ENDBR in every IBT build. Code built with CONFIG_CFI=n is
unchanged. A failed check stops crash kexec too.

An LLM wrote the patch and drafted the changelog. Tested on v7.4-rc1,
defconfig plus CFI, under cfi=off, cfi=kcfi and cfi=fineibt, the last
with and without paranoid and bhi. kexec_file_load(2), kexec_load(2),
crash kexec and a preserve-context round trip pass under QEMU TCG, so
functional only. They also pass in KVM guests on Ice Lake, which has no
IBT, with small loaders in place of kexec-tools. The KHO selftest
passes under TCG, not run with bhi. A pointer of another type is
stopped in all but cfi=off, one to code with no preamble only under
kcfi and paranoid. objtool is silent with clang, CFI on and off, and
GCC 13.3. Bare-metal kexec, IBT hardware, GCC's kCFI and LTO are
untested.
---
 arch/x86/kernel/machine_kexec_64.c   |  6 +-----
 arch/x86/kernel/relocate_kernel_64.S | 17 ++++++++++++++++-
 include/linux/annotate.h             |  5 ++---
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index c3f4a389992d..c15dfbd574cb 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -381,7 +381,7 @@ void machine_kexec_cleanup(struct kimage *image)
  * Do not allocate memory (or fail in any way) in machine_kexec().
  * We are past the point of no return, committed to rebooting now.
  */
-void __nocfi machine_kexec(struct kimage *image)
+void machine_kexec(struct kimage *image)
 {
 	unsigned long reloc_start = (unsigned long)__relocate_kernel_start;
 	relocate_kernel_fn *relocate_kernel_ptr;
@@ -463,10 +463,6 @@ void __nocfi machine_kexec(struct kimage *image)
 
 	__ftrace_enabled_restore(save_ftrace_enabled);
 }
-/*
- * Handover to the next kernel, no CFI concern.
- */
-ANNOTATE_NOCFI_SYM(machine_kexec);
 
 /* arch-dependent functionality related to kexec file-based syscall */
 
diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S
index eaeb77464c06..86e1b1c655d1 100644
--- a/arch/x86/kernel/relocate_kernel_64.S
+++ b/arch/x86/kernel/relocate_kernel_64.S
@@ -5,6 +5,7 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/cfi_types.h>
 #include <linux/stringify.h>
 #include <asm/alternative.h>
 #include <asm/page_types.h>
@@ -59,9 +60,23 @@ SYM_DATA_END(kexec_debug_idt)
 
 	.section .text..relocate_kernel,"ax";
 	.code64
-SYM_CODE_START_NOALIGN(relocate_kernel)
+/*
+ * The kCFI preamble in front of this entry is copied to the control page
+ * with the code, in the form boot-time patching left it, so it must stay
+ * position independent. FineIBT+BHI adds a CALL to a preamble only if it
+ * records arguments, and __CFI_TYPE() records none whatever the prototype.
+ */
+SYM_TYPED_START(relocate_kernel, SYM_L_GLOBAL, SYM_A_NONE)
 	UNWIND_HINT_END_OF_STACK
+#ifdef CONFIG_FINEIBT
+	/*
+	 * IBT is off by now, see cet_disable(), but FineIBT only rewrites the
+	 * preamble of a function that starts with ENDBR.
+	 */
+	ENDBR
+#else
 	ANNOTATE_NOENDBR
+#endif
 	/*
 	 * %rdi indirection_page
 	 * %rsi pa_control_page
diff --git a/include/linux/annotate.h b/include/linux/annotate.h
index 2f1599c9e573..8e9a7e17e64a 100644
--- a/include/linux/annotate.h
+++ b/include/linux/annotate.h
@@ -96,9 +96,8 @@
  */
 #define ANNOTATE_REACHABLE(label)	ASM_ANNOTATE_LABEL(label, ANNOTYPE_REACHABLE)
 /*
- * This should not be used; it annotates away CFI violations. There are a few
- * valid use cases like kexec handover to the next kernel image, and there is
- * no security concern there.
+ * This should not be used; it annotates away CFI violations. The valid use
+ * case is a test that violates CFI on purpose, like LKDTM.
  *
  * There are also a few real issues annotated away, like EFI because we can't
  * control the EFI code.

---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261111-x86-kexec-kcfi-5b2b437413d2


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-12  8:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 23:26 [PATCH] x86/kexec: Type relocate_kernel() to drop __nocfi Ben Cressey
2026-11-12  5:59 ` Josh Poimboeuf
2026-11-12  8:00 ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®