diff mbox series

[Bluez,v1] avdtp: Add check for service capabilities length correctness

Message ID 20200313164001.Bluez.v1.1.I320c1cb9a71bf0793ae3a644548c76b13427a97d@changeid
State New
Headers show
Series [Bluez,v1] avdtp: Add check for service capabilities length correctness | expand

Commit Message

Archie Pusaka March 13, 2020, 8:41 a.m. UTC
From: Archie Pusaka <apusaka@chromium.org>

There is a check for capability length of AVDTP_MEDIA_TRANSPORT,
but there are none for the other capability categories.

Therefore, this patch add such check for these categories:
AVDTP_REPORTING
AVDTP_RECOVERY
AVDTP_CONTENT_PROTECTION
AVDTP_HEADER_COMPRESSION
AVDTP_MULTIPLEXING

Set Configuration Command messages which contains bad length shall
be responded with Set Configuration Reject.

Furthermore, this patch also assign the service category field for
Set Configuration Reject, as what is described in section 8.9.3 of
Bluetooth AVDTP spec.

Signed-off-by: Archie Pusaka <apusaka@chromium.org>
---

 profiles/audio/avdtp.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 0e075f9ff..5faf0279e 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1421,6 +1421,39 @@  static void setconf_cb(struct avdtp *session, struct avdtp_stream *stream,
 	avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
 }
 
+static uint8_t verify_service_capability_length(
+					struct avdtp_service_capability *cap)
+{
+	switch (cap->category) {
+	case AVDTP_MEDIA_TRANSPORT:
+		if (cap->length != 0)
+			return AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
+		break;
+	case AVDTP_REPORTING:
+		if (cap->length != 0)
+			return AVDTP_BAD_PAYLOAD_FORMAT;
+		break;
+	case AVDTP_RECOVERY:
+		if (cap->length != 3)
+			return AVDTP_BAD_RECOVERY_FORMAT;
+		break;
+	case AVDTP_CONTENT_PROTECTION:
+		if (cap->length < 2)
+			return AVDTP_BAD_CP_FORMAT;
+		break;
+	case AVDTP_HEADER_COMPRESSION:
+		if (cap->length != 1)
+			return AVDTP_BAD_ROHC_FORMAT;
+		break;
+	case AVDTP_MULTIPLEXING:
+		if (cap->length < 2 || cap->length > 7)
+			return AVDTP_BAD_MULTIPLEXING_FORMAT;
+		break;
+	}
+
+	return 0;
+}
+
 static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
 				struct setconf_req *req, unsigned int size)
 {
@@ -1487,12 +1520,12 @@  static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
 					&stream->codec,
 					&stream->delay_reporting);
 
-	/* Verify that the Media Transport capability's length = 0. Reject otherwise */
 	for (l = stream->caps; l != NULL; l = g_slist_next(l)) {
 		struct avdtp_service_capability *cap = l->data;
 
-		if (cap->category == AVDTP_MEDIA_TRANSPORT && cap->length != 0) {
-			err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
+		err = verify_service_capability_length(cap);
+		if (err) {
+			category = cap->category;
 			goto failed_stream;
 		}
 	}