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.
/* 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;
}
{
/* 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;
}
/* 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;
}
}
/* Return full access rights */
- *ProtectCode = MM_READWRITE;
+ *ProtectCode = MM_EXECUTE_READWRITE;
return NULL;
}
else if (MI_IS_SESSION_ADDRESS(VirtualAddress))
/* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPpe,
PointerPxe,
- MM_READWRITE,
+ MM_EXECUTE_READWRITE,
CurrentProcess,
MM_NOIRQL);
/* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPde,
PointerPpe,
- MM_READWRITE,
+ MM_EXECUTE_READWRITE,
CurrentProcess,
MM_NOIRQL);
/* Resolve a demand zero fault */
MiResolveDemandZeroFault(PointerPte,
PointerPde,
- MM_READWRITE,
+ MM_EXECUTE_READWRITE,
CurrentProcess,
MM_NOIRQL);
#if MI_TRACE_PFNS
_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
/* 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 */