From cff3c399c63a36bd5f05aa2389d54b0824a567ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Tue, 29 Dec 2020 16:43:03 +0100 Subject: [PATCH] [NTOS:MM] Fix input validation/correction in MmMapViewInSystemSpace --- ntoskrnl/include/ntoskrnl.h | 2 ++ ntoskrnl/mm/section.c | 56 +++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 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 #include #include +#define ENABLE_INTSAFE_SIGNED_FUNCTIONS #include +#undef ENABLE_INTSAFE_SIGNED_FUNCTIONS /* C Headers */ #include 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; + 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; }