aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHui Peng <phui@google.com>2023-07-27 04:09:04 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-08-11 21:06:08 +0000
commita20e893cbb5fd9a1956d99d0638372905bd1c67f (patch)
tree9639ad5772b87ffce92a908fec4ce2869650896c
parent716edfca229fe52439916e319a90379ea851f063 (diff)
downloadbt-a20e893cbb5fd9a1956d99d0638372905bd1c67f.tar.gz
Fix an integer underflow in build_read_multi_rsp
This is a backport of Ia60dd829ff9152c083de1f4c1265bb3ad595dcc4 to sc-dev Bug: 273874525 Test: manual Ignore-AOSP-First: security Tag: #security (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d5f27984f4ca265f28a4adf5835b0198a3e19aed) Merged-In: Ia60dd829ff9152c083de1f4c1265bb3ad595dcc4 Change-Id: Ia60dd829ff9152c083de1f4c1265bb3ad595dcc4
-rw-r--r--stack/gatt/gatt_sr.cc28
1 files changed, 17 insertions, 11 deletions
diff --git a/stack/gatt/gatt_sr.cc b/stack/gatt/gatt_sr.cc
index e358bd977..d689acf16 100644
--- a/stack/gatt/gatt_sr.cc
+++ b/stack/gatt/gatt_sr.cc
@@ -21,6 +21,7 @@
* this file contains the GATT server functions
*
******************************************************************************/
+#include <algorithm>
#include "bt_target.h"
#include "osi/include/osi.h"
@@ -173,12 +174,24 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
}
if (p_rsp != NULL) {
- total_len = (p_buf->len + p_rsp->attr_value.len);
+ total_len = p_buf->len;
if (p_cmd->multi_req.variable_len) {
total_len += 2;
}
if (total_len > mtu) {
+ VLOG(1) << "Buffer space not enough for this data item, skipping";
+ break;
+ }
+
+ len = std::min((size_t) p_rsp->attr_value.len, mtu - total_len);
+
+ if (len == 0) {
+ VLOG(1) << "Buffer space not enough for this data item, skipping";
+ break;
+ }
+
+ if (len < p_rsp->attr_value.len) {
/* just send the partial response for the overflow case */
len = p_rsp->attr_value.len - (total_len - mtu);
is_overflow = true;
@@ -190,20 +203,13 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
}
if (p_cmd->multi_req.variable_len) {
- UINT16_TO_STREAM(p, len);
+ UINT16_TO_STREAM(p, (uint16_t) len);
p_buf->len += 2;
}
if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) {
- // check for possible integer overflow
- if (p_buf->len + len <= UINT16_MAX) {
- memcpy(p, p_rsp->attr_value.value, len);
- if (!is_overflow) p += len;
- p_buf->len += len;
- } else {
- p_cmd->status = GATT_NOT_FOUND;
- break;
- }
+ ARRAY_TO_STREAM(p, p_rsp->attr_value.value, (uint16_t) len);
+ p_buf->len += (uint16_t) len;
} else {
p_cmd->status = GATT_NOT_FOUND;
break;