diff mbox series

[BlueZ] audio/source: Fix crash on authentication failure

Message ID 20250423092027.230229-1-frederic.danis@collabora.com
State New
Headers show
Series [BlueZ] audio/source: Fix crash on authentication failure | expand

Commit Message

Frédéric Danis April 23, 2025, 9:20 a.m. UTC
The AVDTP reference count may decrease under 0 if authentication fails
and avdtp_unref() is called from source_unregister() then when changing
state from SOURCE_STATE_CONNECTING to SOURCE_STATE_DISCONNECTED:

src/shared/mgmt.c:can_read_data() [0x0000] event 0x000b
src/adapter.c:connected_callback() hci0 device EC:28:D3:0B:3B:7B
 connected eir_len 33
src/shared/mgmt.c:can_read_data() [0x0000] event 0x0011
src/adapter.c:bonding_attempt_complete() hci0 bdaddr EC:28:D3:0B:3B:7B
 type 0 status 0x5
src/device.c:device_bonding_complete() bonding (nil) status 0x05
src/device.c:device_bonding_failed() status 5
src/adapter.c:resume_discovery()
src/profile.c:ext_connect() Hands-Free unit failed connect to
 EC:28:D3:0B:3B:7B: Permission denied (13)
src/service.c:change_state() 0x556200cee6d0: device EC:28:D3:0B:3B:7B
 profile Hands-Free unit state changed: connecting -> disconnected (-13)
src/device.c:device_profile_connected() Hands-Free unit Permission
 denied (13)
profiles/audio/a2dp.c:a2dp_source_connect() path
 /org/bluez/hci0/dev_EC_28_D3_0B_3B_7B
profiles/audio/avdtp.c:avdtp_ref() 0x556200d2fb80: ref=1
profiles/audio/avdtp.c:avdtp_ref() 0x556200d2fb80: ref=2
profiles/audio/a2dp.c:setup_ref() 0x556200cf3760: ref=1
profiles/audio/source.c:source_set_state() State changed
 /org/bluez/hci0/dev_EC_28_D3_0B_3B_7B: SOURCE_STATE_DISCONNECTED ->
 SOURCE_STATE_CONNECTING
profiles/audio/source.c:source_connect() stream creation in progress
src/service.c:change_state() 0x556200d08470: device EC:28:D3:0B:3B:7B
 profile a2dp-source state changed: disconnected -> connecting (0)
src/service.c:btd_service_unref() 0x556200cee6d0: ref=1
src/shared/mgmt.c:can_read_data() [0x0000] event 0x000c
src/adapter.c:dev_disconnected() Device EC:28:D3:0B:3B:7B disconnected,
 reason 0
src/adapter.c:adapter_remove_connection()
src/device.c:device_remove_connection() connection removed while
 Connect() is waiting reply
plugins/policy.c:disconnect_cb() reason 0
src/adapter.c:bonding_attempt_complete() hci0 bdaddr EC:28:D3:0B:3B:7B
 type 0 status 0xe
src/device.c:device_bonding_complete() bonding (nil) status 0x0e
src/device.c:device_bonding_failed() status 14
src/adapter.c:resume_discovery()
src/service.c:change_state() 0x556200d08470: device EC:28:D3:0B:3B:7B
 profile a2dp-source state changed: connecting -> disconnected (-103)
src/device.c:device_profile_connected() a2dp-source Software caused
 connection abort (103)
src/service.c:change_state() 0x556200d08470: device EC:28:D3:0B:3B:7B
 profile a2dp-source state changed: disconnected -> unavailable (0)
profiles/audio/source.c:source_unregister()
 /org/bluez/hci0/dev_EC_28_D3_0B_3B_7B
profiles/audio/avdtp.c:avdtp_unref() 0x556200d2fb80: ref=1
profiles/audio/a2dp.c:setup_ref() 0x556200cf3760: ref=2
profiles/audio/a2dp.c:setup_unref() 0x556200cf3760: ref=1
profiles/audio/a2dp.c:a2dp_cancel() aborting setup 0x556200cf3760
profiles/audio/a2dp.c:setup_unref() 0x556200cf3760: ref=0
profiles/audio/a2dp.c:setup_free() 0x556200cf3760
profiles/audio/avdtp.c:avdtp_unref() 0x556200d2fb80: ref=0
profiles/audio/avdtp.c:avdtp_ref() 0x556200d2fb80: ref=1
profiles/audio/avdtp.c:connection_lost() Disconnected from
 EC:28:D3:0B:3B:7B
profiles/audio/source.c:source_set_state() State changed
 /org/bluez/hci0/dev_EC_28_D3_0B_3B_7B: SOURCE_STATE_CONNECTING ->
 SOURCE_STATE_DISCONNECTED
profiles/audio/avdtp.c:avdtp_unref() 0x556200d2fb80: ref=0
profiles/audio/avdtp.c:avdtp_free() 0x556200d2fb80
profiles/audio/a2dp.c:channel_remove() chan 0x556200cf5400
profiles/audio/avdtp.c:avdtp_unref() 0x556200d2fb80: ref=-1
profiles/audio/avdtp.c:avdtp_free() 0x556200d2fb80

This has been tested with:
- BlueZ 5.77 + kernel 5.4
- BlueZ upstream + kernel 6.11
---
 profiles/audio/source.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 885e218bf..b549ed114 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -306,8 +306,10 @@  static void source_free(struct btd_service *service)
 		avdtp_stream_remove_cb(source->session, source->stream,
 					source->cb_id);
 
-	if (source->session)
+	if (source->session) {
 		avdtp_unref(source->session);
+		source->session = NULL;
+	}
 
 	if (source->connect_id > 0) {
 		btd_service_connecting_complete(source->service, -ECANCELED);