Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
87d9fef2
Commit
87d9fef2
authored
Aug 24, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Take stack guarantee into account when handling stack overflows.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
505be3a0
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
58 additions
and
41 deletions
+58
-41
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+6
-7
signal_arm64.c
dlls/ntdll/signal_arm64.c
+6
-7
signal_i386.c
dlls/ntdll/signal_i386.c
+13
-9
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+13
-9
virtual.c
dlls/ntdll/virtual.c
+19
-8
No files found.
dlls/ntdll/ntdll_misc.h
View file @
87d9fef2
...
...
@@ -177,7 +177,7 @@ extern NTSTATUS virtual_create_builtin_view( void *base ) 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_clear_thread_stack
(
void
*
stack_end
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_handle_stack_fault
(
void
*
addr
)
DECLSPEC_HIDDEN
;
extern
int
virtual_handle_stack_fault
(
void
*
addr
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_is_valid_code_address
(
const
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_handle_fault
(
LPCVOID
addr
,
DWORD
err
,
BOOL
on_signal_stack
)
DECLSPEC_HIDDEN
;
extern
unsigned
int
virtual_locked_server_call
(
void
*
req_ptr
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/signal_arm.c
View file @
87d9fef2
...
...
@@ -721,19 +721,18 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
ucontext_t
*
context
=
ucontext
;
/* check for page fault inside the thread stack */
if
(
get_trap_code
(
signal
,
context
)
==
TRAP_ARM_PAGEFLT
&&
(
char
*
)
info
->
si_addr
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
&&
(
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
&&
virtual_handle_stack_fault
(
info
->
si_addr
))
if
(
get_trap_code
(
signal
,
context
)
==
TRAP_ARM_PAGEFLT
)
{
/* check if this was the last guard page */
if
((
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
4096
)
switch
(
virtual_handle_stack_fault
(
info
->
si_addr
))
{
case
1
:
/* handled */
return
;
case
-
1
:
/* overflow */
rec
=
setup_exception
(
context
,
raise_segv_exception
);
rec
->
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
}
return
;
}
}
rec
=
setup_exception
(
context
,
raise_segv_exception
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_STACK_OVERFLOW
)
return
;
...
...
dlls/ntdll/signal_arm64.c
View file @
87d9fef2
...
...
@@ -669,19 +669,18 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
ucontext_t
*
context
=
ucontext
;
/* check for page fault inside the thread stack */
if
(
signal
==
SIGSEGV
&&
(
char
*
)
info
->
si_addr
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
&&
(
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
&&
virtual_handle_stack_fault
(
info
->
si_addr
))
if
(
signal
==
SIGSEGV
)
{
/* check if this was the last guard page */
if
((
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
4096
)
switch
(
virtual_handle_stack_fault
(
info
->
si_addr
))
{
case
1
:
/* handled */
return
;
case
-
1
:
/* overflow */
rec
=
setup_exception
(
context
,
raise_segv_exception
);
rec
->
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
}
return
;
}
}
rec
=
setup_exception
(
context
,
raise_segv_exception
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_STACK_OVERFLOW
)
return
;
...
...
dlls/ntdll/signal_i386.c
View file @
87d9fef2
...
...
@@ -1822,8 +1822,9 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
else
if
((
char
*
)(
stack
-
1
)
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackLimit
)
{
/* stack access below stack limit, may be recoverable */
if
(
virtual_handle_stack_fault
(
stack
-
1
))
exception_code
=
EXCEPTION_STACK_OVERFLOW
;
else
switch
(
virtual_handle_stack_fault
(
stack
-
1
))
{
case
0
:
/* not handled */
{
UINT
diff
=
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackLimit
-
(
char
*
)(
stack
-
1
);
WINE_ERR
(
"stack overflow %u bytes in thread %04x eip %08x esp %08x stack %p-%p-%p
\n
"
,
...
...
@@ -1832,6 +1833,10 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
NtCurrentTeb
()
->
Tib
.
StackLimit
,
NtCurrentTeb
()
->
Tib
.
StackBase
);
abort_thread
(
1
);
}
case
-
1
:
/* overflow */
exception_code
=
EXCEPTION_STACK_OVERFLOW
;
break
;
}
}
stack
--
;
/* push the stack_layout structure */
...
...
@@ -2051,19 +2056,18 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
}
/* check for page fault inside the thread stack */
if
(
get_trap_code
(
context
)
==
TRAP_x86_PAGEFLT
&&
(
char
*
)
siginfo
->
si_addr
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
&&
(
char
*
)
siginfo
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
&&
virtual_handle_stack_fault
(
siginfo
->
si_addr
))
if
(
get_trap_code
(
context
)
==
TRAP_x86_PAGEFLT
)
{
/* check if this was the last guard page */
if
((
char
*
)
siginfo
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
4096
)
switch
(
virtual_handle_stack_fault
(
siginfo
->
si_addr
))
{
case
1
:
/* handled */
return
;
case
-
1
:
/* overflow */
rec
=
setup_exception_record
(
context
,
stack
,
fs
,
gs
,
raise_segv_exception
);
rec
->
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
}
return
;
}
}
rec
=
setup_exception_record
(
context
,
stack
,
fs
,
gs
,
raise_segv_exception
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_STACK_OVERFLOW
)
return
;
...
...
dlls/ntdll/signal_x86_64.c
View file @
87d9fef2
...
...
@@ -2413,8 +2413,9 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
else
if
((
char
*
)(
stack
-
1
)
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackLimit
)
{
/* stack access below stack limit, may be recoverable */
if
(
virtual_handle_stack_fault
(
stack
-
1
))
exception_code
=
EXCEPTION_STACK_OVERFLOW
;
else
switch
(
virtual_handle_stack_fault
(
stack
-
1
))
{
case
0
:
/* not handled */
{
UINT
diff
=
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackLimit
-
(
char
*
)(
stack
-
1
);
ERR
(
"stack overflow %u bytes in thread %04x eip %016lx esp %016lx stack %p-%p-%p
\n
"
,
...
...
@@ -2423,6 +2424,10 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
NtCurrentTeb
()
->
Tib
.
StackLimit
,
NtCurrentTeb
()
->
Tib
.
StackBase
);
abort_thread
(
1
);
}
case
-
1
:
/* overflow */
exception_code
=
EXCEPTION_STACK_OVERFLOW
;
break
;
}
}
stack
--
;
/* push the stack_layout structure */
...
...
@@ -2940,19 +2945,18 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
ucontext_t
*
ucontext
=
sigcontext
;
/* check for page fault inside the thread stack */
if
(
TRAP_sig
(
ucontext
)
==
TRAP_x86_PAGEFLT
&&
(
char
*
)
siginfo
->
si_addr
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
&&
(
char
*
)
siginfo
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
&&
virtual_handle_stack_fault
(
siginfo
->
si_addr
))
if
(
TRAP_sig
(
ucontext
)
==
TRAP_x86_PAGEFLT
)
{
/* check if this was the last guard page */
if
((
char
*
)
siginfo
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
4096
)
switch
(
virtual_handle_stack_fault
(
siginfo
->
si_addr
))
{
case
1
:
/* handled */
return
;
case
-
1
:
/* overflow */
rec
=
setup_exception
(
sigcontext
,
raise_segv_exception
);
rec
->
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
}
return
;
}
}
rec
=
setup_exception
(
sigcontext
,
raise_segv_exception
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_STACK_OVERFLOW
)
return
;
...
...
dlls/ntdll/virtual.c
View file @
87d9fef2
...
...
@@ -2269,26 +2269,37 @@ BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size )
* virtual_handle_stack_fault
*
* Handle an access fault inside the current thread stack.
* Return 1 if safely handled, -1 if handled into the overflow space.
* Called from inside a signal handler.
*/
BOOL
virtual_handle_stack_fault
(
void
*
addr
)
int
virtual_handle_stack_fault
(
void
*
addr
)
{
BOOL
ret
=
FALSE
;
int
ret
=
0
;
if
((
char
*
)
addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
)
return
0
;
if
((
char
*
)
addr
>=
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
)
return
0
;
RtlEnterCriticalSection
(
&
csVirtual
);
/* no need for signal masking inside signal handler */
if
(
get_page_vprot
(
addr
)
&
VPROT_GUARD
)
{
size_t
guaranteed
=
max
(
NtCurrentTeb
()
->
GuaranteedStackBytes
,
page_size
*
(
is_win64
?
2
:
1
)
);
char
*
page
=
ROUND_ADDR
(
addr
,
page_mask
);
set_page_vprot_bits
(
page
,
page_size
,
0
,
VPROT_GUARD
);
mprotect_range
(
page
,
page_size
,
0
,
0
);
NtCurrentTeb
()
->
Tib
.
StackLimit
=
page
;
if
(
page
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
page_size
)
if
(
page
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
page_size
+
guaranteed
)
{
page
-=
page_size
;
set_page_vprot_bits
(
page
,
page_size
,
VPROT_COMMITTED
|
VPROT_GUARD
,
0
);
mprotect_range
(
page
,
page_size
,
0
,
0
)
;
set_page_vprot_bits
(
page
-
page_size
,
page_size
,
VPROT_COMMITTED
|
VPROT_GUARD
,
0
)
;
mprotect_range
(
page
-
page_size
,
page_size
,
0
,
0
);
ret
=
1
;
}
ret
=
TRUE
;
else
/* inside guaranteed space -> overflow exception */
{
page
=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
page_size
;
set_page_vprot_bits
(
page
,
guaranteed
,
VPROT_COMMITTED
,
VPROT_GUARD
);
mprotect_range
(
page
,
guaranteed
,
0
,
0
);
ret
=
-
1
;
}
NtCurrentTeb
()
->
Tib
.
StackLimit
=
page
;
}
RtlLeaveCriticalSection
(
&
csVirtual
);
return
ret
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment