[NTOS:MM] Do not call ExAllocatePool* with PFN lock acquired

Unsurprisingly, it actually might acquire it
This commit is contained in:
Jérôme Gardou 2021-05-21 15:11:50 +02:00 committed by Jérôme Gardou
parent 42e111f26b
commit bec42b6530

View file

@ -2385,6 +2385,7 @@ MmCreateDataFileSection(PSECTION *SectionObject,
}
/* Lock the PFN lock while messing with Section Object pointers */
grab_segment:
OldIrql = MiAcquirePfnLock();
Segment = FileObject->SectionObjectPointer->DataSectionObject;
@ -2402,12 +2403,14 @@ MmCreateDataFileSection(PSECTION *SectionObject,
*/
if (Segment == NULL)
{
/* Release the lock. ExAllocatePoolWithTag might acquire it */
MiReleasePfnLock(OldIrql);
Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
TAG_MM_SECTION_SEGMENT);
if (Segment == NULL)
{
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
MiReleasePfnLock(OldIrql);
ObDereferenceObject(Section);
return STATUS_NO_MEMORY;
}
@ -2417,6 +2420,17 @@ MmCreateDataFileSection(PSECTION *SectionObject,
Segment->SegFlags = MM_DATAFILE_SEGMENT | MM_SEGMENT_INCREATE;
Segment->RefCount = 1;
/* Acquire lock again */
OldIrql = MiAcquirePfnLock();
if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
{
/* Well that's bad luck. Restart it all over */
MiReleasePfnLock(OldIrql);
ExFreePoolWithTag(Segment, TAG_MM_SECTION_SEGMENT);
goto grab_segment;
}
FileObject->SectionObjectPointer->DataSectionObject = Segment;
/* We're safe to release the lock now */
@ -3160,6 +3174,7 @@ MmCreateImageSection(PSECTION *SectionObject,
if (AllocationAttributes & SEC_NO_CHANGE)
Section->u.Flags.NoChange = 1;
grab_image_section_object:
OldIrql = MiAcquirePfnLock();
/* Wait for it to be properly created or deleted */
@ -3178,16 +3193,28 @@ MmCreateImageSection(PSECTION *SectionObject,
{
NTSTATUS StatusExeFmt;
/* Release the lock because ExAllocatePoolWithTag could need to acquire it */
MiReleasePfnLock(OldIrql);
ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
if (ImageSectionObject == NULL)
{
MiReleasePfnLock(OldIrql);
ObDereferenceObject(Section);
return STATUS_NO_MEMORY;
}
ImageSectionObject->SegFlags = MM_SEGMENT_INCREATE;
ImageSectionObject->RefCount = 1;
OldIrql = MiAcquirePfnLock();
if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
{
MiReleasePfnLock(OldIrql);
/* Bad luck. Start over */
ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
goto grab_image_section_object;
}
FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
MiReleasePfnLock(OldIrql);