mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[NTOS:MM] Do not map two pages into hyperspace in MiCopyFromUserPage. CORE-14548
Doing this is not only wrong because it acquires the same spinlock twice, it also completely breaks the TLB flushing logic in MiMapPageInHyperSpace. If the PTE with Offset 1 is still valid when a wrap-around to 0 happens, the TLB flush on wrap-around will not clear the entry for this previous page. After another loop around all hyperspace pages, page 1 is re-used but its TLB entry has not been flushed, which may result into incorrect translation.
This commit is contained in:
parent
ee8d82f29d
commit
b54e5c689c
|
@ -757,8 +757,8 @@ MmAccessFault(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiCopyFromUserPage(
|
MiCopyFromUserPage(
|
||||||
PFN_NUMBER NewPage,
|
PFN_NUMBER DestPage,
|
||||||
PFN_NUMBER OldPage
|
const VOID *SrcAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
/* process.c *****************************************************************/
|
/* process.c *****************************************************************/
|
||||||
|
|
|
@ -1040,23 +1040,21 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiCopyFromUserPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
|
MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
KIRQL Irql, Irql2;
|
KIRQL Irql;
|
||||||
PVOID DestAddress, SrcAddress;
|
PVOID DestAddress;
|
||||||
|
|
||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
|
DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
|
||||||
SrcAddress = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
|
if (DestAddress == NULL)
|
||||||
if (DestAddress == NULL || SrcAddress == NULL)
|
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
|
ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
|
||||||
ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
|
ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
|
||||||
RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
|
RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
|
||||||
MiUnmapPageInHyperSpace(Process, SrcAddress, Irql2);
|
|
||||||
MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
|
MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1779,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Copy the old page
|
* Copy the old page
|
||||||
*/
|
*/
|
||||||
MiCopyFromUserPage(NewPage, OldPage);
|
NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unshare the old page.
|
* Unshare the old page.
|
||||||
|
|
Loading…
Reference in a new issue