diff options
| author | Brian Delwiche <delwiche@google.com> | 2024-09-12 17:26:55 +0000 |
|---|---|---|
| committer | aoleary <seanm187@gmail.com> | 2024-12-30 07:26:36 +0000 |
| commit | 2d3b891bddce74eecd887a62e5b66390e47d64e9 (patch) | |
| tree | 7ea029b1fd4eca4932ed8ce0943e5267fbfe954d | |
| parent | c2a956b86b6327afb5de75ea21c7de77e3fafae3 (diff) | |
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 commit 7de5617f7d5266fe57c990c428621b5d4e92728a)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:61f6c95083aa98c597f1fdf7c871dd826e810f2b)
Merged-In: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
Change-Id: I9b30499d4aed6ab42f3cdb2c0de7df2c1a827404
| -rw-r--r-- | system/stack/gatt/gatt_sr.cc | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc index 1aa5d6c145..5c866cb60c 100644 --- a/system/stack/gatt/gatt_sr.cc +++ b/system/stack/gatt/gatt_sr.cc @@ -733,6 +733,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); @@ -768,6 +773,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; |
