mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-14 10:24:32 -05:00
136 lines
4.6 KiB
Diff
136 lines
4.6 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Brian Delwiche <delwiche@google.com>
|
||
|
Date: Tue, 23 May 2023 23:23:11 +0000
|
||
|
Subject: [PATCH] Fix some OOB errors in BTM parsing
|
||
|
|
||
|
Some HCI BLE events are missing bounds checks, leading to possible OOB
|
||
|
access. Add the appropriate bounds checks on the packets.
|
||
|
|
||
|
Bug: 279169188
|
||
|
Test: atest bluetooth_test_gd_unit, net_test_stack_btm
|
||
|
Tag: #security
|
||
|
Ignore-AOSP-First: Security
|
||
|
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:949eb6b355f1bdcfb5567ebe1b7f00a61b6fb066)
|
||
|
Merged-In: Icf2953c687d9c4e2ca9629474151b8deab6c5f57
|
||
|
Change-Id: Icf2953c687d9c4e2ca9629474151b8deab6c5f57
|
||
|
---
|
||
|
stack/btm/btm_ble_gap.cc | 50 ++++++++++++++++++++++++++++++----------
|
||
|
stack/btu/btu_hcif.cc | 6 +++++
|
||
|
2 files changed, 44 insertions(+), 12 deletions(-)
|
||
|
|
||
|
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
|
||
|
index 4e8471261..8a2c53c30 100644
|
||
|
--- a/stack/btm/btm_ble_gap.cc
|
||
|
+++ b/stack/btm/btm_ble_gap.cc
|
||
|
@@ -1879,19 +1879,27 @@ void btm_ble_process_ext_adv_pkt(uint8_t data_len, uint8_t* data) {
|
||
|
advertising_sid;
|
||
|
int8_t rssi, tx_power;
|
||
|
uint16_t event_type, periodic_adv_int, direct_address_type;
|
||
|
+ size_t bytes_to_process;
|
||
|
|
||
|
/* Only process the results if the inquiry is still active */
|
||
|
if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) return;
|
||
|
|
||
|
+ bytes_to_process = 1;
|
||
|
+
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR) << "Malformed LE extended advertising packet: not enough room "
|
||
|
+ "for num reports";
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
/* Extract the number of reports in this event. */
|
||
|
STREAM_TO_UINT8(num_reports, p);
|
||
|
|
||
|
while (num_reports--) {
|
||
|
- if (p > data + data_len) {
|
||
|
- // TODO(jpawlowski): we should crash the stack here
|
||
|
- BTM_TRACE_ERROR(
|
||
|
- "Malformed LE Extended Advertising Report Event from controller - "
|
||
|
- "can't loop the data");
|
||
|
+ bytes_to_process += 24;
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR) << "Malformed LE extended advertising packet: not enough room "
|
||
|
+ "for metadata";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -1911,8 +1919,11 @@ void btm_ble_process_ext_adv_pkt(uint8_t data_len, uint8_t* data) {
|
||
|
|
||
|
uint8_t* pkt_data = p;
|
||
|
p += pkt_data_len; /* Advance to the the next packet*/
|
||
|
- if (p > data + data_len) {
|
||
|
- LOG(ERROR) << "Invalid pkt_data_len: " << +pkt_data_len;
|
||
|
+
|
||
|
+ bytes_to_process += pkt_data_len;
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR) << "Malformed LE extended advertising packet: not enough room "
|
||
|
+ "for packet data";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -1941,17 +1952,28 @@ void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) {
|
||
|
uint8_t* p = data;
|
||
|
uint8_t legacy_evt_type, addr_type, num_reports, pkt_data_len;
|
||
|
int8_t rssi;
|
||
|
+ size_t bytes_to_process;
|
||
|
|
||
|
/* Only process the results if the inquiry is still active */
|
||
|
if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) return;
|
||
|
|
||
|
+ bytes_to_process = 1;
|
||
|
+
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR)
|
||
|
+ << "Malformed LE advertising packet: not enough room for num reports";
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
/* Extract the number of reports in this event. */
|
||
|
STREAM_TO_UINT8(num_reports, p);
|
||
|
|
||
|
while (num_reports--) {
|
||
|
- if (p > data + data_len) {
|
||
|
- // TODO(jpawlowski): we should crash the stack here
|
||
|
- BTM_TRACE_ERROR("Malformed LE Advertising Report Event from controller");
|
||
|
+ bytes_to_process += 9;
|
||
|
+
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR)
|
||
|
+ << "Malformed LE advertising packet: not enough room for metadata";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -1963,8 +1985,12 @@ void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) {
|
||
|
|
||
|
uint8_t* pkt_data = p;
|
||
|
p += pkt_data_len; /* Advance to the the rssi byte */
|
||
|
- if (p > data + data_len - sizeof(rssi)) {
|
||
|
- LOG(ERROR) << "Invalid pkt_data_len: " << +pkt_data_len;
|
||
|
+
|
||
|
+ // include rssi for this check
|
||
|
+ bytes_to_process += pkt_data_len + 1;
|
||
|
+ if (data_len < bytes_to_process) {
|
||
|
+ LOG(ERROR) << "Malformed LE advertising packet: not enough room for "
|
||
|
+ "packet data and/or RSSI";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
|
||
|
index 720bab266..8c83fa10e 100644
|
||
|
--- a/stack/btu/btu_hcif.cc
|
||
|
+++ b/stack/btu/btu_hcif.cc
|
||
|
@@ -1810,6 +1810,12 @@ static void btu_ble_data_length_change_evt(uint8_t* p, uint16_t evt_len) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ // 2 bytes each for handle, tx_data_len, TxTimer, rx_data_len
|
||
|
+ if (evt_len < 8) {
|
||
|
+ LOG_ERROR(LOG_TAG, "Event packet too short");
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
STREAM_TO_UINT16(handle, p);
|
||
|
STREAM_TO_UINT16(tx_data_len, p);
|
||
|
p += 2; /* Skip the TxTimer */
|