[PATCH v3] gatt-server: Fix integer overflow and 3 CI VLA wanings

zuohsh <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <[email protected]>
By using size_t for realloc len and rejecting allocations exceeding
UINT16_MAX , to prevent truncation into the uint16_t field.

Fix CI warnings: Variable length array is used, use malloc/free instead.
---
 src/shared/gatt-server.c | 42 ++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 709a8f94b..516fceb8e 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -268,7 +268,7 @@ static void read_by_grp_type_cb(struct bt_att_chan *chan, uint16_t mtu,
 	uint16_t start, end;
 	bt_uuid_t type;
 	bt_uuid_t prim, snd;
-	uint8_t rsp_pdu[mtu];
+	uint8_t *rsp_pdu = NULL;
 	uint16_t rsp_len;
 	uint8_t ecode = 0;
 	uint16_t ehandle = 0;
@@ -319,6 +319,12 @@ static void read_by_grp_type_cb(struct bt_att_chan *chan, uint16_t mtu,
 		goto error;
 	}

+	rsp_pdu = malloc(mtu);
+	if (!rsp_pdu) {
+		ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+		goto error;
+	}
+
 	if (!encode_read_by_grp_type_rsp(server->db, q, server->att, mtu,
 							rsp_pdu, &rsp_len)) {
 		ecode = BT_ATT_ERROR_UNLIKELY;
@@ -330,11 +336,14 @@ static void read_by_grp_type_cb(struct bt_att_chan *chan, uint16_t mtu,
 	bt_att_chan_send_rsp(chan, BT_ATT_OP_READ_BY_GRP_TYPE_RSP,
 						rsp_pdu, rsp_len);

+	free(rsp_pdu);
+
 	return;

 error:
 	queue_destroy(q, NULL);
 	bt_att_chan_send_error_rsp(chan, opcode, ehandle, ecode);
+	free(rsp_pdu);
 }

 static void async_read_op_destroy(struct async_read_op *op)
@@ -611,7 +620,7 @@ static void find_info_cb(struct bt_att_chan *chan, uint16_t mtu, uint8_t opcode,
 {
 	struct bt_gatt_server *server = user_data;
 	uint16_t start, end;
-	uint8_t rsp_pdu[mtu];
+	uint8_t *rsp_pdu = NULL;
 	uint16_t rsp_len;
 	uint8_t ecode = 0;
 	uint16_t ehandle = 0;
@@ -648,6 +657,12 @@ static void find_info_cb(struct bt_att_chan *chan, uint16_t mtu, uint8_t opcode,
 		goto error;
 	}

+	rsp_pdu = malloc(mtu);
+	if (!rsp_pdu) {
+		ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+		goto error;
+	}
+
 	if (!encode_find_info_rsp(server->db, q, mtu, rsp_pdu, &rsp_len)) {
 		ecode = BT_ATT_ERROR_UNLIKELY;
 		goto error;
@@ -657,11 +672,14 @@ static void find_info_cb(struct bt_att_chan *chan, uint16_t mtu, uint8_t opcode,

 	queue_destroy(q, NULL);

+	free(rsp_pdu);
+
 	return;

 error:
 	bt_att_chan_send_error_rsp(chan, opcode, ehandle, ecode);
 	queue_destroy(q, NULL);
+	free(rsp_pdu);

 }

@@ -709,7 +727,7 @@ static void find_by_type_val_cb(struct bt_att_chan *chan, uint16_t mtu,
 	struct bt_gatt_server *server = user_data;
 	uint16_t start, end, uuid16;
 	struct find_by_type_val_data data;
-	uint8_t rsp_pdu[mtu];
+	uint8_t *rsp_pdu = NULL;
 	uint16_t ehandle = 0;
 	bt_uuid_t uuid;

@@ -718,6 +736,12 @@ static void find_by_type_val_cb(struct bt_att_chan *chan, uint16_t mtu,
 		goto error;
 	}

+	rsp_pdu = malloc(mtu);
+	if (!rsp_pdu) {
+		data.ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+		goto error;
+	}
+
 	data.pdu = rsp_pdu;
 	data.len = 0;
 	data.mtu = mtu;
@@ -752,10 +776,13 @@ static void find_by_type_val_cb(struct bt_att_chan *chan, uint16_t mtu,
 	bt_att_chan_send_rsp(chan, BT_ATT_OP_FIND_BY_TYPE_RSP,
 					data.pdu, data.len);

+	free(rsp_pdu);
+
 	return;

 error:
 	bt_att_chan_send_error_rsp(chan, opcode, ehandle, data.ecode);
+	free(rsp_pdu);
 }

 static void async_write_op_destroy(struct async_write_op *op)
@@ -1174,12 +1201,12 @@ static bool append_prep_data(struct prep_write_data *prep_data, uint16_t handle,
 					uint16_t length, uint8_t *value)
 {
 	uint8_t *val;
-	uint16_t len;
+	size_t len;

 	if (!length)
 		return true;

-	len = prep_data->length + length;
+	len = (size_t)prep_data->length + (size_t)length;

 	val = realloc(prep_data->value, len);
 	if (!val)
@@ -1188,7 +1215,10 @@ static bool append_prep_data(struct prep_write_data *prep_data, uint16_t handle,
 	memcpy(val + prep_data->length, value, length);

 	prep_data->value = val;
-	prep_data->length = len;
+
+	if (len > UINT16_MAX)
+		return false;
+	prep_data->length = (uint16_t)len;

 	return true;
 }
--
2.43.0
Add fixing for CI reported CheckSmatch wanings.
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.