server: Avoid rounding mapping sizes on the server side.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-07-27 16:49:37 +09:00
parent 24b49c4775
commit 32c7153fdb
7 changed files with 95 additions and 20 deletions

View File

@ -225,11 +225,13 @@ static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size,
static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header )
{
SECTION_BASIC_INFORMATION info;
SECTION_IMAGE_INFORMATION image;
ULONG info_size = 0xdeadbeef;
NTSTATUS status;
HANDLE file, mapping;
ULONG file_size;
LARGE_INTEGER map_size;
/* truncated header is not handled correctly in windows <= w2k3 */
BOOL truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(nt_header->OptionalHeader);
@ -288,7 +290,45 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
/* image.GpValue */
/* image.ImageFlags */
/* image.ImageContainsCode */
map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
CloseHandle( mapping );
map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
status = pNtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
CloseHandle( mapping );
map_size.QuadPart++;
status = pNtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %x\n", id, status );
SetFilePointerEx( file, map_size, NULL, FILE_BEGIN );
SetEndOfFile( file );
status = pNtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %x\n", id, status );
map_size.QuadPart = 1;
status = pNtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
CloseHandle( mapping );
CloseHandle( file );
}
@ -322,7 +362,6 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
ok( info_size == sizeof(info), "NtQuerySection wrong size %u\n", info_size );
ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %x\n", info.Attributes );
ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress );
todo_wine
ok( info.Size.QuadPart == size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
info.Size.u.HighPart, info.Size.u.LowPart, size.u.HighPart, size.u.LowPart );
query_image_section( 1000, dll_name, nt_header );

View File

@ -992,7 +992,6 @@ static void test_MapViewOfFile(void)
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 36, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
@ -1008,7 +1007,6 @@ static void test_MapViewOfFile(void)
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 0x3456, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
@ -1019,6 +1017,10 @@ static void test_MapViewOfFile(void)
todo_wine
ok( status == STATUS_SECTION_TOO_BIG, "NtCreateSection failed %x\n", status );
if (!status) CloseHandle( mapping );
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
&map_size, PAGE_READONLY, SEC_IMAGE, file );
ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection failed %x\n", status );
if (!status) CloseHandle( mapping );
map_size.QuadPart = 0x3452;
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
&map_size, PAGE_READONLY, SEC_COMMIT, file );
@ -1028,9 +1030,17 @@ static void test_MapViewOfFile(void)
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 0x3452, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
size = map_size.QuadPart;
status = pNtMapViewOfSection( mapping, GetCurrentProcess(), &ptr, 0, 0, NULL,
&size, ViewShare, 0, PAGE_READONLY );
ok( !status, "NtMapViewOfSection failed err %x\n", status );
pNtUnmapViewOfSection( GetCurrentProcess(), ptr );
size = map_size.QuadPart + 1;
status = pNtMapViewOfSection( mapping, GetCurrentProcess(), &ptr, 0, 0, NULL,
&size, ViewShare, 0, PAGE_READONLY );
ok( status == STATUS_INVALID_VIEW_SIZE, "NtMapViewOfSection failed err %x\n", status );
CloseHandle(mapping);
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
@ -1055,6 +1065,15 @@ static void test_MapViewOfFile(void)
ok( status == STATUS_SECTION_NOT_IMAGE, "NtQuerySection failed err %x\n", status );
CloseHandle(mapping);
SetFilePointer(file, 0, NULL, FILE_BEGIN);
SetEndOfFile(file);
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
NULL, PAGE_READONLY, SEC_COMMIT, file );
ok( status == STATUS_MAPPED_FILE_SIZE_ZERO, "NtCreateSection failed %x\n", status );
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
NULL, PAGE_READONLY, SEC_IMAGE, file );
ok( status == STATUS_INVALID_FILE_FOR_SECTION, "NtCreateSection failed %x\n", status );
CloseHandle(file);
DeleteFileA(testfile);
}

View File

@ -2636,10 +2636,11 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
void *base = wine_server_get_ptr( image_info.base );
if ((ULONG_PTR)base != image_info.base) base = NULL;
size = full_size;
if (size != full_size) /* truncated */
size = image_info.map_size;
if (size != image_info.map_size) /* truncated */
{
WARN( "Modules larger than 4Gb (%s) not supported\n", wine_dbgstr_longlong(full_size) );
WARN( "Modules larger than 4Gb (%s) not supported\n",
wine_dbgstr_longlong(image_info.map_size) );
res = STATUS_INVALID_PARAMETER;
goto done;
}
@ -2668,9 +2669,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
if (offset.QuadPart >= full_size) goto done;
if (*size_ptr)
{
if (*size_ptr > full_size - offset.QuadPart) goto done;
size = ROUND_SIZE( offset.u.LowPart, *size_ptr );
if (size < *size_ptr) goto done; /* wrap-around */
size = *size_ptr;
if (size > full_size - offset.QuadPart)
{
res = STATUS_INVALID_VIEW_SIZE;
goto done;
}
}
else
{
@ -2682,6 +2686,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
goto done;
}
}
if (!(size = ROUND_SIZE( 0, size ))) goto done; /* wrap-around */
/* Reserve a properly aligned area */

View File

@ -682,6 +682,7 @@ typedef struct
{
client_ptr_t base;
client_ptr_t entry_point;
mem_size_t map_size;
mem_size_t stack_size;
mem_size_t stack_commit;
unsigned int zerobits;
@ -6244,6 +6245,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 506
#define SERVER_PROTOCOL_VERSION 507
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -391,6 +391,7 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
/* load the headers */
if (!file_size) return STATUS_INVALID_FILE_FOR_SECTION;
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;
@ -438,9 +439,9 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
switch (nt.opt.hdr32.Magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
mapping->image.base = nt.opt.hdr32.ImageBase;
mapping->image.entry_point = nt.opt.hdr32.ImageBase + nt.opt.hdr32.AddressOfEntryPoint;
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
mapping->image.stack_size = nt.opt.hdr32.SizeOfStackReserve;
mapping->image.stack_commit = nt.opt.hdr32.SizeOfStackCommit;
mapping->image.subsystem = nt.opt.hdr32.Subsystem;
@ -452,9 +453,9 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
mapping->image.checksum = nt.opt.hdr32.CheckSum;
break;
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
mapping->image.base = nt.opt.hdr64.ImageBase;
mapping->image.entry_point = nt.opt.hdr64.ImageBase + nt.opt.hdr64.AddressOfEntryPoint;
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
mapping->image.stack_size = nt.opt.hdr64.SizeOfStackReserve;
mapping->image.stack_commit = nt.opt.hdr64.SizeOfStackCommit;
mapping->image.subsystem = nt.opt.hdr64.Subsystem;
@ -478,7 +479,9 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
if (pos + size > mapping->size) goto error;
if (!mapping->size) mapping->size = mapping->image.map_size;
else if (mapping->size > mapping->image.map_size) return STATUS_SECTION_TOO_BIG;
if (pos + size > mapping->image.map_size) return STATUS_INVALID_FILE_FOR_SECTION;
if (pos + size > mapping->image.header_size) mapping->image.header_size = pos + size;
if (!(sec = malloc( size ))) goto error;
if (pread( unix_fd, sec, size, pos ) != size) goto error;
@ -513,6 +516,7 @@ static struct object *create_mapping( struct object *root, const struct unicode_
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
return &mapping->obj; /* Nothing else to do */
mapping->size = size;
mapping->flags = flags & (SEC_IMAGE | SEC_NOCACHE | SEC_WRITECOMBINE | SEC_LARGE_PAGES);
mapping->protect = protect;
mapping->fd = NULL;
@ -562,19 +566,19 @@ static struct object *create_mapping( struct object *root, const struct unicode_
set_error( err );
goto error;
}
if (!size)
if (!mapping->size)
{
if (!(size = st.st_size))
if (!(mapping->size = st.st_size))
{
set_error( STATUS_MAPPED_FILE_SIZE_ZERO );
goto error;
}
}
else if (st.st_size < size && !grow_file( unix_fd, size )) goto error;
else if (st.st_size < mapping->size && !grow_file( unix_fd, mapping->size )) goto error;
}
else /* Anonymous mapping (no associated file) */
{
if (!size || (flags & SEC_IMAGE))
if (!mapping->size || (flags & SEC_IMAGE))
{
set_error( STATUS_INVALID_PARAMETER );
goto error;
@ -586,12 +590,12 @@ static struct object *create_mapping( struct object *root, const struct unicode_
mapping->committed->count = 0;
mapping->committed->max = 8;
}
if ((unix_fd = create_temp_file( size )) == -1) goto error;
mapping->size = (mapping->size + page_mask) & ~((mem_size_t)page_mask);
if ((unix_fd = create_temp_file( mapping->size )) == -1) goto error;
if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj,
FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;
allow_fd_caching( mapping->fd );
}
mapping->size = (size + page_mask) & ~((mem_size_t)page_mask);
return &mapping->obj;
error:

View File

@ -698,6 +698,7 @@ typedef struct
{
client_ptr_t base;
client_ptr_t entry_point;
mem_size_t map_size;
mem_size_t stack_size;
mem_size_t stack_commit;
unsigned int zerobits;

View File

@ -1140,12 +1140,18 @@ static void dump_varargs_pe_image_info( const char *prefix, data_size_t size )
{
pe_image_info_t info;
if (!size)
{
fprintf( stderr, "%s{}", prefix );
return;
}
memset( &info, 0, sizeof(info) );
memcpy( &info, cur_data, min( size, sizeof(info) ));
fprintf( stderr, "%s{", prefix );
dump_uint64( "base=", &info.base );
dump_uint64( ",entry_point=", &info.entry_point );
dump_uint64( ",map_size=", &info.map_size );
dump_uint64( ",stack_size=", &info.stack_size );
dump_uint64( ",stack_commit=", &info.stack_commit );
fprintf( stderr, ",zerobits=%08x,subsystem=%08x,subsystem_low=%04x,subsystem_high=%04x,gp=%08x"