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

Commit 2fc3087b 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
Merged-In: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
Change-Id: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
parent 3e5357bb
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -734,6 +734,11 @@ void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid,

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(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);
@@ -769,6 +774,12 @@ static void gatts_process_find_info(tGATT_TCB& tcb, uint16_t cid,
  }

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(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);

@@ -902,6 +913,11 @@ static void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid,

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(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;
@@ -1049,6 +1065,11 @@ static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid,
                                   uint8_t* p_data) {
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(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;