https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d4b4cf744887cbed6863f4...
commit d4b4cf744887cbed6863f44360a25f7f17b34319 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Wed Mar 21 21:22:03 2018 +0100 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Sun Nov 1 09:32:27 2020 +0100
[NTOS:MM] Make sure PXEs/PPEs and PDEs are always MM_EXECUTE_READWRITE
This is required since the NX protection proagates from the highest level, enforcing NX on the entire range, independent of whether lower level P*Es have the bit set or not. It might be useful to add a platform specific constant to allow making page tables NX on architectures that have a different behavior. --- ntoskrnl/mm/ARM3/miarm.h | 10 ++++++++++ ntoskrnl/mm/ARM3/pagfault.c | 10 +++++----- ntoskrnl/mm/amd64/init.c | 12 ++++++------ 3 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 9d85c42afff..8b6cc19b45e 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -945,6 +945,10 @@ MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, /* Write the valid PTE */ ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 1); +#if _M_AMD64 + ASSERT(!MI_IS_PAGE_TABLE_ADDRESS(MiPteToAddress(PointerPte)) || + (TempPte.u.Hard.NoExecute == 0)); +#endif *PointerPte = TempPte; }
@@ -999,6 +1003,9 @@ MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, { /* Write the valid PDE */ ASSERT(PointerPde->u.Hard.Valid == 0); +#ifdef _M_AMD64 + ASSERT(PointerPde->u.Hard.NoExecute == 0); +#endif ASSERT(TempPde.u.Hard.Valid == 1); *PointerPde = TempPde; } @@ -1014,6 +1021,9 @@ MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde, /* Write the invalid PDE */ ASSERT(InvalidPde.u.Hard.Valid == 0); ASSERT(InvalidPde.u.Long != 0); +#ifdef _M_AMD64 + ASSERT(InvalidPde.u.Soft.Protection == MM_EXECUTE_READWRITE); +#endif *PointerPde = InvalidPde; }
diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c index 1ab109e9f65..eefee2b340b 100644 --- a/ntoskrnl/mm/ARM3/pagfault.c +++ b/ntoskrnl/mm/ARM3/pagfault.c @@ -319,7 +319,7 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress, }
/* Return full access rights */ - *ProtectCode = MM_READWRITE; + *ProtectCode = MM_EXECUTE_READWRITE; return NULL; } else if (MI_IS_SESSION_ADDRESS(VirtualAddress)) @@ -2099,7 +2099,7 @@ UserFault: /* Resolve a demand zero fault */ MiResolveDemandZeroFault(PointerPpe, PointerPxe, - MM_READWRITE, + MM_EXECUTE_READWRITE, CurrentProcess, MM_NOIRQL);
@@ -2133,7 +2133,7 @@ UserFault: /* Resolve a demand zero fault */ MiResolveDemandZeroFault(PointerPde, PointerPpe, - MM_READWRITE, + MM_EXECUTE_READWRITE, CurrentProcess, MM_NOIRQL);
@@ -2175,7 +2175,7 @@ UserFault: /* Resolve a demand zero fault */ MiResolveDemandZeroFault(PointerPte, PointerPde, - MM_READWRITE, + MM_EXECUTE_READWRITE, CurrentProcess, MM_NOIRQL); #if MI_TRACE_PFNS @@ -2338,7 +2338,7 @@ UserFault: _WARN("This is probably completely broken!"); MI_WRITE_INVALID_PDE((PMMPDE)PointerPte, DemandZeroPde); #else - MI_WRITE_INVALID_PTE(PointerPte, DemandZeroPde); + MI_WRITE_INVALID_PDE(PointerPte, DemandZeroPde); #endif } else diff --git a/ntoskrnl/mm/amd64/init.c b/ntoskrnl/mm/amd64/init.c index 89aace7dc15..9eae6c9b0da 100644 --- a/ntoskrnl/mm/amd64/init.c +++ b/ntoskrnl/mm/amd64/init.c @@ -25,19 +25,19 @@ extern PMMPTE MmDebugPte; /* GLOBALS *****************************************************************/
/* Template PTE and PDE for a kernel page */ -MMPTE ValidKernelPde = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; -MMPTE ValidKernelPte = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; +MMPTE ValidKernelPde = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; +MMPTE ValidKernelPte = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
/* The same, but for local pages */ -MMPTE ValidKernelPdeLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; -MMPTE ValidKernelPteLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; +MMPTE ValidKernelPdeLocal = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; +MMPTE ValidKernelPteLocal = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
/* Template PDE for a demand-zero page */ -MMPDE DemandZeroPde = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}}; +MMPDE DemandZeroPde = {{MM_EXECUTE_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}}; MMPTE DemandZeroPte = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}};
/* Template PTE for prototype page */ -MMPTE PrototypePte = {{(MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | +MMPTE PrototypePte = {{(MM_EXECUTE_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << 32)}};
/* Template PTE for decommited page */