[NTOS:KE] In KiExitV86Mode, restore KTSS::Esp0 to its standard value. CORE-16531 2123/head
authorThomas Faber <thomas.faber@reactos.org>
Sun, 1 Dec 2019 19:36:13 +0000 (20:36 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Fri, 3 Jan 2020 10:28:09 +0000 (11:28 +0100)
The trap frame is in a random location on the stack, and setting Esp0 there
wastes significant amounts of space and may lead to unexpected stack overflows.

Also use a more descriptive expression for the V86 members of the KTRAP_FRAME.

ntoskrnl/ke/i386/exp.c
ntoskrnl/ke/i386/thrdini.c
ntoskrnl/ke/i386/v86vdm.c

index de97192..87405e6 100644 (file)
@@ -291,8 +291,8 @@ Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
     if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
     {
         /* Bias the stack for the V86 segments */
-        Stack -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) -
-                  FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
+        Stack -= sizeof(KTRAP_FRAME) -
+                 FIELD_OFFSET(KTRAP_FRAME, V86Es);
     }
 
     /* Bias the stack for the FPU area */
index 678bedd..7ce5163 100644 (file)
@@ -369,7 +369,7 @@ KiSwapContextExit(IN PKTHREAD OldThread,
     Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
     if (!((KeGetTrapFrame(NewThread))->EFlags & EFLAGS_V86_MASK))
     {
-        Pcr->TSS->Esp0 -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) - FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
+        Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
     }
     Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
     Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
index e629f8b..0421f00 100644 (file)
@@ -467,17 +467,16 @@ ULONG_PTR
 FASTCALL
 KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
 {
+    PKPCR Pcr = KeGetPcr();
     ULONG_PTR StackFrameUnaligned;
     PKV8086_STACK_FRAME StackFrame;
     PKTHREAD Thread;
-    PKTRAP_FRAME PmTrapFrame;
     PKV86_FRAME V86Frame;
     PFX_SAVE_AREA NpxFrame;
 
     /* Get the stack frame back */
     StackFrameUnaligned = TrapFrame->Esi;
     StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
-    PmTrapFrame = &StackFrame->TrapFrame;
     V86Frame = &StackFrame->V86Frame;
     NpxFrame = &StackFrame->NpxArea;
     ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
@@ -490,7 +489,9 @@ KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
     Thread->InitialStack = (PVOID)((ULONG_PTR)V86Frame->ThreadStack + sizeof(FX_SAVE_AREA));
 
     /* Set ESP0 back in the KTSS */
-    KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&PmTrapFrame->V86Es;
+    Pcr->TSS->Esp0 = (ULONG_PTR)Thread->InitialStack;
+    Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
+    Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
 
     /* Restore TEB addresses */
     Thread->Teb = V86Frame->ThreadTeb;