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

commit f1631b44e120f2c6319fb4d4b113b0a43336b413
Author:     Jérôme Gardou <jerome.gar...@reactos.org>
AuthorDate: Tue Oct 27 17:36:18 2020 +0100
Commit:     Jérôme Gardou <jerome.gar...@reactos.org>
CommitDate: Wed Feb 3 09:41:22 2021 +0100

    [NTOS/MM] Introduce MmMapViewInSystemSpaceEx
---
 ntoskrnl/include/internal/mm.h | 10 +++++++++
 ntoskrnl/mm/ARM3/section.c     | 38 +++++++++++++++++++++++--------
 ntoskrnl/mm/section.c          | 51 ++++++++++++++++++++++++++----------------
 3 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index a8536c3d786..662f49c9bd7 100644
--- a/ntoskrnl/include/internal/mm.h
+++ b/ntoskrnl/include/internal/mm.h
@@ -1313,6 +1313,16 @@ VOID
 NTAPI
 MmFreeSectionSegments(PFILE_OBJECT FileObject);
 
+/* Exported from NT 6.2 Onward. We keep it internal. */
+NTSTATUS
+NTAPI
+MmMapViewInSystemSpaceEx (
+    _In_ PVOID Section,
+    _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase,
+    _Inout_ PSIZE_T ViewSize,
+    _Inout_ PLARGE_INTEGER SectionOffset
+    );
+
 /* sysldr.c ******************************************************************/
 
 VOID
diff --git a/ntoskrnl/mm/ARM3/section.c b/ntoskrnl/mm/ARM3/section.c
index 511f11a5101..938a08d6037 100644
--- a/ntoskrnl/mm/ARM3/section.c
+++ b/ntoskrnl/mm/ARM3/section.c
@@ -416,12 +416,16 @@ NTSTATUS
 NTAPI
 MiAddMappedPtes(IN PMMPTE FirstPte,
                 IN PFN_NUMBER PteCount,
-                IN PCONTROL_AREA ControlArea)
+                IN PCONTROL_AREA ControlArea,
+                IN PLARGE_INTEGER SectionOffset)
 {
     MMPTE TempPte;
     PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte;
     PSUBSECTION Subsection;
 
+    /* Mapping at offset not supported yet */
+    ASSERT(SectionOffset->QuadPart == 0);
+
     /* ARM3 doesn't support this yet */
     ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
     ASSERT(ControlArea->u.Flags.Rom == 0);
@@ -1052,11 +1056,13 @@ NTAPI
 MiMapViewInSystemSpace(IN PVOID Section,
                        IN PMMSESSION Session,
                        OUT PVOID *MappedBase,
-                       IN OUT PSIZE_T ViewSize)
+                       IN OUT PSIZE_T ViewSize,
+                       IN PLARGE_INTEGER SectionOffset)
 {
     PVOID Base;
     PCONTROL_AREA ControlArea;
-    ULONG Buckets, SectionSize;
+    ULONG Buckets;
+    LONGLONG SectionSize;
     NTSTATUS Status;
     PAGED_CODE();
 
@@ -1073,13 +1079,23 @@ MiMapViewInSystemSpace(IN PVOID Section,
     ASSERT(NT_SUCCESS(Status));
 
     /* Get the section size at creation time */
-    SectionSize = ((PSECTION)Section)->SizeOfSection.LowPart;
+    SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart;
 
-    /* If the caller didn't specify a view size, assume the whole section */
-    if (!(*ViewSize)) *ViewSize = SectionSize;
+    /* If the caller didn't specify a view size, assume until the end of the 
section */
+    if (!(*ViewSize))
+    {
+        /* Check for overflow first */
+        if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX)
+        {
+            DPRINT1("Section end is too far away from the specified 
offset.\n");
+            MiDereferenceControlArea(ControlArea);
+            return STATUS_INVALID_VIEW_SIZE;
+        }
+        *ViewSize = SectionSize - SectionOffset->QuadPart;
+    }
 
     /* Check if the caller wanted a larger section than the view */
-    if (*ViewSize > SectionSize)
+    if (SectionOffset->QuadPart + *ViewSize > SectionSize)
     {
         /* Fail */
         DPRINT1("View is too large\n");
@@ -1129,7 +1145,8 @@ MiMapViewInSystemSpace(IN PVOID Section,
     /* Create the actual prototype PTEs for this mapping */
     Status = MiAddMappedPtes(MiAddressToPte(Base),
                              BYTES_TO_PAGES(*ViewSize),
-                             ControlArea);
+                             ControlArea,
+                             SectionOffset);
     ASSERT(NT_SUCCESS(Status));
 
     /* Return the base adress of the mapping and success */
@@ -3016,6 +3033,7 @@ MmMapViewInSessionSpace(IN PVOID Section,
                         IN OUT PSIZE_T ViewSize)
 {
     PAGED_CODE();
+    LARGE_INTEGER SectionOffset;
 
     // HACK
     if (MiIsRosSectionObject(Section))
@@ -3032,10 +3050,12 @@ MmMapViewInSessionSpace(IN PVOID Section,
 
     /* Use the system space API, but with the session view instead */
     ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+    SectionOffset.QuadPart = 0;
     return MiMapViewInSystemSpace(Section,
                                   &MmSessionSpace->Session,
                                   MappedBase,
-                                  ViewSize);
+                                  ViewSize,
+                                  &SectionOffset);
 }
 
 /*
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c
index 04cba04d612..fc2c1a3e904 100644
--- a/ntoskrnl/mm/section.c
+++ b/ntoskrnl/mm/section.c
@@ -88,7 +88,8 @@ NTAPI
 MiMapViewInSystemSpace(IN PVOID Section,
                        IN PVOID Session,
                        OUT PVOID *MappedBase,
-                       IN OUT PSIZE_T ViewSize);
+                       IN OUT PSIZE_T ViewSize,
+                       IN PLARGE_INTEGER SectionOffset);
 
 NTSTATUS
 NTAPI
@@ -3832,7 +3833,7 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
                    PVOID* BaseAddress,
                    SIZE_T ViewSize,
                    ULONG Protect,
-                   ULONG ViewOffset,
+                   LONGLONG ViewOffset,
                    ULONG AllocationType)
 {
     PMEMORY_AREA MArea;
@@ -4417,7 +4418,6 @@ MmMapViewOfSection(IN PVOID SectionObject,
 {
     PSECTION Section;
     PMMSUPPORT AddressSpace;
-    ULONG ViewOffset;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN NotAtBase = FALSE;
 
@@ -4530,7 +4530,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
                                         Section,
                                         &SectionSegments[i],
                                         &SBaseAddress,
-                                        SectionSegments[i].Length.LowPart,
+                                        SectionSegments[i].Length.QuadPart,
                                         SectionSegments[i].Protection,
                                         0,
                                         0);
@@ -4548,6 +4548,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
     else
     {
         PMM_SECTION_SEGMENT Segment = (PMM_SECTION_SEGMENT)Section->Segment;
+        LONGLONG ViewOffset;
 
         /* check for write access */
         if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) &&
@@ -4577,7 +4578,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
         }
         else
         {
-            ViewOffset = SectionOffset->u.LowPart;
+            ViewOffset = SectionOffset->QuadPart;
         }
 
         if ((ViewOffset % PAGE_SIZE) != 0)
@@ -4588,11 +4589,11 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
         if ((*ViewSize) == 0)
         {
-            (*ViewSize) = Section->SizeOfSection.u.LowPart - ViewOffset;
+            (*ViewSize) = Section->SizeOfSection.QuadPart - ViewOffset;
         }
-        else if (((*ViewSize)+ViewOffset) > Section->SizeOfSection.u.LowPart)
+        else if (((*ViewSize)+ViewOffset) > Section->SizeOfSection.QuadPart)
         {
-            (*ViewSize) = Section->SizeOfSection.u.LowPart - ViewOffset;
+            (*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, 
SIZE_T_MAX - PAGE_SIZE);
         }
 
         *ViewSize = PAGE_ROUND_UP(*ViewSize);
@@ -4756,7 +4757,23 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
                         OUT PVOID * MappedBase,
                         IN OUT PSIZE_T ViewSize)
 {
-    PSECTION Section;
+    LARGE_INTEGER SectionOffset;
+
+    SectionOffset.QuadPart = 0;
+
+    return MmMapViewInSystemSpaceEx(SectionObject, MappedBase, ViewSize, 
&SectionOffset);
+}
+
+NTSTATUS
+NTAPI
+MmMapViewInSystemSpaceEx (
+    _In_ PVOID SectionObject,
+    _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase,
+    _Inout_ PSIZE_T ViewSize,
+    _Inout_ PLARGE_INTEGER SectionOffset
+    )
+{
+    PSECTION Section = SectionObject;
     PMM_SECTION_SEGMENT Segment;
     PMMSUPPORT AddressSpace;
     NTSTATUS Status;
@@ -4767,10 +4784,11 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
         return MiMapViewInSystemSpace(SectionObject,
                                       &MmSession,
                                       MappedBase,
-                                      ViewSize);
+                                      ViewSize,
+                                      SectionOffset);
     }
 
-    DPRINT("MmMapViewInSystemSpace() called\n");
+    DPRINT("MmMapViewInSystemSpaceEx() called\n");
 
     Section = SectionObject;
     Segment = (PMM_SECTION_SEGMENT)Section->Segment;
@@ -4780,25 +4798,20 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
     MmLockAddressSpace(AddressSpace);
 
 
-    if ((*ViewSize) == 0)
+    if ((*ViewSize == 0) || ((SectionOffset->QuadPart + *ViewSize) > 
Section->SizeOfSection.QuadPart))
     {
-        (*ViewSize) = Section->SizeOfSection.u.LowPart;
-    }
-    else if ((*ViewSize) > Section->SizeOfSection.u.LowPart)
-    {
-        (*ViewSize) = Section->SizeOfSection.u.LowPart;
+        *ViewSize = MIN((Section->SizeOfSection.QuadPart - 
SectionOffset->QuadPart), SIZE_T_MAX);
     }
 
     MmLockSectionSegment(Segment);
 
-
     Status = MmMapViewOfSegment(AddressSpace,
                                 Section,
                                 Segment,
                                 MappedBase,
                                 *ViewSize,
                                 PAGE_READWRITE,
-                                0,
+                                SectionOffset->QuadPart,
                                 0);
 
     MmUnlockSectionSegment(Segment);

Reply via email to