From: Matt Robinson Subject: [PATCH v2] ntdll: Catch page fault in RtlWow64EnableFsRedirectionEx Message-Id: <1470520821-25208-1-git-send-email-git@nerdoftheherd.com> Date: Sat, 6 Aug 2016 23:00:21 +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. v2: Remove old pointer check as the new code supersedes this. Thanks to Nikolay Sivov & André Hentschel for their feedback. Fixes https://bugs.winehq.org/show_bug.cgi?id=41066 Signed-off-by: Matt Robinson --- dlls/ntdll/directory.c | 13 +++++++++++-- dlls/ntdll/tests/directory.c | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 4a34475..a945e11 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); @@ -2996,9 +2997,17 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirection( BOOLEAN enable ) 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