[PATCH BlueZ 1/2] bap: Remove memory leaks and buffer usage after free

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

 



Make sure the endpoint does not contain uninitialized pointers after
creation. Rework parse_base and parse_array. Add missing unregister in
bap_exit.
---
 profiles/audio/bap.c | 66 ++++++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index ee90426b9812..b164f68d3187 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -278,16 +278,17 @@ static const GDBusPropertyTable ep_properties[] = {
 static int parse_array(DBusMessageIter *iter, struct iovec **iov)
 {
 	DBusMessageIter array;
+	struct iovec tmp_iov = {0};

 	if (!iov)
 		return 0;

-	if (!(*iov))
-		*iov = new0(struct iovec, 1);
-
 	dbus_message_iter_recurse(iter, &array);
-	dbus_message_iter_get_fixed_array(&array, &(*iov)->iov_base,
-						(int *)&(*iov)->iov_len);
+	dbus_message_iter_get_fixed_array(&array, &(tmp_iov).iov_base,
+						(int *)&(tmp_iov).iov_len);
+
+	*iov = util_iov_dup(&tmp_iov, 1);
+
 	return 0;
 }

@@ -300,7 +301,8 @@ static bool parse_base(void *data, size_t len, util_debug_func_t func,
 		.iov_base = data,
 		.iov_len = len,
 	};
-
+	struct iovec *csc_iov = NULL;
+	struct iovec *meta_iov = NULL;
 	uint8_t capsLen, metaLen;
 	uint8_t *hexstream;

@@ -330,22 +332,21 @@ static bool parse_base(void *data, size_t len, util_debug_func_t func,
 				"Codec", codec->id, codec->cid, codec->vid);
 	}

+	/* Fetch Codec Specific Configuration */
 	if (!util_iov_pull_u8(&iov, &capsLen))
 		return false;
 	util_debug(func, NULL, "CC Len %d", capsLen);

 	if (!capsLen)
 		return false;
-	if (caps) {
-		if (!(*caps))
-			*caps = new0(struct iovec, 1);
-		(*caps)->iov_len = capsLen;
-		(*caps)->iov_base = iov.iov_base;
-	}

+	csc_iov = new0(struct iovec, 1);
+	util_iov_memcpy(csc_iov, iov.iov_base, capsLen);
+
+	/* Print Codec Specific Configuration */
 	for (int i = 0; capsLen > 1; i++) {
 		struct bt_ltv *ltv = util_iov_pull_mem(&iov, sizeof(*ltv));
-		uint8_t *caps;
+		uint8_t *csc;

 		if (!ltv) {
 			util_debug(func, NULL, "Unable to parse %s",
@@ -356,35 +357,46 @@ static bool parse_base(void *data, size_t len, util_debug_func_t func,
 		util_debug(func, NULL, "%s #%u: len %u type %u",
 					"CC", i, ltv->len, ltv->type);

-		caps = util_iov_pull_mem(&iov, ltv->len - 1);
-		if (!caps) {
+		csc = util_iov_pull_mem(&iov, ltv->len - 1);
+		if (!csc) {
 			util_debug(func, NULL, "Unable to parse %s",
 								"CC");
 			return false;
 		}
-		util_hexdump(' ', caps, ltv->len - 1, func, NULL);
+		util_hexdump(' ', csc, ltv->len - 1, func, NULL);

 		capsLen -= (ltv->len + 1);
 	}

+	/* Fetch Metadata */
 	if (!util_iov_pull_u8(&iov, &metaLen))
 		return false;
 	util_debug(func, NULL, "Metadata Len %d", metaLen);

 	if (!metaLen)
 		return false;
-	if (meta) {
-		if (!(*meta))
-			*meta = new0(struct iovec, 1);
-		(*meta)->iov_len = metaLen;
-		(*meta)->iov_base = iov.iov_base;
-	}
+
+	meta_iov = new0(struct iovec, 1);
+	util_iov_memcpy(meta_iov, iov.iov_base, metaLen);

 	hexstream = util_iov_pull_mem(&iov, metaLen);
 	if (!hexstream)
 		return false;
 	util_hexdump(' ', hexstream, metaLen, func, NULL);

+	/* Update caps and meta with received Codec Specific Configuration and Metadata */
+	if (caps) {
+		if (*caps)
+			util_iov_free(*caps, 1);
+		*caps = csc_iov;
+	}
+
+	if (meta) {
+		if (*meta)
+			util_iov_free(*meta, 1);
+		*meta = meta_iov;
+	}
+
 	return true;
 }

@@ -780,7 +792,6 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
 	char address[18];
 	struct bap_ep *ep;
 	int fd;
-	struct iovec *base_io;
 	uint32_t presDelay;
 	uint8_t numSubgroups;
 	uint8_t numBis;
@@ -807,12 +818,11 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
 	if (!ep)
 		return;

+	/* Update endpoint with the values of the peer's (BAP source) QOS */
 	update_bcast_qos(&qos, &ep->qos);

-	base_io = new0(struct iovec, 1);
-	util_iov_memcpy(base_io, base.base, base.base_len);
-
-	parse_base(base_io->iov_base, base_io->iov_len, bap_debug,
+	/* Update endpoint with the value received from the peer's (BAP source) BASE */
+	parse_base(base.base, base.base_len, bap_debug,
 			&presDelay, &numSubgroups, &numBis,
 			&codec, &ep->caps, &ep->metadata);

@@ -917,6 +927,7 @@ static struct bap_ep *ep_register_bcast(struct bap_data *data,
 		return ep;

 	ep = new0(struct bap_ep, 1);
+	memset(ep, 0, sizeof(struct bap_ep));
 	ep->data = data;
 	ep->lpac = lpac;
 	ep->rpac = rpac;
@@ -2288,6 +2299,7 @@ static int bap_init(void)
 static void bap_exit(void)
 {
 	btd_profile_unregister(&bap_profile);
+	btd_profile_unregister(&bap_bcast_profile);
 	bt_bap_unregister(bap_id);
 }

--
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