Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70a4d628 authored by Brian Delwiche's avatar Brian Delwiche
Browse files

Fix integer overflow in build_read_multi_rsp

Local variables tracking structure size in build_read_multi_rsp are of
uint16 type but accept a full uint16 range from function arguments while
appending a fixed-length offset.  This can lead to an integer overflow
and unexpected behavior.

Change the locals to size_t, and add a check during reasssignment.

Bug: 273966636
Test: atest bluetooth_test_gd_unit, net_test_stack_btm
Tag: #security
Ignore-AOSP-First: Security
Change-Id: I3a74bdb0d003cb6bf4f282615be8c68836676715
parent 63d140fa
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -143,7 +143,8 @@ void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) {
}

static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
  uint16_t ii, total_len, len;
  uint16_t ii;
  size_t total_len, len;
  uint8_t* p;
  bool is_overflow = false;

@@ -188,7 +189,7 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
        len = p_rsp->attr_value.len - (total_len - mtu);
        is_overflow = true;
        VLOG(1) << StringPrintf(
            "multi read overflow available len=%d val_len=%d", len,
            "multi read overflow available len=%zu val_len=%d", len,
            p_rsp->attr_value.len);
      } else {
        len = p_rsp->attr_value.len;
@@ -200,6 +201,8 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
      }

      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;
@@ -207,6 +210,10 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
          p_cmd->status = GATT_NOT_FOUND;
          break;
        }
      } else {
        p_cmd->status = GATT_NOT_FOUND;
        break;
      }

      if (is_overflow) break;