blob: 30ba0d6e01c70470f108366243fd361a04f29831 [file] [log] [blame]
From 0bd4e7bceeef2c9988e6881292dd53d379fb40f2 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <>
Date: Mon, 13 Jan 2020 18:22:36 +0100
Subject: [PATCH] x86/mm: Fix NX bit clearing issue in kernel_map_pages_in_pgd
commit 75fbef0a8b6b4bb19b9a91b5214f846c2dc5139e upstream.
The following commit:
15f003d20782 ("x86/mm/pat: Don't implicitly allow _PAGE_RW in kernel_map_pages_in_pgd()")
modified kernel_map_pages_in_pgd() to manage writable permissions
of memory mappings in the EFI page table in a different way, but
in the process, it removed the ability to clear NX attributes from
read-only mappings, by clobbering the clear mask if _PAGE_RW is not
being requested.
Failure to remove the NX attribute from read-only mappings is
unlikely to be a security issue, but it does prevent us from
tightening the permissions in the EFI page tables going forward,
so let's fix it now.
Fixes: 15f003d20782 ("x86/mm/pat: Don't implicitly allow _PAGE_RW in kernel_map_pages_in_pgd()
Signed-off-by: Ard Biesheuvel <>
Signed-off-by: Ingo Molnar <>
Signed-off-by: Paul Gortmaker <>
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index e14e95ea7338..d93ac926ea20 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -2325,7 +2325,7 @@ int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
.pgd = pgd,
.numpages = numpages,
.mask_set = __pgprot(0),
- .mask_clr = __pgprot(0),
+ .mask_clr = __pgprot(~page_flags & (_PAGE_NX|_PAGE_RW)),
.flags = 0,
@@ -2334,12 +2334,6 @@ int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
if (!(__supported_pte_mask & _PAGE_NX))
goto out;
- if (!(page_flags & _PAGE_NX))
- cpa.mask_clr = __pgprot(_PAGE_NX);
- if (!(page_flags & _PAGE_RW))
- cpa.mask_clr = __pgprot(_PAGE_RW);
if (!(page_flags & _PAGE_ENC))
cpa.mask_clr = pgprot_encrypted(cpa.mask_clr);