[NTOS:MM/x64] Temporarily release AddressCreationLock in MmCreateVirtualMappingUnsafeEx

This is a hack, because the kernel mode path can incur a recursive page fault with the AddressCreationLock acquired, which would lead to a recursive acquisition, once we do proper locking in MmAccessFault.
To properly fix this the PDE must be made valid, similar to the user mode path, but that is not that simple...
This commit is contained in:
Timo Kreuzer 2023-09-28 20:29:43 +03:00
parent d96b3cd45c
commit e685b25e35

View file

@ -637,6 +637,9 @@ MmCreateVirtualMappingUnsafeEx(
PMMPTE PointerPte; PMMPTE PointerPte;
MMPTE TempPte; MMPTE TempPte;
ULONG_PTR Pte; ULONG_PTR Pte;
#ifdef _M_AMD64
BOOLEAN LockReleased = FALSE;
#endif
DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n", DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
Process, Address, flProtect, Page); Process, Address, flProtect, Page);
@ -665,6 +668,15 @@ MmCreateVirtualMappingUnsafeEx(
if (!MiSynchronizeSystemPde(MiAddressToPde(Address))) if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
MiFillSystemPageDirectory(Address, PAGE_SIZE); MiFillSystemPageDirectory(Address, PAGE_SIZE);
#endif #endif
#ifdef _M_AMD64
/* This is a temporary hack, because we can incur a recursive page fault when accessing the PDE */
if (PsIdleProcess->AddressCreationLock.Owner == KeGetCurrentThread())
{
MmUnlockAddressSpace(MmGetKernelAddressSpace());
LockReleased = TRUE;
}
#endif
} }
else else
{ {
@ -715,6 +727,15 @@ MmCreateVirtualMappingUnsafeEx(
MiIncrementPageTableReferences(Address); MiIncrementPageTableReferences(Address);
MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread()); MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
} }
#ifdef _M_AMD64
else
{
if (LockReleased)
{
MmLockAddressSpace(MmGetKernelAddressSpace());
}
}
#endif
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }