aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Delwiche <delwiche@google.com>2024-09-12 17:26:55 +0000
committeraoleary <seanm187@gmail.com>2024-12-30 07:26:36 +0000
commit2d3b891bddce74eecd887a62e5b66390e47d64e9 (patch)
tree7ea029b1fd4eca4932ed8ce0943e5267fbfe954d
parentc2a956b86b6327afb5de75ea21c7de77e3fafae3 (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.cc21
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;