ntdll: Ignore invalid exit_frame when exiting thread.

Sebastian Lackner sebastian at fds-team.de
Fri Apr 15 02:43:12 CDT 2016


Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---

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



More information about the wine-patches mailing list