thread: Stack guard page should be excluded from the StackLimit in TEB. [Try 2]

Vitaliy Margolen wine-patch at kievinfo.com
Sat Dec 10 01:02:32 CST 2005


Looks like it's required only for the main thread's stack and not the
other threads.
Also it makes no sense to change protection of this guard page on the
first failure. It's the stack overflow doesn't matter how you loot at it.
And because we don't grow stack just fail first time around.

ChangeLog:
thread: Stack guard page should be excluded from the StackLimit in TEB.

 dlls/kernel/thread.c     |    7 ++++---
 dlls/ntdll/signal_i386.c |   10 +++++-----
 dlls/ntdll/virtual.c     |   11 +----------
 3 files changed, 10 insertions(+), 18 deletions(-)
-------------- next part --------------
ea53e55b6bfce1c0bf41f1e39b8b1ce8d171cce1
diff --git a/dlls/kernel/thread.c b/dlls/kernel/thread.c
index fd65b99..d815f53 100644
--- a/dlls/kernel/thread.c
+++ b/dlls/kernel/thread.c
@@ -63,14 +63,15 @@ TEB *THREAD_InitStack( TEB *teb, DWORD s
     stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
     if (stack_size < 1024 * 1024) stack_size = 1024 * 1024;  /* Xlib needs a large stack */
 
-    if (!(base = VirtualAlloc( NULL, stack_size, MEM_COMMIT, PAGE_READWRITE )))
+    if (!(base = VirtualAlloc( NULL, stack_size + page_size, MEM_COMMIT, PAGE_READWRITE )))
         return NULL;
 
     teb->DeallocationStack = base;
+    /* note: limit is lower than base since the stack grows down */
     teb->Tib.StackBase     = (char *)base + stack_size;
-    teb->Tib.StackLimit    = base;  /* note: limit is lower than base since the stack grows down */
+    teb->Tib.StackLimit    = (char *)base + page_size;
 
-    /* Setup guard pages */
+    /* Setup guard pages, which are not included in the stack size */
 
     VirtualProtect( base, 1, PAGE_READWRITE | PAGE_GUARD, &old_prot );
     return teb;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 3cc54af..ca42568 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -830,14 +830,14 @@ 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;
-        if (diff < 4096)
+        LONG diff = (char *)NtCurrentTeb()->Tib.StackLimit - (char *)stack;
+        if (diff < 0)
         {
-            ERR( "stack overflow %u bytes in thread %04lx eip %08lx esp %08lx stack %p-%p\n",
-                 diff, GetCurrentThreadId(), EIP_sig(sigcontext), ESP_sig(sigcontext),
+            ERR( "stack overflow %ld bytes in thread %04lx eip %08lx esp %08lx stack %p-%p\n",
+                 -diff, GetCurrentThreadId(), EIP_sig(sigcontext), ESP_sig(sigcontext),
                  NtCurrentTeb()->Tib.StackLimit, NtCurrentTeb()->Tib.StackBase );
             server_abort_thread(1);
         }
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index d04c79e..3c91dbd 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1188,16 +1188,7 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
     if ((view = VIRTUAL_FindView( addr )))
     {
         BYTE vprot = view->prot[((const char *)addr - (const char *)view->base) >> page_shift];
-        void *page = (void *)((UINT_PTR)addr & ~page_mask);
-        char *stack = NtCurrentTeb()->Tib.StackLimit;
-        if (vprot & VPROT_GUARD)
-        {
-            VIRTUAL_SetProt( view, page, page_mask + 1, vprot & ~VPROT_GUARD );
-            ret = STATUS_GUARD_PAGE_VIOLATION;
-        }
-        /* is it inside the stack guard page? */
-        if (((const char *)addr >= stack) && ((const char *)addr < stack + (page_mask+1)))
-            ret = STATUS_STACK_OVERFLOW;
+        if (vprot & VPROT_GUARD) ret = STATUS_STACK_OVERFLOW;
     }
     RtlLeaveCriticalSection( &csVirtual );
     return ret;


More information about the wine-patches mailing list