Module: wine Branch: master Commit: 131e53a1fc2cd7156b56402c97d53af8da72399e URL: https://source.winehq.org/git/wine.git/?a=commit;h=131e53a1fc2cd7156b56402c9...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jul 22 14:16:22 2020 +0200
ntdll: Avoid private Unix functions in RtlCreateUserStack().
Signed-off-by: Alexandre Julliard julliard@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; }