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_zeroize_notifier_list, invoked late into __crash_kexec(). Subsystems holding secrets can register a callback to scrub 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 --- include/linux/crash_core.h | 5 +++++ kernel/Kconfig.kexec | 8 ++++++++ kernel/crash_core.c | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index bc087124cd78..5c7207c0bba1 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -5,6 +5,7 @@ #include #include #include +#include struct kimage; @@ -34,6 +35,10 @@ static inline void arch_kexec_protect_crashkres(void) { } static inline void arch_kexec_unprotect_crashkres(void) { } #endif +#ifdef CONFIG_CRASH_ZEROIZE +extern struct atomic_notifier_head crash_zeroize_notifier_list; +#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..92ab0a69c8ec 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -179,4 +179,12 @@ config CRASH_MAX_MEMORY_RANGES the computation behind the value provided through the /sys/kernel/crash_elfcorehdr_size attribute. +config CRASH_ZEROIZE + bool "Zeroize secrets on panic" + depends on CRASH_DUMP + help + Wipe secrets (e.g. kernel keyring and memfd_secret pages) on crash or panic. + + If unsure, say N. + endmenu diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 2b36aa9fade0..d3a7763e2759 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,22 @@ /* Per cpu memory for storing cpu states in case of system crash. */ note_buf_t __percpu *crash_notes; +#ifdef CONFIG_CRASH_ZEROIZE +ATOMIC_NOTIFIER_HEAD(crash_zeroize_notifier_list); +EXPORT_SYMBOL_GPL(crash_zeroize_notifier_list); + +static void crash_zeroize(void) +{ + ktime_t zeroize_start = ktime_get(); + + pr_info("Wiping sensitive secrets...\n"); + atomic_notifier_call_chain(&crash_zeroize_notifier_list, 0, NULL); + pr_info("Done in %lld us\n", ktime_us_delta(ktime_get(), zeroize_start)); +} +#else +static inline void crash_zeroize(void) { } +#endif /* CONFIG_CRASH_ZEROIZE */ + /* time to wait for possible DMA to finish before starting the kdump kernel * when a CMA reservation is used */ @@ -142,6 +159,7 @@ void __noclone __crash_kexec(struct pt_regs *regs) crash_save_vmcoreinfo(); machine_crash_shutdown(&fixed_regs); crash_cma_clear_pending_dma(); + crash_zeroize(); machine_kexec(kexec_crash_image); } kexec_unlock(); -- 2.53.0