https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cff3c399c63a36bd5f05a…
commit cff3c399c63a36bd5f05aa2389d54b0824a567ab
Author:     Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Tue Dec 29 16:43:03 2020 +0100
Commit:     Jérôme Gardou <jerome.gardou(a)reactos.org>
CommitDate: Wed Feb 3 09:41:23 2021 +0100
    [NTOS:MM] Fix input validation/correction in MmMapViewInSystemSpace
---
 ntoskrnl/include/ntoskrnl.h |  2 ++
 ntoskrnl/mm/section.c       | 54 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/ntoskrnl/include/ntoskrnl.h b/ntoskrnl/include/ntoskrnl.h
index 7685c36bcf1..353efeb44c3 100644
--- a/ntoskrnl/include/ntoskrnl.h
+++ b/ntoskrnl/include/ntoskrnl.h
@@ -63,7 +63,9 @@
 #include <regstr.h>
 #include <ntstrsafe.h>
 #include <ntpoapi.h>
+#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
 #include <ntintsafe.h>
+#undef ENABLE_INTSAFE_SIGNED_FUNCTIONS
 /* C Headers */
 #include <stdlib.h>
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c
index 4756875a661..17762f8628e 100644
--- a/ntoskrnl/mm/section.c
+++ b/ntoskrnl/mm/section.c
@@ -3249,6 +3249,8 @@ MmMapViewOfSegment(
     NTSTATUS Status;
     ULONG Granularity;
+    ASSERT(ViewSize != 0);
+
     if (Segment->WriteCopy)
     {
         /* We have to do this because the not present fault
@@ -3488,6 +3490,8 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
     {
         if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
+
+        DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
         MmUnlockAddressSpace(AddressSpace);
         return STATUS_NOT_MAPPED_VIEW;
     }
@@ -4009,7 +4013,9 @@ MmMapViewOfSection(IN PVOID SectionObject,
         {
             (*ViewSize) = Section->SizeOfSection.QuadPart - ViewOffset;
         }
-        else if ((ExGetPreviousMode() == UserMode) && (((*ViewSize)+ViewOffset)
> Section->SizeOfSection.QuadPart))
+        else if ((ExGetPreviousMode() == UserMode) &&
+            (((*ViewSize)+ViewOffset) > Section->SizeOfSection.QuadPart) &&
+            (!Section->u.Flags.Reserve))
         {
             /* Dubious */
             (*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, SIZE_T_MAX
- PAGE_SIZE);
@@ -4165,6 +4171,7 @@ MmMapViewInSystemSpaceEx (
     PMM_SECTION_SEGMENT Segment;
     PMMSUPPORT AddressSpace;
     NTSTATUS Status;
+
     PAGED_CODE();
     if (MiIsRosSectionObject(SectionObject) == FALSE)
@@ -4181,15 +4188,49 @@ MmMapViewInSystemSpaceEx (
     Section = SectionObject;
     Segment = (PMM_SECTION_SEGMENT)Section->Segment;
-    AddressSpace = MmGetKernelAddressSpace();
+    if (*ViewSize == 0)
+    {
+        LONGLONG MapSizeLL;
-    MmLockAddressSpace(AddressSpace);
+        /* Page-align the mapping */
+        SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
-    if (*ViewSize == 0)
+        if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart,
SectionOffset->QuadPart, &MapSizeLL)))
+            return STATUS_INVALID_VIEW_SIZE;
+
+        if (!NT_SUCCESS(RtlLongLongToSIZET(MapSizeLL, ViewSize)))
+            return STATUS_INVALID_VIEW_SIZE;
+    }
+    else
     {
-        *ViewSize = MIN((Section->SizeOfSection.QuadPart -
SectionOffset->QuadPart), SIZE_T_MAX);
+        LONGLONG HelperLL;
+
+        /* Get the map end */
+        if (!NT_SUCCESS(RtlLongLongAdd(SectionOffset->QuadPart, *ViewSize,
&HelperLL)))
+            return STATUS_INVALID_VIEW_SIZE;
+
+        /* Round it up, if needed */
+        if (HelperLL % PAGE_SIZE)
+        {
+            if (!NT_SUCCESS(RtlLongLongAdd(HelperLL, PAGE_SIZE - (HelperLL % PAGE_SIZE),
&HelperLL)))
+                return STATUS_INVALID_VIEW_SIZE;
+        }
+
+        /* Now that we have the mapping end, we can align down its start */
+        SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
+
+        /* Get the new size */
+        if (!NT_SUCCESS(RtlLongLongSub(HelperLL, SectionOffset->QuadPart,
&HelperLL)))
+            return STATUS_INVALID_VIEW_SIZE;
+
+        if (!NT_SUCCESS(RtlLongLongToSIZET(HelperLL, ViewSize)))
+            return STATUS_INVALID_VIEW_SIZE;
     }
+    AddressSpace = MmGetKernelAddressSpace();
+
+    MmLockAddressSpace(AddressSpace);
+
     MmLockSectionSegment(Segment);
     Status = MmMapViewOfSegment(AddressSpace,
@@ -4505,6 +4546,7 @@ MmMakePagesResident(
     MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
     if (MemoryArea == NULL)
     {
+        DPRINT1("Unable to find memory area at address %p.\n", Address);
         MmUnlockAddressSpace(AddressSpace);
         return STATUS_NOT_MAPPED_VIEW;
     }
@@ -4608,6 +4650,7 @@ MmRosFlushVirtualMemory(
     if ((MemoryArea == NULL) || (MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) ||
             (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
     {
+        DPRINT1("Unable to find memory area at address %p.\n", Address);
         MmUnlockAddressSpace(AddressSpace);
         return STATUS_NOT_MAPPED_VIEW;
     }
@@ -4766,6 +4809,7 @@ MmMakePagesDirty(
     MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
     if (MemoryArea == NULL)
     {
+        DPRINT1("Unable to find memory area at address %p.\n", Address);
         MmUnlockAddressSpace(AddressSpace);
         return STATUS_NOT_MAPPED_VIEW;
     }