[Bug 50189] New: Multiple 64-bit applications crash with Wine MinGW PE build due to violation of Windows 64-bit ABI (RSP must be 16-byte aligned when making a call to Win64 API)

WineHQ Bugzilla wine-bugs at winehq.org
Wed Nov 25 12:01:33 CST 2020


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

            Bug ID: 50189
           Summary: Multiple 64-bit applications crash with Wine MinGW PE
                    build due to violation of Windows 64-bit ABI (RSP must
                    be 16-byte aligned when making a call to Win64 API)
           Product: Wine
           Version: 5.22
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: -unknown
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

while revisiting some old bugs I've encountered my old friend bug 27680 but now
for LLVM/Clang/LLD based mingw-w64 toolchain.

I don't expect much violators in this "Hall of Shame" #2 though. Most
apps/games from bug 27680 were either fixed by their vendors or are not
relevant anymore.

Anyway, since Wine is nowadays a PE build there should be one collector bug
report for this type of issue.

Example:

SafeNET's Sentinel HASP Runtime v6.6 from bug 45510
(https://bugs.winehq.org/show_bug.cgi?id=45510#c4)

Stable download:

https://web.archive.org/web/20201125113604/http://www.argusone.com/pub/Add_PC_Files/Sentinel_HASP_Run-time_setup/HASPUserSetup.exe

After installation one should set the service to manual start type (3) in
registry to avoid the annoying crashes due to default autostart start type (2).

--- snip ---
$ wine net start hardlock
...
The hardlock service is starting.
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\ntdll.dll" at
000000007BC00000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\kernelbase.dll"
at 000000007B000000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\kernel32.dll"
at 000000007B600000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\winedevice.exe"
at 0000000140000000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\ucrtbase.dll"
at 0000000000250000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\sechost.dll" at
0000000000220000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\advapi32.dll"
at 0000000180000000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\msvcrt.dll" at
0000000000350000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\ntoskrnl.exe"
at 0000000000300000: builtin
0168:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\rpcrt4.dll" at
0000000000AC0000: builtin
0170:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\HAL.dll" at
0000000000DA0000: builtin
0170:trace:loaddll:build_module Loaded
L"C:\\windows\\system32\\drivers\\hardlock.sys" at 0000000000D50000: native
wine: Unhandled page fault on read access to FFFFFFFFFFFFFFFF at address
000000007B62CC3C (thread 0170), starting debugger...
--- snip ---

--- snip ---
$ WINEDEBUG=+loaddll,+ntdll,+ntoskrnl wine net start hardlock
...
00dc:trace:ntoskrnl:ZwLoadDriver
(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\hardlock")
00dc:trace:ntoskrnl:open_driver opened service for driver
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\hardlock"
00dc:trace:ntoskrnl:IoCreateDriver (L"\\Driver\\hardlock", 00000000003154B0)
00dc:trace:ntoskrnl:load_driver loading driver
L"C:\\windows\\system32\\drivers\\hardlock.sys"
00dc:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\HAL.dll" at
0000000000DA0000: builtin
00dc:trace:loaddll:build_module Loaded
L"C:\\windows\\system32\\drivers\\hardlock.sys" at 0000000000D50000: native
00dc:trace:ntoskrnl:ldr_notify_callback loading L"HAL.dll"
00dc:trace:ntdll:NtQuerySystemInformation
(0x00000000,0xc2f3d8,0x00000040,(nil))
00dc:trace:ntoskrnl:ldr_notify_callback loading L"hardlock.sys"
00dc:trace:ntdll:NtQuerySystemInformation
(0x00000000,0xc2f448,0x00000040,(nil))
00dc:trace:ntoskrnl:MmIsAddressValid wine: Unhandled page fault on read access
to FFFFFFFFFFFFFFFF at address 00000000003A7F53 (thread 00dc), starting
debugger...
...
--- snip ---

Crashes in ntoskrnl.MmIsAddressValid().

Relay debug prevents the crash (different stack layout).

NOTE: The driver is obfuscated, all other exceptions are by design and ok.

--- snip ---
...
0108:Call driver init 0000000000D9E1DE
(obj=00000000000431A0,str=L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\hardlock")
0108:trace:seh:dispatch_exception code=c0000096 flags=0 addr=0000000000D9E0C6
ip=d9e0c6 tid=0108
0108:trace:seh:dispatch_exception  rax=0000000000000400 rbx=0000000000d9f150
rcx=0000000000d9e1de rdx=0000000000d9e935
0108:trace:seh:dispatch_exception  rsi=0000000000d9e935 rdi=0000000000d9e1de
rbp=00000000000417f8 rsp=0000000000c2f7b0
0108:trace:seh:dispatch_exception   r8=000000000000081b  r9=0000000000d9e1de
r10=0000000000000028 r11=0000000000000000
0108:trace:seh:dispatch_exception  r12=0000000000c2fc00 r13=00000000000431a0
r14=0000000000043308 r15=0000000000000000
0108:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0
code=c0000096 flags=0
...
0108:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned
ffffffff
0108:trace:seh:dispatch_exception code=c0000096 flags=0 addr=0000000000D9E27E
ip=d9e27e tid=0108
0108:trace:seh:dispatch_exception  rax=0000000000000400 rbx=0000000000d9e1de
rcx=0000000000000000 rdx=000000005960f005
0108:trace:seh:dispatch_exception  rsi=0000000000d9e342 rdi=0000000000d50400
rbp=00000000000417f8 rsp=0000000000c2f7d0
0108:trace:seh:dispatch_exception   r8=000000000000081b  r9=0000000000d50400
r10=000000005960f005 r11=0000000000000000
0108:trace:seh:dispatch_exception  r12=0000000000c2fc00 r13=00000000000431a0
r14=0000000000043308 r15=0000000000000000
0108:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0
code=c0000096 flags=0
0108:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned
ffffffff
0108:Call ntoskrnl.exe.MmIsAddressValid(00307000) ret=00d9e3a9
0108:trace:ntoskrnl:MmIsAddressValid (0000000000307000)
0108:Call KERNEL32.IsBadReadPtr(00307000,00000001) ret=003138c3
0108:Ret  KERNEL32.IsBadReadPtr() retval=00000000 ret=003138c3
0108:Ret  ntoskrnl.exe.MmIsAddressValid() retval=00000001 ret=00d9e3a9
0108:Call ntoskrnl.exe.MmIsAddressValid(00306000) ret=00d9e3a9
0108:trace:ntoskrnl:MmIsAddressValid (0000000000306000)
0108:Call KERNEL32.IsBadReadPtr(00306000,00000001) ret=003138c3
0108:Ret  KERNEL32.IsBadReadPtr() retval=00000000 ret=003138c3
0108:Ret  ntoskrnl.exe.MmIsAddressValid() retval=00000001 ret=00d9e3a9
...
--- snip ---

Context in crash case (only run with +seh):

--- snip ---
00dc:trace:seh:dispatch_exception code=c0000005 flags=0 addr=000000007B62CC3C
ip=7b62cc3c tid=00dc
00dc:trace:seh:dispatch_exception  info[0]=0000000000000000
00dc:trace:seh:dispatch_exception  info[1]=00000000ffffffff
00dc:trace:seh:dispatch_exception  rax=000000007b62adc3 rbx=0000000000c2f738
rcx=0000000000c2f758 rdx=0000000000c2f738
00dc:trace:seh:dispatch_exception  rsi=0000000000313000 rdi=0000000000000001
rbp=0000000000000001 rsp=0000000000c2f700
00dc:trace:seh:dispatch_exception   r8=0000000000d9e343  r9=0000000000d50400
r10=000000009a4512ae r11=000000000004f600
00dc:trace:seh:dispatch_exception  r12=0000000000c2fce0 r13=0000000000019760
r14=0000000000000000 r15=0000000000313000
00dc:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0
code=c0000005 flags=0
00dc:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned 0
00dc:trace:seh:call_vectored_handlers calling handler at 000000007B011860
code=c0000005 flags=0
00dc:trace:seh:call_vectored_handlers handler at 000000007B011860 returned 0
--- snip ---

Disassembly to show no realign prologue with mingw:

<ntoskrnl.MmIsAddressValid>:

--- snip ---
0000000180013880 | push rsi                                      |
0000000180013881 | sub rsp,30                                    |
0000000180013885 | mov rsi,rcx                                   |
0000000180013888 | test byte ptr ds:[<__wine_dbch_ntoskrnl>],8   |
000000018001388F | je ntoskrnl.1800138B5                         |
0000000180013891 | mov qword ptr ss:[rsp+20],rsi                 |
0000000180013896 | lea rdx,qword ptr ds:[<__wine_dbch_ntoskrnl>] |
000000018001389D | lea r8,qword ptr ds:[180024230]               |
00000001800138A4 | lea r9,qword ptr ds:[18002383A]               |
00000001800138AB | mov ecx,3                                     |
00000001800138B0 | call <ntoskrnl.wine_dbg_log>                  |
00000001800138B5 | mov edx,1                                     |
00000001800138BA | mov rcx,rsi                                   |
00000001800138BD | call qword ptr ds:[<&IsBadReadPtr>]           |
00000001800138C3 | test eax,eax                                  |
00000001800138C5 | sete al                                       |
00000001800138C8 | add rsp,30                                    |
00000001800138CC | pop rsi                                       |
00000001800138CD | ret                                           |
--- snip ---

<kernel32.IsBadReadPtr>:

--- snip ---
000000007B62AD70 | push r14                                          |
000000007B62AD72 | push rsi                                          |
000000007B62AD73 | push rdi                                          |
000000007B62AD74 | push rbp                                          |
000000007B62AD75 | push rbx                                          |
000000007B62AD76 | sub rsp,160                                       |
000000007B62AD7D | xor r14d,r14d                                     |
000000007B62AD80 | test rdx,rdx                                      |
000000007B62AD83 | je kernel32.7B62AE4F                              |
000000007B62AD89 | mov rsi,rcx                                       |
000000007B62AD8C | mov ebp,1                                         |
000000007B62AD91 | test rcx,rcx                                      |
000000007B62AD94 | je kernel32.7B62ADEA                              |
000000007B62AD96 | mov rdi,rdx                                       |
000000007B62AD99 | lea rax,qword ptr ds:[<__wine_exception_handler>] |
000000007B62ADA0 | mov qword ptr ss:[rsp+38],rax                     |
000000007B62ADA5 | lea rax,qword ptr ds:[<badptr_handler>]           |
000000007B62ADAC | mov qword ptr ss:[rsp+40],rax                     |
000000007B62ADB1 | lea rcx,qword ptr ss:[rsp+50]              | &__f.jmp
000000007B62ADB6 | lea rbx,qword ptr ss:[rsp+30]              | &__f.frame
000000007B62ADBB | mov rdx,rbx                                | &__f.frame
000000007B62ADBE | call <kernel32.__wine_setjmpex>                   |
000000007B62ADC3 | test eax,eax                                      |
000000007B62ADC5 | je kernel32.7B62ADEE                              |
...
--- snip ---

<kernel32.__wine_setjmpex>:

__wine_setjmpex( &__f.jmp, &__f.frame )

RCX = &__f.jmp = 0x0000000000c2f758 (misaligned)
RDX = &__f.frame = 0x0000000000c2f738

--- snip ---
000000007B62CC08 | mov qword ptr ds:[rcx],rdx           | 
000000007B62CC0B | mov qword ptr ds:[rcx+8],rbx         |
000000007B62CC0F | lea rax,qword ptr ss:[rsp+8]         |
000000007B62CC14 | mov qword ptr ds:[rcx+10],rax        |
000000007B62CC18 | mov qword ptr ds:[rcx+18],rbp        |
000000007B62CC1C | mov qword ptr ds:[rcx+20],rsi        |
000000007B62CC20 | mov qword ptr ds:[rcx+28],rdi        |
000000007B62CC24 | mov qword ptr ds:[rcx+30],r12        |
000000007B62CC28 | mov qword ptr ds:[rcx+38],r13        |
000000007B62CC2C | mov qword ptr ds:[rcx+40],r14        |
000000007B62CC30 | mov qword ptr ds:[rcx+48],r15        |
000000007B62CC34 | mov rax,qword ptr ss:[rsp]           |
000000007B62CC38 | mov qword ptr ds:[rcx+50],rax        |
000000007B62CC3C | movdqa xmmword ptr ds:[rcx+60],xmm6  | SSE2 *boom*
000000007B62CC41 | movdqa xmmword ptr ds:[rcx+70],xmm7  |
000000007B62CC46 | movdqa xmmword ptr ds:[rcx+80],xmm8  |
000000007B62CC4F | movdqa xmmword ptr ds:[rcx+90],xmm9  |
000000007B62CC58 | movdqa xmmword ptr ds:[rcx+A0],xmm10 |
000000007B62CC61 | movdqa xmmword ptr ds:[rcx+B0],xmm11 |
000000007B62CC6A | movdqa xmmword ptr ds:[rcx+C0],xmm12 |
000000007B62CC73 | movdqa xmmword ptr ds:[rcx+D0],xmm13 |
000000007B62CC7C | movdqa xmmword ptr ds:[rcx+E0],xmm14 |
000000007B62CC85 | movdqa xmmword ptr ds:[rcx+F0],xmm15 |
000000007B62CC8E | xor rax,rax                          |
000000007B62CC91 | ret                                  |
--- snip ---

Wine source:

https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c52ab82c6:/dlls/kernel32/virtual.c#l74

--- snip ---
  74 BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT_PTR size )
  75 {
  76     if (!size) return FALSE;  /* handle 0 size case w/o reference */
  77     if (!ptr) return TRUE;
  78     __TRY
  79     {
  80         volatile const char *p = ptr;
  81         char dummy __attribute__((unused));
  82         UINT_PTR count = size;
  83 
  84         while (count > system_info.PageSize)
  85         {
  86             dummy = *p;
  87             p += system_info.PageSize;
  88             count -= system_info.PageSize;
  89         }
  90         dummy = p[0];
  91         dummy = p[count - 1];
  92     }
  93     __EXCEPT( badptr_handler )
  94     {
  95         TRACE("%p caused page fault during read\n", ptr);
  96         return TRUE;
  97     }
  98     __ENDTRY
  99     return FALSE;
 100 }
--- snip ---

https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c52ab82c6:/include/wine/exception.h#l136

--- snip ---
 136 #define __TRY \
 137     do { __WINE_FRAME __f; \
 138          int __first = 1; \
 139          for (;;) if (!__first) \
 140          { \
 141              do {
 142 
 143 #define __EXCEPT(func) \
 144              } while(0); \
 145              __wine_pop_frame( &__f.frame ); \
 146              break; \
 147          } else { \
 148              __f.frame.Handler = __wine_exception_handler; \
 149              __f.u.filter = (func); \
 150              if (__wine_setjmpex( &__f.jmp, &__f.frame )) { \
 151                  const __WINE_FRAME * const __eptr __attribute__((unused))
= &__f; \
 152                  do {
 153 
--- snip ---

https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c52ab82c6:/include/windef.h#l57

--- snip ---
  57 #if !defined(_MSC_VER) && !defined(__stdcall)
  58 # ifdef __i386__
  59 #  ifdef __GNUC__
  60 #   if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) ||
defined(__APPLE__)
  61 #    define __stdcall __attribute__((__stdcall__))
__attribute__((__force_align_arg_pointer__))
  62 #   else
  63 #    define __stdcall __attribute__((__stdcall__))
  64 #   endif
  65 #  else
  66 #   error You need to define __stdcall for your compiler
  67 #  endif
  68 # elif defined(__x86_64__) && defined (__GNUC__)
  69 #  if __has_attribute(__force_align_arg_pointer__)
  70 #   define __stdcall __attribute__((ms_abi))
__attribute__((__force_align_arg_pointer__))
  71 #  else
  72 #   define __stdcall __attribute__((ms_abi))
  73 #  endif
  74 # elif defined(__arm__) && defined (__GNUC__) && !defined(__SOFTFP__)
  75 #   define __stdcall __attribute__((pcs("aapcs-vfp")))
  76 # elif defined(__aarch64__) && defined (__GNUC__)
  77 #  define __stdcall __attribute__((ms_abi))
  78 # else  /* __i386__ */
  79 #  define __stdcall
  80 # endif  /* __i386__ */
  81 #endif /* __stdcall */
--- snip ---

mingw-w64-clang has __stdcall predefined so it doesn't get the gcc treatment.

$ sha1sum HASPUserSetup.exe 
fa5f85d8dfbef3188087f1b6fb0ec81a16e6a26d  HASPUserSetup.exe

$ du -sh HASPUserSetup.exe 
14M    HASPUserSetup.exe

$ wine --version
wine-5.22-64-g92fb63d7754

Regards

-- 
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