From f1631b44e120f2c6319fb4d4b113b0a43336b413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Tue, 27 Oct 2020 17:36:18 +0100 Subject: [PATCH] [NTOS/MM] Introduce MmMapViewInSystemSpaceEx --- ntoskrnl/include/internal/mm.h | 10 +++++++ ntoskrnl/mm/ARM3/section.c | 38 +++++++++++++++++++------ ntoskrnl/mm/section.c | 51 +++++++++++++++++++++------------- 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index a8536c3d786..662f49c9bd7 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -1313,6 +1313,16 @@ VOID NTAPI MmFreeSectionSegments(PFILE_OBJECT FileObject); +/* Exported from NT 6.2 Onward. We keep it internal. */ +NTSTATUS +NTAPI +MmMapViewInSystemSpaceEx ( + _In_ PVOID Section, + _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase, + _Inout_ PSIZE_T ViewSize, + _Inout_ PLARGE_INTEGER SectionOffset + ); + /* sysldr.c ******************************************************************/ VOID diff --git a/ntoskrnl/mm/ARM3/section.c b/ntoskrnl/mm/ARM3/section.c index 511f11a5101..938a08d6037 100644 --- a/ntoskrnl/mm/ARM3/section.c +++ b/ntoskrnl/mm/ARM3/section.c @@ -416,12 +416,16 @@ NTSTATUS NTAPI MiAddMappedPtes(IN PMMPTE FirstPte, IN PFN_NUMBER PteCount, - IN PCONTROL_AREA ControlArea) + IN PCONTROL_AREA ControlArea, + IN PLARGE_INTEGER SectionOffset) { MMPTE TempPte; PMMPTE PointerPte, ProtoPte, LastProtoPte, LastPte; PSUBSECTION Subsection; + /* Mapping at offset not supported yet */ + ASSERT(SectionOffset->QuadPart == 0); + /* ARM3 doesn't support this yet */ ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0); ASSERT(ControlArea->u.Flags.Rom == 0); @@ -1052,11 +1056,13 @@ NTAPI MiMapViewInSystemSpace(IN PVOID Section, IN PMMSESSION Session, OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize) + IN OUT PSIZE_T ViewSize, + IN PLARGE_INTEGER SectionOffset) { PVOID Base; PCONTROL_AREA ControlArea; - ULONG Buckets, SectionSize; + ULONG Buckets; + LONGLONG SectionSize; NTSTATUS Status; PAGED_CODE(); @@ -1073,13 +1079,23 @@ MiMapViewInSystemSpace(IN PVOID Section, ASSERT(NT_SUCCESS(Status)); /* Get the section size at creation time */ - SectionSize = ((PSECTION)Section)->SizeOfSection.LowPart; + SectionSize = ((PSECTION)Section)->SizeOfSection.QuadPart; - /* If the caller didn't specify a view size, assume the whole section */ - if (!(*ViewSize)) *ViewSize = SectionSize; + /* If the caller didn't specify a view size, assume until the end of the section */ + if (!(*ViewSize)) + { + /* Check for overflow first */ + if ((SectionSize - SectionOffset->QuadPart) > SIZE_T_MAX) + { + DPRINT1("Section end is too far away from the specified offset.\n"); + MiDereferenceControlArea(ControlArea); + return STATUS_INVALID_VIEW_SIZE; + } + *ViewSize = SectionSize - SectionOffset->QuadPart; + } /* Check if the caller wanted a larger section than the view */ - if (*ViewSize > SectionSize) + if (SectionOffset->QuadPart + *ViewSize > SectionSize) { /* Fail */ DPRINT1("View is too large\n"); @@ -1129,7 +1145,8 @@ MiMapViewInSystemSpace(IN PVOID Section, /* Create the actual prototype PTEs for this mapping */ Status = MiAddMappedPtes(MiAddressToPte(Base), BYTES_TO_PAGES(*ViewSize), - ControlArea); + ControlArea, + SectionOffset); ASSERT(NT_SUCCESS(Status)); /* Return the base adress of the mapping and success */ @@ -3016,6 +3033,7 @@ MmMapViewInSessionSpace(IN PVOID Section, IN OUT PSIZE_T ViewSize) { PAGED_CODE(); + LARGE_INTEGER SectionOffset; // HACK if (MiIsRosSectionObject(Section)) @@ -3032,10 +3050,12 @@ MmMapViewInSessionSpace(IN PVOID Section, /* Use the system space API, but with the session view instead */ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE); + SectionOffset.QuadPart = 0; return MiMapViewInSystemSpace(Section, &MmSessionSpace->Session, MappedBase, - ViewSize); + ViewSize, + &SectionOffset); } /* diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 04cba04d612..fc2c1a3e904 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -88,7 +88,8 @@ NTAPI MiMapViewInSystemSpace(IN PVOID Section, IN PVOID Session, OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); + IN OUT PSIZE_T ViewSize, + IN PLARGE_INTEGER SectionOffset); NTSTATUS NTAPI @@ -3832,7 +3833,7 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace, PVOID* BaseAddress, SIZE_T ViewSize, ULONG Protect, - ULONG ViewOffset, + LONGLONG ViewOffset, ULONG AllocationType) { PMEMORY_AREA MArea; @@ -4417,7 +4418,6 @@ MmMapViewOfSection(IN PVOID SectionObject, { PSECTION Section; PMMSUPPORT AddressSpace; - ULONG ViewOffset; NTSTATUS Status = STATUS_SUCCESS; BOOLEAN NotAtBase = FALSE; @@ -4530,7 +4530,7 @@ MmMapViewOfSection(IN PVOID SectionObject, Section, &SectionSegments[i], &SBaseAddress, - SectionSegments[i].Length.LowPart, + SectionSegments[i].Length.QuadPart, SectionSegments[i].Protection, 0, 0); @@ -4548,6 +4548,7 @@ MmMapViewOfSection(IN PVOID SectionObject, else { PMM_SECTION_SEGMENT Segment = (PMM_SECTION_SEGMENT)Section->Segment; + LONGLONG ViewOffset; /* check for write access */ if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) && @@ -4577,7 +4578,7 @@ MmMapViewOfSection(IN PVOID SectionObject, } else { - ViewOffset = SectionOffset->u.LowPart; + ViewOffset = SectionOffset->QuadPart; } if ((ViewOffset % PAGE_SIZE) != 0) @@ -4588,11 +4589,11 @@ MmMapViewOfSection(IN PVOID SectionObject, if ((*ViewSize) == 0) { - (*ViewSize) = Section->SizeOfSection.u.LowPart - ViewOffset; + (*ViewSize) = Section->SizeOfSection.QuadPart - ViewOffset; } - else if (((*ViewSize)+ViewOffset) > Section->SizeOfSection.u.LowPart) + else if (((*ViewSize)+ViewOffset) > Section->SizeOfSection.QuadPart) { - (*ViewSize) = Section->SizeOfSection.u.LowPart - ViewOffset; + (*ViewSize) = MIN(Section->SizeOfSection.QuadPart - ViewOffset, SIZE_T_MAX - PAGE_SIZE); } *ViewSize = PAGE_ROUND_UP(*ViewSize); @@ -4756,7 +4757,23 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, OUT PVOID * MappedBase, IN OUT PSIZE_T ViewSize) { - PSECTION Section; + LARGE_INTEGER SectionOffset; + + SectionOffset.QuadPart = 0; + + return MmMapViewInSystemSpaceEx(SectionObject, MappedBase, ViewSize, &SectionOffset); +} + +NTSTATUS +NTAPI +MmMapViewInSystemSpaceEx ( + _In_ PVOID SectionObject, + _Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase, + _Inout_ PSIZE_T ViewSize, + _Inout_ PLARGE_INTEGER SectionOffset + ) +{ + PSECTION Section = SectionObject; PMM_SECTION_SEGMENT Segment; PMMSUPPORT AddressSpace; NTSTATUS Status; @@ -4767,10 +4784,11 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, return MiMapViewInSystemSpace(SectionObject, &MmSession, MappedBase, - ViewSize); + ViewSize, + SectionOffset); } - DPRINT("MmMapViewInSystemSpace() called\n"); + DPRINT("MmMapViewInSystemSpaceEx() called\n"); Section = SectionObject; Segment = (PMM_SECTION_SEGMENT)Section->Segment; @@ -4780,25 +4798,20 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, MmLockAddressSpace(AddressSpace); - if ((*ViewSize) == 0) + if ((*ViewSize == 0) || ((SectionOffset->QuadPart + *ViewSize) > Section->SizeOfSection.QuadPart)) { - (*ViewSize) = Section->SizeOfSection.u.LowPart; - } - else if ((*ViewSize) > Section->SizeOfSection.u.LowPart) - { - (*ViewSize) = Section->SizeOfSection.u.LowPart; + *ViewSize = MIN((Section->SizeOfSection.QuadPart - SectionOffset->QuadPart), SIZE_T_MAX); } MmLockSectionSegment(Segment); - Status = MmMapViewOfSegment(AddressSpace, Section, Segment, MappedBase, *ViewSize, PAGE_READWRITE, - 0, + SectionOffset->QuadPart, 0); MmUnlockSectionSegment(Segment);