diff mbox series

[BlueZ,08/15] shared/bap: Fix possible use-after-free

Message ID 20240516090340.61417-9-hadess@hadess.net (mailing list archive)
State Accepted
Commit 52336ad64548edfddf18c20bd1a58b3c07bf5a4b
Headers show
Series Fix a number of static analysis issues #2 | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch warning WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #60: 2492| /* Sink can autonomously for to Streaming state if io already exits */ /github/workspace/src/src/13665896.patch total: 0 errors, 1 warnings, 33 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/src/13665896.patch has style problems, please review. NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS.
tedd_an/GitLint fail WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search 10: B1 Line exceeds max length (81>80): "bluez-5.75/src/shared/bap.c:2490:2: freed_arg: "stream_set_state" frees "stream"." 11: B1 Line exceeds max length (91>80): "bluez-5.75/src/shared/bap.c:2493:2: deref_after_free: Dereferencing freed pointer "stream"." 13: B3 Line contains hard tab characters (\t): "2492| /* Sink can autonomously for to Streaming state if io already exits */" 14: B3 Line contains hard tab characters (\t): "2493|-> if (stream->io && stream->ep->dir == BT_BAP_SINK)" 15: B3 Line contains hard tab characters (\t): "2494| stream_set_state(stream, BT_BAP_STREAM_STATE_STREAMING);"
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Bastien Nocera May 16, 2024, 9:03 a.m. UTC
stream_set_state() might call bap_stream_detach() if the stream is in
the process of being detached, causing a use-after-free.

Return false from stream_set_state() if the stream is unsafe to
manipulate (ie. was in the process of being detached and freed).

Error: USE_AFTER_FREE (CWE-416): [#def37] [important]
bluez-5.75/src/shared/bap.c:2490:2: freed_arg: "stream_set_state" frees "stream".
bluez-5.75/src/shared/bap.c:2493:2: deref_after_free: Dereferencing freed pointer "stream".
2491|
2492|		/* Sink can autonomously for to Streaming state if io already exits */
2493|->		if (stream->io && stream->ep->dir == BT_BAP_SINK)
2494|			stream_set_state(stream, BT_BAP_STREAM_STATE_STREAMING);
2495|
---
 src/shared/bap.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 1316d7c73d02..0026bc8dc989 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -1298,7 +1298,8 @@  static void bap_stream_state_changed(struct bt_bap_stream *stream)
 	}
 }
 
-static void stream_set_state(struct bt_bap_stream *stream, uint8_t state)
+/* Return false if the stream is being detached */
+static bool stream_set_state(struct bt_bap_stream *stream, uint8_t state)
 {
 	struct bt_bap *bap = stream->bap;
 
@@ -1308,13 +1309,14 @@  static void stream_set_state(struct bt_bap_stream *stream, uint8_t state)
 	bap = bt_bap_ref_safe(bap);
 	if (!bap) {
 		bap_stream_detach(stream);
-		return;
+		return false;
 	}
 
 	if (stream->ops && stream->ops->set_state)
 		stream->ops->set_state(stream, state);
 
 	bt_bap_unref(bap);
+	return true;
 }
 
 static void ep_config_cb(struct bt_bap_stream *stream, int err)
@@ -2487,7 +2489,8 @@  static uint8_t stream_enable(struct bt_bap_stream *stream, struct iovec *meta,
 	util_iov_free(stream->meta, 1);
 	stream->meta = util_iov_dup(meta, 1);
 
-	stream_set_state(stream, BT_BAP_STREAM_STATE_ENABLING);
+	if (!stream_set_state(stream, BT_BAP_STREAM_STATE_ENABLING))
+		return 1;
 
 	/* Sink can autonomously for to Streaming state if io already exits */
 	if (stream->io && stream->ep->dir == BT_BAP_SINK)