L2CAP: Bounds check num_handles in NumCompletedPackets

Bug: 141617601
Test: Pair and connect
Change-Id: I1a8ff39f677c6957e99a4d3cbd278720dd273a83
(cherry picked from commit 2506db7d01939b286e34e404b80a73e6f4dc8593)
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index c70448e..b309cba 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -85,7 +85,7 @@
 static void btu_hcif_hardware_error_evt(uint8_t* p);
 static void btu_hcif_flush_occured_evt(void);
 static void btu_hcif_role_change_evt(uint8_t* p);
-static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p);
+static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p, uint8_t evt_len);
 static void btu_hcif_mode_change_evt(uint8_t* p);
 static void btu_hcif_pin_code_request_evt(uint8_t* p);
 static void btu_hcif_link_key_request_evt(uint8_t* p);
@@ -326,7 +326,7 @@
       btu_hcif_role_change_evt(p);
       break;
     case HCI_NUM_COMPL_DATA_PKTS_EVT:
-      btu_hcif_num_compl_data_pkts_evt(p);
+      btu_hcif_num_compl_data_pkts_evt(p, hci_evt_len);
       break;
     case HCI_MODE_CHANGE_EVT:
       btu_hcif_mode_change_evt(p);
@@ -1699,9 +1699,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p) {
+static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p, uint8_t evt_len) {
   /* Process for L2CAP and SCO */
-  l2c_link_process_num_completed_pkts(p);
+  l2c_link_process_num_completed_pkts(p, evt_len);
 
   /* Send on to SCO */
   /*?? No SCO for now */
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 53b6f32..e58efaf 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -713,7 +713,7 @@
 extern void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb,
                                      BT_HDR* p_buf);
 extern void l2c_link_adjust_allocation(void);
-extern void l2c_link_process_num_completed_pkts(uint8_t* p);
+extern void l2c_link_process_num_completed_pkts(uint8_t* p, uint8_t evt_len);
 extern void l2c_link_process_num_completed_blocks(uint8_t controller_id,
                                                   uint8_t* p, uint16_t evt_len);
 extern void l2c_link_processs_num_bufs(uint16_t num_lm_acl_bufs);
diff --git a/stack/l2cap/l2c_link.cc b/stack/l2cap/l2c_link.cc
index 60e9fd8..958425d 100644
--- a/stack/l2cap/l2c_link.cc
+++ b/stack/l2cap/l2c_link.cc
@@ -40,6 +40,7 @@
 #include "l2c_api.h"
 #include "l2c_int.h"
 #include "l2cdefs.h"
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
@@ -1214,13 +1215,22 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2c_link_process_num_completed_pkts(uint8_t* p) {
+void l2c_link_process_num_completed_pkts(uint8_t* p, uint8_t evt_len) {
   uint8_t num_handles, xx;
   uint16_t handle;
   uint16_t num_sent;
   tL2C_LCB* p_lcb;
 
-  STREAM_TO_UINT8(num_handles, p);
+  if (evt_len > 0) {
+    STREAM_TO_UINT8(num_handles, p);
+  } else {
+    num_handles = 0;
+  }
+
+  if (num_handles > evt_len / (2 * sizeof(uint16_t))) {
+    android_errorWriteLog(0x534e4554, "141617601");
+    num_handles = evt_len / (2 * sizeof(uint16_t));
+  }
 
   for (xx = 0; xx < num_handles; xx++) {
     STREAM_TO_UINT16(handle, p);