[PATCH v2 01/13] kexec: add CRASH_WIPE_SECRETS to wipe secrets before kdump
From: Jan Sebastian Götte <hidden>
Date: 2026-08-11 17:53:15
Also in:
dm-devel, kexec, keyrings, linux-crypto, linux-doc, linux-fscrypt, linux-fsdevel, linux-integrity, linux-mm, linux-nfs, linux-nvme, linux-security-module, lkml
Subsystem:
kdump, the rest · Maintainers:
Andrew Morton, Baoquan He, Mike Rapoport, Pasha Tatashin, Pratyush Yadav, Linus Torvalds
When kdump is used to capture system memory after a panic(), any secret keys currently in RAM end up in the dump. Add an opt-in atomic notifier chain, crash_wipe_secrets_notifier_list, invoked late into __crash_kexec(). Subsystems holding secrets can register a callback to wipe them. Callbacks are run after machine_crash_shutdown() has already stopped the other CPUs and disabled preemption. Callbacks must not wait on locks, which will never be released. This is a best-effort, defence-in-depth measure, not a guarantee. Secrets in flight on the stack, in registers, in DMA buffers, or in other places in memory are out of scope. Signed-off-by: Jan Sebastian Götte <redacted> --- include/linux/crash_core.h | 16 ++++++++++++++++ kernel/Kconfig.kexec | 16 ++++++++++++++++ kernel/crash_core.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+)
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index bc087124cd78..4230463f3faa 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h@@ -5,6 +5,7 @@ #include <linux/linkage.h> #include <linux/elfcore.h> #include <linux/elf.h> +#include <linux/notifier.h> struct kimage;
@@ -34,6 +35,21 @@ static inline void arch_kexec_protect_crashkres(void) { } static inline void arch_kexec_unprotect_crashkres(void) { } #endif +#ifdef CONFIG_CRASH_WIPE_SECRETS +int crash_wipe_secrets_register(struct notifier_block *nb); +int crash_wipe_secrets_unregister(struct notifier_block *nb); +#else +static inline int crash_wipe_secrets_register(struct notifier_block *nb) +{ + return 0; +} + +static inline int crash_wipe_secrets_unregister(struct notifier_block *nb) +{ + return 0; +} +#endif + #ifndef arch_crash_handle_hotplug_event static inline void arch_crash_handle_hotplug_event(struct kimage *image, void *arg) { } #endif
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 15632358bcf7..1d2d273145df 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec@@ -179,4 +179,20 @@ config CRASH_MAX_MEMORY_RANGES the computation behind the value provided through the /sys/kernel/crash_elfcorehdr_size attribute. +config CRASH_WIPE_SECRETS + bool "Wipe secrets before kdump" + depends on CRASH_DUMP + help + Wipe secrets (e.g. kernel keyring and memfd_secret pages) on crash or + panic. This is a best effort, defense-in-depth feature: If the panic + happens at a really bad time, or if copies of the secrets are present + in places like on the stack, in I/O buffers, or in userspace memory + not allocated through memfd_secret, they may still be leaked. + + Note that enabling this feature carries some risk of crashing the + system during the wipe process if the kernel was already unstable + when the panic happened. + + If unsure, say N. + endmenu
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 2b36aa9fade0..95f5c0415e60 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c@@ -23,6 +23,7 @@ #include <linux/objtool.h> #include <linux/delay.h> #include <linux/panic.h> +#include <linux/timekeeping.h> #include <asm/page.h> #include <asm/sections.h>
@@ -33,6 +34,33 @@ /* Per cpu memory for storing cpu states in case of system crash. */ note_buf_t __percpu *crash_notes; +#ifdef CONFIG_CRASH_WIPE_SECRETS +ATOMIC_NOTIFIER_HEAD(crash_wipe_secrets_notifier_list); + +int crash_wipe_secrets_register(struct notifier_block *nb) +{ + return atomic_notifier_chain_register( + &crash_wipe_secrets_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(crash_wipe_secrets_register); + +int crash_wipe_secrets_unregister(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister( + &crash_wipe_secrets_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(crash_wipe_secrets_unregister); + +static void crash_wipe_secrets(void) +{ + pr_info("Wiping sensitive secrets...\n"); + atomic_notifier_call_chain(&crash_wipe_secrets_notifier_list, 0, NULL); + pr_info("Done wiping secrets.\n"); +} +#else +static inline void crash_wipe_secrets(void) { } +#endif /* CONFIG_CRASH_WIPE_SECRETS */ + /* time to wait for possible DMA to finish before starting the kdump kernel * when a CMA reservation is used */
@@ -142,6 +170,7 @@ void __noclone __crash_kexec(struct pt_regs *regs) crash_save_vmcoreinfo(); machine_crash_shutdown(&fixed_regs); crash_cma_clear_pending_dma(); + crash_wipe_secrets(); machine_kexec(kexec_crash_image); } kexec_unlock();
--
2.53.0