ntdll: Try to handle write-watches while we're on the signal stack.
This commit is contained in:
parent
1896064332
commit
6bec132c7a
|
@ -169,7 +169,7 @@ extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_
|
||||||
extern void virtual_clear_thread_stack(void) DECLSPEC_HIDDEN;
|
extern void virtual_clear_thread_stack(void) DECLSPEC_HIDDEN;
|
||||||
extern BOOL virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN;
|
extern BOOL virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) 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 ) DECLSPEC_HIDDEN;
|
extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size ) DECLSPEC_HIDDEN;
|
extern BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size ) DECLSPEC_HIDDEN;
|
extern BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||||
extern SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ) DECLSPEC_HIDDEN;
|
extern SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -443,7 +443,7 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
|
||||||
if (rec->NumberParameters == 2)
|
if (rec->NumberParameters == 2)
|
||||||
{
|
{
|
||||||
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
||||||
rec->ExceptionInformation[0] )))
|
rec->ExceptionInformation[0], FALSE )))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -326,7 +326,7 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
|
||||||
if (rec->NumberParameters == 2)
|
if (rec->NumberParameters == 2)
|
||||||
{
|
{
|
||||||
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
||||||
rec->ExceptionInformation[0] )))
|
rec->ExceptionInformation[0], FALSE )))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1907,7 +1907,7 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
|
||||||
if (rec->ExceptionInformation[1] == 0xffffffff && check_invalid_gs( context ))
|
if (rec->ExceptionInformation[1] == 0xffffffff && check_invalid_gs( context ))
|
||||||
goto done;
|
goto done;
|
||||||
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
||||||
rec->ExceptionInformation[0] )))
|
rec->ExceptionInformation[0], FALSE )))
|
||||||
goto done;
|
goto done;
|
||||||
if (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
|
if (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
|
||||||
rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
|
rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
|
||||||
|
@ -2046,6 +2046,15 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||||
ucontext_t *context = sigcontext;
|
ucontext_t *context = sigcontext;
|
||||||
void *stack = init_handler( sigcontext, &fs, &gs );
|
void *stack = init_handler( sigcontext, &fs, &gs );
|
||||||
|
|
||||||
|
/* check for exceptions on the signal stack caused by write watches */
|
||||||
|
if (get_trap_code(context) == TRAP_x86_PAGEFLT &&
|
||||||
|
(char *)stack >= (char *)get_signal_stack() &&
|
||||||
|
(char *)stack < (char *)get_signal_stack() + signal_stack_size &&
|
||||||
|
!virtual_handle_fault( siginfo->si_addr, (get_error_code(context) >> 1) & 0x09, TRUE ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* check for page fault inside the thread stack */
|
/* check for page fault inside the thread stack */
|
||||||
if (get_trap_code(context) == TRAP_x86_PAGEFLT &&
|
if (get_trap_code(context) == TRAP_x86_PAGEFLT &&
|
||||||
(char *)siginfo->si_addr >= (char *)NtCurrentTeb()->DeallocationStack &&
|
(char *)siginfo->si_addr >= (char *)NtCurrentTeb()->DeallocationStack &&
|
||||||
|
|
|
@ -678,7 +678,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||||
rec.NumberParameters = 2;
|
rec.NumberParameters = 2;
|
||||||
rec.ExceptionInformation[0] = 0; /* FIXME ? */
|
rec.ExceptionInformation[0] = 0; /* FIXME ? */
|
||||||
rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
|
rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
|
||||||
if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0])))
|
if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0], FALSE)))
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -701,7 +701,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||||
rec.NumberParameters = 2;
|
rec.NumberParameters = 2;
|
||||||
rec.ExceptionInformation[0] = 0; /* FIXME ? */
|
rec.ExceptionInformation[0] = 0; /* FIXME ? */
|
||||||
rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
|
rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
|
||||||
if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0])))
|
if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0], FALSE)))
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2286,7 +2286,7 @@ static void raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
if (rec->NumberParameters == 2)
|
if (rec->NumberParameters == 2)
|
||||||
{
|
{
|
||||||
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
||||||
rec->ExceptionInformation[0] )))
|
rec->ExceptionInformation[0], FALSE )))
|
||||||
set_cpu_context( context );
|
set_cpu_context( context );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1521,7 +1521,7 @@ void virtual_clear_thread_stack(void)
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* virtual_handle_fault
|
* virtual_handle_fault
|
||||||
*/
|
*/
|
||||||
NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err )
|
NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
|
||||||
{
|
{
|
||||||
struct file_view *view;
|
struct file_view *view;
|
||||||
NTSTATUS ret = STATUS_ACCESS_VIOLATION;
|
NTSTATUS ret = STATUS_ACCESS_VIOLATION;
|
||||||
|
@ -1542,7 +1542,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err )
|
||||||
/* ignore fault if page is writable now */
|
/* ignore fault if page is writable now */
|
||||||
if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
if (*vprot & VPROT_GUARD)
|
if (!on_signal_stack && (*vprot & VPROT_GUARD))
|
||||||
{
|
{
|
||||||
VIRTUAL_SetProt( view, page, page_size, *vprot & ~VPROT_GUARD );
|
VIRTUAL_SetProt( view, page, page_size, *vprot & ~VPROT_GUARD );
|
||||||
ret = STATUS_GUARD_PAGE_VIOLATION;
|
ret = STATUS_GUARD_PAGE_VIOLATION;
|
||||||
|
|
Loading…
Reference in New Issue