[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 */
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;
}

View file

@ -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

View file

@ -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 */