server: Check PE file architecture at mapping creation time.
This commit is contained in:
parent
55eb7e56e8
commit
e8eb781327
|
@ -599,31 +599,31 @@ todo_wine
|
|||
|
||||
dos_header.e_magic = 0;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection error %08x\n", status );
|
||||
|
||||
dos_header.e_magic = IMAGE_DOS_SIGNATURE;
|
||||
nt_header.Signature = IMAGE_OS2_SIGNATURE;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.Signature = 0xdeadbeef;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.Signature = IMAGE_NT_SIGNATURE;
|
||||
nt_header.OptionalHeader.Magic = 0xdead;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
|
||||
nt_header.FileHeader.Machine = 0xdead;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
switch (orig_machine)
|
||||
|
@ -634,7 +634,7 @@ todo_wine
|
|||
case IMAGE_FILE_MACHINE_ARM64: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; break;
|
||||
}
|
||||
status = map_image_section( &nt_header );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
if (nt_header.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
|
@ -656,7 +656,7 @@ todo_wine
|
|||
nt64.OptionalHeader.SizeOfImage = nt64.OptionalHeader.SizeOfHeaders + 0x1000;
|
||||
nt64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64 );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -677,7 +677,7 @@ todo_wine
|
|||
nt32.OptionalHeader.SizeOfImage = nt32.OptionalHeader.SizeOfHeaders + 0x1000;
|
||||
nt32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32 );
|
||||
todo_wine ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
}
|
||||
|
||||
nt_header.FileHeader.Machine = orig_machine; /* restore it for the next tests */
|
||||
|
|
|
@ -2000,7 +2000,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
|||
else
|
||||
{
|
||||
nts = load_native_dll( load_path, filename, handle, flags, pwm );
|
||||
if (nts == STATUS_INVALID_FILE_FOR_SECTION)
|
||||
if (nts == STATUS_INVALID_IMAGE_NOT_MZ)
|
||||
/* not in PE format, maybe it's a builtin */
|
||||
nts = load_builtin_dll( load_path, filename, handle, flags, pwm );
|
||||
}
|
||||
|
|
|
@ -1031,67 +1031,6 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* check_architecture
|
||||
*
|
||||
* Check the architecture of a PE binary.
|
||||
*/
|
||||
static NTSTATUS check_architecture( const IMAGE_NT_HEADERS *nt )
|
||||
{
|
||||
static const char *arch;
|
||||
|
||||
#ifdef __i386__
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) return STATUS_SUCCESS;
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) /* don't warn for a 64-bit exe */
|
||||
WARN( "loading amd64 dll in 32-bit mode will fail\n" );
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) return STATUS_SUCCESS;
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
||||
{
|
||||
if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) /* don't warn for a 32-bit exe */
|
||||
WARN( "loading 32-bit dll in 64-bit mode will fail\n" );
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
#elif defined(__arm__) && !defined(__ARMEB__)
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM ||
|
||||
nt->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB)
|
||||
return STATUS_SUCCESS;
|
||||
if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_ARMNT)
|
||||
{
|
||||
SYSTEM_CPU_INFORMATION sci;
|
||||
if (SUCCEEDED(NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL )) &&
|
||||
sci.Architecture == PROCESSOR_ARCHITECTURE_ARM && sci.Level >= 7)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (nt->FileHeader.Machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_UNKNOWN: arch = "Unknown"; break;
|
||||
case IMAGE_FILE_MACHINE_I860: arch = "I860"; break;
|
||||
case IMAGE_FILE_MACHINE_I386: arch = "I386"; break;
|
||||
case IMAGE_FILE_MACHINE_R3000: arch = "R3000"; break;
|
||||
case IMAGE_FILE_MACHINE_R4000: arch = "R4000"; break;
|
||||
case IMAGE_FILE_MACHINE_R10000: arch = "R10000"; break;
|
||||
case IMAGE_FILE_MACHINE_ALPHA: arch = "Alpha"; break;
|
||||
case IMAGE_FILE_MACHINE_POWERPC: arch = "PowerPC"; break;
|
||||
case IMAGE_FILE_MACHINE_IA64: arch = "IA-64"; break;
|
||||
case IMAGE_FILE_MACHINE_ALPHA64: arch = "Alpha-64"; break;
|
||||
case IMAGE_FILE_MACHINE_AMD64: arch = "AMD-64"; break;
|
||||
case IMAGE_FILE_MACHINE_ARM: arch = "ARM"; break;
|
||||
case IMAGE_FILE_MACHINE_ARMNT: arch = "ARMNT"; break;
|
||||
case IMAGE_FILE_MACHINE_THUMB: arch = "ARM Thumb"; break;
|
||||
default: arch = wine_dbg_sprintf( "Unknown-%04x", nt->FileHeader.Machine ); break;
|
||||
}
|
||||
ERR( "Trying to load PE image for unsupported architecture %s\n", arch );
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* stat_mapping_file
|
||||
*
|
||||
|
@ -1179,8 +1118,6 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
|
|||
imports = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;
|
||||
if (!imports->Size || !imports->VirtualAddress) imports = NULL;
|
||||
|
||||
if (check_architecture( nt )) goto error;
|
||||
|
||||
/* check for non page-aligned binary */
|
||||
|
||||
if (nt->OptionalHeader.SectionAlignment <= page_mask)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "file.h"
|
||||
#include "handle.h"
|
||||
#include "thread.h"
|
||||
#include "process.h"
|
||||
#include "request.h"
|
||||
#include "security.h"
|
||||
|
||||
|
@ -60,6 +61,7 @@ struct mapping
|
|||
mem_size_t size; /* mapping size */
|
||||
int protect; /* protection flags */
|
||||
struct fd *fd; /* fd for mapped file */
|
||||
enum cpu_type cpu; /* client CPU (for PE image mapping) */
|
||||
int header_size; /* size of headers (for PE image mapping) */
|
||||
client_ptr_t base; /* default base addr (for PE image mapping) */
|
||||
struct ranges *committed; /* list of committed ranges in this mapping */
|
||||
|
@ -366,7 +368,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
|
|||
}
|
||||
|
||||
/* retrieve the mapping parameters for an executable (PE) image */
|
||||
static int get_image_params( struct mapping *mapping, int unix_fd, int protect )
|
||||
static unsigned int get_image_params( struct mapping *mapping, int unix_fd, int protect )
|
||||
{
|
||||
IMAGE_DOS_HEADER dos;
|
||||
IMAGE_SECTION_HEADER *sec = NULL;
|
||||
|
@ -385,15 +387,48 @@ static int get_image_params( struct mapping *mapping, int unix_fd, int protect )
|
|||
|
||||
/* load the headers */
|
||||
|
||||
if (pread( unix_fd, &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
|
||||
if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
|
||||
if (pread( unix_fd, &dos, sizeof(dos), 0 ) != sizeof(dos)) return STATUS_INVALID_IMAGE_NOT_MZ;
|
||||
if (dos.e_magic != IMAGE_DOS_SIGNATURE) return STATUS_INVALID_IMAGE_NOT_MZ;
|
||||
pos = dos.e_lfanew;
|
||||
|
||||
size = pread( unix_fd, &nt, sizeof(nt), pos );
|
||||
if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) goto error;
|
||||
if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
/* zero out Optional header in the case it's not present or partial */
|
||||
if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
|
||||
if (nt.Signature != IMAGE_NT_SIGNATURE) goto error;
|
||||
if (nt.Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
if (*(WORD *)&nt.Signature == IMAGE_OS2_SIGNATURE) return STATUS_INVALID_IMAGE_NE_FORMAT;
|
||||
return STATUS_INVALID_IMAGE_PROTECT;
|
||||
}
|
||||
|
||||
mapping->cpu = current->process->cpu;
|
||||
switch (mapping->cpu)
|
||||
{
|
||||
case CPU_x86:
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_I386) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
break;
|
||||
case CPU_x86_64:
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_POWERPC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
break;
|
||||
case CPU_ARM:
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM &&
|
||||
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB &&
|
||||
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARMNT) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
break;
|
||||
case CPU_ARM64:
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM64) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
break;
|
||||
default:
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
switch (nt.opt.hdr32.Magic)
|
||||
{
|
||||
|
@ -407,8 +442,6 @@ static int get_image_params( struct mapping *mapping, int unix_fd, int protect )
|
|||
mapping->base = nt.opt.hdr64.ImageBase;
|
||||
mapping->header_size = nt.opt.hdr64.SizeOfHeaders;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* load the section headers */
|
||||
|
@ -426,12 +459,11 @@ static int get_image_params( struct mapping *mapping, int unix_fd, int protect )
|
|||
|
||||
mapping->protect = protect;
|
||||
free( sec );
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free( sec );
|
||||
set_error( STATUS_INVALID_FILE_FOR_SECTION );
|
||||
return 0;
|
||||
return STATUS_INVALID_FILE_FOR_SECTION;
|
||||
}
|
||||
|
||||
static struct object *create_mapping( struct directory *root, const struct unicode_str *name,
|
||||
|
@ -494,8 +526,10 @@ static struct object *create_mapping( struct directory *root, const struct unico
|
|||
if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
|
||||
if (protect & VPROT_IMAGE)
|
||||
{
|
||||
if (!get_image_params( mapping, unix_fd, protect )) goto error;
|
||||
return &mapping->obj;
|
||||
unsigned int err = get_image_params( mapping, unix_fd, protect );
|
||||
if (!err) return &mapping->obj;
|
||||
set_error( err );
|
||||
goto error;
|
||||
}
|
||||
if (fstat( unix_fd, &st ) == -1)
|
||||
{
|
||||
|
@ -680,8 +714,15 @@ DECL_HANDLER(get_mapping_info)
|
|||
struct mapping *mapping;
|
||||
struct fd *fd;
|
||||
|
||||
if ((mapping = get_mapping_obj( current->process, req->handle, req->access )))
|
||||
if (!(mapping = get_mapping_obj( current->process, req->handle, req->access ))) return;
|
||||
|
||||
if ((mapping->protect & VPROT_IMAGE) && mapping->cpu != current->process->cpu)
|
||||
{
|
||||
set_error( STATUS_INVALID_IMAGE_FORMAT );
|
||||
release_object( mapping );
|
||||
return;
|
||||
}
|
||||
|
||||
reply->size = mapping->size;
|
||||
reply->protect = mapping->protect;
|
||||
reply->header_size = mapping->header_size;
|
||||
|
@ -689,8 +730,7 @@ DECL_HANDLER(get_mapping_info)
|
|||
reply->shared_file = 0;
|
||||
if ((fd = get_obj_fd( &mapping->obj )))
|
||||
{
|
||||
if (!is_fd_removable(fd))
|
||||
reply->mapping = alloc_handle( current->process, mapping, 0, 0 );
|
||||
if (!is_fd_removable(fd)) reply->mapping = alloc_handle( current->process, mapping, 0, 0 );
|
||||
release_object( fd );
|
||||
}
|
||||
if (mapping->shared_file)
|
||||
|
@ -702,7 +742,6 @@ DECL_HANDLER(get_mapping_info)
|
|||
}
|
||||
}
|
||||
release_object( mapping );
|
||||
}
|
||||
}
|
||||
|
||||
/* get a range of committed pages in a file mapping */
|
||||
|
|
Loading…
Reference in New Issue