[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 <regstr.h>
#include <ntstrsafe.h> #include <ntstrsafe.h>
#include <ntpoapi.h> #include <ntpoapi.h>
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
#include <ntintsafe.h> #include <ntintsafe.h>
#undef ENABLE_INTSAFE_SIGNED_FUNCTIONS
/* C Headers */ /* C Headers */
#include <stdlib.h> #include <stdlib.h>

View file

@ -3249,6 +3249,8 @@ MmMapViewOfSegment(
NTSTATUS Status; NTSTATUS Status;
ULONG Granularity; ULONG Granularity;
ASSERT(ViewSize != 0);
if (Segment->WriteCopy) if (Segment->WriteCopy)
{ {
/* We have to do this because the not present fault /* 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); if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
DPRINT1("Unable to find memory area at address %p.\n", BaseAddress);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW; return STATUS_NOT_MAPPED_VIEW;
} }
@ -4009,7 +4013,9 @@ MmMapViewOfSection(IN PVOID SectionObject,
{ {
(*ViewSize) = Section->SizeOfSection.QuadPart - ViewOffset; (*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 */ /* Dubious */
(*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, SIZE_T_MAX - PAGE_SIZE); (*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, SIZE_T_MAX - PAGE_SIZE);
@ -4165,6 +4171,7 @@ MmMapViewInSystemSpaceEx (
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
PMMSUPPORT AddressSpace; PMMSUPPORT AddressSpace;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
if (MiIsRosSectionObject(SectionObject) == FALSE) if (MiIsRosSectionObject(SectionObject) == FALSE)
@ -4181,15 +4188,49 @@ MmMapViewInSystemSpaceEx (
Section = SectionObject; Section = SectionObject;
Segment = (PMM_SECTION_SEGMENT)Section->Segment; 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(); AddressSpace = MmGetKernelAddressSpace();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (*ViewSize == 0)
{
*ViewSize = MIN((Section->SizeOfSection.QuadPart - SectionOffset->QuadPart), SIZE_T_MAX);
}
MmLockSectionSegment(Segment); MmLockSectionSegment(Segment);
Status = MmMapViewOfSegment(AddressSpace, Status = MmMapViewOfSegment(AddressSpace,
@ -4505,6 +4546,7 @@ MmMakePagesResident(
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL) if (MemoryArea == NULL)
{ {
DPRINT1("Unable to find memory area at address %p.\n", Address);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW; return STATUS_NOT_MAPPED_VIEW;
} }
@ -4608,6 +4650,7 @@ MmRosFlushVirtualMemory(
if ((MemoryArea == NULL) || (MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) || if ((MemoryArea == NULL) || (MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) ||
(MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap)) (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
{ {
DPRINT1("Unable to find memory area at address %p.\n", Address);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW; return STATUS_NOT_MAPPED_VIEW;
} }
@ -4766,6 +4809,7 @@ MmMakePagesDirty(
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL) if (MemoryArea == NULL)
{ {
DPRINT1("Unable to find memory area at address %p.\n", Address);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW; return STATUS_NOT_MAPPED_VIEW;
} }