diff mbox series

[v3,1/2] transport: Update transport release flow for bcast src

Message ID 20231004075646.4277-2-silviu.barbulescu@nxp.com (mailing list archive)
State Superseded
Headers show
Series Update transport acquire/release flow BAP bcast source | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/BuildEll success Build ELL PASS
tedd_an/BluezMake success Bluez Make PASS
tedd_an/MakeCheck success Bluez Make Check PASS
tedd_an/MakeDistcheck success Make Distcheck PASS
tedd_an/CheckValgrind success Check Valgrind PASS
tedd_an/CheckSmatch success CheckSparse PASS
tedd_an/bluezmakeextell success Make External ELL PASS
tedd_an/IncrementalBuild success Incremental Build PASS
tedd_an/ScanBuild success Scan Build PASS

Commit Message

Silviu Florian Barbulescu Oct. 4, 2023, 7:56 a.m. UTC
Update transport release flow for broadcast source

---
 profiles/audio/transport.c | 65 ++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 27 deletions(-)

Comments

bluez.test.bot@gmail.com Oct. 4, 2023, 9:25 a.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=789831

---Test result---

Test Summary:
CheckPatch                    PASS      1.12 seconds
GitLint                       PASS      0.70 seconds
BuildEll                      PASS      27.88 seconds
BluezMake                     PASS      774.89 seconds
MakeCheck                     PASS      12.10 seconds
MakeDistcheck                 PASS      160.36 seconds
CheckValgrind                 PASS      257.00 seconds
CheckSmatch                   PASS      349.02 seconds
bluezmakeextell               PASS      106.28 seconds
IncrementalBuild              PASS      1308.43 seconds
ScanBuild                     PASS      1032.29 seconds



---
Regards,
Linux Bluetooth
Jonas Dreßler Oct. 29, 2023, 9:49 p.m. UTC | #2
Hi Silviu,

this patch introduced a use-after-free, reproducer:

- connect to a2dp sink
- start playing
- pause and wait until stream suspends
- bluetoothd crashes in a2dp_suspend_complete()

Here's the output running with address sanitizer:

bluetoothd[181120]: profiles/audio/a2dp.c:suspend_cfm() Source 
0x60600001e500: Suspend_Cfm
=================================================================
==181120==ERROR: AddressSanitizer: heap-use-after-free on address 
0x60300005a730 at pc 0xaaaaf9dbeea8 bp 0xfffff4d3b690 sp 0xfffff4d3b6a8
READ of size 8 at 0x60300005a730 thread T0
     #0 0xaaaaf9dbeea4 in a2dp_suspend_complete 
profiles/audio/transport.c:426
     #1 0xaaaaf9d7d37c in finalize_suspend profiles/audio/a2dp.c:376
     #2 0xaaaaf9d7e060 in suspend_cfm profiles/audio/a2dp.c:1276
     #3 0xaaaaf9da0ddc in avdtp_delay_report_resp 
profiles/audio/avdtp.c:2928
     #4 0xaaaaf9da0ddc in avdtp_parse_resp profiles/audio/avdtp.c:2997
     #5 0xaaaaf9da0ddc in session_cb profiles/audio/avdtp.c:2286
     #6 0xffff6e77030c in g_main_dispatch ../glib/gmain.c:3476
     #7 0xffff6e77030c in g_main_context_dispatch_unlocked 
../glib/gmain.c:4284
     #8 0xffff6e7ce598 in g_main_context_iterate_unlocked.isra.0 
../glib/gmain.c:4349
     #9 0xffff6e771a60 in g_main_loop_run 
(/lib64/libglib-2.0.so.0+0x61a60) (BuildId: 
7d17ee836a99abf35136ebb46126a95dee66511a)
     #10 0xaaaafa0ad0d8 in mainloop_run src/shared/mainloop-glib.c:66
     #11 0xaaaafa0ad920 in mainloop_run_with_signal 
src/shared/mainloop-notify.c:188
     #12 0xaaaaf9d5489c in main src/main.c:1452
     #13 0xffff6dd209d8 in __libc_start_call_main 
../sysdeps/nptl/libc_start_call_main.h:58
     #14 0xffff6dd20aac in __libc_start_main_impl ../csu/libc-start.c:360
     #15 0xaaaaf9d5686c in _start 
(/home/jonas/git/bluez/src/bluetoothd+0x55686c) (BuildId: 
8922b026a55aac729ed13de54b3a622a31b5bb2b)

0x60300005a730 is located 0 bytes inside of 32-byte region 
[0x60300005a730,0x60300005a750)
freed by thread T0 here:
     #0 0xffff6ea24638 in __interceptor_free.part.0 
(/lib64/libasan.so.8+0xc4638) (BuildId: 
a77e9fa1e1448d41e9a8ddaf28aa5612f3ffc397)
     #1 0xffff6e773114 in g_free (/lib64/libglib-2.0.so.0+0x63114) 
(BuildId: 7d17ee836a99abf35136ebb46126a95dee66511a)
     #2 0xaaaaf9dbc42c in media_transport_remove_owner 
profiles/audio/transport.c:322
     #3 0xaaaaf9dc0b64 in bap_disable_complete 
profiles/audio/transport.c:632
     #4 0xaaaaf9dc0b64 in release profiles/audio/transport.c:674
     #5 0xaaaaf9ff2574 in process_message gdbus/object.c:246
     #6 0xffff6e69de78 in _dbus_object_tree_dispatch_and_unlock 
../../dbus/dbus-object-tree.c:1021
     #7 0xaaaaf9fe44a4 in message_dispatch gdbus/mainloop.c:59
     #8 0xffff6e76c444 in g_idle_dispatch ../glib/gmain.c:6282
     #9 0xffff6e77030c in g_main_dispatch ../glib/gmain.c:3476
     #10 0xffff6e77030c in g_main_context_dispatch_unlocked 
../glib/gmain.c:4284
     #11 0xffff6e7ce598 in g_main_context_iterate_unlocked.isra.0 
../glib/gmain.c:4349
     #12 0xffff6e771a60 in g_main_loop_run 
(/lib64/libglib-2.0.so.0+0x61a60) (BuildId: 
7d17ee836a99abf35136ebb46126a95dee66511a)
     #13 0xaaaafa0ad0d8 in mainloop_run src/shared/mainloop-glib.c:66
     #14 0xaaaafa0ad920 in mainloop_run_with_signal 
src/shared/mainloop-notify.c:188
     #15 0xaaaaf9d5489c in main src/main.c:1452
     #16 0xffff6dd209d8 in __libc_start_call_main 
../sysdeps/nptl/libc_start_call_main.h:58
     #17 0xffff6dd20aac in __libc_start_main_impl ../csu/libc-start.c:360
     #18 0xaaaaf9d5686c in _start 
(/home/jonas/git/bluez/src/bluetoothd+0x55686c) (BuildId: 
8922b026a55aac729ed13de54b3a622a31b5bb2b)

previously allocated by thread T0 here:
     #0 0xffff6ea25218 in calloc (/lib64/libasan.so.8+0xc5218) (BuildId: 
a77e9fa1e1448d41e9a8ddaf28aa5612f3ffc397)
     #1 0xffff6e7769e4 in g_malloc0 (/lib64/libglib-2.0.so.0+0x669e4) 
(BuildId: 7d17ee836a99abf35136ebb46126a95dee66511a)
     #2 0xaaaaf9db89c4 in media_owner_create profiles/audio/transport.c:514
     #3 0xaaaaf9dbd760 in acquire profiles/audio/transport.c:552
     #4 0xaaaaf9dbd760 in acquire profiles/audio/transport.c:538
     #5 0xaaaaf9ff2574 in process_message gdbus/object.c:246
     #6 0xffff6e69de78 in _dbus_object_tree_dispatch_and_unlock 
../../dbus/dbus-object-tree.c:1021
     #7 0xaaaaf9fe44a4 in message_dispatch gdbus/mainloop.c:59
     #8 0xffff6e76c444 in g_idle_dispatch ../glib/gmain.c:6282
     #9 0xffff6e77030c in g_main_dispatch ../glib/gmain.c:3476
     #10 0xffff6e77030c in g_main_context_dispatch_unlocked 
../glib/gmain.c:4284
     #11 0xffff6e7ce598 in g_main_context_iterate_unlocked.isra.0 
../glib/gmain.c:4349
     #12 0xffff6e771a60 in g_main_loop_run 
(/lib64/libglib-2.0.so.0+0x61a60) (BuildId: 
7d17ee836a99abf35136ebb46126a95dee66511a)
     #13 0xaaaafa0ad0d8 in mainloop_run src/shared/mainloop-glib.c:66
     #14 0xaaaafa0ad920 in mainloop_run_with_signal 
src/shared/mainloop-notify.c:188
     #15 0xaaaaf9d5489c in main src/main.c:1452
     #16 0xffff6dd209d8 in __libc_start_call_main 
../sysdeps/nptl/libc_start_call_main.h:58
     #17 0xffff6dd20aac in __libc_start_main_impl ../csu/libc-start.c:360
     #18 0xaaaaf9d5686c in _start 
(/home/jonas/git/bluez/src/bluetoothd+0x55686c) (BuildId: 
8922b026a55aac729ed13de54b3a622a31b5bb2b)

SUMMARY: AddressSanitizer: heap-use-after-free 
profiles/audio/transport.c:426 in a2dp_suspend_complete
Ronan Pigott Dec. 16, 2023, 12:29 a.m. UTC | #3
Hi Silviu,

I encountered a use-after-free in the 5.71 release of Bluez which I
bisected to this patch. The backtrace is below:

#0  0x000055e93dbc8785 in a2dp_suspend_complete (session=<optimized out>, err=0, user_data=0x55e93e432520) at profiles/audio/transport.c:431
#1  0x000055e93dbb97ea in finalize_suspend (data=data@entry=0x55e93e435880) at profiles/audio/a2dp.c:376
#2  0x000055e93dbb98c0 in suspend_cfm (session=0x55e93e4317b0, sep=<optimized out>, stream=<optimized out>, err=0x0, user_data=0x55e93e41e850) at profiles/audio/a2dp.c:1276
#3  0x000055e93dbbfa4b in avdtp_suspend_resp (data=0x55e93e431823, size=<optimized out>, stream=0x55e93e433e60, session=0x55e93e4317b0) at profiles/audio/avdtp.c:2900
#4  avdtp_parse_resp (transaction=<optimized out>, size=<optimized out>, buf=0x55e93e431823, signal_id=<optimized out>, stream=0x55e93e433e60, session=0x55e93e4317b0) at profiles/audio/avdtp.c:2985
#5  session_cb (chan=<optimized out>, cond=<optimized out>, data=0x55e93e4317b0) at profiles/audio/avdtp.c:2286
#6  0x00007f5e225b9f69 in g_main_dispatch (context=0x55e93e3c6800) at ../glib/glib/gmain.c:3476
[...]

Originally reported in [1]

[1] https://gitlab.archlinux.org/archlinux/packaging/packages/bluez/-/issues/3

Cheers,

Ronan
diff mbox series

Patch

diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 1e03b7b51..23ea267f6 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -606,11 +606,38 @@  static DBusMessage *try_acquire(DBusConnection *conn, DBusMessage *msg,
 	return NULL;
 }
 
+static void bap_stop_complete(struct bt_bap_stream *stream,
+					uint8_t code, uint8_t reason,
+					void *user_data)
+{
+	struct media_owner *owner = user_data;
+	struct media_request *req = owner->pending;
+	struct media_transport *transport = owner->transport;
+
+	/* Release always succeeds */
+	if (req) {
+		req->id = 0;
+		media_request_reply(req, 0);
+		media_owner_remove(owner);
+	}
+
+	transport_set_state(transport, TRANSPORT_STATE_IDLE);
+	media_transport_remove_owner(transport);
+}
+
+static void bap_disable_complete(struct bt_bap_stream *stream,
+					uint8_t code, uint8_t reason,
+					void *user_data)
+{
+	bap_stop_complete(stream, code, reason, user_data);
+}
+
 static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
 					void *data)
 {
 	struct media_transport *transport = data;
 	struct media_owner *owner = transport->owner;
+	struct bap_transport *bap = transport->data;
 	const char *sender;
 	struct media_request *req;
 	guint id;
@@ -642,6 +669,11 @@  static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
 	req = media_request_create(msg, id);
 	media_owner_add(owner, req);
 
+	if (bt_bap_stream_get_type(bap->stream) ==
+			BT_BAP_STREAM_TYPE_BCAST) {
+		bap_disable_complete(bap->stream, 0x00, 0x00, owner);
+	}
+
 	return NULL;
 }
 
@@ -1370,32 +1402,6 @@  static guint resume_bap(struct media_transport *transport,
 	return id;
 }
 
-static void bap_stop_complete(struct bt_bap_stream *stream,
-					uint8_t code, uint8_t reason,
-					void *user_data)
-{
-	struct media_owner *owner = user_data;
-	struct media_request *req = owner->pending;
-	struct media_transport *transport = owner->transport;
-
-	/* Release always succeeds */
-	if (req) {
-		req->id = 0;
-		media_request_reply(req, 0);
-		media_owner_remove(owner);
-	}
-
-	transport_set_state(transport, TRANSPORT_STATE_IDLE);
-	media_transport_remove_owner(transport);
-}
-
-static void bap_disable_complete(struct bt_bap_stream *stream,
-					uint8_t code, uint8_t reason,
-					void *user_data)
-{
-	bap_stop_complete(stream, code, reason, user_data);
-}
-
 static guint suspend_bap(struct media_transport *transport,
 				struct media_owner *owner)
 {
@@ -1499,9 +1505,14 @@  static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state,
 			return;
 		break;
 	case BT_BAP_STREAM_STATE_STREAMING:
-		if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
+		if ((bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) ||
+			(bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK))
 			bap_update_bcast_qos(transport);
 		break;
+	case BT_BAP_STREAM_STATE_RELEASING:
+		if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK)
+			return;
+		break;
 	}
 
 	io = bt_bap_stream_get_io(stream);