[PATCH v2] ntdll: Catch page fault in RtlWow64EnableFsRedirectionEx

Matt Robinson git at nerdoftheherd.com
Sat Aug 6 17:00:21 CDT 2016


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 <git at nerdoftheherd.com>
---
 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




More information about the wine-patches mailing list