[ntoskrnl/mm]

- 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
This commit is contained in:
Michael Martin 2010-09-27 08:46:02 +00:00
parent e4ec568733
commit f9692ba22c

View file

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