[NTOS:MM] Pass page fault code to MmAccessFault

Note: before we had a BOOLEAN parameter called StoreInstruction, but in reality it was not specifying whether the fault was from a store store instruction, but whether it was an access violation rather than a page-not-present fault. On x86 without PAE there are only 2 kinds of access violations: (1) Access of a kernel mode page from user mode, which is handled early and (2) access of a read-only (or COW) page with a writing instruction. Therefore we could get away with this, even though it relied on the wrong assumption that a fault, which was not a page-not-present-fault, was automatically a write access. This commit only changes one thing: we pass the full fault-code to MmAccessFault and handle the rest from there in exactly the same way as before. More changes are coming to make things clear.
This commit is contained in:
Timo Kreuzer 2018-01-01 15:25:45 +01:00
parent fe50c655aa
commit 3021c2d571
8 changed files with 17 additions and 9 deletions

View file

@ -106,6 +106,9 @@
#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
#endif
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
/* On x64, these are the same */
#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
#define ValidKernelPpe ValidKernelPde

View file

@ -88,6 +88,9 @@
#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.ReadOnly = 0)
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) TRUE
/* Convert an address to a corresponding PTE */
#define MiAddressToPte(x) \
((PMMPTE)(PTE_BASE + (((ULONG)(x) >> 12) << 2)))

View file

@ -111,6 +111,10 @@
#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
#endif
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
/* On x86, these two are the same */
#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE

View file

@ -744,7 +744,7 @@ MmFreeSpecialPool(
NTSTATUS
NTAPI
MmAccessFault(
IN BOOLEAN StoreInstruction,
IN ULONG FaultCode,
IN PVOID Address,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation

View file

@ -503,8 +503,7 @@ FUNC KiPageFault
sti
/* Call page fault handler */
mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
and ecx, 1
mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // FaultCode
// rdx == Address
mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
and r8b, 1

View file

@ -529,7 +529,7 @@ KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
//
if (KeArmFaultStatusRegisterGet() == 21 || KeArmFaultStatusRegisterGet() == 23)
{
Status = MmAccessFault(FALSE,
Status = MmAccessFault(KeArmFaultStatusRegisterGet(),
Address,
KiGetPreviousMode(TrapFrame),
TrapFrame);

View file

@ -1199,7 +1199,6 @@ FASTCALL
KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
BOOLEAN Present;
BOOLEAN StoreInstruction;
ULONG_PTR Cr2;
NTSTATUS Status;
@ -1227,7 +1226,6 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
_enable();
/* Interpret the error code */
Present = (TrapFrame->ErrCode & 1) != 0;
StoreInstruction = (TrapFrame->ErrCode & 2) != 0;
/* Check if we came in with interrupts disabled */
@ -1237,7 +1235,7 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
Cr2,
(ULONG_PTR)-1,
StoreInstruction,
TrapFrame->ErrCode,
TrapFrame->Eip,
TrapFrame);
}
@ -1339,7 +1337,7 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
NotSListFault:
/* Call the access fault handler */
Status = MmAccessFault(Present,
Status = MmAccessFault(TrapFrame->ErrCode,
(PVOID)Cr2,
KiUserTrap(TrapFrame),
TrapFrame);

View file

@ -201,12 +201,13 @@ extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
NTSTATUS
NTAPI
MmAccessFault(IN BOOLEAN StoreInstruction,
MmAccessFault(IN ULONG FaultCode,
IN PVOID Address,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation)
{
PMEMORY_AREA MemoryArea = NULL;
BOOLEAN StoreInstruction = !MI_IS_NOT_PRESENT_FAULT(FaultCode);
/* Cute little hack for ROS */
if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)