@@ -1232,6 +1232,47 @@ static void stream_stop_complete(struct bt_bap_stream *stream, uint8_t code,
bap_stream_io_detach(stream);
}
+static void bap_req_free(void *data)
+{
+ struct bt_bap_req *req = data;
+ size_t i;
+
+ queue_destroy(req->group, bap_req_free);
+
+ for (i = 0; i < req->len; i++)
+ free(req->iov[i].iov_base);
+
+ free(req->iov);
+ free(req);
+}
+
+static void bap_req_complete(struct bt_bap_req *req,
+ const struct bt_ascs_ase_rsp *rsp)
+{
+ struct queue *group;
+
+ if (!req->func)
+ goto done;
+
+ if (rsp)
+ req->func(req->stream, rsp->code, rsp->reason, req->user_data);
+ else
+ req->func(req->stream, BT_ASCS_RSP_UNSPECIFIED, 0x00,
+ req->user_data);
+
+done:
+ /* Detach from request so it can be freed separately */
+ group = req->group;
+ req->group = NULL;
+
+ queue_foreach(group, (queue_foreach_func_t)bap_req_complete,
+ (void *)rsp);
+
+ queue_destroy(group, NULL);
+
+ bap_req_free(req);
+}
+
static void bap_stream_state_changed(struct bt_bap_stream *stream)
{
struct bt_bap *bap = stream->bap;
@@ -1286,6 +1327,10 @@ static void bap_stream_state_changed(struct bt_bap_stream *stream)
/* Post notification updates */
switch (stream->ep->state) {
case BT_ASCS_ASE_STATE_IDLE:
+ if (bap->req && bap->req->stream == stream) {
+ bap_req_complete(bap->req, NULL);
+ bap->req = NULL;
+ }
bap_stream_detach(stream);
break;
case BT_ASCS_ASE_STATE_QOS:
@@ -2905,20 +2950,6 @@ static void bap_state_free(void *data)
free(state);
}
-static void bap_req_free(void *data)
-{
- struct bt_bap_req *req = data;
- size_t i;
-
- queue_destroy(req->group, bap_req_free);
-
- for (i = 0; i < req->len; i++)
- free(req->iov[i].iov_base);
-
- free(req->iov);
- free(req);
-}
-
static void bap_detached(void *data, void *user_data)
{
struct bt_bap_cb *cb = data;
@@ -3809,6 +3840,11 @@ static bool bap_send(struct bt_bap *bap, struct bt_bap_req *req)
DBG(bap, "req %p len %u", req, iov.iov_len);
+ if (req->stream && !queue_find(bap->streams, NULL, req->stream)) {
+ DBG(bap, "stream %p detached, aborting op 0x%02x", req->op);
+ return false;
+ }
+
if (!gatt_db_attribute_get_char_data(ascs->ase_cp, NULL, &handle,
NULL, NULL, NULL)) {
DBG(bap, "Unable to find Control Point");
@@ -3843,33 +3879,6 @@ static bool bap_send(struct bt_bap *bap, struct bt_bap_req *req)
return true;
}
-static void bap_req_complete(struct bt_bap_req *req,
- const struct bt_ascs_ase_rsp *rsp)
-{
- struct queue *group;
-
- if (!req->func)
- goto done;
-
- if (rsp)
- req->func(req->stream, rsp->code, rsp->reason, req->user_data);
- else
- req->func(req->stream, BT_ASCS_RSP_UNSPECIFIED, 0x00,
- req->user_data);
-
-done:
- /* Detach from request so it can be freed separately */
- group = req->group;
- req->group = NULL;
-
- queue_foreach(group, (queue_foreach_func_t)bap_req_complete,
- (void *)rsp);
-
- queue_destroy(group, NULL);
-
- bap_req_free(req);
-}
-
static bool bap_process_queue(void *data)
{
struct bt_bap *bap = data;
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Requests maybe queued using a stream so when detaching it needs to be canceled otherwise they can lead crashes like bellow: Invalid read of size 8 at 0x1C3247: stream_stop_complete (bap.c:1230) by 0x1BB2A3: bap_req_complete (bap.c:3863) by 0x1C7BB3: bap_req_detach (bap.c:4219) by 0x1C7BB3: bt_bap_detach (bap.c:4231) by 0x1C7BB3: bt_bap_detach (bap.c:4222) by 0x1C7E67: bap_free (bap.c:2937) by 0x1C7E67: bt_bap_unref (bap.c:3090) by 0x1C7E67: bt_bap_unref (bap.c:3082) by 0x18CCC2: test_teardown (test-bap.c:513) by 0x1D826A: teardown_callback (tester.c:434) by 0x491E4FC: g_idle_dispatch (gmain.c:6163) by 0x49224FB: UnknownInlinedFun (gmain.c:3460) by 0x49224FB: g_main_context_dispatch (gmain.c:4200) by 0x49806B7: g_main_context_iterate.isra.0 (gmain.c:4276) by 0x4921AFE: g_main_loop_run (gmain.c:4479) by 0x1E8EF4: mainloop_run (mainloop-glib.c:66) by 0x1E93F7: mainloop_run_with_signal (mainloop-notify.c:188) Address 0x57b9ad0 is 0 bytes inside a block of size 120 free'd at 0x4845B2C: free (vg_replace_malloc.c:985) by 0x1CBAB7: bap_stream_state_changed (bap.c:1290) by 0x1D3104: bap_ep_set_status (bap.c:3673) by 0x1DC746: queue_foreach (queue.c:207) by 0x1A5320: notify_cb (gatt-client.c:2271) by 0x19A1EF: handle_notify (att.c:1012) by 0x19A1EF: can_read_data (att.c:1096) by 0x1D68CF: watch_callback (io-glib.c:157) by 0x49224FB: UnknownInlinedFun (gmain.c:3460) by 0x49224FB: g_main_context_dispatch (gmain.c:4200) by 0x49806B7: g_main_context_iterate.isra.0 (gmain.c:4276) by 0x4921AFE: g_main_loop_run (gmain.c:4479) by 0x1E8EF4: mainloop_run (mainloop-glib.c:66) by 0x1E93F7: mainloop_run_with_signal (mainloop-notify.c:188) --- src/shared/bap.c | 91 ++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 41 deletions(-)