https://git.reactos.org/?p=reactos.git;a=commitdiff;h=601bb49c0d276447fd6435a8f70cc0f190db681a

commit 601bb49c0d276447fd6435a8f70cc0f190db681a
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Mon Oct 9 22:24:01 2023 +0300
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Tue Oct 24 21:45:27 2023 +0300

    [NTOS:MM] Fix MmFreeMemoryArea
    
    - Stay attached while deleting the VAD node
    - Acquire the appropriate working set lock when deleting a VAD node
    - Both are needed for locking correctness
---
 ntoskrnl/mm/marea.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/ntoskrnl/mm/marea.c b/ntoskrnl/mm/marea.c
index ab8bff4a18e..281226c4afc 100644
--- a/ntoskrnl/mm/marea.c
+++ b/ntoskrnl/mm/marea.c
@@ -300,8 +300,7 @@ MmFreeMemoryArea(
         PEPROCESS CurrentProcess = PsGetCurrentProcess();
         PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
 
-        if (Process != NULL &&
-                Process != CurrentProcess)
+        if ((Process != NULL) && (Process != CurrentProcess))
         {
             KeAttachProcess(&Process->Pcb);
         }
@@ -337,12 +336,6 @@ MmFreeMemoryArea(
             }
         }
 
-        if (Process != NULL &&
-                Process != CurrentProcess)
-        {
-            KeDetachProcess();
-        }
-
         //if (MemoryArea->VadNode.StartingVpn < (ULONG_PTR)MmSystemRangeStart 
>> PAGE_SHIFT
         if (MemoryArea->Vad)
         {
@@ -357,14 +350,23 @@ MmFreeMemoryArea(
             ASSERT(MemoryArea->VadNode.u.VadFlags.Spare != 0);
             if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1)
             {
+                MiLockProcessWorkingSet(PsGetCurrentProcess(), 
PsGetCurrentThread());
                 MiRemoveNode((PMMADDRESS_NODE)&MemoryArea->VadNode, 
&Process->VadRoot);
+                MiUnlockProcessWorkingSet(PsGetCurrentProcess(), 
PsGetCurrentThread());
             }
 
             MemoryArea->Vad = NULL;
         }
         else
         {
+            MiLockWorkingSet(PsGetCurrentThread(), &MmSystemCacheWs);
             MiRemoveNode((PMMADDRESS_NODE)&MemoryArea->VadNode, 
&MiRosKernelVadRoot);
+            MiUnlockWorkingSet(PsGetCurrentThread(), &MmSystemCacheWs);
+        }
+
+        if ((Process != NULL) && (Process != CurrentProcess))
+        {
+            KeDetachProcess();
         }
     }
 

Reply via email to