From: Matt Robinson Subject: [PATCH] ntdll: Catch page fault in RtlWow64EnableFsRedirectionEx Message-Id: <1470330341-29610-1-git-send-email-git@nerdoftheherd.com> Date: Thu, 4 Aug 2016 18:05:41 +0100 Previously, RtlWow64EnableFsRedirectionEx only returned STATUS_NOT_IMPLEMENTED if the old_value pointer started with 0x0000, and would cause an unhandled page fault if an invalid handle not starting with 0x00 was passed. However, Windows seems to catch page faults when accessing old_value and returns STATUS_ACCESS_VIOLATION. This adds a test to confirm the behaviour and then wraps the access to old_value in an exception handler. Fixes https://bugs.winehq.org/show_bug.cgi?id=41066 Signed-off-by: Matt Robinson --- dlls/ntdll/directory.c | 12 +++++++++++- dlls/ntdll/tests/directory.c | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 4a34475..13df0d1 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -106,6 +106,7 @@ #include "wine/list.h" #include "wine/library.h" #include "wine/debug.h" +#include "wine/exception.h" WINE_DEFAULT_DEBUG_CHANNEL(file); @@ -2998,7 +2999,16 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value ) if (!is_wow64) return STATUS_NOT_IMPLEMENTED; if (((ULONG_PTR)old_value >> 16) == 0) return STATUS_ACCESS_VIOLATION; - *old_value = !ntdll_get_thread_data()->wow64_redir; + __TRY + { + *old_value = !ntdll_get_thread_data()->wow64_redir; + } + __EXCEPT_PAGE_FAULT + { + return STATUS_ACCESS_VIOLATION; + } + __ENDTRY + ntdll_get_thread_data()->wow64_redir = !disable; return STATUS_SUCCESS; } diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c index a135d4f..d39b488 100644 --- a/dlls/ntdll/tests/directory.c +++ b/dlls/ntdll/tests/directory.c @@ -861,6 +861,8 @@ static void test_redirection(void) ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 ); ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); + status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)0xDEADBEEF ); + ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); status = pRtlWow64EnableFsRedirection( FALSE ); ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); -- 2.7.4