[PATCH 0/1] MR8638: kernel32/tests: Don't go beyond user space virtual address limit.
In get_valloc_info, if mem happens to point to the last chunk of memory in the user space virtual address space, "p += info2.RegionSize" will cause it to go over the limit, and subsequent VirtualQueries will fail, thus info2 won't be changed, thus the loop exit condition is never met (well until p wraps around, that is). * * * Witnessed this in CI: ``` 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7ffffffe0000, info_class=0, 0x442120, 48, 0xfd4a0) 012c:0130:trace:virtual:get_vprot_range_size base 0x7ffffffe0000, size 0x10000, mask 0xbf. 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7ffffffe0000, info_class=0, 0x442170, 48, 0xfd520) 012c:0130:trace:virtual:get_vprot_range_size base 0x7ffffffe0000, size 0x10000, mask 0xbf. 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7fffffff0000, info_class=0, 0x442170, 48, 0xfd5e0) 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000000000, info_class=0, 0x442170, 48, 0xfd820) 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000010000, info_class=0, 0x442170, 48, 0xfda60) 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000020000, info_class=0, 0x442170, 48, 0xfdca0) 012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000030000, info_class=0, 0x442170, 48, 0xfdee0) ... ``` and winetest logs: ``` ... heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.322 Test failed: init size 0: got 0. heap.c:3662:3.323 Test failed: init size 0: got 0. heap.c:3662:3.323 Test failed: init size 0: got 0. ... ``` ad infinitum Probably made more likely by ASan since it takes a big chunk of the address space. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8638
From: Yuxuan Shui <yshui(a)codeweavers.com> In get_valloc_info, if mem happens to point to the last chunk of memory in the user space virtual address space, "p += info2.RegionSize" will cause it to go over the limit, and subsequent VirtualQueries will fail, thus info2 won't be changed, thus the loop exit condition is never met (well until p wraps around, that is). --- dlls/kernel32/tests/heap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index f88a140a115..ec3549ac605 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -3648,15 +3648,20 @@ static void test_GlobalMemoryStatus(void) static void get_valloc_info( void *mem, char **base, SIZE_T *alloc_size ) { MEMORY_BASIC_INFORMATION info, info2; + SYSTEM_BASIC_INFORMATION si; + NTSTATUS status; SIZE_T size; char *p; + status = NtQuerySystemInformation(SystemBasicInformation, &si, sizeof(si), NULL); + ok( !status, "NtQuerySystemInformation returned %#lx\n", status ); + size = VirtualQuery( mem, &info, sizeof(info) ); ok( size == sizeof(info), "got %Iu.\n", size ); info2 = info; p = info.AllocationBase; - while (1) + while (p < (char *)si.HighestUserAddress) { size = VirtualQuery( p, &info2, sizeof(info2) ); ok( size == sizeof(info), "got %Iu.\n", size ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8638
participants (2)
-
Yuxuan Shui -
Yuxuan Shui (@yshui)