When an async object enters the async queue, its fd is released (to avoid
a reference cycle I assume?). In screen_buffer_destroy, the screen_buffer's
fd is released first, this cause it to be freed even when it could still be
referenced by an async object in the queue. This means free_async_queue
could use freed memory.
* * *
Found in ASan CI, but here is a much better report:
<details>
<summary>report</summary>
```
=================================================================
==3803229==ERROR: AddressSanitizer: heap-use-after-free on address 0x5120006d6650 at pc 0x000000448b29 bp 0x7fff2dbcc5b0 sp 0x7fff2dbcc5a8
READ of size 8 at 0x5120006d6650 thread T0
#0 0x448b28 in fd_get_completion /home/shui/programs/wine/server/fd.c:2793
#1 0x4084f3 in free_async_queue /home/shui/programs/wine/server/async.c:231
#2 0x4228e4 in screen_buffer_destroy /home/shui/programs/wine/server/console.c:866
#3 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#4 0x421f13 in console_destroy /home/shui/programs/wine/server/console.c:768
#5 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#6 0x424d3a in console_connection_close_handle /home/shui/programs/wine/server/console.c:1285
#7 0x451498 in handle_table_destroy /home/shui/programs/wine/server/handle.c:185
#8 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#9 0x4515a2 in close_process_handles /home/shui/programs/wine/server/handle.c:198
#10 0x4805e5 in process_killed /home/shui/programs/wine/server/process.c:990
#11 0x480ab5 in remove_process_thread /home/shui/programs/wine/server/process.c:1040
#12 0x4fe26e in kill_thread /home/shui/programs/wine/server/thread.c:1574
#13 0x480f56 in kill_process /home/shui/programs/wine/server/process.c:1097
#14 0x47fbba in process_poll_event /home/shui/programs/wine/server/process.c:882
#15 0x43c954 in fd_poll_event /home/shui/programs/wine/server/fd.c:510
#16 0x43d338 in main_loop_epoll /home/shui/programs/wine/server/fd.c:618
#17 0x43dec3 in main_loop /home/shui/programs/wine/server/fd.c:972
#18 0x45e6a4 in main /home/shui/programs/wine/server/main.c:239
#19 0x7f4cf7f1d4d7 in __libc_start_call_main (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a4d7) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#20 0x7f4cf7f1d59a in __libc_start_main_alias_1 (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a59a) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#21 0x406a84 in _start (/home/shui/.cache/wine-builds/wow+asan/server/wineserver+0x406a84)
0x5120006d6650 is located 272 bytes inside of 288-byte region [0x5120006d6540,0x5120006d6660)
freed by thread T0 here:
#0 0x7f4cf81f73f8 in free.part.0 (/nix/store/6vzcxjxa2wlh3p9f5nhbk62bl3q313ri-gcc-14.3.0-lib/lib/libasan.so.8+0xfb3f8)
#1 0x4776f5 in free_object /home/shui/programs/wine/server/object.c:333
#2 0x478913 in release_object /home/shui/programs/wine/server/object.c:557
#3 0x4228d4 in screen_buffer_destroy /home/shui/programs/wine/server/console.c:865
#4 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#5 0x421f13 in console_destroy /home/shui/programs/wine/server/console.c:768
#6 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#7 0x424d3a in console_connection_close_handle /home/shui/programs/wine/server/console.c:1285
#8 0x451498 in handle_table_destroy /home/shui/programs/wine/server/handle.c:185
#9 0x478907 in release_object /home/shui/programs/wine/server/object.c:556
#10 0x4515a2 in close_process_handles /home/shui/programs/wine/server/handle.c:198
#11 0x4805e5 in process_killed /home/shui/programs/wine/server/process.c:990
#12 0x480ab5 in remove_process_thread /home/shui/programs/wine/server/process.c:1040
#13 0x4fe26e in kill_thread /home/shui/programs/wine/server/thread.c:1574
#14 0x480f56 in kill_process /home/shui/programs/wine/server/process.c:1097
#15 0x47fbba in process_poll_event /home/shui/programs/wine/server/process.c:882
#16 0x43c954 in fd_poll_event /home/shui/programs/wine/server/fd.c:510
#17 0x43d338 in main_loop_epoll /home/shui/programs/wine/server/fd.c:618
#18 0x43dec3 in main_loop /home/shui/programs/wine/server/fd.c:972
#19 0x45e6a4 in main /home/shui/programs/wine/server/main.c:239
#20 0x7f4cf7f1d4d7 in __libc_start_call_main (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a4d7) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#21 0x7f4cf7f1d59a in __libc_start_main_alias_1 (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a59a) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#22 0x406a84 in _start (/home/shui/.cache/wine-builds/wow+asan/server/wineserver+0x406a84)
previously allocated by thread T0 here:
#0 0x7f4cf81f8757 in malloc (/nix/store/6vzcxjxa2wlh3p9f5nhbk62bl3q313ri-gcc-14.3.0-lib/lib/libasan.so.8+0xfc757)
#1 0x476b07 in mem_alloc /home/shui/programs/wine/server/object.c:223
#2 0x47724d in alloc_object /home/shui/programs/wine/server/object.c:304
#3 0x442b6f in alloc_pseudo_fd /home/shui/programs/wine/server/fd.c:1747
#4 0x4214b0 in create_screen_buffer /home/shui/programs/wine/server/console.c:655
#5 0x422e92 in console_server_lookup_name /home/shui/programs/wine/server/console.c:930
#6 0x477b0b in lookup_named_object /home/shui/programs/wine/server/object.c:379
#7 0x4781c8 in open_named_object /home/shui/programs/wine/server/object.c:489
#8 0x449525 in req_open_file_object /home/shui/programs/wine/server/fd.c:2858
#9 0x4cea17 in call_req_handler /home/shui/programs/wine/server/request.c:305
#10 0x4cf082 in read_request /home/shui/programs/wine/server/request.c:360
#11 0x4f793a in thread_poll_event /home/shui/programs/wine/server/thread.c:581
#12 0x43c954 in fd_poll_event /home/shui/programs/wine/server/fd.c:510
#13 0x43d338 in main_loop_epoll /home/shui/programs/wine/server/fd.c:618
#14 0x43dec3 in main_loop /home/shui/programs/wine/server/fd.c:972
#15 0x45e6a4 in main /home/shui/programs/wine/server/main.c:239
#16 0x7f4cf7f1d4d7 in __libc_start_call_main (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a4d7) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#17 0x7f4cf7f1d59a in __libc_start_main_alias_1 (/nix/store/g2jzxk3s7cnkhh8yq55l4fbvf639zy37-glibc-2.40-66/lib/libc.so.6+0x2a59a) (BuildId: f117ee0f586dfa828cbdd08e37393c8f04f6480a)
#18 0x406a84 in _start (/home/shui/.cache/wine-builds/wow+asan/server/wineserver+0x406a84)
SUMMARY: AddressSanitizer: heap-use-after-free /home/shui/programs/wine/server/fd.c:2793 in fd_get_completion
Shadow bytes around the buggy address:
0x5120006d6380: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x5120006d6400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x5120006d6480: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
0x5120006d6500: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x5120006d6580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x5120006d6600: fd fd fd fd fd fd fd fd fd fd[fd]fd fa fa fa fa
0x5120006d6680: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x5120006d6700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x5120006d6780: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x5120006d6800: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x5120006d6880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==3803229==ABORTING
```
</details>
I think this is the right fix?
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8642
Streams hold a reference to the source, but this reference should not be taken until `Start()` is called because freeing the media source depends on release in `Shutdown()` of the stream's reference to the source. We could create the streams in `media_source_create()` and take source refs for them in `Start()`, but that's potentially confusing and fragile.
Streams can persist after the media source is destroyed. In that case, they cannot access the source object and it should be released and set to null. Windows behaviour is to release references to the source in `Shutdown()`. If we don't do this and a buggy app were to leak a stream object, the media source object would also leak and `wg_parser_destroy()` would not be called.
--
v8: winegstreamer: Release stream references to the media source in Shutdown().
winegstreamer: Do not create MF stream objects until the media source is started.
mfplat/tests: Test video stream release after media source release.
mfplat/tests: Add more media source refcount checks.
https://gitlab.winehq.org/wine/wine/-/merge_requests/6783
For calls with return values, we emit a IsReturn parameter for it into
__MIDL_ProcFormatString. During the INITOUT phase, client_do_args will try to
read at this address. But we do not generate a _RetVal member for the
_PARAM_STRUCTS types used by proxies, this means client_do_args will read out
of bound.
* * *
An example is `IDispatchEx_RemoteInvokeEx_Proxy`
asan complaint:
```
015c:0160:err:asan:asan_report ASan: read of 4 bytes at 015A88DC, caller 6A9A0EFA (__asan_report_load4_noabort, /home/shui/programs/wine/dlls/asan_dynamic_thunk/thunk.c:1031,1)
015c:0160:err:asan:asan_report stacktrace:
015c:0160:err:asan:asan_report 6A9A0EFA (__asan_report_load4_noabort, /home/shui/programs/wine/dlls/asan_dynamic_thunk/thunk.c:1031,1)
015c:0160:err:asan:asan_report 6A9ACB2C (client_do_args, /home/shui/programs/wine/dlls/rpcrt4/ndr_stubless.c:511,17)
015c:0160:err:asan:asan_report 6A9C5913 (ndr_client_call, /home/shui/programs/wine/dlls/rpcrt4/ndr_stubless.c:794,9)
015c:0160:err:asan:asan_report 6A965438 (NdrpClientCall2, /home/shui/programs/wine/dlls/rpcrt4/ndr_stubless.c:929,22)
015c:0160:err:asan:asan_report 6A916C77 (NdrClientCall2)
015c:0160:err:asan:asan_report 68662856 (IDispatchEx_RemoteInvokeEx_Proxy, dlls/dispex/i386-windows/disp_ex_p.c:82,15)
015c:0160:err:asan:asan_report 68661D6E (IDispatchEx_InvokeEx_Proxy, /home/shui/programs/wine/dlls/dispex/usrmarshal.c:100,10)
015c:0160:err:asan:asan_report 00401187 (IDispatchEx_InvokeEx, include/dispex.h:319,12)
015c:0160:err:asan:asan_report 00408F36 (test_dispex, /home/shui/programs/wine/dlls/dispex/tests/marshal.c:391,10)
015c:0160:err:asan:asan_report 004061FF (func_marshal, /home/shui/programs/wine/dlls/dispex/tests/marshal.c:433,5)
015c:0160:err:asan:asan_report 00407B60 (run_test, /home/shui/programs/wine/include/wine/test.h:794,9)
015c:0160:err:asan:asan_report 00407426 (main, /home/shui/programs/wine/include/wine/test.h:912,1)
015c:0160:err:asan:asan_report 0040767C (mainCRTStartup, /home/shui/programs/wine/dlls/msvcrt/crt_main.c:60,11)
015c:0160:err:asan:asan_report 7901FA24 (BaseThreadInitThunk)
015c:0160:err:asan:asan_report 7A50E0F7 (call_thread_func_wrapper)
015c:0160:err:asan:asan_report 7A5B6ADD (call_thread_func, /home/shui/programs/wine/dlls/ntdll/signal_i386.c:505,5)
015c:0160:err:asan:asan_report info:
015c:0160:err:asan:asan_report partial granule: 4
015c:0160:err:asan:asan_report stack-buffer-overflow, addr is 4 bytes to the right of the end of stack
015c:0160:err:asan:asan_report stack: [015A8820, 015A8860)
015c:0160:err:asan:asan_report stack pc: 6866252C (IDispatchEx_RemoteInvokeEx_Proxy, dlls/dispex/i386-windows/disp_ex_p.c:54,1), descr: 2 32 4 10 _RetVal:55 48 44 11 __params:69
```
the parameters info:
```
0024:trace:rpc:ndr_client_call INITOUT
0024:trace:rpc:client_do_args param[0]: 015EB834 type 08 IsIn IsBasetype
0024:trace:rpc:client_do_args param[1]: 015EB838 type 08 IsIn IsBasetype
0024:trace:rpc:client_do_args param[2]: 015EB83C type 08 IsIn IsBasetype
0024:trace:rpc:client_do_args param[3]: 015EB840 type 16 MustSize MustFree IsIn IsSimpleRef
0024:trace:rpc:client_do_args param[4]: 015EB844 type b4 MustSize MustFree IsOut IsSimpleRef ServerAllocSize = 16
0024:trace:rpc:client_do_args param[5]: 015EB848 type 1a MustSize MustFree IsOut IsSimpleRef ServerAllocSize = 32
0024:trace:rpc:client_do_args param[6]: 015EB84C type 2f MustSize MustFree IsIn
0024:trace:rpc:client_do_args param[7]: 015EB850 type 08 IsIn IsBasetype
0024:trace:rpc:client_do_args param[8]: 015EB854 type 1b MustSize MustFree IsIn IsSimpleRef
0024:trace:rpc:client_do_args param[9]: 015EB858 type 21 MustSize MustFree IsIn IsOut IsSimpleRef
0024:trace:rpc:client_do_args param[10]: 015EB85C type 08 IsOut IsReturn IsBasetype
```
reading of `param[10]` at `015EB85C`, which is the non-existent `_RetVal`, triggers the asan report.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8639
In get_valloc_info, if mem happens to point to the last chunk of memory in the
user space virtual address space, "p += info2.RegionSize" will cause it to go
over the limit, and subsequent VirtualQueries will fail, thus info2 won't be
changed, thus the loop exit condition is never met (well until p wraps around,
that is).
* * *
Witnessed this in CI:
```
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7ffffffe0000, info_class=0, 0x442120, 48, 0xfd4a0)
012c:0130:trace:virtual:get_vprot_range_size base 0x7ffffffe0000, size 0x10000, mask 0xbf.
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7ffffffe0000, info_class=0, 0x442170, 48, 0xfd520)
012c:0130:trace:virtual:get_vprot_range_size base 0x7ffffffe0000, size 0x10000, mask 0xbf.
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x7fffffff0000, info_class=0, 0x442170, 48, 0xfd5e0)
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000000000, info_class=0, 0x442170, 48, 0xfd820)
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000010000, info_class=0, 0x442170, 48, 0xfda60)
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000020000, info_class=0, 0x442170, 48, 0xfdca0)
012c:0130:trace:virtual:NtQueryVirtualMemory (0xffffffffffffffff, 0x800000030000, info_class=0, 0x442170, 48, 0xfdee0)
...
```
and winetest logs:
```
...
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.322 Test failed: init size 0: got 0.
heap.c:3662:3.323 Test failed: init size 0: got 0.
heap.c:3662:3.323 Test failed: init size 0: got 0.
...
```
ad infinitum
Probably made more likely by ASan since it takes a big chunk of the address space.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8638
This fixes Trials Fusion often crashing when disconnecting a controller while there are more still connected.
--
v6: hidclass: Set Status for pending IRPs of removed devices to STATUS_DEVICE_NOT_CONNECTED.
ntdll/tests: Test IOSB values of the cancel operation.
https://gitlab.winehq.org/wine/wine/-/merge_requests/7797
--
v2: windows.media.speech: Disable format check when initializing mmdevapi.
winmm: Disable format check when initializing mmdevapi.
libs/faudio: Disable format check when initializing mmdevapi.
mmdevapi: Disable format check when initializing spatial audio.
mmdevapi: Introduce a private interface to disable the format check.
mmdevapi/tests: Test 32-bit PCM sample formats.
winepulse.drv: Allow 32-bit PCM audio samples.
mmdevapi: Allow a sampling rate mismatch when rate adjust is supported.
mmdevapi/tests: Test audio client initialization with rate adjust flag.
mmdevapi/tests: Add a couple of spatialaudio checks.
https://gitlab.winehq.org/wine/wine/-/merge_requests/8598