https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bec42b653031205a375671...
commit bec42b653031205a37567179ba6a70bce8fcfb02 Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Fri May 21 15:11:50 2021 +0200 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Fri Jun 25 10:28:51 2021 +0200
[NTOS:MM] Do not call ExAllocatePool* with PFN lock acquired
Unsurprisingly, it actually might acquire it --- ntoskrnl/mm/section.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index b6a6ca67b4c..d758e8d3de0 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -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);