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