Snap for 4994203 from 3c0e9cebe77840f14a7324f4c8d56df3c4393f23 to pie-vts-release

Change-Id: I10cfb7003a876541ae2227835a56a60e5551481e
diff --git a/bta/ag/bta_ag_sco.cc b/bta/ag/bta_ag_sco.cc
index f28b3c2..083108b 100644
--- a/bta/ag/bta_ag_sco.cc
+++ b/bta/ag/bta_ag_sco.cc
@@ -553,6 +553,14 @@
   APPL_TRACE_DEBUG("%s", __func__);
   bta_ag_cb.sco.p_curr_scb = p_scb;
 
+  // Workaround for misbehaving HFs such as Sony XAV AX100 car kit and Sony
+  // MW600 Headset, which indicate WBS support in SDP, but no codec
+  // negotiation support in BRSF. In this case, using mSBC codec can result
+  // background noise or no audio. Thus, defaulting to CVSD instead.
+  if (!(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
+    p_scb->sco_codec = UUID_CODEC_CVSD;
+  }
+
   if ((p_scb->codec_updated || p_scb->codec_fallback) &&
       (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
     /* Change the power mode to Active until SCO open is completed. */
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index 03c5b90..5abda87 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -3075,11 +3075,14 @@
       }
     }
   } else {
-    BTM_SecDeleteDevice(remote_bd_addr);
+    // remote_bd_addr comes from security record, which is removed in
+    // BTM_SecDeleteDevice.
+    RawAddress addr_copy = remote_bd_addr;
+    BTM_SecDeleteDevice(addr_copy);
     /* need to remove all pending background connection */
-    BTA_GATTC_CancelOpen(0, remote_bd_addr, false);
+    BTA_GATTC_CancelOpen(0, addr_copy, false);
     /* remove all cached GATT information */
-    BTA_GATTC_Refresh(remote_bd_addr);
+    BTA_GATTC_Refresh(addr_copy);
   }
 }
 
diff --git a/bta/hd/bta_hd_act.cc b/bta/hd/bta_hd_act.cc
index 8819983..0d677ee 100644
--- a/bta/hd/bta_hd_act.cc
+++ b/bta/hd/bta_hd_act.cc
@@ -36,6 +36,7 @@
 #include "bta_sys.h"
 #include "btm_api.h"
 
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
@@ -510,6 +511,10 @@
   APPL_TRACE_API("%s", __func__);
 
   if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
+    if (len < 1) {
+      android_errorWriteLog(0x534e4554, "109757986");
+      return;
+    }
     ret.report_id = *p_buf;
 
     len--;
@@ -544,15 +549,31 @@
 
   APPL_TRACE_API("%s", __func__);
 
+  uint16_t remaining_len = p_msg->len;
+  if (remaining_len < 1) {
+    android_errorWriteLog(0x534e4554, "109757168");
+    return;
+  }
+
   ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
   p_buf++;
+  remaining_len--;
 
   if (bta_hd_cb.use_report_id) {
+    if (remaining_len < 1) {
+      android_errorWriteLog(0x534e4554, "109757168");
+      return;
+    }
     ret.report_id = *p_buf;
     p_buf++;
+    remaining_len--;
   }
 
   if (rep_size_follows) {
+    if (remaining_len < 2) {
+      android_errorWriteLog(0x534e4554, "109757168");
+      return;
+    }
     ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
   }
 
@@ -579,11 +600,19 @@
 
   APPL_TRACE_API("%s", __func__);
 
+  if (len < 1) {
+    android_errorWriteLog(0x534e4554, "110846194");
+    return;
+  }
   ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
   p_buf++;
   len--;
 
   if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
+    if (len < 1) {
+      android_errorWriteLog(0x534e4554, "109757435");
+      return;
+    }
     ret.report_id = *p_buf;
 
     len--;
diff --git a/btif/src/btif_hf.cc b/btif/src/btif_hf.cc
index 5388986..37f9471 100644
--- a/btif/src/btif_hf.cc
+++ b/btif/src/btif_hf.cc
@@ -1032,12 +1032,20 @@
         dialnum[newidx++] = '+';
       }
       for (size_t i = 0; number[i] != 0; i++) {
+        if (newidx >= (sizeof(dialnum) - res_strlen - 1)) {
+          android_errorWriteLog(0x534e4554, "79266386");
+          break;
+        }
         if (utl_isdialchar(number[i])) {
           dialnum[newidx++] = number[i];
         }
       }
       dialnum[newidx] = 0;
-      snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum, type);
+      // Reserve 5 bytes for ["][,][3_digit_type]
+      snprintf(&ag_res.str[res_strlen], rem_bytes - 5, ",\"%s", dialnum);
+      std::stringstream remaining_string;
+      remaining_string << "\"," << type;
+      strncat(&ag_res.str[res_strlen], remaining_string.str().c_str(), 5);
     }
   }
   BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, ag_res);
@@ -1184,6 +1192,13 @@
           else
             xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"%s\"", number);
           ag_res.num = type;
+          // 5 = [,][3_digit_type][null_terminator]
+          if (xx > static_cast<int>(sizeof(ag_res.str) - 5)) {
+            android_errorWriteLog(0x534e4554, "79431031");
+            xx = sizeof(ag_res.str) - 5;
+            // Null terminating the string
+            memset(&ag_res.str[xx], 0, 5);
+          }
 
           if (res == BTA_AG_CALL_WAIT_RES)
             snprintf(&ag_res.str[xx], sizeof(ag_res.str) - xx, ",%d", type);
diff --git a/stack/btm/btm_dev.cc b/stack/btm/btm_dev.cc
index 66382e8..5368fad 100644
--- a/stack/btm/btm_dev.cc
+++ b/stack/btm/btm_dev.cc
@@ -149,17 +149,16 @@
   return true;
 }
 
-/*******************************************************************************
+/** Free resources associated with the device associated with |bd_addr| address.
  *
- * Function         BTM_SecDeleteDevice
+ * *** WARNING ***
+ * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function
+ * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is
+ * no longer valid!
+ * *** WARNING ***
  *
- * Description      Free resources associated with the device.
- *
- * Parameters:      bd_addr          - BD address of the peer
- *
- * Returns          true if removed OK, false if not found or ACL link is active
- *
- ******************************************************************************/
+ * Returns true if removed OK, false if not found or ACL link is active.
+ */
 bool BTM_SecDeleteDevice(const RawAddress& bd_addr) {
   if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
       BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) {
@@ -170,9 +169,10 @@
 
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   if (p_dev_rec != NULL) {
+    RawAddress bda = p_dev_rec->bd_addr;
     btm_sec_free_dev(p_dev_rec);
     /* Tell controller to get rid of the link key, if it has one stored */
-    BTM_DeleteStoredLinkKey(&p_dev_rec->bd_addr, NULL);
+    BTM_DeleteStoredLinkKey(&bda, NULL);
   }
 
   return true;
diff --git a/stack/hid/hidh_conn.cc b/stack/hid/hidh_conn.cc
index 76c03a6..6f99c88 100644
--- a/stack/hid/hidh_conn.cc
+++ b/stack/hid/hidh_conn.cc
@@ -42,6 +42,7 @@
 #include "hidh_api.h"
 #include "hidh_int.h"
 
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 static uint8_t find_conn_by_cid(uint16_t cid);
@@ -799,6 +800,14 @@
     return;
   }
 
+  if (p_msg->len < 1) {
+    HIDH_TRACE_WARNING("Rcvd L2CAP data, invalid length %d, should be >= 1",
+                       p_msg->len);
+    osi_free(p_msg);
+    android_errorWriteLog(0x534e4554, "80493272");
+    return;
+  }
+
   ttype = HID_GET_TRANS_FROM_HDR(*p_data);
   param = HID_GET_PARAM_FROM_HDR(*p_data);
   rep_type = param & HID_PAR_REP_TYPE_MASK;
diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h
index 146a1b8..6ffc0f9 100644
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -1411,15 +1411,16 @@
                              uint8_t key_type, tBTM_IO_CAP io_cap,
                              uint8_t pin_length);
 
-/*******************************************************************************
+/** Free resources associated with the device associated with |bd_addr| address.
  *
- * Function         BTM_SecDeleteDevice
+ * *** WARNING ***
+ * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function
+ * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is
+ * no longer valid!
+ * *** WARNING ***
  *
- * Description      Free resources associated with the device.
- *
- * Returns          true if rmoved OK, false if not found
- *
- ******************************************************************************/
+ * Returns true if removed OK, false if not found or ACL link is active.
+ */
 extern bool BTM_SecDeleteDevice(const RawAddress& bd_addr);
 
 /*******************************************************************************
diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc
index ec0992a..5fc01f9 100644
--- a/stack/l2cap/l2c_ble.cc
+++ b/stack/l2cap/l2c_ble.cc
@@ -594,6 +594,12 @@
   uint16_t credit;
   p_pkt_end = p + pkt_len;
 
+  if (p + 4 > p_pkt_end) {
+    android_errorWriteLog(0x534e4554, "80261585");
+    LOG(ERROR) << "invalid read";
+    return;
+  }
+
   STREAM_TO_UINT8(cmd_code, p);
   STREAM_TO_UINT8(id, p);
   STREAM_TO_UINT16(cmd_len, p);
@@ -619,6 +625,12 @@
       break;
 
     case L2CAP_CMD_BLE_UPDATE_REQ:
+      if (p + 8 > p_pkt_end) {
+        android_errorWriteLog(0x534e4554, "80261585");
+        LOG(ERROR) << "invalid read";
+        return;
+      }
+
       STREAM_TO_UINT16(min_interval, p); /* 0x0006 - 0x0C80 */
       STREAM_TO_UINT16(max_interval, p); /* 0x0006 - 0x0C80 */
       STREAM_TO_UINT16(latency, p);      /* 0x0000 - 0x03E8 */
@@ -660,6 +672,12 @@
       break;
 
     case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ:
+      if (p + 10 > p_pkt_end) {
+        android_errorWriteLog(0x534e4554, "80261585");
+        LOG(ERROR) << "invalid read";
+        return;
+      }
+
       STREAM_TO_UINT16(con_info.psm, p);
       STREAM_TO_UINT16(rcid, p);
       STREAM_TO_UINT16(mtu, p);
@@ -743,6 +761,12 @@
       }
       if (p_ccb) {
         L2CAP_TRACE_DEBUG("I remember the connection req");
+        if (p + 10 > p_pkt_end) {
+          android_errorWriteLog(0x534e4554, "80261585");
+          LOG(ERROR) << "invalid read";
+          return;
+        }
+
         STREAM_TO_UINT16(p_ccb->remote_cid, p);
         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p);
         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p);
@@ -788,6 +812,12 @@
       break;
 
     case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT:
+      if (p + 4 > p_pkt_end) {
+        android_errorWriteLog(0x534e4554, "80261585");
+        LOG(ERROR) << "invalid read";
+        return;
+      }
+
       STREAM_TO_UINT16(lcid, p);
       p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid);
       if (p_ccb == NULL) {
@@ -821,6 +851,11 @@
       break;
 
     case L2CAP_CMD_DISC_RSP:
+      if (p + 4 > p_pkt_end) {
+        android_errorWriteLog(0x534e4554, "80261585");
+        LOG(ERROR) << "invalid read";
+        return;
+      }
       STREAM_TO_UINT16(rcid, p);
       STREAM_TO_UINT16(lcid, p);
 
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 2574f88..a69c029 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -511,6 +511,7 @@
             default:
               /* sanity check option length */
               if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) {
+                if (p + cfg_len > p_next_cmd) return;
                 p += cfg_len;
                 if ((cfg_code & 0x80) == 0) {
                   cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index 91b5ae2..386f62f 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -421,6 +421,13 @@
       attr_len = sdpu_get_attrib_entry_len(p_attr);
       /* if there is a partial attribute pending to be sent */
       if (p_ccb->cont_info.attr_offset) {
+        if (attr_len < p_ccb->cont_info.attr_offset) {
+          android_errorWriteLog(0x534e4554, "79217770");
+          LOG(ERROR) << "offset is bigger than attribute length";
+          sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+                                  SDP_TEXT_BAD_CONT_LEN);
+          return;
+        }
         p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len,
                                                 &p_ccb->cont_info.attr_offset);
 
@@ -661,6 +668,13 @@
         attr_len = sdpu_get_attrib_entry_len(p_attr);
         /* if there is a partial attribute pending to be sent */
         if (p_ccb->cont_info.attr_offset) {
+          if (attr_len < p_ccb->cont_info.attr_offset) {
+            android_errorWriteLog(0x534e4554, "79217770");
+            LOG(ERROR) << "offset is bigger than attribute length";
+            sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+                                    SDP_TEXT_BAD_CONT_LEN);
+            return;
+          }
           p_rsp = sdpu_build_partial_attrib_entry(
               p_rsp, p_attr, rem_len, &p_ccb->cont_info.attr_offset);