diff mbox series

arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()

Message ID 20240902163309.97113-1-faresx@amazon.de (mailing list archive)
State New, archived
Headers show
Series arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec() | expand

Commit Message

Fares Mehanna Sept. 2, 2024, 4:33 p.m. UTC
The reasons for PTEs in the kernel direct map to be marked invalid are not
limited to kfence / debug pagealloc machinery. In particular,
memfd_secret() also steals pages with set_direct_map_invalid_noflush().

When building the transitional page tables for kexec from the current
kernel's page tables, those pages need to become regular writable pages,
otherwise, if the relocation places kexec segments over such pages, a fault
will occur during kexec, leading to host going dark during kexec.

This patch addresses the kexec issue by marking any PTE as valid if it is
not none. While this fixes the kexec crash, it does not address the
security concern that if processes owning secret memory are not terminated
before kexec, the secret content will be mapped in the new kernel without
being scrubbed.

Suggested-by: Jan H. Schönherr <jschoenh@amazon.de>
Signed-off-by: Fares Mehanna <faresx@amazon.de>
---
 arch/arm64/mm/trans_pgd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Will Deacon Sept. 4, 2024, 4:12 p.m. UTC | #1
On Mon, 02 Sep 2024 16:33:08 +0000, Fares Mehanna wrote:
> The reasons for PTEs in the kernel direct map to be marked invalid are not
> limited to kfence / debug pagealloc machinery. In particular,
> memfd_secret() also steals pages with set_direct_map_invalid_noflush().
> 
> When building the transitional page tables for kexec from the current
> kernel's page tables, those pages need to become regular writable pages,
> otherwise, if the relocation places kexec segments over such pages, a fault
> will occur during kexec, leading to host going dark during kexec.
> 
> [...]

Applied to arm64 (for-next/mm), thanks!

[1/1] arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()
      https://git.kernel.org/arm64/c/7eced90b202d

Cheers,
diff mbox series

Patch

diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 5139a28130c0..0f7b484cb2ff 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -42,14 +42,16 @@  static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 		 * the temporary mappings we use during restore.
 		 */
 		__set_pte(dst_ptep, pte_mkwrite_novma(pte));
-	} else if ((debug_pagealloc_enabled() ||
-		   is_kfence_address((void *)addr)) && !pte_none(pte)) {
+	} else if (!pte_none(pte)) {
 		/*
 		 * debug_pagealloc will removed the PTE_VALID bit if
 		 * the page isn't in use by the resume kernel. It may have
 		 * been in use by the original kernel, in which case we need
 		 * to put it back in our copy to do the restore.
 		 *
+		 * Other cases include kfence / vmalloc / memfd_secret which
+		 * may call `set_direct_map_invalid_noflush()`.
+		 *
 		 * Before marking this entry valid, check the pfn should
 		 * be mapped.
 		 */