Merge cherrypicks of [4027705, 4027707, 4027735, 4027736, 4026840, 4025434, 4027755, 4025350, 4025351, 4025352, 4027737, 4027738, 4027660, 4027661, 4027663, 4027665, 4027102, 4027103, 4027104, 4027105, 4027106, 4027717, 4027718, 4027756, 4025353, 4027710, 4027711, 4027712, 4027713, 4027714, 4027795, 4027796, 4027797, 4027798, 4027757, 4027758, 4027799, 4027800, 4026842, 4027667, 4027668, 4027669] into sparse-4732990-L09800000171085564

Change-Id: I58bb32c9649be8eb478eedccba66e0822941df2e
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index 187bc68..175e3fa 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -28,6 +28,7 @@
 #include <base/bind.h>
 #include <base/callback.h>
 #include <base/logging.h>
+#include <cutils/log.h>
 #include <string.h>
 
 #include "bt_common.h"
@@ -146,6 +147,8 @@
 #define BTA_DM_SWITCH_DELAY_TIMER_MS 500
 #endif
 
+#define BTA_MAX_SERVICES 32
+
 static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr);
 static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr);
 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
@@ -1486,7 +1489,7 @@
   tBT_UUID service_uuid;
 
   uint32_t num_uuids = 0;
-  uint8_t uuid_list[32][MAX_UUID_SIZE];  // assuming a max of 32 services
+  uint8_t uuid_list[BTA_MAX_SERVICES][MAX_UUID_SIZE];  // assuming a max of 32 services
 
   if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) ||
       (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) ||
@@ -1554,8 +1557,12 @@
                 bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index -
                                                 1];
             /* Add to the list of UUIDs */
-            sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
-            num_uuids++;
+            if (num_uuids < BTA_MAX_SERVICES) {
+              sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
+              num_uuids++;
+            } else {
+              android_errorWriteLog(0x534e4554, "74016921");
+            }
           }
         }
       }
@@ -1587,8 +1594,12 @@
             SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
         if (p_sdp_rec) {
           if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
-            memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
-            num_uuids++;
+            if (num_uuids < BTA_MAX_SERVICES) {
+              memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
+              num_uuids++;
+            } else {
+              android_errorWriteLog(0x534e4554, "74016921");
+            }
           }
         }
       } while (p_sdp_rec);
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index 41e0bf6..789cce8 100644
--- a/bta/pan/bta_pan_act.cc
+++ b/bta/pan/bta_pan_act.cc
@@ -171,31 +171,25 @@
 static void bta_pan_data_buf_ind_cback(uint16_t handle, const RawAddress& src,
                                        const RawAddress& dst, uint16_t protocol,
                                        BT_HDR* p_buf, bool ext, bool forward) {
-  tBTA_PAN_SCB* p_scb;
-  BT_HDR* p_new_buf;
-
-  p_scb = bta_pan_scb_by_handle(handle);
+  tBTA_PAN_SCB* p_scb = bta_pan_scb_by_handle(handle);
   if (p_scb == NULL) {
     return;
   }
 
-  if (sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset) {
-    /* offset smaller than data structure in front of actual data */
-    if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len >
-        PAN_BUF_SIZE) {
-      android_errorWriteLog(0x534e4554, "63146237");
-      APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
-                       p_buf->len);
-      return;
-    }
-    p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
-    memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS),
-           (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
-    p_new_buf->len = p_buf->len;
-    p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
-  } else {
-    p_new_buf = p_buf;
+  if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len >
+      PAN_BUF_SIZE) {
+    android_errorWriteLog(0x534e4554, "63146237");
+    APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
+                     p_buf->len);
+    return;
   }
+
+  BT_HDR* p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
+  memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS),
+         (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
+  p_new_buf->len = p_buf->len;
+  p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
+
   /* copy params into the space before the data */
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->src = src;
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->dst = dst;
diff --git a/stack/bnep/bnep_api.cc b/stack/bnep/bnep_api.cc
index 923ce50..e5d3c09 100644
--- a/stack/bnep/bnep_api.cc
+++ b/stack/bnep/bnep_api.cc
@@ -23,6 +23,7 @@
  ******************************************************************************/
 
 #include "bnep_api.h"
+#include <log/log.h>
 #include <string.h>
 #include "bnep_int.h"
 
@@ -383,6 +384,10 @@
         protocol = 0;
       else {
         new_len += 4;
+        if (new_len > org_len) {
+          android_errorWriteLog(0x534e4554, "74947856");
+          return BNEP_IGNORE_CMD;
+        }
         p_data[2] = 0;
         p_data[3] = 0;
       }
@@ -479,6 +484,10 @@
         protocol = 0;
       else {
         new_len += 4;
+        if (new_len > org_len) {
+          android_errorWriteLog(0x534e4554, "74947856");
+          return BNEP_IGNORE_CMD;
+        }
         p_data[2] = 0;
         p_data[3] = 0;
       }
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index f621fdb..463fca3 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -607,7 +607,6 @@
   if (bnep_cb.p_data_buf_cb) {
     (*bnep_cb.p_data_buf_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
                              p_buf, fw_ext_present);
-    osi_free(p_buf);
   } else if (bnep_cb.p_data_ind_cb) {
     (*bnep_cb.p_data_ind_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
                              p, rem_len, fw_ext_present);
diff --git a/stack/btm/btm_ble_bgconn.cc b/stack/btm/btm_ble_bgconn.cc
index f11a50e..f2f8307 100644
--- a/stack/btm/btm_ble_bgconn.cc
+++ b/stack/btm/btm_ble_bgconn.cc
@@ -209,11 +209,9 @@
   } else {
     /* not a known device, i.e. attempt to connect to device never seen before
      */
-    uint8_t addr_type =
-        BTM_IS_PUBLIC_BDA(bd_addr) ? BLE_ADDR_PUBLIC : BLE_ADDR_RANDOM;
     started = true;
     if (to_add)
-      background_connection_add(addr_type, bd_addr);
+      background_connection_add(BLE_ADDR_PUBLIC, bd_addr);
     else
       background_connection_remove(bd_addr);
   }
diff --git a/stack/btm/btm_ble_int_types.h b/stack/btm/btm_ble_int_types.h
index e7a4be3..b539211 100644
--- a/stack/btm/btm_ble_int_types.h
+++ b/stack/btm/btm_ble_int_types.h
@@ -85,13 +85,6 @@
   return ((x.address)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB;
 }
 
-#define BLE_PUBLIC_ADDR_MSB_MASK 0xC0
-/*  most significant bit, bit7, bit6 is 10 to be public address*/
-#define BLE_PUBLIC_ADDR_MSB 0x80
-inline bool BTM_IS_PUBLIC_BDA(const RawAddress& x) {
-  return ((x.address)[0] & BLE_PUBLIC_ADDR_MSB_MASK) == BLE_PUBLIC_ADDR_MSB;
-}
-
 /* LE scan activity bit mask, continue with LE inquiry bits */
 /* observe is in progress */
 #define BTM_LE_OBSERVE_ACTIVE 0x80
diff --git a/stack/gatt/gatt_sr.cc b/stack/gatt/gatt_sr.cc
index 3af9866..f9e8f53 100644
--- a/stack/gatt/gatt_sr.cc
+++ b/stack/gatt/gatt_sr.cc
@@ -22,6 +22,7 @@
  *
  ******************************************************************************/
 
+#include <log/log.h>
 #include "bt_target.h"
 #include "bt_utils.h"
 #include "osi/include/osi.h"
@@ -281,8 +282,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code,
-                                 UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
+                                 uint8_t* p_data) {
   uint8_t *p = p_data, flag, i = 0;
   uint32_t trans_id = 0;
   tGATT_IF gatt_if;
@@ -301,6 +302,13 @@
   }
 #endif
 
+  if (len < sizeof(flag)) {
+    android_errorWriteLog(0x534e4554, "73172115");
+    LOG(ERROR) << __func__ << "invalid length";
+    gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false);
+    return;
+  }
+
   STREAM_TO_UINT8(flag, p);
 
   /* mask the flag */
@@ -780,7 +788,8 @@
 void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint8_t op_code,
                                     uint16_t len, uint8_t* p_data) {
   tBT_UUID uuid;
-  uint16_t s_hdl, e_hdl, err_hdl = 0;
+  uint16_t s_hdl = 0, e_hdl = 0, err_hdl = 0;
+  if (len < 4) android_errorWriteLog(0x534e4554, "73125709");
   tGATT_STATUS reason =
       gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
 
@@ -940,9 +949,19 @@
  */
 static void gatts_process_read_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
                                    uint8_t op_code, uint16_t handle,
-                                   UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+                                   uint16_t len, uint8_t* p_data) {
   size_t buf_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
   uint16_t offset = 0;
+
+  if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) {
+    /* Error: packet length is too short */
+    LOG(ERROR) << __func__ << ": packet length=" << len
+               << " too short. min=" << sizeof(uint16_t);
+    android_errorWriteWithInfoLog(0x534e4554, "73172115", -1, NULL, 0);
+    gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, 0, false);
+    return;
+  }
+
   BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
 
   if (op_code == GATT_REQ_READ_BLOB) STREAM_TO_UINT16(offset, p_data);
@@ -964,7 +983,7 @@
   if (reason != GATT_SUCCESS) {
     osi_free(p_msg);
 
-    /* in theroy BUSY is not possible(should already been checked), protected
+    /* in theory BUSY is not possible(should already been checked), protected
      * check */
     if (reason != GATT_PENDING && reason != GATT_BUSY)
       gatt_send_error_rsp(tcb, reason, op_code, handle, false);
diff --git a/stack/l2cap/l2c_fcr.cc b/stack/l2cap/l2c_fcr.cc
index 0e5a84a..9c2742f 100644
--- a/stack/l2cap/l2c_fcr.cc
+++ b/stack/l2cap/l2c_fcr.cc
@@ -24,6 +24,7 @@
  ******************************************************************************/
 
 #include <base/logging.h>
+#include <log/log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -855,8 +856,24 @@
     p_buf->offset += sizeof(sdu_length);
     p_data->offset = 0;
 
-  } else
+  } else {
     p_data = p_ccb->ble_sdu;
+    if (p_buf->len > (p_ccb->ble_sdu_length - p_data->len)) {
+      L2CAP_TRACE_ERROR("%s: buffer length=%d too big. max=%d. Dropped",
+                        __func__, p_data->len,
+                        (p_ccb->ble_sdu_length - p_data->len));
+      android_errorWriteWithInfoLog(0x534e4554, "75298652", -1, NULL, 0);
+      osi_free(p_buf);
+
+      /* Throw away all pending fragments and disconnects */
+      p_ccb->is_first_seg = true;
+      osi_free(p_ccb->ble_sdu);
+      p_ccb->ble_sdu = NULL;
+      p_ccb->ble_sdu_length = 0;
+      l2cu_disconnect_chnl(p_ccb);
+      return;
+    }
+  }
 
   memcpy((uint8_t*)(p_data + 1) + p_data->offset + p_data->len,
          (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
@@ -869,9 +886,6 @@
     p_ccb->ble_sdu_length = 0;
   } else if (p_data->len < p_ccb->ble_sdu_length) {
     p_ccb->is_first_seg = false;
-  } else {
-    L2CAP_TRACE_ERROR("%s Length in the SDU messed up", __func__);
-    // TODO: reset every thing may be???
   }
 
   osi_free(p_buf);
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 83d1737..7c1ef48 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -320,8 +320,16 @@
 
     switch (cmd_code) {
       case L2CAP_CMD_REJECT:
+        if (p + 2 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(rej_reason, p);
         if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) {
+          if (p + 2 > p_next_cmd) {
+            android_errorWriteLog(0x534e4554, "74202041");
+            return;
+          }
           STREAM_TO_UINT16(rej_mtu, p);
           /* What to do with the MTU reject ? We have negotiated an MTU. For now
            */
@@ -332,6 +340,10 @@
                               p_lcb->handle, rej_mtu);
         }
         if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) {
+          if (p + 4 > p_next_cmd) {
+            android_errorWriteLog(0x534e4554, "74202041");
+            return;
+          }
           STREAM_TO_UINT16(rcid, p);
           STREAM_TO_UINT16(lcid, p);
 
@@ -365,6 +377,10 @@
         break;
 
       case L2CAP_CMD_CONN_REQ:
+        if (p + 4 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(con_info.psm, p);
         STREAM_TO_UINT16(rcid, p);
         p_rcb = l2cu_find_rcb_by_psm(con_info.psm);
@@ -396,6 +412,10 @@
         break;
 
       case L2CAP_CMD_CONN_RSP:
+        if (p + 8 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(con_info.remote_cid, p);
         STREAM_TO_UINT16(lcid, p);
         STREAM_TO_UINT16(con_info.l2cap_result, p);
@@ -427,6 +447,10 @@
         cfg_rej = false;
         cfg_rej_len = 0;
 
+        if (p + 4 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(lcid, p);
         STREAM_TO_UINT16(cfg_info.flags, p);
 
@@ -437,22 +461,38 @@
                 false;
 
         while (p < p_cfg_end) {
+          if (p + 2 > p_next_cmd) {
+            android_errorWriteLog(0x534e4554, "74202041");
+            return;
+          }
           STREAM_TO_UINT8(cfg_code, p);
           STREAM_TO_UINT8(cfg_len, p);
 
           switch (cfg_code & 0x7F) {
             case L2CAP_CFG_TYPE_MTU:
               cfg_info.mtu_present = true;
+              if (p + 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT16(cfg_info.mtu, p);
               break;
 
             case L2CAP_CFG_TYPE_FLUSH_TOUT:
               cfg_info.flush_to_present = true;
+              if (p + 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT16(cfg_info.flush_to, p);
               break;
 
             case L2CAP_CFG_TYPE_QOS:
               cfg_info.qos_present = true;
+              if (p + 2 + 5 * 4 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
               STREAM_TO_UINT8(cfg_info.qos.service_type, p);
               STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
@@ -464,6 +504,10 @@
 
             case L2CAP_CFG_TYPE_FCR:
               cfg_info.fcr_present = true;
+              if (p + 3 + 3 * 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.fcr.mode, p);
               STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
               STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
@@ -474,11 +518,19 @@
 
             case L2CAP_CFG_TYPE_FCS:
               cfg_info.fcs_present = true;
+              if (p + 1 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.fcs, p);
               break;
 
             case L2CAP_CFG_TYPE_EXT_FLOW:
               cfg_info.ext_flow_spec_present = true;
+              if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
               STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
               STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -523,6 +575,10 @@
 
       case L2CAP_CMD_CONFIG_RSP:
         p_cfg_end = p + cmd_len;
+        if (p + 6 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(lcid, p);
         STREAM_TO_UINT16(cfg_info.flags, p);
         STREAM_TO_UINT16(cfg_info.result, p);
@@ -532,22 +588,38 @@
                 false;
 
         while (p < p_cfg_end) {
+          if (p + 2 > p_next_cmd) {
+            android_errorWriteLog(0x534e4554, "74202041");
+            return;
+          }
           STREAM_TO_UINT8(cfg_code, p);
           STREAM_TO_UINT8(cfg_len, p);
 
           switch (cfg_code & 0x7F) {
             case L2CAP_CFG_TYPE_MTU:
               cfg_info.mtu_present = true;
+              if (p + 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT16(cfg_info.mtu, p);
               break;
 
             case L2CAP_CFG_TYPE_FLUSH_TOUT:
               cfg_info.flush_to_present = true;
+              if (p + 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT16(cfg_info.flush_to, p);
               break;
 
             case L2CAP_CFG_TYPE_QOS:
               cfg_info.qos_present = true;
+              if (p + 2 + 5 * 4 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
               STREAM_TO_UINT8(cfg_info.qos.service_type, p);
               STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
@@ -559,6 +631,10 @@
 
             case L2CAP_CFG_TYPE_FCR:
               cfg_info.fcr_present = true;
+              if (p + 3 + 3 * 2 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.fcr.mode, p);
               STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
               STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
@@ -569,11 +645,19 @@
 
             case L2CAP_CFG_TYPE_FCS:
               cfg_info.fcs_present = true;
+              if (p + 1 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.fcs, p);
               break;
 
             case L2CAP_CFG_TYPE_EXT_FLOW:
               cfg_info.ext_flow_spec_present = true;
+              if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+                android_errorWriteLog(0x534e4554, "74202041");
+                return;
+              }
               STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
               STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
               STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -603,6 +687,10 @@
         break;
 
       case L2CAP_CMD_DISC_REQ:
+        if (p + 4 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(lcid, p);
         STREAM_TO_UINT16(rcid, p);
 
@@ -618,6 +706,10 @@
         break;
 
       case L2CAP_CMD_DISC_RSP:
+        if (p + 4 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(rcid, p);
         STREAM_TO_UINT16(lcid, p);
 
@@ -645,6 +737,10 @@
         break;
 
       case L2CAP_CMD_INFO_REQ:
+        if (p + 2 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(info_type, p);
         l2cu_send_peer_info_rsp(p_lcb, id, info_type);
         break;
@@ -656,6 +752,10 @@
           p_lcb->w4_info_rsp = false;
         }
 
+        if (p + 4 > p_next_cmd) {
+          android_errorWriteLog(0x534e4554, "74202041");
+          return;
+        }
         STREAM_TO_UINT16(info_type, p);
         STREAM_TO_UINT16(result, p);
 
@@ -663,6 +763,10 @@
 
         if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
             (result == L2CAP_INFO_RESP_RESULT_SUCCESS)) {
+          if (p + 4 > p_next_cmd) {
+            android_errorWriteLog(0x534e4554, "74202041");
+            return;
+          }
           STREAM_TO_UINT32(p_lcb->peer_ext_fea, p);
 
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
diff --git a/stack/pan/pan_main.cc b/stack/pan/pan_main.cc
index d7cd27b..6a55423 100644
--- a/stack/pan/pan_main.cc
+++ b/stack/pan/pan_main.cc
@@ -595,12 +595,11 @@
       if (pan_cb.pan_data_buf_ind_cb)
         (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf,
                                       ext, forward);
-      else if (pan_cb.pan_data_ind_cb) {
+      else if (pan_cb.pan_data_ind_cb)
         (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
                                   ext, forward);
-        osi_free(p_buf);
-      }
 
+      osi_free(p_buf);
       return;
     }
 
@@ -625,13 +624,10 @@
   if (pan_cb.pan_data_buf_ind_cb)
     (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf, ext,
                                   forward);
-  else if (pan_cb.pan_data_ind_cb) {
+  else if (pan_cb.pan_data_ind_cb)
     (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
                               forward);
-    osi_free(p_buf);
-  } else
-    osi_free(p_buf);
-
+  osi_free(p_buf);
   return;
 }
 
diff --git a/stack/smp/p_256_ecc_pp.cc b/stack/smp/p_256_ecc_pp.cc
index b416e1d..911dc54 100644
--- a/stack/smp/p_256_ecc_pp.cc
+++ b/stack/smp/p_256_ecc_pp.cc
@@ -245,3 +245,25 @@
   multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
   multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
 }
+
+bool ECC_ValidatePoint(const Point& pt) {
+  const size_t kl = KEY_LENGTH_DWORDS_P256;
+  p_256_init_curve(kl);
+
+  // Ensure y^2 = x^3 + a*x + b (mod p); a = -3
+
+  // y^2 mod p
+  uint32_t y2_mod[kl] = {0};
+  multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl);
+
+  // Right hand side calculation
+  uint32_t rhs[kl] = {0};
+  multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl);
+  uint32_t three[kl] = {0};
+  three[0] = 3;
+  multiprecision_sub_mod(rhs, rhs, three, kl);
+  multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl);
+  multiprecision_add_mod(rhs, rhs, curve_p256.b, kl);
+
+  return multiprecision_compare(rhs, y2_mod, kl) == 0;
+}
diff --git a/stack/smp/p_256_ecc_pp.h b/stack/smp/p_256_ecc_pp.h
index dcc4211..b7a8e00 100644
--- a/stack/smp/p_256_ecc_pp.h
+++ b/stack/smp/p_256_ecc_pp.h
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include <cstdbool>
 #include "p_256_multprecision.h"
 
 typedef struct {
@@ -55,6 +56,8 @@
 extern elliptic_curve_t curve;
 extern elliptic_curve_t curve_p256;
 
+bool ECC_ValidatePoint(const Point& p);
+
 void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength);
 
 #define ECC_PointMult(q, p, n, keyLength) \
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index df9fab9..2103776 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -22,6 +22,7 @@
 #include "include/bt_target.h"
 #include "stack/btm/btm_int.h"
 #include "stack/include/l2c_api.h"
+#include "stack/smp/p_256_ecc_pp.h"
 #include "stack/smp/smp_int.h"
 #include "utils/include/bt_utils.h"
 
@@ -655,6 +656,17 @@
 
   STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
   STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
+
+  Point pt;
+  memcpy(pt.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN);
+  memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN);
+
+  if (!ECC_ValidatePoint(pt)) {
+    android_errorWriteLog(0x534e4554, "72377774");
+    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+    return;
+  }
+
   p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
 
   smp_wait_for_both_public_keys(p_cb, NULL);