From a20e893cbb5fd9a1956d99d0638372905bd1c67f Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Thu, 27 Jul 2023 04:09:04 +0000 Subject: 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 --- stack/gatt/gatt_sr.cc | 28 +++++++++++++++++----------- 1 file 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 #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; -- cgit v1.2.3