Alexandre Julliard : ntdll: Avoid private Unix functions in RtlCreateUserStack().
Alexandre Julliard
julliard at winehq.org
Wed Jul 22 16:34:29 CDT 2020
Module: wine
Branch: master
Commit: 131e53a1fc2cd7156b56402c97d53af8da72399e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=131e53a1fc2cd7156b56402c97d53af8da72399e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 22 14:16:22 2020 +0200
ntdll: Avoid private Unix functions in RtlCreateUserStack().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/loader.c | 2 +-
dlls/ntdll/unix/loader.c | 1 -
dlls/ntdll/unix/unix_private.h | 3 ++-
dlls/ntdll/unix/virtual.c | 3 ++-
dlls/ntdll/unixlib.h | 3 +--
dlls/ntdll/virtual.c | 32 +++++++++++++++++++++++++++++++-
6 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 18adb55c22..adb1ed871b 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -4016,7 +4016,7 @@ void __wine_process_init(void)
RemoveEntryList( &wm->ldr.InMemoryOrderLinks );
InsertHeadList( &peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderLinks );
- unix_funcs->virtual_alloc_thread_stack( &stack, 0, 0, NULL );
+ RtlCreateUserStack( 0, 0, 0, 0x10000, 0x10000, &stack );
teb->Tib.StackBase = stack.StackBase;
teb->Tib.StackLimit = stack.StackLimit;
teb->DeallocationStack = stack.DeallocationStack;
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index dc4a579132..22ba928541 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1400,7 +1400,6 @@ static struct unix_funcs unix_funcs =
get_build_id,
get_host_version,
virtual_map_section,
- virtual_alloc_thread_stack,
virtual_locked_recvmsg,
virtual_release_address_space,
virtual_set_large_address_space,
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 50f27c6d68..7b4d34dead 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -108,7 +108,6 @@ extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
-extern NTSTATUS CDECL virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
extern ssize_t CDECL virtual_locked_recvmsg( int fd, struct msghdr *hdr, int flags ) DECLSPEC_HIDDEN;
extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
extern void CDECL virtual_set_large_address_space(void) DECLSPEC_HIDDEN;
@@ -196,6 +195,8 @@ extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN;
+extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size,
+ SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
extern void virtual_map_user_shared_data(void) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) DECLSPEC_HIDDEN;
extern unsigned int virtual_locked_server_call( void *req_ptr ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 67c58642a7..f3fec7c29c 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2735,7 +2735,8 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
/***********************************************************************
* virtual_alloc_thread_stack
*/
-NTSTATUS CDECL virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size )
+NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size,
+ SIZE_T *pthread_size )
{
struct file_view *view;
NTSTATUS status;
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
index 118f38a248..a706b174b4 100644
--- a/dlls/ntdll/unixlib.h
+++ b/dlls/ntdll/unixlib.h
@@ -28,7 +28,7 @@ struct msghdr;
struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */
-#define NTDLL_UNIXLIB_VERSION 91
+#define NTDLL_UNIXLIB_VERSION 92
struct unix_funcs
{
@@ -91,7 +91,6 @@ struct unix_funcs
NTSTATUS (CDECL *virtual_map_section)( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
ULONG protect, pe_image_info_t *image_info );
- NTSTATUS (CDECL *virtual_alloc_thread_stack)( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size );
ssize_t (CDECL *virtual_locked_recvmsg)( int fd, struct msghdr *hdr, int flags );
void (CDECL *virtual_release_address_space)(void);
void (CDECL *virtual_set_large_address_space)(void);
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 1f582ffe60..3ba4b8afbc 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -44,6 +44,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(virtual);
NTSTATUS WINAPI RtlCreateUserStack( SIZE_T commit, SIZE_T reserve, ULONG zero_bits,
SIZE_T commit_align, SIZE_T reserve_align, INITIAL_TEB *stack )
{
+ PROCESS_STACK_ALLOCATION_INFORMATION alloc;
+ NTSTATUS status;
+
TRACE("commit %#lx, reserve %#lx, zero_bits %u, commit_align %#lx, reserve_align %#lx, stack %p\n",
commit, reserve, zero_bits, commit_align, reserve_align, stack);
@@ -60,7 +63,34 @@ NTSTATUS WINAPI RtlCreateUserStack( SIZE_T commit, SIZE_T reserve, ULONG zero_bi
reserve = (reserve + reserve_align - 1) & ~(reserve_align - 1);
commit = (commit + commit_align - 1) & ~(commit_align - 1);
- return unix_funcs->virtual_alloc_thread_stack( stack, reserve, commit, NULL );
+ if (reserve < commit) reserve = commit;
+ if (reserve < 0x100000) reserve = 0x100000;
+ reserve = (reserve + 0xffff) & ~0xffff; /* round to 64K boundary */
+
+ alloc.ReserveSize = reserve;
+ alloc.ZeroBits = zero_bits;
+ status = NtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
+ &alloc, sizeof(alloc) );
+ if (!status)
+ {
+ void *addr = alloc.StackBase;
+ SIZE_T size = page_size;
+
+ NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 0, &size, MEM_COMMIT, PAGE_NOACCESS );
+ addr = (char *)alloc.StackBase + page_size;
+ NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 0, &size, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD );
+ addr = (char *)alloc.StackBase + 2 * page_size;
+ size = reserve - 2 * page_size;
+ NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 0, &size, MEM_COMMIT, PAGE_READWRITE );
+
+ /* note: limit is lower than base since the stack grows down */
+ stack->OldStackBase = 0;
+ stack->OldStackLimit = 0;
+ stack->DeallocationStack = alloc.StackBase;
+ stack->StackBase = (char *)alloc.StackBase + reserve;
+ stack->StackLimit = (char *)alloc.StackBase + 2 * page_size;
+ }
+ return status;
}
More information about the wine-cvs
mailing list