mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to block deallocation of thread stack for current thread (fixes Wine Staging Bug #241).
This commit is contained in:
parent
f3b30373fb
commit
76f5985038
@ -39,10 +39,11 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [11]:**
|
||||
**Bug fixes and features included in the next upcoming release [12]:**
|
||||
|
||||
* Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699))
|
||||
* Catch invalid memory accesses in imagehlp.CheckSumMappedFile
|
||||
* Do not allow to deallocate thread stack for current thread
|
||||
* Fix detection of case-insensitive systems in MSYS2
|
||||
* Implement enumeration of sound devices and basic properties to dxdiagn ([Wine Bug #32613](https://bugs.winehq.org/show_bug.cgi?id=32613))
|
||||
* Implement shell32 NewMenu class with new folder item ([Wine Bug #24812](https://bugs.winehq.org/show_bug.cgi?id=24812))
|
||||
|
2
debian/changelog
vendored
2
debian/changelog
vendored
@ -20,6 +20,8 @@ wine-staging (1.7.50) UNRELEASED; urgency=low
|
||||
precision registry timestamps.
|
||||
* Added patch to use a helper function for NtWaitForMultipleObjects and
|
||||
NtWaitForSingleObject.
|
||||
* Added patch to block deallocation of thread stack for current thread (fixes
|
||||
Wine Staging Bug #241).
|
||||
* Removed patch to move security cookie initialization from memory management
|
||||
to loader (accepted upstream).
|
||||
* Removed patches for stub of D3DCompileFromFile and D3DCompile2 (accepted
|
||||
|
@ -0,0 +1,191 @@
|
||||
From dae71e69de99580ced403804e944c7a13e0519e9 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 21 Aug 2015 06:39:47 +0800
|
||||
Subject: ntdll: Do not allow to allocate thread stack for current thread.
|
||||
|
||||
---
|
||||
dlls/ntdll/ntdll_misc.h | 10 ++++++++++
|
||||
dlls/ntdll/signal_arm.c | 7 +++++++
|
||||
dlls/ntdll/signal_arm64.c | 7 +++++++
|
||||
dlls/ntdll/signal_i386.c | 8 +++++++-
|
||||
dlls/ntdll/signal_powerpc.c | 7 +++++++
|
||||
dlls/ntdll/signal_x86_64.c | 7 +++++++
|
||||
dlls/ntdll/virtual.c | 12 ++++++++++++
|
||||
7 files changed, 57 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index 46776a6..14b47ac 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -242,8 +242,18 @@ struct ntdll_thread_data
|
||||
WINE_VM86_TEB_INFO vm86; /* 1fc vm86 private data */
|
||||
void *exit_frame; /* 204 exit frame pointer */
|
||||
#endif
|
||||
+ void *pthread_stack; /* 208/318 pthread stack */
|
||||
};
|
||||
|
||||
+C_ASSERT( FIELD_OFFSET(TEB, SpareBytes1) + sizeof(struct ntdll_thread_data) <=
|
||||
+ FIELD_OFFSET(TEB, GdiTebBatch) + sizeof(((TEB *)0)->GdiTebBatch) );
|
||||
+
|
||||
+#ifdef __i386__
|
||||
+C_ASSERT( FIELD_OFFSET(TEB, SpareBytes1) + FIELD_OFFSET(struct ntdll_thread_data, vm86) == FIELD_OFFSET(TEB, GdiTebBatch) );
|
||||
+C_ASSERT( FIELD_OFFSET(TEB, SpareBytes1) + FIELD_OFFSET(struct ntdll_thread_data, vm86) == 0x1fc );
|
||||
+C_ASSERT( FIELD_OFFSET(TEB, SpareBytes1) + FIELD_OFFSET(struct ntdll_thread_data, gs) == 0x1d8 );
|
||||
+#endif
|
||||
+
|
||||
static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
|
||||
{
|
||||
return (struct ntdll_thread_data *)NtCurrentTeb()->SpareBytes1;
|
||||
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
|
||||
index cfb9df1..07c8b0a 100644
|
||||
--- a/dlls/ntdll/signal_arm.c
|
||||
+++ b/dlls/ntdll/signal_arm.c
|
||||
@@ -902,12 +902,19 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
void signal_free_thread( TEB *teb )
|
||||
{
|
||||
SIZE_T size;
|
||||
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
|
||||
|
||||
if (teb->DeallocationStack)
|
||||
{
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||
}
|
||||
+ if ((ULONG_PTR)thread_data->pthread_stack & 1)
|
||||
+ {
|
||||
+ void *addr = (void *)((ULONG_PTR)thread_data->pthread_stack & ~1);
|
||||
+ size = 0;
|
||||
+ NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||
+ }
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||
}
|
||||
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
|
||||
index 7259831..09bdfe0 100644
|
||||
--- a/dlls/ntdll/signal_arm64.c
|
||||
+++ b/dlls/ntdll/signal_arm64.c
|
||||
@@ -776,12 +776,19 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
void signal_free_thread( TEB *teb )
|
||||
{
|
||||
SIZE_T size;
|
||||
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
|
||||
|
||||
if (teb->DeallocationStack)
|
||||
{
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||
}
|
||||
+ if ((ULONG_PTR)thread_data->pthread_stack & 1)
|
||||
+ {
|
||||
+ void *addr = (void *)((ULONG_PTR)thread_data->pthread_stack & ~1);
|
||||
+ size = 0;
|
||||
+ NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||
+ }
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||
}
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index f550c63..1007358 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -2616,12 +2616,18 @@ void signal_free_thread( TEB *teb )
|
||||
SIZE_T size;
|
||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
|
||||
|
||||
- if (thread_data) wine_ldt_free_fs( thread_data->fs );
|
||||
+ wine_ldt_free_fs( thread_data->fs );
|
||||
if (teb->DeallocationStack)
|
||||
{
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||
}
|
||||
+ if ((ULONG_PTR)thread_data->pthread_stack & 1)
|
||||
+ {
|
||||
+ void *addr = (void *)((ULONG_PTR)thread_data->pthread_stack & ~1);
|
||||
+ size = 0;
|
||||
+ NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||
+ }
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||
}
|
||||
diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c
|
||||
index d2e7819..c673d6e 100644
|
||||
--- a/dlls/ntdll/signal_powerpc.c
|
||||
+++ b/dlls/ntdll/signal_powerpc.c
|
||||
@@ -982,12 +982,19 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
void signal_free_thread( TEB *teb )
|
||||
{
|
||||
SIZE_T size;
|
||||
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
|
||||
|
||||
if (teb->DeallocationStack)
|
||||
{
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||
}
|
||||
+ if ((ULONG_PTR)thread_data->pthread_stack & 1)
|
||||
+ {
|
||||
+ void *addr = (void *)((ULONG_PTR)thread_data->pthread_stack & ~1);
|
||||
+ size = 0;
|
||||
+ NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||
+ }
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||
}
|
||||
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
|
||||
index a1ee02d..1db9f27 100644
|
||||
--- a/dlls/ntdll/signal_x86_64.c
|
||||
+++ b/dlls/ntdll/signal_x86_64.c
|
||||
@@ -2732,12 +2732,19 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
void signal_free_thread( TEB *teb )
|
||||
{
|
||||
SIZE_T size;
|
||||
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
|
||||
|
||||
if (teb->DeallocationStack)
|
||||
{
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||
}
|
||||
+ if ((ULONG_PTR)thread_data->pthread_stack & 1)
|
||||
+ {
|
||||
+ void *addr = (void *)((ULONG_PTR)thread_data->pthread_stack & ~1);
|
||||
+ size = 0;
|
||||
+ NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||
+ }
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||
}
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index 9d35693..b40674b 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -1486,6 +1486,8 @@ NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commi
|
||||
teb->DeallocationStack = view->base;
|
||||
teb->Tib.StackBase = (char *)view->base + view->size;
|
||||
teb->Tib.StackLimit = (char *)view->base + 2 * page_size;
|
||||
+ ((struct ntdll_thread_data *)teb->SpareBytes1)->pthread_stack = view->base;
|
||||
+
|
||||
done:
|
||||
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
return status;
|
||||
@@ -2119,6 +2121,16 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
/* Free the pages */
|
||||
|
||||
if (size || (base != view->base)) status = STATUS_INVALID_PARAMETER;
|
||||
+ else if (view->base == (void *)((ULONG_PTR)ntdll_get_thread_data()->pthread_stack & ~1))
|
||||
+ {
|
||||
+ ULONG_PTR stack = (ULONG_PTR)ntdll_get_thread_data()->pthread_stack;
|
||||
+ if (stack & 1) status = STATUS_INVALID_PARAMETER;
|
||||
+ else
|
||||
+ {
|
||||
+ WARN( "Application tried to deallocate current pthread stack %p, deferring\n", view->base);
|
||||
+ ntdll_get_thread_data()->pthread_stack = (void *)(stack | 1);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
delete_view( view );
|
||||
--
|
||||
2.5.0
|
||||
|
1
patches/ntdll-Dealloc_Thread_Stack/definition
Normal file
1
patches/ntdll-Dealloc_Thread_Stack/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Do not allow to deallocate thread stack for current thread
|
@ -162,6 +162,7 @@ patch_enable_all ()
|
||||
enable_ntdll_Activation_Context="$1"
|
||||
enable_ntdll_CLI_Images="$1"
|
||||
enable_ntdll_DOS_Attributes="$1"
|
||||
enable_ntdll_Dealloc_Thread_Stack="$1"
|
||||
enable_ntdll_DeviceType_Systemroot="$1"
|
||||
enable_ntdll_DllRedirects="$1"
|
||||
enable_ntdll_Exception="$1"
|
||||
@ -571,6 +572,9 @@ 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"
|
||||
;;
|
||||
@ -3602,6 +3606,19 @@ 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 allocate thread stack for current thread.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-DeviceType_Systemroot
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
Reference in New Issue
Block a user