* [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
* Re: [PATCH] x86/kexec: Type relocate_kernel() to drop __nocfi
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
1 sibling, 0 replies; 3+ messages in thread
From: Josh Poimboeuf @ 2026-11-12 5:59 UTC (permalink / raw)
To: Ben Cressey
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, x86, linux-kernel, Sami Tolvanen, Kees Cook,
Nathan Chancellor, llvm, Peter Zijlstra, kexec, David Woodhouse
On Wed, Nov 11, 2026 at 03:26:59PM -0800, Ben Cressey wrote:
> 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.
No objection to the change itself, but PLEASE no LLM-written changelogs
or comments, they tend to read like Rube Goldberg machines and these are
no exception...
--
Josh
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] x86/kexec: Type relocate_kernel() to drop __nocfi
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
1 sibling, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2026-11-12 8:00 UTC (permalink / raw)
To: Ben Cressey
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, x86, linux-kernel, Sami Tolvanen, Kees Cook,
Nathan Chancellor, llvm, Josh Poimboeuf, kexec, David Woodhouse
On Wed, Nov 11, 2026 at 03:26:59PM -0800, Ben Cressey wrote:
> 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.
I don't understand this; what?
^ 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®