https://git.reactos.org/?p=reactos.git;a=commitdiff;h=addf824d8739e937098e10fc3cd05ca094016d6e

commit addf824d8739e937098e10fc3cd05ca094016d6e
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Mon Dec 21 13:54:29 2020 +0100
Commit:     Jérôme Gardou <[email protected]>
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,

Reply via email to