From: Sebastian Lackner Subject: ntdll: Ignore invalid exit_frame when exiting thread. Message-Id: <57109B90.9060806@fds-team.de> Date: Fri, 15 Apr 2016 09:43:12 +0200 Signed-off-by: Sebastian Lackner --- When applications switch to a custom stack, exit_frame is not necessarily valid anymore. dlls/ntdll/signal_i386.c | 16 ++++++++++++++++ dlls/ntdll/signal_x86_64.c | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 59dca6c..b837863 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2772,6 +2772,14 @@ void call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg, void *frame ) void WINAPI RtlExitUserThread( ULONG status ) { if (!ntdll_get_thread_data()->exit_frame) exit_thread( status ); + if (ntdll_get_thread_data()->exit_frame <= NtCurrentTeb()->DeallocationStack || + ntdll_get_thread_data()->exit_frame > NtCurrentTeb()->Tib.StackBase) + { + WARN( "exit frame outside of stack limits in thread %04x frame %p stack %p-%p\n", + GetCurrentThreadId(), ntdll_get_thread_data()->exit_frame, + NtCurrentTeb()->Tib.StackLimit, NtCurrentTeb()->Tib.StackBase ); + exit_thread( status ); + } call_thread_exit_func( status, exit_thread, ntdll_get_thread_data()->exit_frame ); } @@ -2781,6 +2789,14 @@ void WINAPI RtlExitUserThread( ULONG status ) void abort_thread( int status ) { if (!ntdll_get_thread_data()->exit_frame) terminate_thread( status ); + if (ntdll_get_thread_data()->exit_frame <= NtCurrentTeb()->DeallocationStack || + ntdll_get_thread_data()->exit_frame > NtCurrentTeb()->Tib.StackBase) + { + WARN( "exit frame outside of stack limits in thread %04x frame %p stack %p-%p\n", + GetCurrentThreadId(), ntdll_get_thread_data()->exit_frame, + NtCurrentTeb()->Tib.StackLimit, NtCurrentTeb()->Tib.StackBase ); + terminate_thread( status ); + } call_thread_exit_func( status, terminate_thread, ntdll_get_thread_data()->exit_frame ); } diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index a79fd6e..6527527 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -3793,6 +3793,14 @@ __ASM_GLOBAL_FUNC( call_thread_exit_func, void WINAPI RtlExitUserThread( ULONG status ) { if (!ntdll_get_thread_data()->exit_frame) exit_thread( status ); + if (ntdll_get_thread_data()->exit_frame <= NtCurrentTeb()->DeallocationStack || + ntdll_get_thread_data()->exit_frame > NtCurrentTeb()->Tib.StackBase) + { + WARN( "exit frame outside of stack limits in thread %04x frame %p stack %p-%p\n", + GetCurrentThreadId(), ntdll_get_thread_data()->exit_frame, + NtCurrentTeb()->Tib.StackLimit, NtCurrentTeb()->Tib.StackBase ); + exit_thread( status ); + } call_thread_exit_func( status, exit_thread, ntdll_get_thread_data()->exit_frame ); } @@ -3802,6 +3810,14 @@ void WINAPI RtlExitUserThread( ULONG status ) void abort_thread( int status ) { if (!ntdll_get_thread_data()->exit_frame) terminate_thread( status ); + if (ntdll_get_thread_data()->exit_frame <= NtCurrentTeb()->DeallocationStack || + ntdll_get_thread_data()->exit_frame > NtCurrentTeb()->Tib.StackBase) + { + WARN( "exit frame outside of stack limits in thread %04x frame %p stack %p-%p\n", + GetCurrentThreadId(), ntdll_get_thread_data()->exit_frame, + NtCurrentTeb()->Tib.StackLimit, NtCurrentTeb()->Tib.StackBase ); + terminate_thread( status ); + } call_thread_exit_func( status, terminate_thread, ntdll_get_thread_data()->exit_frame ); } -- 2.7.1