diff mbox series

[BlueZ,2/6] shared/bap: Fix potential stream access after free

Message ID 20240527075422.18953-3-iulia.tanasescu@nxp.com (mailing list archive)
State Accepted
Commit af2873b2691291e165b3ee3f24b651433885537f
Headers show
Series Add new BAP BSRC/SCC tests | 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/IncrementalBuild success Incremental Build PASS

Commit Message

Iulia Tanasescu May 27, 2024, 7:54 a.m. UTC
In bap_bcast_set_state, state->func might trigger the stream to be
released, thus the stream would have been freed before reaching the
switch. After calling stream->func, the stream reference should not
be accessed anymore, apart from when the stream has not yet been
released and those cases will be handled inside the switch.

This commit also handles the case when stream ops might lead to a
state machine that ends with stream release, so the stream should
avoid being accessed after the ops are executed.
---
 src/shared/bap.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 1d9f59f21..ec54da341 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2051,7 +2051,7 @@  static void bap_bcast_set_state(struct bt_bap_stream *stream, uint8_t state)
 	}
 
 	/* Post notification updates */
-	switch (stream->state) {
+	switch (state) {
 	case BT_ASCS_ASE_STATE_IDLE:
 		if (stream->ops && stream->ops->detach)
 			stream->ops->detach(stream);
@@ -5293,6 +5293,7 @@  unsigned int bt_bap_stream_config(struct bt_bap_stream *stream,
 					void *user_data)
 {
 	unsigned int id;
+	struct bt_bap *bap;
 
 	if (!bap_stream_valid(stream))
 		return 0;
@@ -5303,9 +5304,11 @@  unsigned int bt_bap_stream_config(struct bt_bap_stream *stream,
 	if (!bt_bap_ref_safe(stream->bap))
 		return 0;
 
+	bap = stream->bap;
+
 	id = stream->ops->config(stream, qos, data, func, user_data);
 
-	bt_bap_unref(stream->bap);
+	bt_bap_unref(bap);
 
 	return id;
 }
@@ -5565,6 +5568,7 @@  unsigned int bt_bap_stream_enable(struct bt_bap_stream *stream,
 					void *user_data)
 {
 	unsigned int id;
+	struct bt_bap *bap;
 
 	if (!bap_stream_valid(stream))
 		return 0;
@@ -5575,10 +5579,12 @@  unsigned int bt_bap_stream_enable(struct bt_bap_stream *stream,
 	if (!bt_bap_ref_safe(stream->bap))
 		return 0;
 
+	bap = stream->bap;
+
 	id = stream->ops->enable(stream, enable_links, metadata, func,
 					user_data);
 
-	bt_bap_unref(stream->bap);
+	bt_bap_unref(bap);
 
 	return id;
 }
@@ -5588,6 +5594,7 @@  unsigned int bt_bap_stream_start(struct bt_bap_stream *stream,
 					void *user_data)
 {
 	unsigned int id;
+	struct bt_bap *bap;
 
 	if (!bap_stream_valid(stream))
 		return 0;
@@ -5598,9 +5605,11 @@  unsigned int bt_bap_stream_start(struct bt_bap_stream *stream,
 	if (!bt_bap_ref_safe(stream->bap))
 		return 0;
 
+	bap = stream->bap;
+
 	id = stream->ops->start(stream, func, user_data);
 
-	bt_bap_unref(stream->bap);
+	bt_bap_unref(bap);
 
 	return id;
 }
@@ -5611,6 +5620,7 @@  unsigned int bt_bap_stream_disable(struct bt_bap_stream *stream,
 					void *user_data)
 {
 	unsigned int id;
+	struct bt_bap *bap;
 
 	if (!bap_stream_valid(stream))
 		return 0;
@@ -5621,9 +5631,11 @@  unsigned int bt_bap_stream_disable(struct bt_bap_stream *stream,
 	if (!bt_bap_ref_safe(stream->bap))
 		return 0;
 
+	bap = stream->bap;
+
 	id = stream->ops->disable(stream, disable_links, func, user_data);
 
-	bt_bap_unref(stream->bap);
+	bt_bap_unref(bap);
 
 	return id;
 }