diff options
author | Hui Peng <phui@google.com> | 2023-07-27 04:09:04 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-08-11 21:06:08 +0000 |
commit | a20e893cbb5fd9a1956d99d0638372905bd1c67f (patch) | |
tree | 9639ad5772b87ffce92a908fec4ce2869650896c | |
parent | 716edfca229fe52439916e319a90379ea851f063 (diff) | |
download | bt-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.cc | 28 |
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; |