[PATCH BlueZ 2/2] bap: Fix crash on unexpected disconnect

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

If an unexpected disconnect happens while bt_bap_config is pending the
following trace can be observed, to fix it bt_bap_config is reworked so
it no longer attempts to create and config the stream in place, instead
it just return the new stream and the function is renamed to
bt_bap_stream_new:

Invalid write of size 4
   at 0x3980D8: config_cb (bap.c:395)
   by 0x4DF5A3: bap_req_complete (bap.c:3471)
   by 0x4E9D33: bap_req_detach (bap.c:3807)
   by 0x4E9D33: bt_bap_detach (bap.c:3819)
   by 0x4E9D33: bt_bap_detach (bap.c:3810)
   by 0x397AA9: bap_disconnect (bap.c:1342)
   by 0x4223E0: btd_service_disconnect (service.c:305)
   by 0x4974D8F: g_slist_foreach (in /usr/lib64/libglib-2.0.so.0.7200.3)
   by 0x438FC3: att_disconnected_cb (device.c:5160)
   by 0x49A6C6: queue_foreach (queue.c:207)
   by 0x4B463B: disconnect_cb (att.c:701)
   by 0x5054DF: watch_callback (io-glib.c:157)
   by 0x495BFAE: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.7200.3)
   by 0x49B12C7: ??? (in /usr/lib64/libglib-2.0.so.0.7200.3)
 Address 0x6576940 is 96 bytes inside a block of size 112 free'd
   at 0x48480E4: free (vg_replace_malloc.c:872)
   by 0x48F78D: remove_interface (object.c:660)
   by 0x490489: g_dbus_unregister_interface (object.c:1394)
   by 0x397BA8: ep_remove (bap.c:1330)
   by 0x49ACF4: queue_remove_if (queue.c:279)
   by 0x49B0AC: queue_remove_all (queue.c:321)
   by 0x397A7C: bap_disconnect (bap.c:1339)
   by 0x4223E0: btd_service_disconnect (service.c:305)
   by 0x4974D8F: g_slist_foreach (in /usr/lib64/libglib-2.0.so.0.7200.3)
   by 0x438FC3: att_disconnected_cb (device.c:5160)
   by 0x49A6C6: queue_foreach (queue.c:207)
   by 0x4B463B: disconnect_cb (att.c:701)
 Block was alloc'd at
   at 0x484586F: malloc (vg_replace_malloc.c:381)
   by 0x49B432: util_malloc (util.c:43)
   by 0x39A1D9: ep_register (bap.c:563)
   by 0x39A1D9: pac_found (bap.c:664)
   by 0x4E5FEA: bap_foreach_pac (bap.c:3980)
   by 0x4EA437: bap_notify_ready (bap.c:2736)
   by 0x4EA437: bap_idle (bap.c:3711)
   by 0x4B52F0: idle_notify (gatt-client.c:171)
   by 0x49ACF4: queue_remove_if (queue.c:279)
   by 0x49B0AC: queue_remove_all (queue.c:321)
   by 0x4C092C: notify_client_idle (gatt-client.c:180)
   by 0x4C092C: request_unref (gatt-client.c:199)
   by 0x4AACB5: destroy_att_send_op (att.c:209)
   by 0x4B2B88: handle_rsp (att.c:862)
   by 0x4B2B88: can_read_data (att.c:1052)
   by 0x5054DF: watch_callback (io-glib.c:157)
---
 profiles/audio/bap.c | 28 ++++++++++++----------------
 src/shared/bap.c     | 16 ++--------------
 src/shared/bap.h     |  6 ++----
 3 files changed, 16 insertions(+), 34 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index b8c75f195854..dfdf8725589d 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -466,15 +466,13 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 	/* TODO: Check if stream capabilities match add support for Latency
 	 * and PHY.
 	 */
-	if (ep->stream)
-		ep->id = bt_bap_stream_config(ep->stream, &ep->qos, ep->caps,
-						config_cb, ep);
-	else
-		ep->stream = bt_bap_config(ep->data->bap, ep->lpac, ep->rpac,
-						&ep->qos, ep->caps,
-						config_cb, ep);
+	if (!ep->stream)
+		ep->stream = bt_bap_stream_new(ep->data->bap, ep->lpac,
+						ep->rpac, &ep->qos, ep->caps);
 
-	if (!ep->stream) {
+	ep->id = bt_bap_stream_config(ep->stream, &ep->qos, ep->caps,
+						config_cb, ep);
+	if (!ep->id) {
 		DBG("Unable to config stream");
 		free(ep->caps);
 		ep->caps = NULL;
@@ -604,15 +602,13 @@ static void bap_config(void *data, void *user_data)
 	/* TODO: Check if stream capabilities match add support for Latency
 	 * and PHY.
 	 */
-	if (ep->stream)
-		ep->id = bt_bap_stream_config(ep->stream, &ep->qos, ep->caps,
-						config_cb, ep);
-	else
-		ep->stream = bt_bap_config(ep->data->bap, ep->lpac, ep->rpac,
-						&ep->qos, ep->caps,
-						config_cb, ep);
+	if (!ep->stream)
+		ep->stream = bt_bap_stream_new(ep->data->bap, ep->lpac,
+						ep->rpac, &ep->qos, ep->caps);
 
-	if (!ep->stream) {
+	ep->id = bt_bap_stream_config(ep->stream, &ep->qos, ep->caps,
+						config_cb, ep);
+	if (!ep->id) {
 		DBG("Unable to config stream");
 		util_iov_free(ep->caps, 1);
 		ep->caps = NULL;
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 3ebcd81f16c1..952b7be260ab 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -4176,18 +4176,15 @@ int bt_bap_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
 	return 0;
 }
 
-struct bt_bap_stream *bt_bap_config(struct bt_bap *bap,
+struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap,
 					struct bt_bap_pac *lpac,
 					struct bt_bap_pac *rpac,
 					struct bt_bap_qos *pqos,
-					struct iovec *data,
-					bt_bap_stream_func_t func,
-					void *user_data)
+					struct iovec *data)
 {
 	struct bt_bap_stream *stream;
 	struct bt_bap_endpoint *ep;
 	struct match_pac match;
-	int id;
 
 	if (!bap || !bap->rdb || queue_isempty(bap->remote_eps))
 		return NULL;
@@ -4244,15 +4241,6 @@ struct bt_bap_stream *bt_bap_config(struct bt_bap *bap,
 	if (!stream)
 		stream = bap_stream_new(bap, ep, lpac, rpac, data, true);
 
-	id = bt_bap_stream_config(stream, pqos, data, func, user_data);
-	if (!id) {
-		DBG(bap, "Unable to config stream");
-		queue_remove(bap->streams, stream);
-		ep->stream = NULL;
-		free(stream);
-		return NULL;
-	}
-
 	return stream;
 }
 
diff --git a/src/shared/bap.h b/src/shared/bap.h
index 47a15636ca22..bd13abef9ce5 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -190,13 +190,11 @@ void *bt_bap_pac_get_user_data(struct bt_bap_pac *pac);
 int bt_bap_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
 			bt_bap_pac_select_t func, void *user_data);
 
-struct bt_bap_stream *bt_bap_config(struct bt_bap *bap,
+struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap,
 					struct bt_bap_pac *lpac,
 					struct bt_bap_pac *rpac,
 					struct bt_bap_qos *pqos,
-					struct iovec *data,
-					bt_bap_stream_func_t func,
-					void *user_data);
+					struct iovec *data);
 
 struct bt_bap *bt_bap_stream_get_session(struct bt_bap_stream *stream);
 uint8_t bt_bap_stream_get_state(struct bt_bap_stream *stream);
-- 
2.39.2




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux