[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.
This commit is contained in:
Timo Kreuzer 2018-03-21 21:22:03 +01:00
parent d55811f160
commit d4b4cf7448
3 changed files with 21 additions and 11 deletions

View file

@ -945,6 +945,10 @@ MI_WRITE_VALID_PTE(IN PMMPTE PointerPte,
/* Write the valid PTE */ /* Write the valid PTE */
ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(PointerPte->u.Hard.Valid == 0);
ASSERT(TempPte.u.Hard.Valid == 1); 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; *PointerPte = TempPte;
} }
@ -999,6 +1003,9 @@ MI_WRITE_VALID_PDE(IN PMMPDE PointerPde,
{ {
/* Write the valid PDE */ /* Write the valid PDE */
ASSERT(PointerPde->u.Hard.Valid == 0); ASSERT(PointerPde->u.Hard.Valid == 0);
#ifdef _M_AMD64
ASSERT(PointerPde->u.Hard.NoExecute == 0);
#endif
ASSERT(TempPde.u.Hard.Valid == 1); ASSERT(TempPde.u.Hard.Valid == 1);
*PointerPde = TempPde; *PointerPde = TempPde;
} }
@ -1014,6 +1021,9 @@ MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde,
/* Write the invalid PDE */ /* Write the invalid PDE */
ASSERT(InvalidPde.u.Hard.Valid == 0); ASSERT(InvalidPde.u.Hard.Valid == 0);
ASSERT(InvalidPde.u.Long != 0); ASSERT(InvalidPde.u.Long != 0);
#ifdef _M_AMD64
ASSERT(InvalidPde.u.Soft.Protection == MM_EXECUTE_READWRITE);
#endif
*PointerPde = InvalidPde; *PointerPde = InvalidPde;
} }

View file

@ -319,7 +319,7 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress,
} }
/* Return full access rights */ /* Return full access rights */
*ProtectCode = MM_READWRITE; *ProtectCode = MM_EXECUTE_READWRITE;
return NULL; return NULL;
} }
else if (MI_IS_SESSION_ADDRESS(VirtualAddress)) else if (MI_IS_SESSION_ADDRESS(VirtualAddress))
@ -2099,7 +2099,7 @@ UserFault:
/* Resolve a demand zero fault */ /* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPpe, MiResolveDemandZeroFault(PointerPpe,
PointerPxe, PointerPxe,
MM_READWRITE, MM_EXECUTE_READWRITE,
CurrentProcess, CurrentProcess,
MM_NOIRQL); MM_NOIRQL);
@ -2133,7 +2133,7 @@ UserFault:
/* Resolve a demand zero fault */ /* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPde, MiResolveDemandZeroFault(PointerPde,
PointerPpe, PointerPpe,
MM_READWRITE, MM_EXECUTE_READWRITE,
CurrentProcess, CurrentProcess,
MM_NOIRQL); MM_NOIRQL);
@ -2175,7 +2175,7 @@ UserFault:
/* Resolve a demand zero fault */ /* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPte, MiResolveDemandZeroFault(PointerPte,
PointerPde, PointerPde,
MM_READWRITE, MM_EXECUTE_READWRITE,
CurrentProcess, CurrentProcess,
MM_NOIRQL); MM_NOIRQL);
#if MI_TRACE_PFNS #if MI_TRACE_PFNS
@ -2338,7 +2338,7 @@ UserFault:
_WARN("This is probably completely broken!"); _WARN("This is probably completely broken!");
MI_WRITE_INVALID_PDE((PMMPDE)PointerPte, DemandZeroPde); MI_WRITE_INVALID_PDE((PMMPDE)PointerPte, DemandZeroPde);
#else #else
MI_WRITE_INVALID_PTE(PointerPte, DemandZeroPde); MI_WRITE_INVALID_PDE(PointerPte, DemandZeroPde);
#endif #endif
} }
else else

View file

@ -25,19 +25,19 @@ extern PMMPTE MmDebugPte;
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
/* Template PTE and PDE for a kernel page */ /* Template PTE and PDE for a kernel page */
MMPTE ValidKernelPde = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; MMPTE ValidKernelPde = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
MMPTE ValidKernelPte = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; MMPTE ValidKernelPte = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
/* The same, but for local pages */ /* The same, but for local pages */
MMPTE ValidKernelPdeLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; MMPTE ValidKernelPdeLocal = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
MMPTE ValidKernelPteLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; MMPTE ValidKernelPteLocal = {{PTE_VALID|PTE_EXECUTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
/* Template PDE for a demand-zero page */ /* 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}}; MMPTE DemandZeroPte = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}};
/* Template PTE for prototype page */ /* 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)}}; PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << 32)}};
/* Template PTE for decommited page */ /* Template PTE for decommited page */