ntdll: Avoid recursive exception handler calls when handling guard pages.
The ATL check leads to problems when a page is protected with guard page protection. raise_segv_exception is called with EXCEPTION_EXECUTE_FAULT. The ATL check tries to read the memory, and triggers another exception handler. This time the virtual_handle_fault check is executed, and removes the guard page protection. Afterwards, when the ATL check returns, the exception is _not_ catched by virtual_handle_fault, but instead passed to the application.
This commit is contained in:
parent
9a806d0f1c
commit
0cf3d78167
|
@ -1818,7 +1818,6 @@ static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTR
|
|||
if (rec->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
|
||||
{
|
||||
|
||||
todo_wine
|
||||
ok( rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT ||
|
||||
broken(!(flags & MEM_EXECUTE_OPTION_DISABLE) && rec->ExceptionInformation[0] == EXCEPTION_READ_FAULT), /* Windows 2000 */
|
||||
"ExceptionInformation[0] is %d instead of %d\n", (DWORD)rec->ExceptionInformation[0], EXCEPTION_EXECUTE_FAULT );
|
||||
|
@ -1971,7 +1970,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
|||
if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
|
||||
else
|
||||
todo_wine
|
||||
ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
|
||||
|
||||
ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
|
||||
|
|
|
@ -1821,17 +1821,19 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
|
|||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
if (rec->NumberParameters == 2)
|
||||
{
|
||||
if (rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT && check_atl_thunk( rec, context ))
|
||||
goto done;
|
||||
if (rec->ExceptionInformation[1] == 0xffffffff && check_invalid_gs( context ))
|
||||
goto done;
|
||||
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
|
||||
rec->ExceptionInformation[0] )))
|
||||
goto done;
|
||||
/* send EXCEPTION_EXECUTE_FAULT only if data execution prevention is enabled */
|
||||
if (rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
|
||||
if (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
|
||||
rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
|
||||
{
|
||||
ULONG flags;
|
||||
if (check_atl_thunk( rec, context ))
|
||||
goto done;
|
||||
|
||||
/* send EXCEPTION_EXECUTE_FAULT only if data execution prevention is enabled */
|
||||
NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags,
|
||||
&flags, sizeof(flags), NULL );
|
||||
if (!(flags & MEM_EXECUTE_OPTION_DISABLE))
|
||||
|
|
Loading…
Reference in New Issue