Module: wine Branch: master Commit: f6f38e24906ebbe1d22d32c62338be4354a55bd5 URL: https://gitlab.winehq.org/wine/wine/-/commit/f6f38e24906ebbe1d22d32c62338be4...
Author: Alexandre Julliard julliard@winehq.org Date: Thu May 25 11:25:40 2023 +0200
server: Return STATUS_IMAGE_MACHINE_TYPE_MISMATCH when the mapping's machine differs from the process.
---
dlls/ntdll/loader.c | 8 ++++---- dlls/ntdll/tests/wow64.c | 1 - dlls/ntdll/unix/loader.c | 8 ++++++-- dlls/ntdll/unix/process.c | 2 +- dlls/ntdll/unix/virtual.c | 1 + include/wine/server_protocol.h | 4 +++- server/mapping.c | 20 ++++++++++++-------- server/protocol.def | 1 + server/request.h | 3 ++- server/trace.c | 2 ++ 10 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index feaacea83e7..b6bf9264f08 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2630,8 +2630,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam NTSTATUS 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) return status; + if (!NT_SUCCESS(status)) return status;
if ((*pwm = find_existing_module( module ))) /* already loaded */ { @@ -2643,9 +2642,10 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam return STATUS_SUCCESS; } #ifdef _WIN64 - if (!convert_to_pe64( module, image_info )) status = STATUS_INVALID_IMAGE_FORMAT; + if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH && !convert_to_pe64( module, image_info )) + status = STATUS_INVALID_IMAGE_FORMAT; #endif - if (!status) status = build_module( load_path, nt_name, &module, image_info, id, flags, system, pwm ); + if (NT_SUCCESS(status)) status = build_module( load_path, nt_name, &module, image_info, id, flags, system, pwm ); if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module ); return status; } diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index e0df09c197c..b99b22fb1af 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -737,7 +737,6 @@ static void test_image_mappings(void) size = 0; ext.ULong = IMAGE_FILE_MACHINE_I386; status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 ); - todo_wine ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status ); NtUnmapViewOfSection( process, ptr ); NtClose( mapping ); diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 985f7a7c25a..dba8e2f614e 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1553,7 +1553,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T if (found_image) status = STATUS_NOT_SUPPORTED; WARN( "cannot find builtin library for %s\n", debugstr_us(nt_name) ); done: - if (status >= 0 && ext) + if (NT_SUCCESS(status) && ext) { strcpy( ext, ".so" ); load_builtin_unixlib( *module, ptr ); @@ -1694,7 +1694,11 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO if (!status) { status = virtual_map_module( mapping, module, &size, info, 0, machine ); - if (!status && info->u.s.ComPlusNativeReady) info->Machine = native_machine; + if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH && info->u.s.ComPlusNativeReady) + { + info->Machine = native_machine; + status = STATUS_SUCCESS; + } NtClose( mapping ); } else if (status == STATUS_INVALID_IMAGE_NOT_MZ && loadorder != LO_NATIVE) diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index dfcfc874d37..fa8022d9968 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -801,7 +801,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_ } goto done; } - if (!machine) machine = (pe_info.image_flags & IMAGE_FLAGS_ComPlusNativeReady) ? native_machine : pe_info.machine; + if (!machine) machine = pe_info.machine; if (!(startup_info = create_startup_info( attr.ObjectName, params, &startup_info_size ))) goto done; env_size = get_env_size( params, &winedebug );
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 059ce303bc0..6835f9cd645 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2810,6 +2810,7 @@ static NTSTATUS virtual_map_image( HANDLE mapping, void **addr_ptr, SIZE_T *size req->mapping = wine_server_obj_handle( mapping ); req->base = wine_server_client_ptr( view->base ); req->size = size; + req->machine = image_info->machine; status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 905425753e3..45a50106408 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1998,6 +1998,8 @@ struct map_image_view_request obj_handle_t mapping; client_ptr_t base; mem_size_t size; + unsigned short machine; + char __pad_34[6]; }; struct map_image_view_reply { @@ -6412,7 +6414,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 768 +#define SERVER_PROTOCOL_VERSION 769
/* ### protocol_version end ### */
diff --git a/server/mapping.c b/server/mapping.c index 655a686adea..bcb05ec8f8f 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -385,14 +385,10 @@ struct memory_view *get_exe_view( struct process *process )
static void set_process_machine( struct process *process, struct memory_view *view ) { - unsigned short machine = view->image.machine; - - if (machine == IMAGE_FILE_MACHINE_I386 && (view->image.image_flags & IMAGE_FLAGS_ComPlusNativeReady)) - { - if (is_machine_supported( IMAGE_FILE_MACHINE_AMD64 )) machine = IMAGE_FILE_MACHINE_AMD64; - else if (is_machine_supported( IMAGE_FILE_MACHINE_ARM64 )) machine = IMAGE_FILE_MACHINE_ARM64; - } - process->machine = machine; + if (view->image.image_flags & IMAGE_FLAGS_ComPlusNativeReady) + process->machine = native_machine; + else + process->machine = view->image.machine; }
static int generate_dll_event( struct thread *thread, int code, struct memory_view *view ) @@ -1274,8 +1270,16 @@ DECL_HANDLER(map_image_view) view->committed = NULL; view->shared = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL; view->image = mapping->image; + view->image.machine = req->machine; add_process_view( current, view ); + if (view->base != mapping->image.base) set_error( STATUS_IMAGE_NOT_AT_BASE ); + if (view->image.machine != current->process->machine) + { + /* on 32-bit, the native 64-bit machine is allowed */ + if (is_machine_64bit( current->process->machine ) || view->image.machine != native_machine) + set_error( STATUS_IMAGE_MACHINE_TYPE_MISMATCH ); + } }
done: diff --git a/server/protocol.def b/server/protocol.def index 950b98a4e23..95ddb1d5011 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1612,6 +1612,7 @@ enum server_fd_type obj_handle_t mapping; /* file mapping handle */ client_ptr_t base; /* view base address (page-aligned) */ mem_size_t size; /* view size */ + unsigned short machine; /* machine in the mapped view */ @END
diff --git a/server/request.h b/server/request.h index 2f430e16cfb..bb1863b2b85 100644 --- a/server/request.h +++ b/server/request.h @@ -1126,7 +1126,8 @@ C_ASSERT( sizeof(struct map_view_request) == 48 ); C_ASSERT( FIELD_OFFSET(struct map_image_view_request, mapping) == 12 ); C_ASSERT( FIELD_OFFSET(struct map_image_view_request, base) == 16 ); C_ASSERT( FIELD_OFFSET(struct map_image_view_request, size) == 24 ); -C_ASSERT( sizeof(struct map_image_view_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct map_image_view_request, machine) == 32 ); +C_ASSERT( sizeof(struct map_image_view_request) == 40 ); C_ASSERT( sizeof(struct map_builtin_view_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct unmap_view_request, base) == 16 ); C_ASSERT( sizeof(struct unmap_view_request) == 24 ); diff --git a/server/trace.c b/server/trace.c index 54dd40c3a62..93c98b85590 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2185,6 +2185,7 @@ static void dump_map_image_view_request( const struct map_image_view_request *re fprintf( stderr, " mapping=%04x", req->mapping ); dump_uint64( ", base=", &req->base ); dump_uint64( ", size=", &req->size ); + fprintf( stderr, ", machine=%04x", req->machine ); }
static void dump_map_builtin_view_request( const struct map_builtin_view_request *req ) @@ -5436,6 +5437,7 @@ static const struct { "HANDLE_NOT_CLOSABLE", STATUS_HANDLE_NOT_CLOSABLE }, { "HOST_UNREACHABLE", STATUS_HOST_UNREACHABLE }, { "ILLEGAL_FUNCTION", STATUS_ILLEGAL_FUNCTION }, + { "IMAGE_MACHINE_TYPE_MISMATCH", STATUS_IMAGE_MACHINE_TYPE_MISMATCH }, { "IMAGE_NOT_AT_BASE", STATUS_IMAGE_NOT_AT_BASE }, { "INFO_LENGTH_MISMATCH", STATUS_INFO_LENGTH_MISMATCH }, { "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },