Alexandre Julliard : ntdll: Check for file mappings that cannot be loaded as dlls.

Alexandre Julliard julliard at winehq.org
Tue Jan 30 14:38:14 CST 2018


Module: wine
Branch: master
Commit: a8a74134e852fa4dbf4d0fd59e4b82ae6b728d92
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a8a74134e852fa4dbf4d0fd59e4b82ae6b728d92

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jan 30 14:16:34 2018 +0100

ntdll: Check for file mappings that cannot be loaded as dlls.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/loader.c |  2 +-
 dlls/ntdll/loader.c          | 46 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index bd23a1c..a954de2 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -424,7 +424,7 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header, int line )
             {
                 ok( mod != NULL, "%u: loading failed err %u\n", line, GetLastError() );
             }
-            else todo_wine_if (is_win64 || is_wow64)
+            else
             {
                 ok( !mod, "%u: loading succeeded\n", line );
                 ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "%u: wrong error %u\n", line, GetLastError() );
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 2b0fefc..77a16b3 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1761,6 +1761,27 @@ static NTSTATUS perform_relocations( void *module, SIZE_T len )
     return STATUS_SUCCESS;
 }
 
+
+/* On WoW64 setups, an image mapping can also be created for the other 32/64 CPU */
+/* but it cannot necessarily be loaded as a dll, so we need some additional checks */
+static BOOL is_valid_binary( const pe_image_info_t *info )
+{
+#ifdef __i386__
+    return info->machine == IMAGE_FILE_MACHINE_I386;
+#elif defined(__x86_64__)
+    return info->machine == IMAGE_FILE_MACHINE_AMD64 || !info->contains_code;
+#elif defined(__arm__)
+    return info->machine == IMAGE_FILE_MACHINE_ARM ||
+           info->machine == IMAGE_FILE_MACHINE_THUMB ||
+           info->machine == IMAGE_FILE_MACHINE_ARMNT;
+#elif defined(__aarch64__)
+    return info->machine == IMAGE_FILE_MACHINE_ARM64 || !info->contains_code;
+#else
+    return FALSE;  /* no wow64 support on other platforms */
+#endif
+}
+
+
 /******************************************************************************
  *	load_native_dll  (internal)
  */
@@ -1774,6 +1795,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
     SIZE_T len = 0;
     WINE_MODREF *wm;
     NTSTATUS status;
+    pe_image_info_t image_info;
 
     TRACE("Trying native dll %s\n", debugstr_w(name));
 
@@ -1784,8 +1806,15 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
     if (status != STATUS_SUCCESS) return status;
 
     module = NULL;
-    status = NtMapViewOfSection( mapping, NtCurrentProcess(),
-                                 &module, 0, 0, &size, &len, ViewShare, 0, PAGE_EXECUTE_READ );
+    status = virtual_map_section( mapping, &module, 0, 0, NULL, &len, PAGE_EXECUTE_READ, &image_info );
+    NtClose( mapping );
+
+    if ((status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE) &&
+        !is_valid_binary( &image_info ))
+    {
+        NtUnmapViewOfSection( NtCurrentProcess(), module );
+        return STATUS_INVALID_IMAGE_FORMAT;
+    }
 
     /* perform base relocation, if necessary */
 
@@ -1795,15 +1824,15 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
     if (status != STATUS_SUCCESS)
     {
         if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
-        goto done;
+        return status;
     }
 
     /* create the MODREF */
 
     if (!(wm = alloc_module( module, name )))
     {
-        status = STATUS_NO_MEMORY;
-        goto done;
+        if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
+        return STATUS_NO_MEMORY;
     }
 
     set_security_cookie( module, len );
@@ -1829,7 +1858,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
              * around with no problems, so we don't care.
              * As these might reference our wm, we don't free it.
              */
-            goto done;
+            return status;
         }
     }
 
@@ -1852,10 +1881,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
 
     wm->ldr.LoadCount = 1;
     *pwm = wm;
-    status = STATUS_SUCCESS;
-done:
-    NtClose( mapping );
-    return status;
+    return STATUS_SUCCESS;
 }
 
 




More information about the wine-cvs mailing list