https://git.reactos.org/?p=reactos.git;a=commitdiff;h=15fbcc19b9e18115ce649…
commit 15fbcc19b9e18115ce649955a6291ecfd1b8ce53
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed May 10 20:28:20 2023 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Tue May 16 22:03:13 2023 +0300
[NTOS:KE/x64] Fix KiConvertToGuiThread
- Do not allocate a new stack, if the thread already has a large one. This prevents
the function from freeing a large stack as a normal stack and subsequently leaking system
PTEs.
- Fix the check for failure of PsConvertToGuiThread (test eax, not rax, for being
negative, because by default rax is zero extended from eax, not sign extended). This fixes
an infinite loop on failure.
---
ntoskrnl/ke/amd64/trap.S | 13 ++++++++++---
sdk/include/asm/ksamd64.template.h | 1 +
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S
index 150d08d8133..082160893b4 100644
--- a/ntoskrnl/ke/amd64/trap.S
+++ b/ntoskrnl/ke/amd64/trap.S
@@ -1041,6 +1041,11 @@ FUNC KiConvertToGuiThread
.allocstack 40
.endprolog
+ /* Check if we already have a large stack */
+ mov rax, gs:[PcCurrentThread]
+ cmp byte ptr [rax + KTHREAD_LargeStack], 0
+ jnz AlreadyLargeStack
+
// NewStack = (ULONG_PTR)MmCreateKernelStack(TRUE, 0);
mov cl, 1
xor rdx, rdx
@@ -1050,10 +1055,10 @@ FUNC KiConvertToGuiThread
test rax, rax
jz KiConvertToGuiThreadFailed
- /* OldStack = KeSwitchKernelStack((PVOID)NewStack, (PVOID)(NewStack -
KERNEL_STACK_SIZE)); */
+ /* OldStack = KeSwitchKernelStack((PVOID)NewStack, (PVOID)(NewStack -
KERNEL_LARGE_STACK_COMMIT )); */
mov rcx, rax
mov rdx, rax
- sub rdx, KERNEL_STACK_SIZE
+ sub rdx, KERNEL_LARGE_STACK_COMMIT
call KeSwitchKernelStack
// MmDeleteKernelStack(OldStack, FALSE);
@@ -1061,11 +1066,13 @@ FUNC KiConvertToGuiThread
xor rdx, rdx
call MmDeleteKernelStack
+AlreadyLargeStack:
+
/* Call the worker function */
call PsConvertToGuiThread
/* Check for failure */
- test rax, rax
+ test eax, eax
js KiConvertToGuiThreadFailed
/* Disable interrupts for return */
diff --git a/sdk/include/asm/ksamd64.template.h b/sdk/include/asm/ksamd64.template.h
index 6fcb43149ea..db36c5767bc 100644
--- a/sdk/include/asm/ksamd64.template.h
+++ b/sdk/include/asm/ksamd64.template.h
@@ -1047,6 +1047,7 @@ OFFSET(KTHREAD_TrapFrame, KTHREAD, TrapFrame),
OFFSET(KTHREAD_PreviousMode, KTHREAD, PreviousMode),
OFFSET(KTHREAD_KernelStack, KTHREAD, KernelStack),
OFFSET(KTHREAD_UserApcPending, KTHREAD, ApcState.UserApcPending),
+OFFSET(KTHREAD_LargeStack, KTHREAD, LargeStack),
HEADER("KINTERRUPT"),
OFFSET(KINTERRUPT_Type, KINTERRUPT, Type),