http://bugs.winehq.org/show_bug.cgi?id=32558
Bug #: 32558 Summary: Visual Studio 2010 (10.0) Express Edition web installer crashes due to winhttp reporting available chunk size > 32 KiB (heap corruption) Product: Wine Version: 1.5.20 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: winhttp AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net Classification: Unclassified
Hello folks,
I noticed strange crashes with the web installer of Visual Studio 2010 (10.0) Express Edition. Sometimes the installer would just bail out silently during download.
Prerequisite: 'winetricks -q dotnet20 dotnet40'
Unfortunately +relay or even repeated installer runs succeed most of the time so it's not easily to reproduce/track down (also depends on client connection to server). Also running the inner installer under debugger changes symptoms.
Fortunately I managed get a crash with +relay at one time (using inner installer).
--- snip --- $ WINEDEBUG=+tid,+seh,+loaddll,+winhttp,+relay wine ./setup.exe /web /CreatedTemp /NoExclude /InstalledFrom . >>log.txt 2>&1 ... 002a:trace:loaddll:load_native_dll Loaded L"Z:\home\focht\Downloads\test\dlmgr.dll" at 0x364c0000: native ... 0030:Call oleaut32.SysAllocString(00c00840 L"dlmgr: Starting download attempt 1 of 3 for http://go.microsoft.com/fwlink/?LinkId=165067&clcid=0x409 using Http") ret=3593f268 0030:Ret oleaut32.SysAllocString() retval=01560ec4 ret=3593f268 ... 0030:Call ntdll.RtlAllocateHeap(00453000,00000008,00008000) ret=364e1884 0030:Ret ntdll.RtlAllocateHeap() retval=0045bdc8 ret=364e1884 ... 0042:Call KERNEL32.CreateFileW(0186f540 L"C:\users\focht\Temp\30319.01\1033\VC_EXP\wcu\watson\dw20shared.msi",00000002,00000000,00000000,00000002,00000080,00000000) ret=364db8ff 0042:Ret KERNEL32.CreateFileW() retval=000001e8 ret=364db8ff ... 0042:Call winhttp.WinHttpQueryHeaders(00000003,00000005,00000000,0b56e850,0b56e840,00000000) ret=364d77ed 0042:trace:winhttp:WinHttpQueryHeaders 0x3, 0x00000005, (null), 0xb56e850, 0xb56e840, (nil) 0042:trace:winhttp:addref_object 0x1718bc0 -> refcount = 3 0042:trace:winhttp:grab_object handle 0x3 -> 0x1718bc0 0042:trace:winhttp:query_headers attribute L"Content-Length" 0042:trace:winhttp:get_header_index L"Content-Length" 0042:trace:winhttp:get_header_index returning 12 0042:trace:winhttp:query_headers returning string: L"1850368" 0042:trace:winhttp:release_object object 0x1718bc0 refcount = 2 0042:Ret winhttp.WinHttpQueryHeaders() retval=00000001 ret=364d77ed 0042:Call winhttp.WinHttpQueryDataAvailable(00000003,00000000) ret=364d77a6 0042:trace:winhttp:WinHttpQueryDataAvailable 0x3, (nil) 0042:trace:winhttp:addref_object 0x1718bc0 -> refcount = 3 0042:trace:winhttp:grab_object handle 0x3 -> 0x1718bc0 0042:Call ntdll.RtlAllocateHeap(00110000,00000000,0000000c) ret=7e2dc554 0042:Ret ntdll.RtlAllocateHeap() retval=0186fa68 ret=7e2dc554 0042:trace:winhttp:addref_object 0x1718bc0 -> refcount = 4 0042:Call KERNEL32.QueueUserWorkItem(7e2dc7e9,0186fa68,00000010) ret=7e2dc85b 0042:Ret KERNEL32.QueueUserWorkItem() retval=00000001 ret=7e2dc85b 0042:trace:winhttp:release_object object 0x1718bc0 refcount = 3 0042:Ret winhttp.WinHttpQueryDataAvailable() retval=00000001 ret=364d77a6 --- snip ---
Download for first component is 1850368 bytes in total. The installer allocates a 32 KiB buffer and begins async download using winhttp.
The "good" sequence reads like this:
--- snip --- ... 0044:Call winhttp.WinHttpReadData(00000003,0045bdc8,00001554,00000000) ret=364d7787 0042:Call ntdll.RtlFreeHeap(00110000,00000000,01718950) ret=7e2dc63a 0044:trace:winhttp:WinHttpReadData 0x3, 0x45bdc8, 5460, (nil) 0042:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7e2dc63a 0044:trace:winhttp:addref_object 0x1718bc0 -> refcount = 3 0044:trace:winhttp:grab_object handle 0x3 -> 0x1718bc0 0044:Call ntdll.RtlAllocateHeap(00110000,00000000,00000014) ret=7e2dc554 0044:Ret ntdll.RtlAllocateHeap() retval=01718cb0 ret=7e2dc554 0044:trace:winhttp:addref_object 0x1718bc0 -> refcount = 4 0044:Call KERNEL32.QueueUserWorkItem(7e2dc7e9,01718cb0,00000010) ret=7e2dc85b 0042:trace:winhttp:query_headers attribute L"Transfer-Encoding" 0042:trace:winhttp:get_header_index L"Transfer-Encoding" 0042:trace:winhttp:get_header_index returning -1 0042:trace:winhttp:read_data *** async=1, to_read=5460, num_bytes: 5460, ret=1, callback=0x364da8e0, buffer=0x45bdc8 0042:trace:winhttp:read_data *** buf heap magic=0x455355, size=0x8000 0042:trace:winhttp:send_callback 0x1718bc0, 0x00080000, 0x45bdc8, 5460 0042:Call KERNEL32.WriteFile(000001e8,0045bdc8,00001554,0b56e814,00000000) ret=364db83b 0042:Ret KERNEL32.WriteFile() retval=00000001 ret=364db83b ... 0044:Ret KERNEL32.QueueUserWorkItem() retval=00000001 ret=7e2dc85b ... 0044:trace:winhttp:release_object object 0x1718bc0 refcount = 3 0042:Ret KERNEL32.GetLastError() retval=00002f76 ret=364dfd2f 0044:Ret winhttp.WinHttpReadData() retval=00000001 ret=364d7787 --- snip ---
"trace:winhttp:read_data ***" trace message was added by me for diagnosis immediately before the send callback (also heap magic and size dump because +heap is not usable here).
At one point we get this interesting sequence:
--- snip --- ... 000d:Call winhttp.WinHttpQueryDataAvailable(00000003,00000000) ret=364d77a6 000d:trace:winhttp:WinHttpQueryDataAvailable 0x3, (nil) 000d:trace:winhttp:addref_object 0x1718bc0 -> refcount = 3 000d:trace:winhttp:grab_object handle 0x3 -> 0x1718bc0 000d:Call ntdll.RtlAllocateHeap(00110000,00000000,0000000c) ret=7e2dc554 000d:Ret ntdll.RtlAllocateHeap() retval=01718cb0 ret=7e2dc554 000d:trace:winhttp:addref_object 0x1718bc0 -> refcount = 4 000d:Call KERNEL32.QueueUserWorkItem(7e2dc7e9,01718cb0,00000010) ret=7e2dc85b 000d:Ret KERNEL32.QueueUserWorkItem() retval=00000001 ret=7e2dc85b 0042:trace:winhttp:query_data 73440 bytes available 000d:trace:winhttp:release_object object 0x1718bc0 refcount = 3 0042:trace:winhttp:send_callback 0x1718bc0, 0x00040000, 0xb56e90c, 4 000d:Ret winhttp.WinHttpQueryDataAvailable() retval=00000001 ret=364d77a6 ... 0042:Call winhttp.WinHttpReadData(00000003,0045bdc8,00011ee0,00000000) ret=364d7787 000d:Call ntdll.RtlFreeHeap(00110000,00000000,01870290) ret=7e2dc63a 0042:trace:winhttp:WinHttpReadData 0x3, 0x45bdc8, 73440, (nil) 000d:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7e2dc63a 0042:trace:winhttp:addref_object 0x1718bc0 -> refcount = 3 0042:trace:winhttp:grab_object handle 0x3 -> 0x1718bc0 0042:Call ntdll.RtlAllocateHeap(00110000,00000000,00000014) ret=7e2dc554 0042:Ret ntdll.RtlAllocateHeap() retval=01870290 ret=7e2dc554 0042:trace:winhttp:addref_object 0x1718bc0 -> refcount = 4 0042:Call KERNEL32.QueueUserWorkItem(7e2dc7e9,01870290,00000010) ret=7e2dc85b 0042:Ret KERNEL32.QueueUserWorkItem() retval=00000001 ret=7e2dc85b 0044:trace:winhttp:query_headers attribute L"Transfer-Encoding" 0042:trace:winhttp:release_object object 0x1718bc0 refcount = 3 0044:trace:winhttp:get_header_index L"Transfer-Encoding" 0042:Ret winhttp.WinHttpReadData() retval=00000001 ret=364d7787 0044:trace:winhttp:get_header_index returning -1 0042:trace:winhttp:release_object object 0x1718bc0 refcount = 2 0042:Call ntdll.RtlFreeHeap(00110000,00000000,01718cb0) ret=7e2dc63a 0042:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7e2dc63a 0044:trace:winhttp:read_data *** async=1, to_read=73440, num_bytes: 73440, ret=1, callback=0x364da8e0, buffer=0x45bdc8 0044:trace:winhttp:read_data *** buf heap magic=0x455355, size=0x8000 0044:trace:winhttp:send_callback 0x1718bc0, 0x00080000, 0x45bdc8, 73440 ... --- snip ---
73440 bytes available reported and WinHttpReadData() is called from installer with the _same_ original buffer (0x45bdc8) which was allocated with 32 KiB (0x8000 bytes) - no realloc in between! This obviously leads to a heap overwrite and some time later to crashes.
--- snip --- ... 000d:trace:winhttp:read_data *** async=1, to_read=5760, num_bytes: 5760, ret=1, callback=0x364da8e0, buffer=0x45bdc8 000d:trace:winhttp:read_data *** buf heap magic=0x455355, size=0x8000 000d:trace:winhttp:send_callback 0x1718bc0, 0x00080000, 0x45bdc8, 5760 000d:Call KERNEL32.WriteFile(000001e8,0045bdc8,00001680,0b76e814,00000000) ret=364db83b 000d:Ret KERNEL32.WriteFile() retval=00000001 ret=364db83b 000d:Call ntdll.RtlAllocateHeap(00110000,00000000,00000080) ret=364ee12c 000d:Ret ntdll.RtlAllocateHeap() retval=0186fc18 ret=364ee12c 000d:Call KERNEL32.GetLastError() ret=364dfd2f 000d:Ret KERNEL32.GetLastError() retval=00002f76 ret=364dfd2f 000d:Call KERNEL32.GetLastError() ret=364dfd2f 000d:Ret KERNEL32.GetLastError() retval=00002f76 ret=364dfd2f 000d:trace:seh:raise_exception code=c0000005 flags=0 addr=0x364e4b6f ip=364e4b6f tid=000d 000d:trace:seh:raise_exception info[0]=00000000 000d:trace:seh:raise_exception info[1]=98211559 000d:trace:seh:raise_exception eax=982114ad ebx=00000002 ecx=0b76e30c edx=00000000 esi=0b76e53a edi=0b76e53a 000d:trace:seh:raise_exception ebp=0b76e740 esp=0b76e2bc cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010202 --- snip ---
I added a small code snippet to automatically report/truncate available chunk size to 32 KiB if larger.
--- snip --- ... fixme:winhttp:query_data truncating data avail from 50400 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 89632 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 71264 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 91776 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 116608 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 93920 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 69792 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 96064 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 67616 to 32768 bytes! fixme:winhttp:query_data truncating data avail from 59328 to 32768 bytes! ... --- snip ---
With that change in place the web installer runs rock stable, sometimes reaching download speeds of 2-3 MiB/s using winhttp (not maxing out my connection - that might be server-side bandwidth issue).
I've not found any useful info on MSDN about a 32 KiB limit on winhttp chunk size. Maybe the MS guys who wrote the installer made some assumption about some underlying native winsock implementation limitation on Windows.
It might be interesting to see what max. chunk size native winhttp reports to clients.
Regards
http://bugs.winehq.org/show_bug.cgi?id=32558
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download, Installer URL| |https://www.microsoft.com/v | |isualstudio/eng/downloads#d | |-2010-express
--- Comment #1 from Anastasius Focht focht@gmx.net 2012-12-26 18:17:51 CST --- Hello folks,
filling fields ...
$ du -sh vc_web.exe 3.2M vc_web.exe
$ sha1sum vc_web.exe c2d61a5424aa474a169e59199aa2158a858833f6 vc_web.exe
$ wine --version wine-1.5.20
Regards
http://bugs.winehq.org/show_bug.cgi?id=32558
--- Comment #2 from Anastasius Focht focht@gmx.net 2012-12-27 07:43:58 CST --- Hello folks,
Microsoft Visual Studio 2010 Professional Web Installer (Trial version) seems also affected by this. Limiting chunk size to max. 32 KiB avoids the problem and lets the online installer run stable (downloads multi-GiB payloads successfully).
Download link: https://www.microsoft.com/en-us/download/details.aspx?id=2890
Regards
http://bugs.winehq.org/show_bug.cgi?id=32558
Sylvain Petreolle spetreolle@yahoo.fr changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |spetreolle@yahoo.fr
http://bugs.winehq.org/show_bug.cgi?id=32558
--- Comment #3 from Hans Leidekker hans@meelstraat.net 2013-03-27 03:17:18 CDT --- This should be fixed by bb3097f01e532583c8c78c9daf64ff29f8eb255c.
http://bugs.winehq.org/show_bug.cgi?id=32558
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |bb3097f01e532583c8c78c9daf6 | |4ff29f8eb255c Status|NEW |RESOLVED Resolution| |FIXED
--- Comment #4 from Austin English austinenglish@gmail.com 2013-03-27 16:02:09 CDT --- (In reply to comment #2)
Hello folks,
Microsoft Visual Studio 2010 Professional Web Installer (Trial version) seems also affected by this. Limiting chunk size to max. 32 KiB avoids the problem and lets the online installer run stable (downloads multi-GiB payloads successfully).
Download link: https://www.microsoft.com/en-us/download/details.aspx?id=2890
Regards
Works for me in wine-1.5.26-88-gfbe7ab5
http://bugs.winehq.org/show_bug.cgi?id=32558
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #5 from Alexandre Julliard julliard@winehq.org 2013-03-29 13:32:50 CDT --- Closing bugs fixed in 1.5.27.
https://bugs.winehq.org/show_bug.cgi?id=32558
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- URL|https://www.microsoft.com/v |https://web.archive.org/web |isualstudio/eng/downloads#d |/20130329153355/http://down |-2010-express |load.microsoft.com/download | |/D/B/C/DBC11267-9597-46FF-8 | |377-E194A73970D6/vs_proweb. | |exe