https://git.reactos.org/?p=reactos.git;a=commitdiff;h=07de9d1da34daa7035e86…
commit 07de9d1da34daa7035e86a8c0df5e9d11dbdab43
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sun Dec 1 20:36:13 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Fri Jan 3 11:28:09 2020 +0100
[NTOS:KE] In KiExitV86Mode, restore KTSS::Esp0 to its standard value. CORE-16531
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 | 4 ++--
ntoskrnl/ke/i386/thrdini.c | 2 +-
ntoskrnl/ke/i386/v86vdm.c | 7 ++++---
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c
index de97192c32a..87405e6032f 100644
--- a/ntoskrnl/ke/i386/exp.c
+++ b/ntoskrnl/ke/i386/exp.c
@@ -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 */
diff --git a/ntoskrnl/ke/i386/thrdini.c b/ntoskrnl/ke/i386/thrdini.c
index 678bedd113e..7ce51632af2 100644
--- a/ntoskrnl/ke/i386/thrdini.c
+++ b/ntoskrnl/ke/i386/thrdini.c
@@ -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;
diff --git a/ntoskrnl/ke/i386/v86vdm.c b/ntoskrnl/ke/i386/v86vdm.c
index e629f8bb44e..0421f005217 100644
--- a/ntoskrnl/ke/i386/v86vdm.c
+++ b/ntoskrnl/ke/i386/v86vdm.c
@@ -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;