mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-22 09:58:09 +02:00
When a link enters the "ERROR" state, it is scheduled for destruction in
`module-link-factory.c:link_state_changed()`, which queues `destroy_link()`
to be executed on the context's work queue.
However, if the link is destroyed by means of `pw_impl_link_destroy()`
directly after that, then `link_destroy()` unregisters the associated
`pw_global`'s event hook, resulting in `global_destroy()` not being called
when `pw_impl_link_destroy()` proceeds to call `pw_global_destroy()` some
time later. This causes the scheduled async work to not be cancelled. When
it runs later, it will trigger a use-after-free since the `link_data` object
is directly tied to the `pw_impl_link` object.
For example, if the link is destroyed when the client disconnects:
==259313==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ce753028af0 at pc 0x7f475354a565 bp 0x7ffd71501930 sp 0x7ffd71501920
READ of size 8 at 0x7ce753028af0 thread T0
#0 0x7f475354a564 in destroy_link ../src/modules/module-link-factory.c:253
#1 0x7f475575a234 in process_work_queue ../src/pipewire/work-queue.c:67
#2 0x7b47504e7f24 in source_event_func ../spa/plugins/support/loop.c:1011
[...]
0x7ce753028af0 is located 1136 bytes inside of 1208-byte region [0x7ce753028680,0x7ce753028b38)
freed by thread T0 here:
#0 0x7f475631f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51
#1 0x7f4755594a44 in pw_impl_link_destroy ../src/pipewire/impl-link.c:1742
#2 0x7f475569dc11 in do_destroy_link ../src/pipewire/impl-port.c:1386
#3 0x7f47556a428b in pw_impl_port_for_each_link ../src/pipewire/impl-port.c:1673
#4 0x7f475569dc3e in pw_impl_port_unlink ../src/pipewire/impl-port.c:1392
#5 0x7f47556a02d8 in pw_impl_port_destroy ../src/pipewire/impl-port.c:1453
#6 0x7f4755634f79 in pw_impl_node_destroy ../src/pipewire/impl-node.c:2447
#7 0x7b474f722ba8 in client_node_resource_destroy ../src/modules/module-client-node/client-node.c:1253
#8 0x7f47556d7c6c in pw_resource_destroy ../src/pipewire/resource.c:325
#9 0x7f475545f07d in destroy_resource ../src/pipewire/impl-client.c:627
#10 0x7f47554550cd in pw_map_for_each ../src/pipewire/map.h:222
#11 0x7f4755460aa4 in pw_impl_client_destroy ../src/pipewire/impl-client.c:681
#12 0x7b474fb0658b in handle_client_error ../src/modules/module-protocol-native.c:471
[...]
Fix this by cancelling the work queue item in `link_destroy()`, which should
always run, regardless of the ordering of events.
Fixes #4691
|
||
|---|---|---|
| .. | ||
| module-adapter | ||
| module-avb | ||
| module-client-device | ||
| module-client-node | ||
| module-jack-tunnel | ||
| module-metadata | ||
| module-netjack2 | ||
| module-profiler | ||
| module-protocol-native | ||
| module-protocol-pulse | ||
| module-raop | ||
| module-roc | ||
| module-rt | ||
| module-rtp | ||
| module-session-manager | ||
| module-vban | ||
| module-zeroconf-discover | ||
| spa | ||
| flatpak-utils.h | ||
| meson.build | ||
| module-access.c | ||
| module-adapter.c | ||
| module-avb.c | ||
| module-client-device.c | ||
| module-client-node.c | ||
| module-combine-stream.c | ||
| module-echo-cancel.c | ||
| module-example-filter.c | ||
| module-example-sink.c | ||
| module-example-source.c | ||
| module-fallback-sink.c | ||
| module-ffado-driver.c | ||
| module-filter-chain.c | ||
| module-jack-tunnel.c | ||
| module-jackdbus-detect.c | ||
| module-link-factory.c | ||
| module-loopback.c | ||
| module-metadata.c | ||
| module-netjack2-driver.c | ||
| module-netjack2-manager.c | ||
| module-parametric-equalizer.c | ||
| module-pipe-tunnel.c | ||
| module-portal.c | ||
| module-profiler.c | ||
| module-protocol-native.c | ||
| module-protocol-pulse.c | ||
| module-protocol-simple.c | ||
| module-pulse-tunnel.c | ||
| module-raop-discover.c | ||
| module-raop-sink.c | ||
| module-roc-sink.c | ||
| module-roc-source.c | ||
| module-rt.c | ||
| module-rtp-sap.c | ||
| module-rtp-session.c | ||
| module-rtp-sink.c | ||
| module-rtp-source.c | ||
| module-session-manager.c | ||
| module-snapcast-discover.c | ||
| module-spa-device-factory.c | ||
| module-spa-device.c | ||
| module-spa-node-factory.c | ||
| module-spa-node.c | ||
| module-vban-recv.c | ||
| module-vban-send.c | ||
| module-x11-bell.c | ||
| module-zeroconf-discover.c | ||
| network-utils.h | ||