[NTOSKRNL]

Implement the "SLIST hack". It checks whether the access to the Next member of the first list item of an iSList caused the exception, this can happen, when a concurrent thread pops the first entry and frees its memory between the point where the address of the entry is loaded and the access to it. This is done before the call to MmAccessFault to handle the theoretical scenario of a guard page exception being triggered by the fault, which we don't want to be handled.
Currently only kernel mode is handled.

svn path=/trunk/; revision=52628
This commit is contained in:
Timo Kreuzer 2011-07-11 03:36:29 +00:00
parent 8aa496d875
commit 93a416ddfd
2 changed files with 30 additions and 8 deletions

View file

@ -457,6 +457,7 @@ extern VOID __cdecl KiTrap08(VOID);
extern VOID __cdecl KiTrap13(VOID);
extern VOID __cdecl KiFastCallEntry(VOID);
extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
extern VOID NTAPI ExpInterlockedPopEntrySListResume(VOID);
extern VOID __cdecl CopyParams(VOID);
extern VOID __cdecl ReadBatch(VOID);
extern VOID __cdecl FrRestore(VOID);

View file

@ -1199,6 +1199,35 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
#endif
}
/* Check for S-LIST fault in kernel mode */
if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
{
PSLIST_HEADER SListHeader;
/* Sanity check that the assembly is correct:
This must be mov ebx, [eax]
Followed by cmpxchg8b [ebp] */
ASSERT((((UCHAR*)TrapFrame->Eip)[0] == 0x8B) &&
(((UCHAR*)TrapFrame->Eip)[1] == 0x18) &&
(((UCHAR*)TrapFrame->Eip)[2] == 0x0F) &&
(((UCHAR*)TrapFrame->Eip)[3] == 0xC7) &&
(((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
(((UCHAR*)TrapFrame->Eip)[5] == 0x00));
/* Get the pointer to the SLIST_HEADER */
SListHeader = (PSLIST_HEADER)TrapFrame->Ebp;
/* Check if the Next member of the SLIST_HEADER was changed */
if (SListHeader->Next.Next != (PSLIST_ENTRY)TrapFrame->Eax)
{
/* Restart the operation */
TrapFrame->Eip = (ULONG_PTR)ExpInterlockedPopEntrySListResume;
/* Continue execution */
KiEoiHelper(TrapFrame);
}
}
/* Call the access fault handler */
Status = MmAccessFault(TrapFrame->ErrCode & 1,
(PVOID)Cr2,
@ -1206,14 +1235,6 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
TrapFrame);
if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame);
/* Check for S-LIST fault */
if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
{
/* Not yet implemented */
UNIMPLEMENTED;
while (TRUE);
}
/* Check for syscall fault */
#if 0
if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||