use-after-free when dbus connection fails
I noticed the
W 18:44:42.436816 GLib-GObject (null):(null):(null): invalid unclassed pointer in cast to 'WpTransition'
C 18:44:42.436831 wp-transition (null):(null):(null): wp_transition_return_error: assertion 'WP_IS_TRANSITION (self)' failed
messages in pipewire#2772.
When wireplumber is launched as follows:
DBUS_SESSION_BUS_ADDRESS= wireplumber
it triggers the following use-after-free:
=================================================================
==262555==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00001fea0 at pc 0x7f94ee423f2b bp 0x7ffed0698850 sp 0x7ffed0698840
READ of size 8 at 0x60b00001fea0 thread T0
#0 0x7f94ee423f2a in g_type_check_instance_cast ../gobject/gtype.c:4134
#1 0x56025fa04b19 in WP_TRANSITION ../subprojects/wireplumber/lib/wp/transition.h:23
#2 0x56025fa0538b in on_plugin_activated ../subprojects/wireplumber/src/main.c:105
#3 0x7f94ee387dc6 in g_cclosure_marshal_VOID__OBJECT ../gobject/gmarshal.c:1852
#4 0x7f94ee373415 in g_closure_invoke ../gobject/gclosure.c:832
#5 0x7f94efa30d9e in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:379
#6 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#7 0x7f94e9c79c7f in on_dbus_activated ../subprojects/wireplumber/modules/module-reserve-device/plugin.c:109
#8 0x7f94ee387dc6 in g_cclosure_marshal_VOID__OBJECT ../gobject/gmarshal.c:1852
#9 0x7f94ee373415 in g_closure_invoke ../gobject/gclosure.c:832
#10 0x7f94efa30d9e in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:379
#11 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#12 0x7f94ef9b84a1 in wp_object_abort_activation ../subprojects/wireplumber/lib/wp/object.c:502
#13 0x7f94ef9b866f in wp_object_abort_activation ../subprojects/wireplumber/lib/wp/object.c:512
#14 0x7f94ef9b7689 in on_transition_completed ../subprojects/wireplumber/lib/wp/object.c:353
#15 0x7f94ee3863c4 in g_cclosure_marshal_VOID__PARAM ../gobject/gmarshal.c:1516
#16 0x7f94ee373415 in g_closure_invoke ../gobject/gclosure.c:832
#17 0x7f94ee3f0a93 in signal_emit_unlocked_R ../gobject/gsignal.c:3796
#18 0x7f94ee3eda5c in g_signal_emit_valist ../gobject/gsignal.c:3549
#19 0x7f94ee3eec00 in g_signal_emit ../gobject/gsignal.c:3606
#20 0x7f94ee392bd3 in g_object_dispatch_properties_changed ../gobject/gobject.c:1428
#21 0x7f94ee393620 in g_object_notify_by_spec_internal ../gobject/gobject.c:1544
#22 0x7f94ee3938b1 in g_object_notify ../gobject/gobject.c:1594
#23 0x7f94efa30dfd in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:384
#24 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#25 0x7f94ef97ec76 in on_got_bus ../subprojects/wireplumber/lib/wp/dbus.c:79
#26 0x7f94ebc8d797 in g_task_return_now ../gio/gtask.c:1232
#27 0x7f94ebc8d8fc in complete_in_idle_cb ../gio/gtask.c:1246
#28 0x7f94edac3fb3 in g_idle_dispatch ../glib/gmain.c:6124
#29 0x7f94edab2f96 in g_main_dispatch ../glib/gmain.c:3444
#30 0x7f94edab9cfe in g_main_context_dispatch ../glib/gmain.c:4162
#31 0x7f94edaba7b0 in g_main_context_iterate ../glib/gmain.c:4238
#32 0x7f94edabbe2f in g_main_loop_run ../glib/gmain.c:4438
#33 0x56025fa08886 in main ../subprojects/wireplumber/src/main.c:484
#34 0x7f94ee63c28f (/usr/lib/libc.so.6+0x2328f)
#35 0x7f94ee63c349 in __libc_start_main (/usr/lib/libc.so.6+0x23349)
#36 0x56025fa04634 in _start ../sysdeps/x86_64/start.S:115
0x60b00001fea0 is located 64 bytes inside of 104-byte region [0x60b00001fe60,0x60b00001fec8)
freed by thread T0 here:
#0 0x7f94efebe672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f94edadf879 in g_free ../glib/gmem.c:229
#2 0x7f94ee411a35 in g_type_free_instance ../gobject/gtype.c:2022
#3 0x7f94ee3a6517 in g_object_unref ../gobject/gobject.c:3925
#4 0x7f94efa30e0c in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:387
#5 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#6 0x56025fa05396 in on_plugin_activated ../subprojects/wireplumber/src/main.c:105
#7 0x7f94ee387dc6 in g_cclosure_marshal_VOID__OBJECT ../gobject/gmarshal.c:1852
#8 0x7f94ee373415 in g_closure_invoke ../gobject/gclosure.c:832
#9 0x7f94efa30d9e in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:379
#10 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#11 0x7f94ea818805 in on_dbus_activated ../subprojects/wireplumber/modules/module-portal-permissionstore.c:197
#12 0x7f94ee387dc6 in g_cclosure_marshal_VOID__OBJECT ../gobject/gmarshal.c:1852
#13 0x7f94ee373415 in g_closure_invoke ../gobject/gclosure.c:832
#14 0x7f94efa30d9e in wp_transition_return ../subprojects/wireplumber/lib/wp/transition.c:379
#15 0x7f94efa32183 in wp_transition_return_error ../subprojects/wireplumber/lib/wp/transition.c:504
#16 0x7f94ef97ec76 in on_got_bus ../subprojects/wireplumber/lib/wp/dbus.c:79
#17 0x7f94ebc8d797 in g_task_return_now ../gio/gtask.c:1232
#18 0x7f94ebc8d8fc in complete_in_idle_cb ../gio/gtask.c:1246
#19 0x7f94edac3fb3 in g_idle_dispatch ../glib/gmain.c:6124
#20 0x7f94edab2f96 in g_main_dispatch ../glib/gmain.c:3444
#21 0x7f94edab9cfe in g_main_context_dispatch ../glib/gmain.c:4162
#22 0x7f94edaba7b0 in g_main_context_iterate ../glib/gmain.c:4238
#23 0x7f94edabbe2f in g_main_loop_run ../glib/gmain.c:4438
#24 0x56025fa08886 in main ../subprojects/wireplumber/src/main.c:484
#25 0x7f94ee63c28f (/usr/lib/libc.so.6+0x2328f)
previously allocated by thread T0 here:
#0 0x7f94efebf411 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7f94edadf78d in g_malloc0 ../glib/gmem.c:163
#2 0x7f94ee40fc55 in g_type_create_instance ../gobject/gtype.c:1925
#3 0x7f94ee39901f in g_object_new_internal ../gobject/gobject.c:2228
#4 0x7f94ee39a032 in g_object_new_with_properties ../gobject/gobject.c:2391
#5 0x7f94ee397b05 in g_object_new ../gobject/gobject.c:2037
#6 0x7f94efa2fe1c in wp_transition_new_closure ../subprojects/wireplumber/lib/wp/transition.c:210
#7 0x7f94efa2fd56 in wp_transition_new ../subprojects/wireplumber/lib/wp/transition.c:180
#8 0x56025fa08843 in main ../subprojects/wireplumber/src/main.c:480
#9 0x7f94ee63c28f (/usr/lib/libc.so.6+0x2328f)
SUMMARY: AddressSanitizer: heap-use-after-free ../gobject/gtype.c:4134 in g_type_check_instance_cast
Shadow bytes around the buggy address:
0x0c167fffbf80: 00 fa fa fa fa fa fa fa fa fa 00 00 00 00 00 00
0x0c167fffbf90: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
0x0c167fffbfa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa
0x0c167fffbfb0: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
0x0c167fffbfc0: 00 00 00 00 fa fa fa fa fa fa fa fa fd fd fd fd
=>0x0c167fffbfd0: fd fd fd fd[fd]fd fd fd fd fa fa fa fa fa fa fa
0x0c167fffbfe0: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fa
0x0c167fffbff0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c167fffc000: 00 00 00 00 00 fa fa fa fa fa fa fa fa fa 00 00
0x0c167fffc010: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x0c167fffc020: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
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
==262555==ABORTING
It looks like wp_transition_return()
unrefs the transition:
/* WARNING */
g_object_unref (self);
So if multiple plugins fail to activate in the same tick, then the later ones will run into a user-after-free as far as I can see.