Windows: Extend user handle access masks in callbacks where necessary

While most applications will just create ALL_ACCESS handles which
support the additional operations FEX needs over the regular windows syscall
(usually just QUERY_INFORMATION to lookup the thread object), it is
valid for them to pass in the minimal set required for each operation
and windows/wine will reject any other operations (e.g. querying the TEB
base on a handle with only the SUSPEND right). Windows permits
duplicating handles to extend their permissions given the process itself
has such permissions, so do that as necessary for the operations FEX
needs.
This commit is contained in:
Billy Laws committed 2025-08-12 03:19:20 +01:00
1 parent b2b5ccf69c
commit 1ac3d3c5a6
4 files changed
+79 -30

No files matched your search

+6 -4
View File
@@ -964,8 +964,10 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) {
return STATUS_ACCESS_DENIED;
}
auto ThreadDup = FEX::Windows::DupHandle(Thread, THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME);
THREAD_BASIC_INFORMATION Info;
if (auto Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) {
if (auto Err = NtQueryInformationThread(*ThreadDup, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) {
return Err;
}
@@ -974,12 +976,12 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) {
if (!Self) {
CONTEXT TmpContext;
// If we are suspending a thread that isn't ourselves, try to suspend it first so we know internal JIT locks aren't being held.
NtSuspendThread(Thread, NULL);
NtSuspendThread(*ThreadDup, NULL);
// This will wait for the thread to be suspended
NtGetContextThread(Thread, &TmpContext);
NtGetContextThread(*ThreadDup, &TmpContext);
}
const auto [Err, CPUArea] = GetThreadCPUArea(Thread);
const auto [Err, CPUArea] = GetThreadCPUArea(*ThreadDup);
if (Err) {
return Err;
}