[NTOS:MM] Make sure PXEs/PPEs and PDEs are always MM_EXECUTE_READWRITE
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 21 Mar 2018 20:22:03 +0000 (21:22 +0100)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 1 Nov 2020 08:32:27 +0000 (09:32 +0100)
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
ntoskrnl/mm/ARM3/pagfault.c
ntoskrnl/mm/amd64/init.c

index 9d85c42..8b6cc19 100644 (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;
 }
 
index 1ab109e..eefee2b 100644 (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
index 89aace7..9eae6c9 100644 (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 */