[NTOS:MM] Fix passing section size to MiCreatePagingFileMap & fix maximum size check

Also return the right status instead of stupidly asserting when failing to allocate memory.
This commit is contained in:
Jérôme Gardou 2020-12-14 18:19:28 +01:00
parent cb196d1e39
commit abcbd44641

View file

@ -1505,14 +1505,15 @@ MiCreateDataFileMap(IN PFILE_OBJECT File,
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
static
NTSTATUS NTSTATUS
NTAPI NTAPI
MiCreatePagingFileMap(OUT PSEGMENT *Segment, MiCreatePagingFileMap(OUT PSEGMENT *Segment,
IN PSIZE_T MaximumSize, IN PLARGE_INTEGER MaximumSize,
IN ULONG ProtectionMask, IN ULONG ProtectionMask,
IN ULONG AllocationAttributes) IN ULONG AllocationAttributes)
{ {
SIZE_T SizeLimit; ULONGLONG SizeLimit;
PFN_COUNT PteCount; PFN_COUNT PteCount;
PMMPTE PointerPte; PMMPTE PointerPte;
MMPTE TempPte; MMPTE TempPte;
@ -1525,18 +1526,19 @@ MiCreatePagingFileMap(OUT PSEGMENT *Segment,
ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0); ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
/* Pagefile-backed sections need a known size */ /* Pagefile-backed sections need a known size */
if (!(*MaximumSize)) return STATUS_INVALID_PARAMETER_4; if (!MaximumSize || !MaximumSize->QuadPart || MaximumSize->QuadPart < 0)
return STATUS_INVALID_PARAMETER_4;
/* Calculate the maximum size possible, given the Prototype PTEs we'll need */ /* Calculate the maximum size possible, given the Prototype PTEs we'll need */
SizeLimit = MAXULONG_PTR - sizeof(SEGMENT); SizeLimit = MmSizeOfPagedPoolInBytes - sizeof(SEGMENT);
SizeLimit /= sizeof(MMPTE); SizeLimit /= sizeof(MMPTE);
SizeLimit <<= PAGE_SHIFT; SizeLimit <<= PAGE_SHIFT;
/* Fail if this size is too big */ /* Fail if this size is too big */
if (*MaximumSize > SizeLimit) return STATUS_SECTION_TOO_BIG; if (MaximumSize->QuadPart > SizeLimit) return STATUS_SECTION_TOO_BIG;
/* Calculate how many Prototype PTEs will be needed */ /* Calculate how many Prototype PTEs will be needed */
PteCount = (PFN_COUNT)((*MaximumSize + PAGE_SIZE - 1) >> PAGE_SHIFT); PteCount = (PFN_COUNT)((MaximumSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT);
/* For commited memory, we must have a valid protection mask */ /* For commited memory, we must have a valid protection mask */
if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0); if (AllocationAttributes & SEC_COMMIT) ASSERT(ProtectionMask != 0);
@ -1546,14 +1548,21 @@ MiCreatePagingFileMap(OUT PSEGMENT *Segment,
sizeof(SEGMENT) + sizeof(SEGMENT) +
sizeof(MMPTE) * (PteCount - 1), sizeof(MMPTE) * (PteCount - 1),
'tSmM'); 'tSmM');
ASSERT(NewSegment); if (!NewSegment)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
*Segment = NewSegment; *Segment = NewSegment;
/* Now allocate the control area, which has the subsection structure */ /* Now allocate the control area, which has the subsection structure */
ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlArea = ExAllocatePoolWithTag(NonPagedPool,
sizeof(CONTROL_AREA) + sizeof(SUBSECTION), sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
'tCmM'); 'tCmM');
ASSERT(ControlArea); if (!ControlArea)
{
ExFreePoolWithTag(Segment, 'tSmM');
return STATUS_INSUFFICIENT_RESOURCES;
}
/* And zero it out, filling the basic segmnet pointer and reference fields */ /* And zero it out, filling the basic segmnet pointer and reference fields */
RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION)); RtlZeroMemory(ControlArea, sizeof(CONTROL_AREA) + sizeof(SUBSECTION));
@ -2611,7 +2620,7 @@ MmCreateArm3Section(OUT PVOID *SectionObject,
/* So this must be a pagefile-backed section, create the mappings needed */ /* So this must be a pagefile-backed section, create the mappings needed */
Status = MiCreatePagingFileMap(&NewSegment, Status = MiCreatePagingFileMap(&NewSegment,
(PSIZE_T)InputMaximumSize, InputMaximumSize,
ProtectionMask, ProtectionMask,
AllocationAttributes); AllocationAttributes);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;