[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