[ntoskrnl/mm]
authorMichael Martin <michael.martin@reactos.org>
Mon, 27 Sep 2010 08:46:02 +0000 (08:46 +0000)
committerMichael Martin <michael.martin@reactos.org>
Mon, 27 Sep 2010 08:46:02 +0000 (08:46 +0000)
- Acquire rundown protection on process to make sure it is not being terminated and before attempting to do anything with the process. Fixed a rare case of PspDeleteProcess being called twice for a process, resulting in bugcheck.

svn path=/trunk/; revision=48905

reactos/ntoskrnl/mm/rmap.c

index 35b4b57..1647335 100644 (file)
@@ -208,6 +208,13 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
       return(STATUS_UNSUCCESSFUL);
    }
    Process = entry->Process;
+
+   if (!ExAcquireRundownProtection(&Process->RundownProtect))
+   {
+      ExReleaseFastMutex(&RmapListLock);
+      return STATUS_PROCESS_IS_TERMINATING;
+   }
+
    Address = entry->Address;
    if ((((ULONG_PTR)Address) & 0xFFF) != 0)
    {
@@ -220,6 +227,7 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
       ExReleaseFastMutex(&RmapListLock);
       if (!NT_SUCCESS(Status))
       {
+         ExReleaseRundownProtection(&Process->RundownProtect);
          return Status;
       }
       AddressSpace = &Process->Vm;
@@ -235,6 +243,7 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
    if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
    {
       MmUnlockAddressSpace(AddressSpace);
+      ExReleaseRundownProtection(&Process->RundownProtect);
       if (Address < MmSystemRangeStart)
       {
          ObDereferenceObject(Process);
@@ -256,6 +265,7 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
       if (PageOp == NULL)
       {
          MmUnlockAddressSpace(AddressSpace);
+         ExReleaseRundownProtection(&Process->RundownProtect);
          if (Address < MmSystemRangeStart)
          {
             ObDereferenceObject(Process);
@@ -281,6 +291,7 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
       if (PageOp == NULL)
       {
          MmUnlockAddressSpace(AddressSpace);
+         ExReleaseRundownProtection(&Process->RundownProtect);
          if (Address < MmSystemRangeStart)
          {
             ObDereferenceObject(Process);
@@ -303,6 +314,9 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
    {
       KeBugCheck(MEMORY_MANAGEMENT);
    }
+
+   ExReleaseRundownProtection(&Process->RundownProtect);
+
    if (Address < MmSystemRangeStart)
    {
       ObDereferenceObject(Process);
@@ -499,6 +513,7 @@ MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
    ExAcquireFastMutex(&RmapListLock);
    previous_entry = NULL;
    current_entry = MmGetRmapListHeadPage(Page);
+
    while (current_entry != NULL)
    {
       if (current_entry->Process == (PEPROCESS)Process &&
@@ -514,14 +529,14 @@ MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
          }
          ExReleaseFastMutex(&RmapListLock);
          ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
-        if (Process == NULL)
-        {
-           Process = PsInitialSystemProcess;
-        }
-        if (Process)
-        {
+         if (Process == NULL)
+         {
+            Process = PsInitialSystemProcess;
+         }
+         if (Process)
+         {
             (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
-        }
+         }
          return;
       }
       previous_entry = current_entry;