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

Commit 7de5617f authored by Brian Delwiche's avatar Brian Delwiche
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
Change-Id: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
parent ab9d496a
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -772,6 +772,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);
@@ -804,6 +809,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);
@@ -949,6 +960,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;
@@ -1096,6 +1112,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;