[Bug 53270] New: test_WSARecv() fails when using wow64 thunks [Wow64ApcRoutine() overwrites return value set by NtContinue()]

WineHQ Bugzilla wine-bugs at winehq.org
Sat Jun 25 20:34:00 CDT 2022


https://bugs.winehq.org/show_bug.cgi?id=53270

            Bug ID: 53270
           Summary: test_WSARecv() fails when using wow64 thunks
                    [Wow64ApcRoutine() overwrites return value set by
                    NtContinue()]
           Product: Wine
           Version: 7.11
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Keywords: source, testcase
          Severity: normal
          Priority: P2
         Component: ntdll
          Assignee: wine-bugs at winehq.org
          Reporter: z.figura12 at gmail.com
      Distribution: ---

Created attachment 72642
  --> https://bugs.winehq.org/attachment.cgi?id=72642
test diff

This might be a bit early since the wow64 path isn't exactly supported, but
(with a couple patches to ntdll to enable it in the first place) it works well
enough to expose a bug in its own implementation, which is more than a little
tricky to solve.

I'm attaching a diff to the tests, which I will submit upstream, which
demonstrates the root of the problem.

KiUserApcDispatcher can be called from three-ish places: wait functions,
NtTestAlert, and NtContinue. In the case of the former two KiUserApcDispatcher
will be passed a wow64 context which, among other things, has its %rax/%eax set
to STATUS_USER_APC or STATUS_SUCCESS respectively. In the latter case %rax/%eax
comes from the passed-in context.

Wow64ApcRoutine tries to translate the %rax from the 64-bit context into the
%eax that the 32-bit context will restore to. In the former two cases this is
STATUS_USER_APC or STATUS_SUCCESS and things work fine. In the latter case,
however, this overwrites %eax from the passed-in 32-bit context. Note that we
don't get the right %eax from ntdll either, because (a) ntdll gives us a 64-bit
context anyway, and (b) we don't use NtContinue but rather NtTestAlert. That
does mean we could fix it by using NtContinue and putting the %eax value into
%rax, which is a bit weird but I don't know if there's a better option.

This is wrong inherently, as the attached tests show, but it more saliently
ends up breaking LdrInitializeThunk, because on i386 RtlUserThreadStart is
called with %eax pointing to the thread procedure, and we then overwrite that
with zero.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list