[NTOS:MM] Fix input validation/correction in MmMapViewInSystemSpace

This commit is contained in:
Jérôme Gardou 2020-12-29 16:43:03 +01:00
parent 8287a098b9
commit cff3c399c6
2 changed files with 52 additions and 6 deletions

View file

@ -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>

View file

@ -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;
if (*ViewSize == 0)
{
LONGLONG MapSizeLL;
/* Page-align the mapping */
SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
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
{
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);
if (*ViewSize == 0)
{
*ViewSize = MIN((Section->SizeOfSection.QuadPart - SectionOffset->QuadPart), SIZE_T_MAX);
}
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;
}