Alexandre Julliard : TEB.StackLimit should not include the guard page.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 12 11:10:26 CST 2005


Module: wine
Branch: refs/heads/master
Commit: f3dad37ba2671a7d86c5770e498252e3363e809c
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=f3dad37ba2671a7d86c5770e498252e3363e809c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec 12 17:28:32 2005 +0100

TEB.StackLimit should not include the guard page.

---

 dlls/kernel/process.c    |    5 +++--
 dlls/ntdll/signal_i386.c |    4 ++--
 dlls/ntdll/thread.c      |    8 +++++---
 dlls/ntdll/virtual.c     |    2 +-
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c
index af9e23f..42c4033 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -978,7 +978,8 @@ static void *init_stack(void)
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
 
     stack_size = max( nt->OptionalHeader.SizeOfStackReserve, nt->OptionalHeader.SizeOfStackCommit );
-    stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
+    stack_size += page_size;  /* for the guard page */
+    stack_size = (stack_size + 0xffff) & ~0xffff;  /* round to 64K boundary */
     if (stack_size < 1024 * 1024) stack_size = 1024 * 1024;  /* Xlib needs a large stack */
 
     if (!(base = VirtualAlloc( NULL, stack_size, MEM_COMMIT, PAGE_READWRITE )))
@@ -990,7 +991,7 @@ static void *init_stack(void)
     /* note: limit is lower than base since the stack grows down */
     NtCurrentTeb()->DeallocationStack = base;
     NtCurrentTeb()->Tib.StackBase     = (char *)base + stack_size;
-    NtCurrentTeb()->Tib.StackLimit    = base;
+    NtCurrentTeb()->Tib.StackLimit    = (char *)base + page_size;
 
     /* setup guard page */
     VirtualProtect( base, 1, PAGE_READWRITE | PAGE_GUARD, NULL );
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 3cc54af..2a7fdf5 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -830,10 +830,10 @@ static EXCEPTION_RECORD *setup_exception
     }
 
     if (stack - 1 > stack || /* check for overflow in subtraction */
-        (char *)(stack - 1) < (char *)NtCurrentTeb()->Tib.StackLimit + 4096 ||
+        (char *)(stack - 1) < (char *)NtCurrentTeb()->Tib.StackLimit ||
         (char *)stack > (char *)NtCurrentTeb()->Tib.StackBase)
     {
-        UINT diff = (char *)NtCurrentTeb()->Tib.StackLimit + 4096 - (char *)stack;
+        UINT diff = (char *)NtCurrentTeb()->Tib.StackLimit - (char *)stack;
         if (diff < 4096)
         {
             ERR( "stack overflow %u bytes in thread %04lx eip %08lx esp %08lx stack %p-%p\n",
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 8367751..07cd08d 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -201,7 +201,7 @@ static void start_thread( struct wine_pt
     PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
     void *arg = startup_info->entry_arg;
     struct debug_info debug_info;
-    SIZE_T size;
+    SIZE_T size, page_size = getpagesize();
 
     debug_info.str_pos = debug_info.strings;
     debug_info.out_pos = debug_info.output;
@@ -219,10 +219,10 @@ static void start_thread( struct wine_pt
                              &size, MEM_SYSTEM, PAGE_READWRITE );
     /* limit is lower than base since the stack grows down */
     teb->Tib.StackBase  = (char *)info->stack_base + info->stack_size;
-    teb->Tib.StackLimit = info->stack_base;
+    teb->Tib.StackLimit = (char *)info->stack_base + page_size;
 
     /* setup the guard page */
-    size = 1;
+    size = page_size;
     NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size,
                             PAGE_READWRITE | PAGE_GUARD, NULL );
     RtlFreeHeap( GetProcessHeap(), 0, info );
@@ -252,6 +252,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
     DWORD tid = 0;
     int request_pipe[2];
     NTSTATUS status;
+    SIZE_T page_size = getpagesize();
 
     if( ! is_current_process( process ) )
     {
@@ -307,6 +308,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
         if (!stack_commit) stack_commit = nt->OptionalHeader.SizeOfStackCommit;
     }
     if (stack_reserve < stack_commit) stack_reserve = stack_commit;
+    stack_reserve += page_size;  /* for the guard page */
     stack_reserve = (stack_reserve + 0xffff) & ~0xffff;  /* round to 64K boundary */
     if (stack_reserve < 1024 * 1024) stack_reserve = 1024 * 1024;  /* Xlib needs a large stack */
 
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index f3984f0..7d2d445 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1196,7 +1196,7 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
             ret = STATUS_GUARD_PAGE_VIOLATION;
         }
         /* is it inside the stack guard page? */
-        if (((const char *)addr >= stack) && ((const char *)addr < stack + (page_mask+1)))
+        if (((const char *)addr >= stack - (page_mask + 1)) && ((const char *)addr < stack))
             ret = STATUS_STACK_OVERFLOW;
     }
     RtlLeaveCriticalSection( &csVirtual );




More information about the wine-cvs mailing list