server: Return STATUS_IMAGE_MACHINE_TYPE_MISMATCH when the mapping's machine differs from the process.

This commit is contained in:
Alexandre Julliard 2023-05-25 11:25:40 +02:00
parent c306e76645
commit f6f38e2490
10 changed files with 32 additions and 18 deletions

View file

@ -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;
}

View file

@ -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 );

View file

@ -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)

View file

@ -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 );

View file

@ -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;

View file

@ -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 ### */

View file

@ -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:

View file

@ -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

View file

@ -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 );

View file

@ -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 },