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