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;
}