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

Commit 69cb902b authored by Brian Delwiche's avatar Brian Delwiche Committed by Android Build Coastguard Worker
Browse files

Fix OOB writes in gatt_sr.cc

At various points in gatt_sr.cc, the output of the
gatt_tcb_get_payload_size function is used without checking for a
positive length.  However, in exceptional cases it is possible for the
channel to be closed at the time the function is called, which will lead
to a zero length and cause an OOB write in subsequent processing.

Fix all of these.

Bug: 364026473
Bug: 364027038
Bug: 364027949
Bug: 364025411
Test: m libbluetooth
Test: researcher POC
Flag: EXEMPT trivial validity checks
Tag: #security
Ignore-AOSP-First: Security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7de5617f7d5266fe57c990c428621b5d4e92728a)
Merged-In: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
Change-Id: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
parent 37e53929
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -768,6 +768,11 @@ void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_

  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  // This can happen if the channel is already closed.
  if (payload_size == 0) {
    return;
  }

  uint16_t msg_len = (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
  BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
  reason = gatt_build_primary_service_rsp(p_msg, tcb, cid, op_code, s_hdl, e_hdl, p_data, value);
@@ -800,6 +805,12 @@ static void gatts_process_find_info(tGATT_TCB& tcb, uint16_t cid, uint8_t op_cod
  }

  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  // This can happen if the channel is already closed.
  if (payload_size == 0) {
    return;
  }

  uint16_t buf_len = (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);

  BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
@@ -945,6 +956,11 @@ static void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid, uint8_t

  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  // This can happen if the channel is already closed.
  if (payload_size == 0) {
    return;
  }

  size_t msg_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
  BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
  uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
@@ -1092,6 +1108,11 @@ static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid, tGATT_SRV_LIST_
                                   uint8_t* p_data) {
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  // This can happen if the channel is already closed.
  if (payload_size == 0) {
    return;
  }

  size_t buf_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
  uint16_t offset = 0;