Merge cherrypicks of [3478016, 3477857, 3477909, 3478630, 3478631, 3478556, 3478557, 3477761, 3477762, 3477763, 3478043, 3478044, 3478045, 3478441, 3478442, 3478443, 3478018, 3478558, 3478559, 3478560, 3478561, 3478562, 3478563, 3478564, 3478565, 3478566, 3478567, 3478568, 3478569] into oc-m5-release

Change-Id: I5f8b31320dfd1622956acd584eaf53ed729107be
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index 0cbb9f7..41e0bf6 100644
--- a/bta/pan/bta_pan_act.cc
+++ b/bta/pan/bta_pan_act.cc
@@ -174,6 +174,11 @@
   tBTA_PAN_SCB* p_scb;
   BT_HDR* p_new_buf;
 
+  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 >
@@ -181,7 +186,6 @@
       android_errorWriteLog(0x534e4554, "63146237");
       APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
                        p_buf->len);
-      osi_free(p_buf);
       return;
     }
     p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
@@ -189,7 +193,6 @@
            (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);
-    osi_free(p_buf);
   } else {
     p_new_buf = p_buf;
   }
@@ -200,12 +203,6 @@
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->ext = ext;
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->forward = forward;
 
-  p_scb = bta_pan_scb_by_handle(handle);
-  if (p_scb == NULL) {
-    osi_free(p_new_buf);
-    return;
-  }
-
   fixed_queue_enqueue(p_scb->data_queue, p_new_buf);
   BT_HDR* p_event = (BT_HDR*)osi_malloc(sizeof(BT_HDR));
   p_event->layer_specific = handle;
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index e1c87fc..9bf9cc5 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -71,7 +71,6 @@
   size_t rescheduled_count;
   size_t total_updates;
   period_ms_t last_update_ms;
-  stat_t callback_execution;
   stat_t overdue_scheduling;
   stat_t premature_scheduling;
 } alarm_stats_t;
@@ -155,8 +154,7 @@
 static void callback_dispatch(void* context);
 static bool timer_create_internal(const clockid_t clock_id, timer_t* timer);
 static void update_scheduling_stats(alarm_stats_t* stats, period_ms_t now_ms,
-                                    period_ms_t deadline_ms,
-                                    period_ms_t execution_delta_ms);
+                                    period_ms_t deadline_ms);
 // Registers |queue| for processing alarm callbacks on |thread|.
 // |queue| may not be NULL. |thread| may not be NULL.
 static void alarm_register_processing_queue(fixed_queue_t* queue,
@@ -584,14 +582,12 @@
   std::lock_guard<std::recursive_mutex> cb_lock(*alarm->callback_mutex);
   lock.unlock();
 
-  period_ms_t t0 = now();
-  callback(data);
-  period_ms_t t1 = now();
-
   // Update the statistics
-  CHECK(t1 >= t0);
-  period_ms_t delta = t1 - t0;
-  update_scheduling_stats(&alarm->stats, t0, deadline, delta);
+  update_scheduling_stats(&alarm->stats, now(), deadline);
+
+  // NOTE: Do NOT access "alarm" after the callback, as a safety precaution
+  // in case the callback itself deleted the alarm.
+  callback(data);
 }
 
 static void alarm_ready_mloop(alarm_t* alarm) {
@@ -696,13 +692,10 @@
 }
 
 static void update_scheduling_stats(alarm_stats_t* stats, period_ms_t now_ms,
-                                    period_ms_t deadline_ms,
-                                    period_ms_t execution_delta_ms) {
+                                    period_ms_t deadline_ms) {
   stats->total_updates++;
   stats->last_update_ms = now_ms;
 
-  update_stat(&stats->callback_execution, execution_delta_ms);
-
   if (deadline_ms < now_ms) {
     // Overdue scheduling
     period_ms_t delta_ms = now_ms - deadline_ms;
@@ -749,7 +742,7 @@
     dprintf(fd, "%-51s: %zu / %zu / %zu / %zu\n",
             "    Action counts (sched/resched/exec/cancel)",
             stats->scheduled_count, stats->rescheduled_count,
-            stats->callback_execution.count, stats->canceled_count);
+            stats->total_updates, stats->canceled_count);
 
     dprintf(fd, "%-51s: %zu / %zu\n",
             "    Deviation counts (overdue/premature)",
@@ -761,9 +754,6 @@
             (unsigned long long)alarm->period,
             (long long)(alarm->deadline - just_now));
 
-    dump_stat(fd, &stats->callback_execution,
-              "    Callback execution time in ms (total/max/avg)");
-
     dump_stat(fd, &stats->overdue_scheduling,
               "    Overdue scheduling time in ms (total/max/avg)");
 
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index cc5ec1d..1ed6963 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -21,6 +21,7 @@
 #include "avrc_defs.h"
 #include "avrc_int.h"
 #include "bt_common.h"
+#include "log/log.h"
 
 /*****************************************************************************
  *  Global data
@@ -158,6 +159,12 @@
         status = AVRC_STS_INTERNAL_ERR;
         break;
       }
+
+      if (p_result->get_cur_app_val.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
+        android_errorWriteLog(0x534e4554, "63146237");
+        p_result->get_cur_app_val.num_attr = AVRC_MAX_APP_ATTR_SIZE;
+      }
+
       p_u8 = p_result->get_cur_app_val.attrs;
       for (xx = 0, yy = 0; xx < p_result->get_cur_app_val.num_attr; xx++) {
         /* only report the valid player app attributes */
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index ce09c47..f621fdb 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -34,6 +34,7 @@
 
 #include "l2c_api.h"
 #include "l2cdefs.h"
+#include "log/log.h"
 
 #include "btm_api.h"
 #include "btu.h"
@@ -446,6 +447,12 @@
   type = *p++;
   extension_present = type >> 7;
   type &= 0x7f;
+  if (type >= sizeof(bnep_frame_hdr_sizes) / sizeof(bnep_frame_hdr_sizes[0])) {
+    BNEP_TRACE_EVENT("BNEP - rcvd frame, bad type: 0x%02x", type);
+    android_errorWriteLog(0x534e4554, "68818034");
+    osi_free(p_buf);
+    return;
+  }
   if ((rem_len <= bnep_frame_hdr_sizes[type]) || (rem_len > BNEP_MTU_SIZE)) {
     BNEP_TRACE_EVENT("BNEP - rcvd frame, bad len: %d  type: 0x%02x", p_buf->len,
                      type);
@@ -474,18 +481,20 @@
       org_len = rem_len;
       new_len = 0;
       do {
+        if (org_len < 2) break;
         ext = *p++;
         length = *p++;
         p += length;
 
+        new_len = (length + 2);
+        if (new_len > org_len) break;
+
         if ((!(ext & 0x7F)) && (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG))
           bnep_send_command_not_understood(p_bcb, *p);
 
-        new_len += (length + 2);
-
-        if (new_len > org_len) break;
-
+        org_len -= new_len;
       } while (ext & 0x80);
+      android_errorWriteLog(0x534e4554, "67863755");
     }
 
     osi_free(p_buf);
@@ -530,6 +539,8 @@
       } else {
         while (extension_present && p && rem_len) {
           ext_type = *p++;
+          rem_len--;
+          android_errorWriteLog(0x534e4554, "69271284");
           extension_present = ext_type >> 7;
           ext_type &= 0x7F;
 
@@ -596,6 +607,7 @@
   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/bnep/bnep_utils.cc b/stack/bnep/bnep_utils.cc
index a362635..3bab9ee 100644
--- a/stack/bnep/bnep_utils.cc
+++ b/stack/bnep/bnep_utils.cc
@@ -22,6 +22,8 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
+
 #include <stdio.h>
 #include <string.h>
 #include "bnep_int.h"
@@ -750,6 +752,13 @@
       break;
 
     case BNEP_SETUP_CONNECTION_REQUEST_MSG:
+      if (*rem_len < 1) {
+        BNEP_TRACE_ERROR(
+            "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
+            __func__);
+        android_errorWriteLog(0x534e4554, "69177292");
+        goto bad_packet_length;
+      }
       len = *p++;
       if (*rem_len < ((2 * len) + 1)) {
         BNEP_TRACE_ERROR(
@@ -775,6 +784,13 @@
       break;
 
     case BNEP_FILTER_NET_TYPE_SET_MSG:
+      if (*rem_len < 2) {
+        BNEP_TRACE_ERROR(
+            "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
+            __func__);
+        android_errorWriteLog(0x534e4554, "69177292");
+        goto bad_packet_length;
+      }
       BE_STREAM_TO_UINT16(len, p);
       if (*rem_len < (len + 2)) {
         BNEP_TRACE_ERROR(
@@ -800,6 +816,13 @@
       break;
 
     case BNEP_FILTER_MULTI_ADDR_SET_MSG:
+      if (*rem_len < 2) {
+        BNEP_TRACE_ERROR(
+            "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
+            __func__);
+        android_errorWriteLog(0x534e4554, "69177292");
+        goto bad_packet_length;
+      }
       BE_STREAM_TO_UINT16(len, p);
       if (*rem_len < (len + 2)) {
         BNEP_TRACE_ERROR(
diff --git a/stack/btu/btu_init.cc b/stack/btu/btu_init.cc
index c847211..e383fd3 100644
--- a/stack/btu/btu_init.cc
+++ b/stack/btu/btu_init.cc
@@ -89,6 +89,8 @@
   /* Free the mandatory core stack components */
   l2c_free();
 
+  sdp_free();
+
   gatt_free();
 }
 
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index fd9339f..7eea5fd 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -33,6 +33,7 @@
 #include "hcidefs.h"
 #include "hcimsgs.h"
 #include "l2cdefs.h"
+#include "log/log.h"
 #include "sdp_api.h"
 #include "sdpint.h"
 
@@ -43,9 +44,12 @@
 /******************************************************************************/
 /*            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 process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
-static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
-static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
+static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                       uint8_t* p_reply_end);
+static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                     uint8_t* p_reply_end);
+static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                            uint8_t* p_reply_end);
 static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end);
 static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db,
                                  const RawAddress& p_bda);
@@ -187,7 +191,7 @@
   if (p_ccb->is_attr_search) {
     p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR;
 
-    process_service_search_attr_rsp(p_ccb, NULL);
+    process_service_search_attr_rsp(p_ccb, NULL, NULL);
   } else {
     /* First step is to get a list of the handles from the server. */
     /* We are not searching for a specific attribute, so we will   */
@@ -221,6 +225,7 @@
 
   /* Got a reply!! Check what we got back */
   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  uint8_t* p_end = p + p_msg->len;
 
   BE_STREAM_TO_UINT8(rsp_pdu, p);
 
@@ -229,21 +234,21 @@
   switch (rsp_pdu) {
     case SDP_PDU_SERVICE_SEARCH_RSP:
       if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) {
-        process_service_search_rsp(p_ccb, p);
+        process_service_search_rsp(p_ccb, p, p_end);
         invalid_pdu = false;
       }
       break;
 
     case SDP_PDU_SERVICE_ATTR_RSP:
       if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) {
-        process_service_attr_rsp(p_ccb, p);
+        process_service_attr_rsp(p_ccb, p, p_end);
         invalid_pdu = false;
       }
       break;
 
     case SDP_PDU_SERVICE_SEARCH_ATTR_RSP:
       if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) {
-        process_service_search_attr_rsp(p_ccb, p);
+        process_service_search_attr_rsp(p_ccb, p, p_end);
         invalid_pdu = false;
       }
       break;
@@ -266,7 +271,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                       uint8_t* p_reply_end) {
   uint16_t xx;
   uint16_t total, cur_handles, orig;
   uint8_t cont_len;
@@ -298,6 +304,11 @@
       sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
       return;
     }
+    if (p_reply + cont_len > p_reply_end) {
+      android_errorWriteLog(0x534e4554, "68161546");
+      sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
+      return;
+    }
     /* stay in the same state */
     sdp_snd_service_search_req(p_ccb, cont_len, p_reply);
   } else {
@@ -305,7 +316,7 @@
     p_ccb->disc_state = SDP_DISC_WAIT_ATTR;
 
     /* Kick off the first attribute request */
-    process_service_attr_rsp(p_ccb, NULL);
+    process_service_attr_rsp(p_ccb, NULL, NULL);
   }
 }
 
@@ -370,7 +381,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                     uint8_t* p_reply_end) {
   uint8_t *p_start, *p_param_len;
   uint16_t param_len, list_byte_count;
   bool cont_request_needed = false;
@@ -469,8 +481,12 @@
 
     /* Was this a continuation request ? */
     if (cont_request_needed) {
-      memcpy(p, p_reply, *p_reply + 1);
-      p += *p_reply + 1;
+      if ((p_reply + *p_reply + 1) <= p_reply_end) {
+        memcpy(p, p_reply, *p_reply + 1);
+        p += *p_reply + 1;
+      } else {
+        android_errorWriteLog(0x534e4554, "68161546");
+      }
     } else
       UINT8_TO_BE_STREAM(p, 0);
 
@@ -502,7 +518,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+                                            uint8_t* p_reply_end) {
   uint8_t *p, *p_start, *p_end, *p_param_len;
   uint8_t type;
   uint32_t seq_len;
@@ -599,8 +616,12 @@
 
     /* No continuation for first request */
     if (p_reply) {
-      memcpy(p, p_reply, *p_reply + 1);
-      p += *p_reply + 1;
+      if ((p_reply + *p_reply + 1) <= p_reply_end) {
+        memcpy(p, p_reply, *p_reply + 1);
+        p += *p_reply + 1;
+      } else {
+        android_errorWriteLog(0x534e4554, "68161546");
+      }
     } else
       UINT8_TO_BE_STREAM(p, 0);
 
diff --git a/stack/sdp/sdp_main.cc b/stack/sdp/sdp_main.cc
index e9fd225..8f72aaa 100644
--- a/stack/sdp/sdp_main.cc
+++ b/stack/sdp/sdp_main.cc
@@ -73,6 +73,10 @@
   /* Clears all structures and local SDP database (if Server is enabled) */
   memset(&sdp_cb, 0, sizeof(tSDP_CB));
 
+  for (int i = 0; i < SDP_MAX_CONNECTIONS; i++) {
+    sdp_cb.ccb[i].sdp_conn_timer = alarm_new("sdp.sdp_conn_timer");
+  }
+
   /* Initialize the L2CAP configuration. We only care about MTU and flush */
   sdp_cb.l2cap_my_cfg.mtu_present = true;
   sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE;
@@ -122,6 +126,13 @@
   }
 }
 
+void sdp_free(void) {
+  for (int i = 0; i < SDP_MAX_CONNECTIONS; i++) {
+    alarm_free(sdp_cb.ccb[i].sdp_conn_timer);
+    sdp_cb.ccb[i].sdp_conn_timer = NULL;
+  }
+}
+
 #if (SDP_DEBUG == TRUE)
 /*******************************************************************************
  *
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index da85cda..b18f429 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -23,6 +23,8 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -341,6 +343,12 @@
     return;
   }
 
+  if (max_list_len < 4) {
+    sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
+    android_errorWriteLog(0x534e4554, "68776054");
+    return;
+  }
+
   /* Free and reallocate buffer */
   osi_free(p_ccb->rsp_list);
   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
@@ -551,6 +559,12 @@
 
   memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
 
+  if (max_list_len < 4) {
+    sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
+    android_errorWriteLog(0x534e4554, "68817966");
+    return;
+  }
+
   /* Free and reallocate buffer */
   osi_free(p_ccb->rsp_list);
   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index 720c746..803e963 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -108,8 +108,9 @@
   /* Look through each connection control block for a free one */
   for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
     if (p_ccb->con_state == SDP_STATE_IDLE) {
+      alarm_t* alarm = p_ccb->sdp_conn_timer;
       memset(p_ccb, 0, sizeof(tCONN_CB));
-      p_ccb->sdp_conn_timer = alarm_new("sdp.sdp_conn_timer");
+      p_ccb->sdp_conn_timer = alarm;
       return (p_ccb);
     }
   }
@@ -129,8 +130,7 @@
  ******************************************************************************/
 void sdpu_release_ccb(tCONN_CB* p_ccb) {
   /* Ensure timer is stopped */
-  alarm_free(p_ccb->sdp_conn_timer);
-  p_ccb->sdp_conn_timer = NULL;
+  alarm_cancel(p_ccb->sdp_conn_timer);
 
   /* Drop any response pointer we may be holding */
   p_ccb->con_state = SDP_STATE_IDLE;
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index 3a046b6..a2d5089 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -222,6 +222,7 @@
 
 /* Functions provided by sdp_main.cc */
 extern void sdp_init(void);
+extern void sdp_free(void);
 extern void sdp_disconnect(tCONN_CB* p_ccb, uint16_t reason);
 
 #if (SDP_DEBUG == TRUE)
diff --git a/stack/smp/smp_utils.cc b/stack/smp/smp_utils.cc
index 8bdce6b..c7f7be6 100644
--- a/stack/smp/smp_utils.cc
+++ b/stack/smp/smp_utils.cc
@@ -315,8 +315,7 @@
   l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP);
   if (l2cap_ret == L2CAP_DW_FAILED) {
     smp_cb.total_tx_unacked -= 1;
-    SMP_TRACE_ERROR("SMP   failed to pass msg:0x%0x to L2CAP",
-                    *((uint8_t*)(p_toL2CAP + 1) + p_toL2CAP->offset));
+    SMP_TRACE_ERROR("SMP failed to pass msg to L2CAP");
     return false;
   } else
     return true;