From 63b62953683fc62e95d5df8cb975009554aff1a3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 21 Jan 2021 13:41:16 +0100 Subject: [PATCH] ntdll: Check for valid architecture before mapping the module. Signed-off-by: Alexandre Julliard --- dlls/ntdll/loader.c | 33 +++++++++++++++--------------- dlls/ntdll/unix/loader.c | 43 +++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index fa757fefa90..fec33c8017c 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1985,6 +1985,8 @@ static BOOL convert_to_pe64( HMODULE module, const SECTION_IMAGE_INFORMATION *in void *addr = module; ULONG i, old_prot; + if (nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return TRUE; /* already 64-bit */ + TRACE( "%p\n", module ); if (NtProtectVirtualMemory( NtCurrentProcess(), &addr, &size, PAGE_READWRITE, &old_prot )) @@ -2304,34 +2306,31 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm, void SECTION_MAP_READ | SECTION_MAP_EXECUTE, NULL, &size, PAGE_EXECUTE_READ, SEC_IMAGE, handle ); if (!status) + { + NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL ); + if (!is_valid_binary( handle, image_info )) + { + TRACE( "%s is for arch %x, continuing search\n", debugstr_us(nt_name), image_info->Machine ); + status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; + NtClose( mapping ); + } + } + NtClose( handle ); + if (!status) { if (*module) { NtUnmapViewOfSection( NtCurrentProcess(), *module ); *module = NULL; } - NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL ); status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len, ViewShare, 0, PAGE_EXECUTE_READ ); if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS; +#ifdef _WIN64 + if (!status && !convert_to_pe64( *module, image_info )) status = STATUS_INVALID_IMAGE_FORMAT; +#endif NtClose( mapping ); } - if (!status && !is_valid_binary( handle, image_info )) - { - TRACE( "%s is for arch %x, continuing search\n", debugstr_us(nt_name), image_info->Machine ); - NtUnmapViewOfSection( NtCurrentProcess(), *module ); - *module = NULL; - status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; - } -#ifdef _WIN64 - if (!status && - image_info->Machine != IMAGE_FILE_MACHINE_AMD64 && - image_info->Machine != IMAGE_FILE_MACHINE_ARM64) - { - if (!convert_to_pe64( *module, image_info )) status = STATUS_INVALID_IMAGE_FORMAT; - } -#endif - NtClose( handle ); return status; } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 43c769f2d2a..972793ac3e9 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1077,7 +1077,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module ) /* check a PE library architecture */ -static BOOL is_valid_binary( HMODULE module, const SECTION_IMAGE_INFORMATION *info ) +static BOOL is_valid_binary( const SECTION_IMAGE_INFORMATION *info ) { #ifdef __i386__ return info->Machine == IMAGE_FILE_MACHINE_I386; @@ -1138,7 +1138,7 @@ static inline char *prepend( char *buffer, const char *str, size_t len ) /*********************************************************************** * open_dll_file * - * Open a file for a new dll. Helper for find_dll_file. + * Open a file for a new dll. Helper for open_builtin_file. */ static NTSTATUS open_dll_file( const char *name, void **module, SECTION_IMAGE_INFORMATION *image_info ) { @@ -1187,37 +1187,40 @@ static NTSTATUS open_dll_file( const char *name, void **module, SECTION_IMAGE_IN NtClose( handle ); if (status) return status; - if (*module) - { - NtUnmapViewOfSection( NtCurrentProcess(), *module ); - *module = NULL; - } NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL ); - status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len, - ViewShare, 0, PAGE_EXECUTE_READ ); - if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS; - NtClose( mapping ); - if (status) return status; - /* ignore non-builtins */ if (!(image_info->u.ImageFlags & IMAGE_FLAGS_WineBuiltin)) { WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) ); status = STATUS_DLL_NOT_FOUND; } - else if (!is_valid_binary( *module, image_info )) + else if (!is_valid_binary( image_info )) { TRACE( "%s is for arch %x, continuing search\n", debugstr_a(name), image_info->Machine ); status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; } - - if (!status) status = add_builtin_module( *module, NULL, &st ); - - if (status) + else { - NtUnmapViewOfSection( NtCurrentProcess(), *module ); - *module = NULL; + if (*module) + { + NtUnmapViewOfSection( NtCurrentProcess(), *module ); + *module = NULL; + } + status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len, + ViewShare, 0, PAGE_EXECUTE_READ ); + if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS; + + if (!status) + { + status = add_builtin_module( *module, NULL, &st ); + if (status) + { + NtUnmapViewOfSection( NtCurrentProcess(), *module ); + *module = NULL; + } + } } + NtClose( mapping ); return status; }