[PATCH 0/1] MR4742: server: Allow PROCESS_QUERY_INFORMATION on LIMITED handle.
A handle created with just PROCESS_QUERY_LIMITED_INFORMATION should be returned when queried with PROCESS_QUERY_INFORMATION. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56093 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4742
From: Bernhard Übelacker <bernhardu(a)mailbox.org> A handle created with just PROCESS_QUERY_LIMITED_INFORMATION should be returned when queried with PROCESS_QUERY_INFORMATION. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56093 --- dlls/kernel32/tests/process.c | 26 ++++++++++++++++++++++++++ server/handle.c | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index e0f1d210e58..2c3b49dca41 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -2545,6 +2545,31 @@ static void test_DuplicateHandle(void) CloseHandle(out); } +static void test_DuplicateHandle_limited(void) +{ + void *addr; + HANDLE h; + MEMORY_BASIC_INFORMATION info; + int ret; + + addr = VirtualAllocEx(GetCurrentProcess(), 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS); + ok(addr != NULL, "VirtualAllocEx error %ld\n", GetLastError()); + + ret = DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &h, + SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_DUP_HANDLE | PROCESS_VM_READ |PROCESS_VM_OPERATION, + TRUE, 0); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = VirtualQueryEx(h, addr, &info, sizeof(info)); + ok(ret == sizeof(info) || + broken(ret == 0 && GetLastError() == ERROR_ACCESS_DENIED) /* <= win8*/, + "VirtualQueryEx error ret=0x%x %ld\n", ret, GetLastError()); + + ok(CloseHandle(h), "CloseHandle error %ld\n", GetLastError()); + ok(VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree error %ld\n", GetLastError()); +} + #define test_completion(a, b, c, d, e) _test_completion(__LINE__, a, b, c, d, e) static void _test_completion(int line, HANDLE port, DWORD ekey, ULONG_PTR evalue, ULONG_PTR eoverlapped, DWORD wait) { @@ -5458,6 +5483,7 @@ START_TEST(process) test_ProcessorCount(); test_RegistryQuota(); test_DuplicateHandle(); + test_DuplicateHandle_limited(); test_StdHandleInheritance(); test_GetNumaProcessorNode(); test_session_info(); diff --git a/server/handle.c b/server/handle.c index 0595fdb403b..7f20685351b 100644 --- a/server/handle.c +++ b/server/handle.c @@ -477,6 +477,13 @@ struct object *get_handle_obj( struct process *process, obj_handle_t handle, set_error( STATUS_OBJECT_TYPE_MISMATCH ); /* not the right type */ return NULL; } + if ((access & PROCESS_QUERY_INFORMATION) && + !(entry->access & PROCESS_QUERY_INFORMATION) && + (entry->access & PROCESS_QUERY_LIMITED_INFORMATION)) + { + access &= ~PROCESS_QUERY_INFORMATION; + access |= PROCESS_QUERY_LIMITED_INFORMATION; + } if ((entry->access & access) != access) { set_error( STATUS_ACCESS_DENIED ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4742
the fix can't be in server/handle.c (the access bits meaning depends on the object you're considering...) looking at server/process.c:process_map_access: setting PROCESS_QUERY_INFORMATION always set PROCESS_QUERY_LIMITED_INFORMATION (but not the other way around) so you need to figure out where an access is tested against PROCESS_QUERY_INFORMATION while it should be against PROCESS_QUERY_LIMITED_INFORMATION hint: VirtualQueryEx -\> NtQueryVirtualMemory -\> get_basic_memory_info -\> which queues an APC (APC_VIRTUAL_QUERY) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4742#note_56417
participants (2)
-
Bernhard Übelacker -
eric pouech (@epo)