[NTOS:MM] Add a MmChangeKernelResourceSectionProtection() helper. (#1649)
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 13 Jul 2019 22:04:19 +0000 (00:04 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 14 Jul 2019 20:23:49 +0000 (22:23 +0200)
This allows setting the memory protection of the kernel's resource
section as will. MmMakeKernelResourceSectionWritable() is re-implemented
around this helper.

ntoskrnl/include/internal/mm.h
ntoskrnl/mm/ARM3/sysldr.c

index da3a720..32fd7b1 100644 (file)
@@ -1370,6 +1370,10 @@ MiInitializeLoadedModuleList(
     IN PLOADER_PARAMETER_BLOCK LoaderBlock
 );
 
     IN PLOADER_PARAMETER_BLOCK LoaderBlock
 );
 
+BOOLEAN
+NTAPI
+MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask);
+
 VOID
 NTAPI
 MmMakeKernelResourceSectionWritable(VOID);
 VOID
 NTAPI
 MmMakeKernelResourceSectionWritable(VOID);
index 036c385..ab6e116 100644 (file)
@@ -2281,20 +2281,20 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     return TRUE;
 }
 
     return TRUE;
 }
 
-VOID
+BOOLEAN
 NTAPI
 NTAPI
-MmMakeKernelResourceSectionWritable(VOID)
+MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
 {
     PMMPTE PointerPte;
     MMPTE TempPte;
 
     /* Don't do anything if the resource section is already writable */
     if (MiKernelResourceStartPte == NULL || MiKernelResourceEndPte == NULL)
 {
     PMMPTE PointerPte;
     MMPTE TempPte;
 
     /* Don't do anything if the resource section is already writable */
     if (MiKernelResourceStartPte == NULL || MiKernelResourceEndPte == NULL)
-        return;
+        return FALSE;
 
     /* If the resource section is physical, we cannot change its protection */
     if (MI_IS_PHYSICAL_ADDRESS(MiPteToAddress(MiKernelResourceStartPte)))
 
     /* If the resource section is physical, we cannot change its protection */
     if (MI_IS_PHYSICAL_ADDRESS(MiPteToAddress(MiKernelResourceStartPte)))
-        return;
+        return FALSE;
 
     /* Loop the PTEs */
     for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
 
     /* Loop the PTEs */
     for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
@@ -2303,19 +2303,36 @@ MmMakeKernelResourceSectionWritable(VOID)
         TempPte = *PointerPte;
 
         /* Update the protection */
         TempPte = *PointerPte;
 
         /* Update the protection */
-        MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, MM_READWRITE, TempPte.u.Hard.PageFrameNumber);
+        MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
         MI_UPDATE_VALID_PTE(PointerPte, TempPte);
     }
 
         MI_UPDATE_VALID_PTE(PointerPte, TempPte);
     }
 
-    /*
-     * Invalidate the cached resource section PTEs
-     * so as to not change its protection again later.
-     */
-    MiKernelResourceStartPte = NULL;
-    MiKernelResourceEndPte = NULL;
-
     /* Only flush the current processor's TLB */
     KeFlushCurrentTb();
     /* Only flush the current processor's TLB */
     KeFlushCurrentTb();
+    return TRUE;
+}
+
+VOID
+NTAPI
+MmMakeKernelResourceSectionWritable(VOID)
+{
+    /* Don't do anything if the resource section is already writable */
+    if (MiKernelResourceStartPte == NULL || MiKernelResourceEndPte == NULL)
+        return;
+
+    /* If the resource section is physical, we cannot change its protection */
+    if (MI_IS_PHYSICAL_ADDRESS(MiPteToAddress(MiKernelResourceStartPte)))
+        return;
+
+    if (MmChangeKernelResourceSectionProtection(MM_READWRITE))
+    {
+        /*
+         * Invalidate the cached resource section PTEs
+         * so as to not change its protection again later.
+         */
+        MiKernelResourceStartPte = NULL;
+        MiKernelResourceEndPte = NULL;
+    }
 }
 
 LOGICAL
 }
 
 LOGICAL