[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.
This commit is contained in:
Timo Kreuzer 2023-05-10 20:28:20 +03:00
parent c7fd9983cb
commit 15fbcc19b9
2 changed files with 11 additions and 3 deletions

View file

@ -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 */

View file

@ -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),