https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d4b4cf744887cbed6863f…
commit d4b4cf744887cbed6863f44360a25f7f17b34319
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Mar 21 21:22:03 2018 +0100
Commit: Timo Kreuzer <timo.kreuzer(a)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 */