| From 0bd4e7bceeef2c9988e6881292dd53d379fb40f2 Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ardb@kernel.org> |
| 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 <ardb@kernel.org> |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Link: https://lore.kernel.org/r/20200113172245.27925-5-ardb@kernel.org |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| 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); |
| |
| -- |
| 2.7.4 |
| |