https://git.reactos.org/?p=reactos.git;a=commitdiff;h=addf824d8739e937098e1…
commit addf824d8739e937098e10fc3cd05ca094016d6e
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Mon Dec 21 13:54:29 2020 +0100
Commit: Jérôme Gardou <jerome.gardou(a)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,