OSDN Git Service

Fix potential OOB when parsing inquiry results
authorJakub Pawlowski <jpawlowski@google.com>
Fri, 4 Oct 2019 14:40:41 +0000 (16:40 +0200)
committerMyles Watson <mylesgw@google.com>
Thu, 19 Dec 2019 21:20:42 +0000 (21:20 +0000)
Bug: 141620271
Change-Id: I30c7558b1ae1a77d0004760ef831480347a06e11
(cherry picked from commit c44516749af81bc5fc79afc0772f42bf0ec37bd4)

stack/btm/btm_inq.cc
stack/btm/btm_int.h
stack/btu/btu_hcif.cc

index 1a5d7f5..ef16359 100644 (file)
@@ -25,6 +25,7 @@
  *
  ******************************************************************************/
 
+#include <log/log.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -1602,7 +1603,8 @@ static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq) {
  * Returns          void
  *
  ******************************************************************************/
-void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode) {
+void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
+                             uint8_t inq_res_mode) {
   uint8_t num_resp, xx;
   RawAddress bda;
   tINQ_DB_ENT* p_i;
@@ -1631,10 +1633,29 @@ void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode) {
 
   STREAM_TO_UINT8(num_resp, p);
 
-  if (inq_res_mode == BTM_INQ_RESULT_EXTENDED && (num_resp > 1)) {
-    BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
-                    num_resp);
-    return;
+  if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
+    if (num_resp > 1) {
+      BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
+                      num_resp);
+      return;
+    }
+
+    constexpr uint16_t extended_inquiry_result_size = 254;
+    if (hci_evt_len - 1 != extended_inquiry_result_size) {
+      android_errorWriteLog(0x534e4554, "141620271");
+      BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
+                      num_resp, hci_evt_len);
+      return;
+    }
+  } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
+             inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
+    constexpr uint16_t inquiry_result_size = 14;
+    if (hci_evt_len < num_resp * inquiry_result_size) {
+      android_errorWriteLog(0x534e4554, "141620271");
+      BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
+                      num_resp, hci_evt_len);
+      return;
+    }
   }
 
   for (xx = 0; xx < num_resp; xx++) {
index ee1d655..88cb724 100644 (file)
@@ -65,7 +65,8 @@ extern void btm_inq_remote_name_timer_timeout(void* data);
 /* Inquiry related functions */
 extern void btm_clr_inq_db(const RawAddress* p_bda);
 extern void btm_inq_db_init(void);
-extern void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode);
+extern void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
+                                    uint8_t inq_res_mode);
 extern void btm_process_inq_complete(uint8_t status, uint8_t mode);
 extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
 extern void btm_event_filter_complete(uint8_t* p);
index c70448e..31ae528 100644 (file)
@@ -64,9 +64,10 @@ extern void smp_cancel_start_encryption_attempt();
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
 static void btu_hcif_inquiry_comp_evt(uint8_t* p);
-static void btu_hcif_inquiry_result_evt(uint8_t* p);
-static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p);
-static void btu_hcif_extended_inquiry_result_evt(uint8_t* p);
+static void btu_hcif_inquiry_result_evt(uint8_t* p, uint8_t hci_evt_len);
+static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p, uint8_t hci_evt_len);
+static void btu_hcif_extended_inquiry_result_evt(uint8_t* p,
+                                                 uint8_t hci_evt_len);
 
 static void btu_hcif_connection_comp_evt(uint8_t* p);
 static void btu_hcif_connection_request_evt(uint8_t* p);
@@ -263,13 +264,13 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) {
       btu_hcif_inquiry_comp_evt(p);
       break;
     case HCI_INQUIRY_RESULT_EVT:
-      btu_hcif_inquiry_result_evt(p);
+      btu_hcif_inquiry_result_evt(p, hci_evt_len);
       break;
     case HCI_INQUIRY_RSSI_RESULT_EVT:
-      btu_hcif_inquiry_rssi_result_evt(p);
+      btu_hcif_inquiry_rssi_result_evt(p, hci_evt_len);
       break;
     case HCI_EXTENDED_INQUIRY_RESULT_EVT:
-      btu_hcif_extended_inquiry_result_evt(p);
+      btu_hcif_extended_inquiry_result_evt(p, hci_evt_len);
       break;
     case HCI_CONNECTION_COMP_EVT:
       btu_hcif_connection_comp_evt(p);
@@ -948,9 +949,9 @@ static void btu_hcif_inquiry_comp_evt(uint8_t* p) {
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_inquiry_result_evt(uint8_t* p) {
+static void btu_hcif_inquiry_result_evt(uint8_t* p, uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_STANDARD);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_STANDARD);
 }
 
 /*******************************************************************************
@@ -962,9 +963,9 @@ static void btu_hcif_inquiry_result_evt(uint8_t* p) {
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p) {
+static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p, uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_WITH_RSSI);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_WITH_RSSI);
 }
 
 /*******************************************************************************
@@ -976,9 +977,10 @@ static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p) {
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_extended_inquiry_result_evt(uint8_t* p) {
+static void btu_hcif_extended_inquiry_result_evt(uint8_t* p,
+                                                 uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_EXTENDED);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_EXTENDED);
 }
 
 /*******************************************************************************