[Bug 47480] New: Rhinoceros 6 (.NET 4.x app) crashes in rsaenh during local license file validation

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jul 7 12:44:39 CDT 2019


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

            Bug ID: 47480
           Summary: Rhinoceros 6 (.NET 4.x app) crashes in rsaenh during
                    local license file validation
           Product: Wine
           Version: 4.12
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: rsaenh
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

as it says.

Prerequisites:

* .NET Framework 4.5.x ('winetricks -q dotnet452')

The app installer downloads and installs MS VC++ 2005, 2010, 2013, 2017 runtime
redistributables on its own.

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/Rhino 6/System

$ WINEDEBUG=+seh,+loaddll,+process,+relay,+crypt wine ./Rhino.exe >>log.txt
2>&1
...
00fd:Call
advapi32.CryptImportKey(02499d30,103ab638,0000002c,00000000,00000001,0024a648)
ret=0c7855dc
00fd:trace:crypt:CryptImportKey (0x2499d30, 0x103ab638, 44, 0x0, 00000001,
0x24a648)
00fd:Call
rsaenh.CPImportKey(00000005,103ab638,0000002c,00000000,00000001,02499cf0)
ret=7f515c928426
00fd:trace:crypt:RSAENH_CPImportKey (hProv=00000005, pbData=00000000103AB638,
dwDataLen=44, hPubKey=00000000, dwFlags=00000001, phKey=0000000002499CF0)
00fd:trace:crypt:import_key blob type: 8
00fd:Call KERNEL32.IsBadStringPtrA(6652bb20,ffffffffffffffff) ret=6650c54b
00fd:Ret  KERNEL32.IsBadStringPtrA() retval=00000000 ret=6650c54b
00fd:trace:crypt:new_key alg = "AES-256", dwKeyLen = 256
00fd:Call ntdll.RtlAllocateHeap(00010000,00000000,00000408) ret=665033c4
00fd:Ret  ntdll.RtlAllocateHeap() retval=024e5020 ret=665033c4
00fd:Call msvcrt.memcpy(024e5360,103ab644,00000020) ret=665130b7
00fd:Ret  msvcrt.memcpy() retval=024e5360 ret=665130b7
00fd:Ret  rsaenh.CPImportKey() retval=00000001 ret=7f515c928426 
...
00fd:Call KERNEL32.CreateFileW(101bb42c
L"C:\\ProgramData\\McNeel\\Rhinoceros\\6.0\\License
Manager\\Licenses\\55500d41-3a41-4474-99b3-684032a4f4df.lic",ffffffff80000000,00000001,00000000,00000003,00100000,00000000)
ret=0a2d47b4
00fd:Ret  KERNEL32.CreateFileW() retval=00000308 ret=0a2d47b4
...
00fd:Call advapi32.CryptContextAddRef(02499d30,00000000,00000000) ret=0c78b52c
00fd:trace:crypt:CryptContextAddRef (0x2499d30, (nil), 00000000)
00fd:Ret  advapi32.CryptContextAddRef() retval=00000001 ret=0c78b52c
...
00fd:Call advapi32.CryptDuplicateKey(02499ce0,00000000,00000000,0024a5c8)
ret=0c78c54f
00fd:trace:crypt:CryptDuplicateKey (0x2499ce0, (nil), 00000000, 0x24a5c8)
00fd:Call rsaenh.CPDuplicateKey(00000005,00000006,00000000,00000000,024e4910)
ret=7f515c926238
00fd:trace:crypt:RSAENH_CPDuplicateKey (hUID=00000005, hKey=00000006,
pdwReserved=0000000000000000, dwFlags=00000000, phKey=00000000024E4910)
00fd:Call ntdll.RtlAllocateHeap(00010000,00000000,00000408) ret=665033c4
00fd:Ret  ntdll.RtlAllocateHeap() retval=024ca230 ret=665033c4
00fd:Call ntdll.RtlAllocateHeap(00010000,00000000,00000000) ret=6650d79d
00fd:Ret  ntdll.RtlAllocateHeap() retval=024e4980 ret=6650d79d
00fd:Call msvcrt.memcpy(024e4980,00000000,00000000) ret=6650d7cf
00fd:Ret  msvcrt.memcpy() retval=024e4980 ret=6650d7cf
00fd:Call ntdll.RtlAllocateHeap(00010000,00000000,00000000) ret=6650d7f8
00fd:Ret  ntdll.RtlAllocateHeap() retval=0239bca0 ret=6650d7f8
00fd:Call msvcrt.memcpy(0239bca0,00000000,00000000) ret=6650d826
00fd:Ret  msvcrt.memcpy() retval=0239bca0 ret=6650d826
00fd:Ret  rsaenh.CPDuplicateKey() retval=00000001 ret=7f515c926238
00fd:Ret  advapi32.CryptDuplicateKey() retval=00000001 ret=0c78c54f
00fd:Call advapi32.CryptContextAddRef(02499d30,00000000,00000000) ret=0c784f09
00fd:trace:crypt:CryptContextAddRef (0x2499d30, (nil), 00000000)
00fd:Ret  advapi32.CryptContextAddRef() retval=00000001 ret=0c784f09
00fd:Call KERNEL32.GetLastError() ret=02b2a82b
00fd:Ret  KERNEL32.GetLastError() retval=00000000 ret=02b2a82b 
...
00fd:Call advapi32.CryptSetKeyParam(024e4900,00000004,101c2030,00000000)
ret=0c78cbf6
00fd:trace:crypt:CryptSetKeyParam (0x24e4900, 4, 0x101c2030, 00000000)
00fd:Call rsaenh.CPSetKeyParam(00000005,00000004,00000004,101c2030,00000000)
ret=7f515c928b9d
00fd:trace:crypt:RSAENH_CPSetKeyParam (hProv=00000005, hKey=00000004,
dwParam=00000004, pbData=00000000101C2030, dwFlags=00000000)
00fd:Ret  rsaenh.CPSetKeyParam() retval=00000001 ret=7f515c928b9d
00fd:Ret  advapi32.CryptSetKeyParam() retval=00000001 ret=0c78cbf6
00fd:Call KERNEL32.GetLastError() ret=02b2a82b
00fd:Ret  KERNEL32.GetLastError() retval=00000000 ret=02b2a82b
00fd:Call advapi32.CryptSetKeyParam(024e4900,00000001,101c1fe0,00000000)
ret=0c78cbf6
00fd:trace:crypt:CryptSetKeyParam (0x24e4900, 1, 0x101c1fe0, 00000000)
00fd:Call rsaenh.CPSetKeyParam(00000005,00000004,00000001,101c1fe0,00000000)
ret=7f515c928b9d
00fd:trace:crypt:RSAENH_CPSetKeyParam (hProv=00000005, hKey=00000004,
dwParam=00000001, pbData=00000000101C1FE0, dwFlags=00000000)
00fd:Call msvcrt.memcpy(024ca5b0,101c1fe0,00000010) ret=6650db94
00fd:Ret  msvcrt.memcpy() retval=024ca5b0 ret=6650db94
00fd:Ret  rsaenh.CPSetKeyParam() retval=00000001 ret=7f515c928b9d
00fd:Ret  advapi32.CryptSetKeyParam() retval=00000001 ret=0c78cbf6
00fd:Call KERNEL32.GetLastError() ret=02b2a82b
00fd:Ret  KERNEL32.GetLastError() retval=00000000 ret=02b2a82b 
...
00fd:Call
advapi32.CryptDecrypt(024e4900,00000000,00000000,00000000,101c2100,0024a638)
ret=0c78de54
00fd:trace:crypt:CryptDecrypt (0x24e4900, 0x0, 0, 00000000, 0x101c2100,
0x24a638)
00fd:Call
rsaenh.CPDecrypt(00000005,00000004,00000000,00000000,00000000,101c2100,0024a638)
ret=7f515c92594c
00fd:trace:crypt:RSAENH_CPDecrypt (hProv=00000005, hKey=00000004,
hHash=00000000, Final=0, dwFlags=00000000, pbData=00000000101C2100,
pdwDataLen=000000000024A638)
00fd:Call msvcrt.memcpy(101c2100,0024a240,00000010) ret=66513f82
00fd:Ret  msvcrt.memcpy() retval=101c2100 ret=66513f82
00fd:Call msvcrt.memcpy(101c2110,0024a240,00000010) ret=66513f82
00fd:Ret  msvcrt.memcpy() retval=101c2110 ret=66513f82
00fd:Call msvcrt.memcpy(101c2120,0024a240,00000010) ret=66513f82 
...
00fd:Call msvcrt.memcpy(101c2820,0024a240,00000010) ret=66513f82
00fd:Ret  msvcrt.memcpy() retval=101c2820 ret=66513f82
00fd:Ret  rsaenh.CPDecrypt() retval=00000001 ret=7f515c92594c
00fd:Ret  advapi32.CryptDecrypt() retval=00000001 ret=0c78de54
...
00fd:Call
advapi32.CryptDecrypt(024e4900,00000000,00000000,00000000,101c2ff0,0024a6f8)
ret=0c78de54
00fd:trace:crypt:CryptDecrypt (0x24e4900, 0x0, 0, 00000000, 0x101c2ff0,
0x24a6f8)
00fd:Call
rsaenh.CPDecrypt(00000005,00000004,00000000,00000000,00000000,101c2ff0,0024a6f8)
ret=7f515c92594c
00fd:trace:crypt:RSAENH_CPDecrypt (hProv=00000005, hKey=00000004,
hHash=00000000, Final=0, dwFlags=00000000, pbData=00000000101C2FF0,
pdwDataLen=000000000024A6F8)
00fd:Call msvcrt.memcpy(101c2ff0,0024a300,00000010) ret=66513f82
00fd:Ret  msvcrt.memcpy() retval=101c2ff0 ret=66513f82
00fd:Ret  rsaenh.CPDecrypt() retval=00000001 ret=7f515c92594c
00fd:Ret  advapi32.CryptDecrypt() retval=00000001 ret=0c78de54
00fd:Call KERNEL32.GetLastError() ret=02b2a82b
...
00fd:Call
advapi32.CryptDecrypt(024e4900,00000000,00000001,00000000,101c3068,0024a680)
ret=0c78de54
00fd:trace:crypt:CryptDecrypt (0x24e4900, 0x0, 1, 00000000, 0x101c3068,
0x24a680)
00fd:Call
rsaenh.CPDecrypt(00000005,00000004,00000000,00000001,00000000,101c3068,0024a680)
ret=7f515c92594c
00fd:trace:crypt:RSAENH_CPDecrypt (hProv=00000005, hKey=00000004,
hHash=00000000, Final=1, dwFlags=00000000, pbData=00000000101C3068,
pdwDataLen=000000000024A680)
00fd:trace:seh:NtRaiseException code=c0000005 flags=0 addr=0x66513fc9
ip=66513fc9 tid=00fd
00fd:trace:seh:NtRaiseException  info[0]=0000000000000000
00fd:trace:seh:NtRaiseException  info[1]=00000001101c3067
00fd:trace:seh:NtRaiseException  rax=0000000000000000 rbx=0000000000000005
rcx=00000000ffffffff rdx=00000000ffffffff
00fd:trace:seh:NtRaiseException  rsi=0000000000000000 rdi=00000000101c3068
rbp=00000000024ca230 rsp=000000000024a1f0
00fd:trace:seh:NtRaiseException   r8=0000000073620457  r9=000000000024a268
r10=00000000024ca230 r11=0000000000000000
00fd:trace:seh:NtRaiseException  r12=0000000000000000 r13=000000000024a680
r14=0000000000000000 r15=0000000000000001
00fd:trace:seh:call_vectored_handlers calling handler at 0x2c729d8
code=c0000005 flags=0
00fd:Call KERNEL32.GetLastError() ret=02c72a0c
00fd:Ret  KERNEL32.GetLastError() retval=00000000 ret=02c72a0c
00fd:trace:seh:call_vectored_handlers handler at 0x2c729d8 returned 0
...
--- snip ---

Debugger:

--- snip ---
...

Wine-dbg>si
0x0000000066513fbe RSAENH_CPDecrypt+0x28e
[Z:\home\focht\projects\wine\mainline-src\dlls\rsaenh\rsaenh.c:2696] in rsaenh:
leal    0xffffffffffffffff(%rax),%edx
2696                if (pbData[*pdwDataLen-1] &&

Wine-dbg>si
0x0000000066513fc1 RSAENH_CPDecrypt+0x291
[Z:\home\focht\projects\wine\mainline-src\dlls\rsaenh\rsaenh.c:2696] in rsaenh:
movq    0x0000000000000078(%rsp),%r10
2696                if (pbData[*pdwDataLen-1] &&

Wine-dbg>si
0x0000000066513fc6 RSAENH_CPDecrypt+0x296
[Z:\home\focht\projects\wine\mainline-src\dlls\rsaenh\rsaenh.c:2696] in rsaenh:
movq    %rdx,%rcx
2696                if (pbData[*pdwDataLen-1] &&

Wine-dbg>si
0x0000000066513fc9 RSAENH_CPDecrypt+0x299
[Z:\home\focht\projects\wine\mainline-src\dlls\rsaenh\rsaenh.c:2696] in rsaenh:
movzbl    (%rdi,%rdx,1),%r9d
2696                if (pbData[*pdwDataLen-1] &&

Wine-dbg>info reg
Register dump:
 rip:0000000066513fc9 rsp:000000000022a2f0 rbp:00000000024c5650 eflags:00000202
(   - --  I   - - - )
 rax:0000000000000000 rbx:0000000000000005 rcx:00000000ffffffff
rdx:00000000ffffffff
 rsi:0000000000000000 rdi:00000000101cbe58  r8:0000000073620457 
r9:000000000022a368 r10:00000000024c5650
 r11:0000000066513d30 r12:0000000000000000 r13:000000000022a680
r14:0000000000000000 r15:0000000000000001
--- snip ---

https://source.winehq.org/git/wine.git/blob/18fbc3a3cf880f35ab497c0e2026fe850536c6bb:/dlls/rsaenh/rsaenh.c#l2623

--- snip ---
2623 BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH
hHash, BOOL Final, 
2624                              DWORD dwFlags, BYTE *pbData, DWORD
*pdwDataLen)
2625 {
2626     CRYPTKEY *pCryptKey;
2627     BYTE *in, out[RSAENH_MAX_BLOCK_SIZE], o[RSAENH_MAX_BLOCK_SIZE];
2628     DWORD i, j, k;
2629     DWORD dwMax;
2630 
2631     TRACE("(hProv=%08lx, hKey=%08lx, hHash=%08lx, Final=%d, dwFlags=%08x,
pbData=%p, "
2632           "pdwDataLen=%p)\n", hProv, hKey, hHash, Final, dwFlags, pbData,
pdwDataLen);
...
2661     dwMax=*pdwDataLen;
2662 
2663     if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) {
2664         for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen,
in+=pCryptKey->dwBlockLen) {
2665             switch (pCryptKey->dwMode) {
2666                 case CRYPT_MODE_ECB:
2667                     encrypt_block_impl(pCryptKey->aiAlgid, 0,
&pCryptKey->context, in, out, 
2668                                        RSAENH_DECRYPT);
2669                     break;
2670                 
2671                 case CRYPT_MODE_CBC:
2672                     encrypt_block_impl(pCryptKey->aiAlgid, 0,
&pCryptKey->context, in, out, 
2673                                        RSAENH_DECRYPT);
2674                     for (j=0; j<pCryptKey->dwBlockLen; j++) out[j] ^=
pCryptKey->abChainVector[j];
2675                     memcpy(pCryptKey->abChainVector, in,
pCryptKey->dwBlockLen);
2676                     break;
2677 
2678                 case CRYPT_MODE_CFB:
2679                     for (j=0; j<pCryptKey->dwBlockLen; j++) {
2680                         encrypt_block_impl(pCryptKey->aiAlgid, 0,
&pCryptKey->context, 
2681                                            pCryptKey->abChainVector, o,
RSAENH_ENCRYPT);
2682                         out[j] = in[j] ^ o[0];
2683                         for (k=0; k<pCryptKey->dwBlockLen-1; k++) 
2684                             pCryptKey->abChainVector[k] =
pCryptKey->abChainVector[k+1];
2685                         pCryptKey->abChainVector[k] = in[j];
2686                     }
2687                     break;
2688                     
2689                 default:
2690                     SetLastError(NTE_BAD_ALGID);
2691                     return FALSE;
2692             }
2693             memcpy(in, out, pCryptKey->dwBlockLen);
2694         }
2695         if (Final) {
2696             if (pbData[*pdwDataLen-1] &&
2697              pbData[*pdwDataLen-1] <= pCryptKey->dwBlockLen &&
2698              pbData[*pdwDataLen-1] <= *pdwDataLen) {
2699                 BOOL padOkay = TRUE;
2700 
2701                 /* check that every bad byte has the same value */
2702                 for (i = 1; padOkay && i < pbData[*pdwDataLen-1]; i++)
2703                     if (pbData[*pdwDataLen - i - 1] != pbData[*pdwDataLen
- 1])
2704                         padOkay = FALSE;
2705                 if (padOkay)
2706                     *pdwDataLen -= pbData[*pdwDataLen-1];
2707                 else {
2708                     SetLastError(NTE_BAD_DATA);
2709                     setup_key(pCryptKey);
2710                     return FALSE;
2711                 }
2712             }
2713             else {
2714                 SetLastError(NTE_BAD_DATA);
2715                 setup_key(pCryptKey);
2716                 return FALSE;
2717             }
2718         }
...
2734     
2735     if (Final) setup_key(pCryptKey);
...
--- some ---

Line 2696, the caller which seems some jitted .NET code passed zero *pdwDataLen
for whatever reason.

Microsoft docs:

https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt

--- quote ---
...
pbData

A pointer to a buffer that contains the data to be decrypted. After the
decryption has been performed, the plaintext is placed back into this same
buffer.

The number of encrypted bytes in this buffer is specified by pdwDataLen.

pdwDataLen

A pointer to a DWORD value that indicates the length of the pbData buffer.
Before calling this function, the calling application sets the DWORD value to
the number of bytes to be decrypted. Upon return, the DWORD value contains the
number of bytes of the decrypted plaintext.

When a block cipher is used, this data length must be a multiple of the block
size unless this is the final section of data to be decrypted and the Final
parameter is TRUE.
--- quote ---

I've added a check for zero *pdwDataLen in line 2695 to skip that block and it
made the app successfully start. I don't know if this is just undocumented
behaviour or an application bug.

$ sha1sum rhino_en-us_6.15.19164.21011.exe 
85e34606c761ec7229cbe2c6ba7efeae7e778a97  rhino_en-us_6.15.19164.21011.exe

$ du -sh rhino_en-us_6.15.19164.21011.exe 
263M    rhino_en-us_6.15.19164.21011.exe

$ wine --version
wine-4.12.1

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