https://git.reactos.org/?p=reactos.git;a=commitdiff;h=addf824d8739e937098e10...
commit addf824d8739e937098e10fc3cd05ca094016d6e Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Mon Dec 21 13:54:29 2020 +0100 Commit: Jérôme Gardou jerome.gardou@reactos.org CommitDate: Wed Feb 3 09:41:23 2021 +0100
[NTOS:MM] Keep image maps & file maps coherent at the time of creating the image map --- ntoskrnl/mm/section.c | 128 +++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 63 deletions(-)
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index b9242c6eade..4756875a661 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -2448,6 +2448,19 @@ ExeFmtpAllocateSegments(IN ULONG NrSegments) return Segments; }
+static NTSTATUS +MmMapViewOfSegment(PMMSUPPORT AddressSpace, + BOOLEAN AsImage, + PMM_SECTION_SEGMENT Segment, + PVOID* BaseAddress, + SIZE_T ViewSize, + ULONG Protect, + LONGLONG ViewOffset, + ULONG AllocationType); +static NTSTATUS +MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, + PVOID BaseAddress); + static NTSTATUS NTAPI @@ -2490,36 +2503,57 @@ ExeFmtpReadFile(IN PVOID File, BufferSize = Length + OffsetAdjustment; BufferSize = PAGE_ROUND_UP(BufferSize);
- /* Flush data since we're about to perform a non-cached read */ - CcFlushCache(FileObject->SectionObjectPointer, - &FileOffset, - BufferSize, - &Iosb); - /* * It's ok to use paged pool, because this is a temporary buffer only used in * the loading of executables. The assumption is that MmCreateSection is * always called at low IRQLs and that these buffers don't survive a brief * initialization phase */ - Buffer = ExAllocatePoolWithTag(PagedPool, - BufferSize, - 'rXmM'); + Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, 'rXmM'); if (!Buffer) { return STATUS_INSUFFICIENT_RESOURCES; }
- UsedSize = 0; + if (FileObject->SectionObjectPointer->DataSectionObject) + { + PVOID SegmentMap = NULL;
- Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb); + /* Get the data from the file mapping instead */ + MmLockAddressSpace(MmGetKernelAddressSpace()); + Status = MmMapViewOfSegment(MmGetKernelAddressSpace(), + FALSE, + FileObject->SectionObjectPointer->DataSectionObject, + &SegmentMap, + BufferSize, + PAGE_READONLY, + FileOffset.QuadPart, + 0); + MmUnlockAddressSpace(MmGetKernelAddressSpace());
- UsedSize = (ULONG)Iosb.Information; + if (!NT_SUCCESS(Status)) + return Status; + + RtlCopyMemory(Buffer, SegmentMap, BufferSize); + UsedSize = BufferSize;
- if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment) + MmLockAddressSpace(MmGetKernelAddressSpace()); + + MmUnmapViewOfSegment(MmGetKernelAddressSpace(), SegmentMap); + + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + } + else { - Status = STATUS_IN_PAGE_ERROR; - ASSERT(!NT_SUCCESS(Status)); + Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb); + + UsedSize = (ULONG)Iosb.Information; + + if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment) + { + Status = STATUS_IN_PAGE_ERROR; + ASSERT(!NT_SUCCESS(Status)); + } }
if(NT_SUCCESS(Status)) @@ -3102,7 +3136,6 @@ MmCreateImageSection(PSECTION *SectionObject, if (ImageSectionObject == NULL) { NTSTATUS StatusExeFmt; - PMM_SECTION_SEGMENT DataSectionObject;
ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT); if (ImageSectionObject == NULL) @@ -3116,44 +3149,12 @@ MmCreateImageSection(PSECTION *SectionObject, ImageSectionObject->RefCount = 1; FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
- /* Get a ref on the data section object */ - DataSectionObject = FileObject->SectionObjectPointer->DataSectionObject; - while (DataSectionObject && (DataSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE))) - { - LARGE_INTEGER ShortTime; - - MiReleasePfnLock(OldIrql); - - ShortTime.QuadPart = - 10 * 100 * 1000; - KeDelayExecutionThread(KernelMode, FALSE, &ShortTime); - - OldIrql = MiAcquirePfnLock(); - DataSectionObject = FileObject->SectionObjectPointer->DataSectionObject; - ASSERT(DataSectionObject->SegFlags & MM_DATAFILE_SEGMENT); - } - - /* Get a ref on it. */ - if (DataSectionObject) - InterlockedIncrementUL(&DataSectionObject->RefCount); - MiReleasePfnLock(OldIrql);
- if (DataSectionObject) + /* Purge the cache */ + if (CcIsFileCached(FileObject)) { - if ((DataSectionObject->SectionCount - (FileObject->SectionObjectPointer->SharedCacheMap != NULL)) > 0) - { - /* Someone's got a section opened. Deny creation */ - DPRINT1("Denying image creation for %wZ: Sections opened: %lu.\n", - &FileObject->FileName, DataSectionObject->SectionCount); - InterlockedExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject, NULL); - ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT); - MmDereferenceSegment(DataSectionObject); - ObDereferenceObject(Section); - return STATUS_ACCESS_DENIED; - } - - /* Purge the cache. */ - CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE); + CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL); }
StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject); @@ -3234,14 +3235,15 @@ MmCreateImageSection(PSECTION *SectionObject,
static NTSTATUS -MmMapViewOfSegment(PMMSUPPORT AddressSpace, - PSECTION Section, - PMM_SECTION_SEGMENT Segment, - PVOID* BaseAddress, - SIZE_T ViewSize, - ULONG Protect, - LONGLONG ViewOffset, - ULONG AllocationType) +MmMapViewOfSegment( + PMMSUPPORT AddressSpace, + BOOLEAN AsImage, + PMM_SECTION_SEGMENT Segment, + PVOID* BaseAddress, + SIZE_T ViewSize, + ULONG Protect, + LONGLONG ViewOffset, + ULONG AllocationType) { PMEMORY_AREA MArea; NTSTATUS Status; @@ -3297,7 +3299,7 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
MArea->SectionData.Segment = Segment; MArea->SectionData.ViewOffset.QuadPart = ViewOffset; - if (Section->u.Flags.Image) + if (AsImage) { MArea->VadNode.u.VadFlags.VadType = VadImageMap; } @@ -3932,7 +3934,7 @@ MmMapViewOfSection(IN PVOID SectionObject, ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress); MmLockSectionSegment(&SectionSegments[i]); Status = MmMapViewOfSegment(AddressSpace, - Section, + TRUE, &SectionSegments[i], &SBaseAddress, SectionSegments[i].Length.QuadPart, @@ -4017,7 +4019,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
MmLockSectionSegment(Segment); Status = MmMapViewOfSegment(AddressSpace, - Section, + FALSE, Segment, BaseAddress, *ViewSize, @@ -4191,7 +4193,7 @@ MmMapViewInSystemSpaceEx ( MmLockSectionSegment(Segment);
Status = MmMapViewOfSegment(AddressSpace, - Section, + Section->u.Flags.Image, Segment, MappedBase, *ViewSize,