https://git.reactos.org/?p=reactos.git;a=commitdiff;h=15fbcc19b9e18115ce6499...
commit 15fbcc19b9e18115ce649955a6291ecfd1b8ce53 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Wed May 10 20:28:20 2023 +0300 Commit: Timo Kreuzer timo.kreuzer@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),