TEB.StackLimit should not include the guard page.
This commit is contained in:
parent
8a8a94aecb
commit
f3dad37ba2
|
@ -978,7 +978,8 @@ static void *init_stack(void)
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
|
||||||
|
|
||||||
stack_size = max( nt->OptionalHeader.SizeOfStackReserve, nt->OptionalHeader.SizeOfStackCommit );
|
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 (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, MEM_COMMIT, PAGE_READWRITE )))
|
||||||
|
@ -990,7 +991,7 @@ static void *init_stack(void)
|
||||||
/* note: limit is lower than base since the stack grows down */
|
/* note: limit is lower than base since the stack grows down */
|
||||||
NtCurrentTeb()->DeallocationStack = base;
|
NtCurrentTeb()->DeallocationStack = base;
|
||||||
NtCurrentTeb()->Tib.StackBase = (char *)base + stack_size;
|
NtCurrentTeb()->Tib.StackBase = (char *)base + stack_size;
|
||||||
NtCurrentTeb()->Tib.StackLimit = base;
|
NtCurrentTeb()->Tib.StackLimit = (char *)base + page_size;
|
||||||
|
|
||||||
/* setup guard page */
|
/* setup guard page */
|
||||||
VirtualProtect( base, 1, PAGE_READWRITE | PAGE_GUARD, NULL );
|
VirtualProtect( base, 1, PAGE_READWRITE | PAGE_GUARD, NULL );
|
||||||
|
|
|
@ -830,10 +830,10 @@ static EXCEPTION_RECORD *setup_exception( SIGCONTEXT *sigcontext, raise_func fun
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack - 1 > stack || /* check for overflow in subtraction */
|
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)
|
(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)
|
if (diff < 4096)
|
||||||
{
|
{
|
||||||
ERR( "stack overflow %u bytes in thread %04lx eip %08lx esp %08lx stack %p-%p\n",
|
ERR( "stack overflow %u bytes in thread %04lx eip %08lx esp %08lx stack %p-%p\n",
|
||||||
|
|
|
@ -201,7 +201,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
|
||||||
PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
|
PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
|
||||||
void *arg = startup_info->entry_arg;
|
void *arg = startup_info->entry_arg;
|
||||||
struct debug_info debug_info;
|
struct debug_info debug_info;
|
||||||
SIZE_T size;
|
SIZE_T size, page_size = getpagesize();
|
||||||
|
|
||||||
debug_info.str_pos = debug_info.strings;
|
debug_info.str_pos = debug_info.strings;
|
||||||
debug_info.out_pos = debug_info.output;
|
debug_info.out_pos = debug_info.output;
|
||||||
|
@ -219,10 +219,10 @@ static void start_thread( struct wine_pthread_thread_info *info )
|
||||||
&size, MEM_SYSTEM, PAGE_READWRITE );
|
&size, MEM_SYSTEM, PAGE_READWRITE );
|
||||||
/* limit is lower than base since the stack grows down */
|
/* limit is lower than base since the stack grows down */
|
||||||
teb->Tib.StackBase = (char *)info->stack_base + info->stack_size;
|
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 */
|
/* setup the guard page */
|
||||||
size = 1;
|
size = page_size;
|
||||||
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size,
|
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size,
|
||||||
PAGE_READWRITE | PAGE_GUARD, NULL );
|
PAGE_READWRITE | PAGE_GUARD, NULL );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||||
|
@ -252,6 +252,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
DWORD tid = 0;
|
DWORD tid = 0;
|
||||||
int request_pipe[2];
|
int request_pipe[2];
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
SIZE_T page_size = getpagesize();
|
||||||
|
|
||||||
if( ! is_current_process( process ) )
|
if( ! is_current_process( process ) )
|
||||||
{
|
{
|
||||||
|
@ -307,6 +308,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
if (!stack_commit) stack_commit = nt->OptionalHeader.SizeOfStackCommit;
|
if (!stack_commit) stack_commit = nt->OptionalHeader.SizeOfStackCommit;
|
||||||
}
|
}
|
||||||
if (stack_reserve < stack_commit) stack_reserve = stack_commit;
|
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 */
|
stack_reserve = (stack_reserve + 0xffff) & ~0xffff; /* round to 64K boundary */
|
||||||
if (stack_reserve < 1024 * 1024) stack_reserve = 1024 * 1024; /* Xlib needs a large stack */
|
if (stack_reserve < 1024 * 1024) stack_reserve = 1024 * 1024; /* Xlib needs a large stack */
|
||||||
|
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID addr )
|
||||||
ret = STATUS_GUARD_PAGE_VIOLATION;
|
ret = STATUS_GUARD_PAGE_VIOLATION;
|
||||||
}
|
}
|
||||||
/* is it inside the stack guard page? */
|
/* 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;
|
ret = STATUS_STACK_OVERFLOW;
|
||||||
}
|
}
|
||||||
RtlLeaveCriticalSection( &csVirtual );
|
RtlLeaveCriticalSection( &csVirtual );
|
||||||
|
|
Loading…
Reference in New Issue