From 141fc0844c3c642065692b05a699d599a92a7bce Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 13 Apr 2016 06:52:07 +0200 Subject: [PATCH] Added patch to ignore invalid exit_frame when exiting thread. This makes the ntdll-Dealloc_Thread_Stack patchset unnecessary. --- patches/ntdll-Dealloc_Thread_Stack/definition | 1 + ...valid-exit_frame-when-exiting-thread.patch | 81 +++++++++++++++++++ patches/ntdll-Thread_Stack/definition | 1 + patches/patchinstall.sh | 21 +---- 4 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 patches/ntdll-Thread_Stack/0002-ntdll-Ignore-invalid-exit_frame-when-exiting-thread.patch diff --git a/patches/ntdll-Dealloc_Thread_Stack/definition b/patches/ntdll-Dealloc_Thread_Stack/definition index b0f50a6f..7b04369a 100644 --- a/patches/ntdll-Dealloc_Thread_Stack/definition +++ b/patches/ntdll-Dealloc_Thread_Stack/definition @@ -1 +1,2 @@ Fixes: Do not allow to deallocate thread stack for current thread +Disabled: true diff --git a/patches/ntdll-Thread_Stack/0002-ntdll-Ignore-invalid-exit_frame-when-exiting-thread.patch b/patches/ntdll-Thread_Stack/0002-ntdll-Ignore-invalid-exit_frame-when-exiting-thread.patch new file mode 100644 index 00000000..e9640660 --- /dev/null +++ b/patches/ntdll-Thread_Stack/0002-ntdll-Ignore-invalid-exit_frame-when-exiting-thread.patch @@ -0,0 +1,81 @@ +From 15ef836edec8fa90f4d02d15d6b071439a65b855 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 13 Apr 2016 06:49:03 +0200 +Subject: ntdll: Ignore invalid exit_frame when exiting thread. + +--- + 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 9834c9f..8c09758 100644 +--- a/dlls/ntdll/signal_i386.c ++++ b/dlls/ntdll/signal_i386.c +@@ -2832,6 +2832,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 ); + } + +@@ -2841,6 +2849,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 93475d54..ffbb0f0 100644 +--- a/dlls/ntdll/signal_x86_64.c ++++ b/dlls/ntdll/signal_x86_64.c +@@ -3831,6 +3831,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 ); + } + +@@ -3840,6 +3848,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 + diff --git a/patches/ntdll-Thread_Stack/definition b/patches/ntdll-Thread_Stack/definition index 0f34b18d..44859cb7 100644 --- a/patches/ntdll-Thread_Stack/definition +++ b/patches/ntdll-Thread_Stack/definition @@ -1,2 +1,3 @@ Fixes: Use a separate stack when starting new threads +Fixes: Ignore invalid exit_frame when exiting thread Depends: ntdll-ThreadTime diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 7f01856c..9b68a33c 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -197,7 +197,6 @@ patch_enable_all () enable_ntdll_ApiSetQueryApiSetPresence="$1" enable_ntdll_CLI_Images="$1" enable_ntdll_DOS_Attributes="$1" - enable_ntdll_Dealloc_Thread_Stack="$1" enable_ntdll_DeviceType_Systemroot="$1" enable_ntdll_DllOverrides_WOW64="$1" enable_ntdll_DllRedirects="$1" @@ -765,9 +764,6 @@ patch_enable () ntdll-DOS_Attributes) enable_ntdll_DOS_Attributes="$2" ;; - ntdll-Dealloc_Thread_Stack) - enable_ntdll_Dealloc_Thread_Stack="$2" - ;; ntdll-DeviceType_Systemroot) enable_ntdll_DeviceType_Systemroot="$2" ;; @@ -4639,19 +4635,6 @@ if test "$enable_ntdll_DOS_Attributes" -eq 1; then ) >> "$patchlist" fi -# Patchset ntdll-Dealloc_Thread_Stack -# | -# | Modified files: -# | * dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_arm.c, dlls/ntdll/signal_arm64.c, dlls/ntdll/signal_i386.c, -# | dlls/ntdll/signal_powerpc.c, dlls/ntdll/signal_x86_64.c, dlls/ntdll/virtual.c -# | -if test "$enable_ntdll_Dealloc_Thread_Stack" -eq 1; then - patch_apply ntdll-Dealloc_Thread_Stack/0001-ntdll-Do-not-allow-to-allocate-thread-stack-for-curr.patch - ( - echo '+ { "Sebastian Lackner", "ntdll: Do not allow to deallocate thread stack for current thread.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-DeviceType_Systemroot # | # | This patchset fixes the following Wine bugs: @@ -5132,12 +5115,14 @@ fi # | * ntdll-ThreadTime # | # | Modified files: -# | * dlls/ntdll/thread.c +# | * dlls/ntdll/signal_i386.c, dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c # | if test "$enable_ntdll_Thread_Stack" -eq 1; then patch_apply ntdll-Thread_Stack/0001-ntdll-Use-a-separate-stack-when-starting-new-threads.patch + patch_apply ntdll-Thread_Stack/0002-ntdll-Ignore-invalid-exit_frame-when-exiting-thread.patch ( echo '+ { "Sebastian Lackner", "ntdll: Use a separate stack when starting new threads.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Ignore invalid exit_frame when exiting thread.", 1 },'; ) >> "$patchlist" fi