Signed-off-by: Brendan Shanks bshanks@codeweavers.com ---
The map_view() change fixes native DLLs, and virtual_map_section() for builtin DLLs. I wasn't sure how to test a native DLL.
This showed up under Wow64 when running the 64-bit Notepad++ installer (a 32-bit EXE), which runs 32-bit regsvr32 to register a 64-bit DLL. regsvr32 calls LoadLibraryExW() with LOAD_LIBRARY_AS_IMAGE_RESOURCE, which was returning a truncated pointer to the DLLs base address. Accessing this then crashed.
dlls/ntdll/tests/virtual.c | 1 - dlls/ntdll/unix/virtual.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index cd374cf2ea4..0b1b7921d8a 100644 --- a/dlls/ntdll/tests/virtual.c +++ b/dlls/ntdll/tests/virtual.c @@ -933,7 +933,6 @@ static void test_NtMapViewOfSection(void) { ok(status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE, "NtMapViewOfSection returned %08lx\n", status); ok(!((ULONG_PTR)ptr & 0xffff), "returned memory %p is not aligned to 64k\n", ptr); - todo_wine ok(((UINT_PTR)ptr & ~get_zero_bits_mask(zero_bits)) == 0, "NtMapViewOfSection returned address %p\n", ptr);
status = NtUnmapViewOfSection(process, ptr); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 94b300c5057..026026529cf 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -1902,7 +1902,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (base) { - if (is_beyond_limit( base, size, address_space_limit )) + if (is_beyond_limit( base, size, (void*)(get_zero_bits_mask( zero_bits ) & (UINT_PTR)address_space_limit) )) return STATUS_WORKING_SET_LIMIT_RANGE; status = map_fixed_area( base, size, vprot ); if (status != STATUS_SUCCESS) return status; @@ -2540,7 +2540,8 @@ static NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_PTR z filename = (WCHAR *)(image_info + 1); /* check if we can replace that mapping with the builtin */ res = load_builtin( image_info, filename, addr_ptr, size_ptr ); - if (res == STATUS_IMAGE_ALREADY_LOADED) + if (res == STATUS_IMAGE_ALREADY_LOADED || + is_beyond_limit( (void *)image_info->base, image_info->map_size, (void *)get_zero_bits_mask( zero_bits ) )) res = virtual_map_image( handle, access, addr_ptr, size_ptr, zero_bits, shared_file, alloc_type, image_info, filename, FALSE ); if (shared_file) NtClose( shared_file );