[PATCH v2 0/2] MR269: ntdll: Respect zero_bits when mapping a builtin or native PE file.
Without the changes, the test passes or fails based on the binutils version being used. v2.35 (used on the Debian 11 testbot) gives 64-bit DLLs an image base under 4GB, and the test always passes. On a system with binutils 2.37 or later, 64-bit DLLs are based above 4GBs, and the test will fail. 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. -- v2: ntdll: Respect zero_bits/limit when mapping a PE file. ntdll/tests: Test NtMapViewOfSection with a 64-bit DLL and zero_bits > 31. https://gitlab.winehq.org/wine/wine/-/merge_requests/269
From: Brendan Shanks <bshanks(a)codeweavers.com> --- dlls/ntdll/tests/virtual.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index 6831fe3c522..a239a75ad47 100644 --- a/dlls/ntdll/tests/virtual.c +++ b/dlls/ntdll/tests/virtual.c @@ -1265,6 +1265,32 @@ static void test_NtMapViewOfSection(void) CloseHandle(file); DeleteFileA(testfile); + /* test zero_bits > 31 with a 64-bit DLL file image mapping */ + if (is_win64) + { + file = CreateFileA("c:\\windows\\system32\\version.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n"); + + mapping = CreateFileMappingA(file, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, NULL); + ok(mapping != 0, "CreateFileMapping failed\n"); + + ptr = NULL; + size = 0; + offset.QuadPart = 0; + zero_bits = 0x7fffffff; + status = NtMapViewOfSection(mapping, process, &ptr, zero_bits, 0, &offset, &size, 1, 0, PAGE_READONLY); + + 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); + ok(((UINT_PTR)ptr & ~get_zero_bits_mask(zero_bits)) == 0, "NtMapViewOfSection returned address %p\n", ptr); + + status = NtUnmapViewOfSection(process, ptr); + ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status); + + NtClose(mapping); + CloseHandle(file); + } + TerminateProcess(process, 0); CloseHandle(process); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/269
From: Brendan Shanks <bshanks(a)codeweavers.com> --- dlls/ntdll/unix/virtual.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 0f66429fc9d..f2657be32ce 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -1923,6 +1923,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, { if (is_beyond_limit( base, size, address_space_limit )) return STATUS_WORKING_SET_LIMIT_RANGE; + if (limit && is_beyond_limit( base, size, (void *)limit )) + return STATUS_CONFLICTING_ADDRESSES; status = map_fixed_area( base, size, vprot ); if (status != STATUS_SUCCESS) return status; ptr = base; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/269
The single change in `map_view` now fixes both builtin and native DLLs. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/269#note_23632
participants (2)
-
Brendan Shanks -
Brendan Shanks (@bshanks)