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

x86/crash: make the page that stores the dm crypt keys inaccessible

This adds an addition layer of protection for the saved copy of dm crypt
key. Trying to access the saved copy will cause page fault.

Link: https://lkml.kernel.org/r/20250502011246.99238-9-coxu@redhat.com
Signed-off-by: Coiby Xu <coxu@redhat.com>
Suggested-by: Pingfan Liu <kernelfans@gmail.com>
Acked-by: Baoquan He <bhe@redhat.com>
Cc: "Daniel P. Berrange" <berrange@redhat.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Jan Pazdziora <jpazdziora@redhat.com>
Cc: Milan Broz <gmazyland@gmail.com>
Cc: Ondrej Kozina <okozina@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Coiby Xu and committed by
Andrew Morton
cc66e486 5eb3f605

+22
+22
arch/x86/kernel/machine_kexec_64.c
··· 598 598 kexec_mark_range(control, crashk_res.end, protect); 599 599 } 600 600 601 + /* make the memory storing dm crypt keys in/accessible */ 602 + static void kexec_mark_dm_crypt_keys(bool protect) 603 + { 604 + unsigned long start_paddr, end_paddr; 605 + unsigned int nr_pages; 606 + 607 + if (kexec_crash_image->dm_crypt_keys_addr) { 608 + start_paddr = kexec_crash_image->dm_crypt_keys_addr; 609 + end_paddr = start_paddr + kexec_crash_image->dm_crypt_keys_sz - 1; 610 + nr_pages = (PAGE_ALIGN(end_paddr) - PAGE_ALIGN_DOWN(start_paddr))/PAGE_SIZE; 611 + if (protect) 612 + set_memory_np((unsigned long)phys_to_virt(start_paddr), nr_pages); 613 + else 614 + __set_memory_prot( 615 + (unsigned long)phys_to_virt(start_paddr), 616 + nr_pages, 617 + __pgprot(_PAGE_PRESENT | _PAGE_NX | _PAGE_RW)); 618 + } 619 + } 620 + 601 621 void arch_kexec_protect_crashkres(void) 602 622 { 603 623 kexec_mark_crashkres(true); 624 + kexec_mark_dm_crypt_keys(true); 604 625 } 605 626 606 627 void arch_kexec_unprotect_crashkres(void) 607 628 { 629 + kexec_mark_dm_crypt_keys(false); 608 630 kexec_mark_crashkres(false); 609 631 } 610 632 #endif