[PATCH BlueZ] lib: Add bt_realloc

zuohsh <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <[email protected]>
Add a bt_realloc wrapper that takes a pointer-to-pointer and only updates
the original on success, so that a failed realloc cannot leak the
existing buffer or leave a NULL pointer for the caller to dereference.

shared/ad: use bt_realloc in bt_ad_add_data(),
           bt_ad_add_manufacturer_data() and  bt_ad_add_service_data().
shared/bap: use  bt_realloc in ascs_ase_rsp_add().
lib/sdp: use bt_realloc in sdp_service_attr_req(), sdp_process() and
        sdp_service_search_attr_req().
---
 lib/bluetooth/bluetooth.c | 13 +++++++++++++
 lib/bluetooth/bluetooth.h |  2 ++
 lib/bluetooth/sdp.c       | 22 +++++++++++++++++++---
 src/shared/ad.c           |  9 ++++++---
 src/shared/bap.c          |  3 ++-
 5 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/lib/bluetooth/bluetooth.c b/lib/bluetooth/bluetooth.c
index 6e0977360..38f92f9e8 100644
--- a/lib/bluetooth/bluetooth.c
+++ b/lib/bluetooth/bluetooth.c
@@ -178,6 +178,19 @@ void *bt_malloc0(size_t size)
 	return calloc(size, 1);
 }
 
+bool bt_realloc(void *ptr, size_t size)
+{
+	void **pptr = ptr;
+	void *tmp;
+
+	tmp = realloc(*pptr, size);
+	if (!tmp)
+		return false;
+
+	*pptr = tmp;
+	return true;
+}
+
 void bt_free(void *ptr)
 {
 	free(ptr);
diff --git a/lib/bluetooth/bluetooth.h b/lib/bluetooth/bluetooth.h
index f9f22c3f7..5151c50f2 100644
--- a/lib/bluetooth/bluetooth.h
+++ b/lib/bluetooth/bluetooth.h
@@ -20,6 +20,7 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <string.h>
 #include <endian.h>
 #include <byteswap.h>
@@ -458,6 +459,7 @@ int basnprintf(char *str, size_t size, const char *format, ...);
 
 void *bt_malloc(size_t size);
 void *bt_malloc0(size_t size);
+bool bt_realloc(void *ptr, size_t size);
 void bt_free(void *ptr);
 
 int bt_error(uint16_t code);
diff --git a/lib/bluetooth/sdp.c b/lib/bluetooth/sdp.c
index 8c0865398..0e49ae2a6 100644
--- a/lib/bluetooth/sdp.c
+++ b/lib/bluetooth/sdp.c
@@ -3697,7 +3697,12 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
 			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
 
 			/* build concatenated response buffer */
-			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
+			if (!bt_realloc(&rsp_concat_buf.data,
+					rsp_concat_buf.data_size + rsp_count)) {
+				SDPERR("Failed to reallocate buffer");
+				status = -1;
+				goto end;
+			}
 			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
 			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
 			memcpy(targetPtr, pdata, rsp_count);
@@ -4338,7 +4343,13 @@ int sdp_process(sdp_session_t *session)
 	 * This is a split response, need to concatenate intermediate
 	 * responses and the last one which will have cstate length == 0
 	 */
-	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
+	if (!bt_realloc(&t->rsp_concat_buf.data,
+			t->rsp_concat_buf.data_size + rsp_count)) {
+		SDPERR("Failed to reallocate buffer");
+		status = 0xffff;
+		t->err = ENOMEM;
+		goto end;
+	}
 	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
 	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
 	memcpy(targetPtr, pdata, rsp_count);
@@ -4560,7 +4571,12 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search
 			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
 
 			/* build concatenated response buffer */
-			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
+			if (!bt_realloc(&rsp_concat_buf.data,
+					rsp_concat_buf.data_size + rsp_count)) {
+				SDPERR("Failed to reallocate buffer");
+				status = -1;
+				goto end;
+			}
 			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
 			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
 			memcpy(targetPtr, pdata, rsp_count);
diff --git a/src/shared/ad.c b/src/shared/ad.c
index b1d1b8461..35aafd437 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -386,7 +386,8 @@ static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data,
 	if (new_data) {
 		if (new_data->len == len && !memcmp(new_data->data, data, len))
 			return false;
-		new_data->data = realloc(new_data->data, len);
+		if (!bt_realloc(&new_data->data, len))
+			return false;
 		memcpy(new_data->data, data, len);
 		new_data->len = len;
 		return true;
@@ -844,7 +845,8 @@ bool bt_ad_add_manufacturer_data(struct bt_ad *ad, uint16_t manufacturer_id,
 	if (new_data) {
 		if (new_data->len == len && !memcmp(new_data->data, data, len))
 			return false;
-		new_data->data = realloc(new_data->data, len);
+		if (!bt_realloc(&new_data->data, len))
+			return false;
 		memcpy(new_data->data, data, len);
 		new_data->len = len;
 		return true;
@@ -980,7 +982,8 @@ bool bt_ad_add_service_data(struct bt_ad *ad, const bt_uuid_t *uuid, void *data,
 	if (new_data) {
 		if (new_data->len == len && !memcmp(new_data->data, data, len))
 			return false;
-		new_data->data = realloc(new_data->data, len);
+		if (!bt_realloc(&new_data->data, len))
+			return false;
 		memcpy(new_data->data, data, len);
 		new_data->len = len;
 		return true;
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 1660b8b2c..319de76dd 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -1000,7 +1000,8 @@ static void ascs_ase_rsp_add(struct iovec *iov, uint8_t id,
 	}
 
 	iov->iov_len += sizeof(*rsp);
-	iov->iov_base = realloc(iov->iov_base, iov->iov_len);
+	if (!bt_realloc(&iov->iov_base, iov->iov_len))
+		return;
 
 	rsp = iov->iov_base + (iov->iov_len - sizeof(*rsp));
 	rsp->ase = id;
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.