mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[NTOS:MM] Keep image maps & file maps coherent at the time of creating the image map
This commit is contained in:
parent
543112008a
commit
addf824d87
|
@ -2448,6 +2448,19 @@ ExeFmtpAllocateSegments(IN ULONG NrSegments)
|
|||
return Segments;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
MmMapViewOfSegment(PMMSUPPORT AddressSpace,
|
||||
BOOLEAN AsImage,
|
||||
PMM_SECTION_SEGMENT Segment,
|
||||
PVOID* BaseAddress,
|
||||
SIZE_T ViewSize,
|
||||
ULONG Protect,
|
||||
LONGLONG ViewOffset,
|
||||
ULONG AllocationType);
|
||||
static NTSTATUS
|
||||
MmUnmapViewOfSegment(PMMSUPPORT AddressSpace,
|
||||
PVOID BaseAddress);
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -2490,36 +2503,57 @@ ExeFmtpReadFile(IN PVOID File,
|
|||
BufferSize = Length + OffsetAdjustment;
|
||||
BufferSize = PAGE_ROUND_UP(BufferSize);
|
||||
|
||||
/* Flush data since we're about to perform a non-cached read */
|
||||
CcFlushCache(FileObject->SectionObjectPointer,
|
||||
&FileOffset,
|
||||
BufferSize,
|
||||
&Iosb);
|
||||
|
||||
/*
|
||||
* It's ok to use paged pool, because this is a temporary buffer only used in
|
||||
* the loading of executables. The assumption is that MmCreateSection is
|
||||
* always called at low IRQLs and that these buffers don't survive a brief
|
||||
* initialization phase
|
||||
*/
|
||||
Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||
BufferSize,
|
||||
'rXmM');
|
||||
Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, 'rXmM');
|
||||
if (!Buffer)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
UsedSize = 0;
|
||||
|
||||
Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
|
||||
|
||||
UsedSize = (ULONG)Iosb.Information;
|
||||
|
||||
if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
|
||||
if (FileObject->SectionObjectPointer->DataSectionObject)
|
||||
{
|
||||
Status = STATUS_IN_PAGE_ERROR;
|
||||
ASSERT(!NT_SUCCESS(Status));
|
||||
PVOID SegmentMap = NULL;
|
||||
|
||||
/* Get the data from the file mapping instead */
|
||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||
Status = MmMapViewOfSegment(MmGetKernelAddressSpace(),
|
||||
FALSE,
|
||||
FileObject->SectionObjectPointer->DataSectionObject,
|
||||
&SegmentMap,
|
||||
BufferSize,
|
||||
PAGE_READONLY,
|
||||
FileOffset.QuadPart,
|
||||
0);
|
||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
RtlCopyMemory(Buffer, SegmentMap, BufferSize);
|
||||
UsedSize = BufferSize;
|
||||
|
||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||
|
||||
MmUnmapViewOfSegment(MmGetKernelAddressSpace(), SegmentMap);
|
||||
|
||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
|
||||
|
||||
UsedSize = (ULONG)Iosb.Information;
|
||||
|
||||
if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
|
||||
{
|
||||
Status = STATUS_IN_PAGE_ERROR;
|
||||
ASSERT(!NT_SUCCESS(Status));
|
||||
}
|
||||
}
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
|
@ -3102,7 +3136,6 @@ MmCreateImageSection(PSECTION *SectionObject,
|
|||
if (ImageSectionObject == NULL)
|
||||
{
|
||||
NTSTATUS StatusExeFmt;
|
||||
PMM_SECTION_SEGMENT DataSectionObject;
|
||||
|
||||
ImageSectionObject = ExAllocatePoolZero(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
|
||||
if (ImageSectionObject == NULL)
|
||||
|
@ -3116,44 +3149,12 @@ MmCreateImageSection(PSECTION *SectionObject,
|
|||
ImageSectionObject->RefCount = 1;
|
||||
FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
|
||||
|
||||
/* Get a ref on the data section object */
|
||||
DataSectionObject = FileObject->SectionObjectPointer->DataSectionObject;
|
||||
while (DataSectionObject && (DataSectionObject->SegFlags & (MM_SEGMENT_INDELETE | MM_SEGMENT_INCREATE)))
|
||||
{
|
||||
LARGE_INTEGER ShortTime;
|
||||
|
||||
MiReleasePfnLock(OldIrql);
|
||||
|
||||
ShortTime.QuadPart = - 10 * 100 * 1000;
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
|
||||
|
||||
OldIrql = MiAcquirePfnLock();
|
||||
DataSectionObject = FileObject->SectionObjectPointer->DataSectionObject;
|
||||
ASSERT(DataSectionObject->SegFlags & MM_DATAFILE_SEGMENT);
|
||||
}
|
||||
|
||||
/* Get a ref on it. */
|
||||
if (DataSectionObject)
|
||||
InterlockedIncrementUL(&DataSectionObject->RefCount);
|
||||
|
||||
MiReleasePfnLock(OldIrql);
|
||||
|
||||
if (DataSectionObject)
|
||||
/* Purge the cache */
|
||||
if (CcIsFileCached(FileObject))
|
||||
{
|
||||
if ((DataSectionObject->SectionCount - (FileObject->SectionObjectPointer->SharedCacheMap != NULL)) > 0)
|
||||
{
|
||||
/* Someone's got a section opened. Deny creation */
|
||||
DPRINT1("Denying image creation for %wZ: Sections opened: %lu.\n",
|
||||
&FileObject->FileName, DataSectionObject->SectionCount);
|
||||
InterlockedExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject, NULL);
|
||||
ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
|
||||
MmDereferenceSegment(DataSectionObject);
|
||||
ObDereferenceObject(Section);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* Purge the cache. */
|
||||
CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
|
||||
CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
|
||||
|
@ -3234,14 +3235,15 @@ MmCreateImageSection(PSECTION *SectionObject,
|
|||
|
||||
|
||||
static NTSTATUS
|
||||
MmMapViewOfSegment(PMMSUPPORT AddressSpace,
|
||||
PSECTION Section,
|
||||
PMM_SECTION_SEGMENT Segment,
|
||||
PVOID* BaseAddress,
|
||||
SIZE_T ViewSize,
|
||||
ULONG Protect,
|
||||
LONGLONG ViewOffset,
|
||||
ULONG AllocationType)
|
||||
MmMapViewOfSegment(
|
||||
PMMSUPPORT AddressSpace,
|
||||
BOOLEAN AsImage,
|
||||
PMM_SECTION_SEGMENT Segment,
|
||||
PVOID* BaseAddress,
|
||||
SIZE_T ViewSize,
|
||||
ULONG Protect,
|
||||
LONGLONG ViewOffset,
|
||||
ULONG AllocationType)
|
||||
{
|
||||
PMEMORY_AREA MArea;
|
||||
NTSTATUS Status;
|
||||
|
@ -3297,7 +3299,7 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
|
|||
|
||||
MArea->SectionData.Segment = Segment;
|
||||
MArea->SectionData.ViewOffset.QuadPart = ViewOffset;
|
||||
if (Section->u.Flags.Image)
|
||||
if (AsImage)
|
||||
{
|
||||
MArea->VadNode.u.VadFlags.VadType = VadImageMap;
|
||||
}
|
||||
|
@ -3932,7 +3934,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
|
|||
((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
|
||||
MmLockSectionSegment(&SectionSegments[i]);
|
||||
Status = MmMapViewOfSegment(AddressSpace,
|
||||
Section,
|
||||
TRUE,
|
||||
&SectionSegments[i],
|
||||
&SBaseAddress,
|
||||
SectionSegments[i].Length.QuadPart,
|
||||
|
@ -4017,7 +4019,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
|
|||
|
||||
MmLockSectionSegment(Segment);
|
||||
Status = MmMapViewOfSegment(AddressSpace,
|
||||
Section,
|
||||
FALSE,
|
||||
Segment,
|
||||
BaseAddress,
|
||||
*ViewSize,
|
||||
|
@ -4191,7 +4193,7 @@ MmMapViewInSystemSpaceEx (
|
|||
MmLockSectionSegment(Segment);
|
||||
|
||||
Status = MmMapViewOfSegment(AddressSpace,
|
||||
Section,
|
||||
Section->u.Flags.Image,
|
||||
Segment,
|
||||
MappedBase,
|
||||
*ViewSize,
|
||||
|
|
Loading…
Reference in a new issue