HearingAidAudioSource implementation am: be754da679
am: e9dcaa3d80

Change-Id: I305f5dd1175fcb68f1f76f9932ac4791615a48fe
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index bbcd183..75d5e94 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 163a54e..83a661d 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) {
@@ -697,13 +693,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;
@@ -750,7 +743,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)",
@@ -762,9 +755,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/osi/src/config.cc b/osi/src/config.cc
index 18360bf..d4ed2e6 100644
--- a/osi/src/config.cc
+++ b/osi/src/config.cc
@@ -17,6 +17,7 @@
  ******************************************************************************/
 
 #include "osi/include/config.h"
+#include "log/log.h"
 
 #include <base/files/file_path.h>
 #include <base/logging.h>
@@ -170,14 +171,23 @@
     sec = std::prev(config->sections.end());
   }
 
+  std::string value_no_newline;
+  size_t newline_position = value.find("\n");
+  if (newline_position != std::string::npos) {
+    android_errorWriteLog(0x534e4554, "70808273");
+    value_no_newline = value.substr(0, newline_position);
+  } else {
+    value_no_newline = value;
+  }
+
   for (entry_t& entry : sec->entries) {
     if (entry.key == key) {
-      entry.value = value;
+      entry.value = value_no_newline;
       return;
     }
   }
 
-  sec->entries.emplace_back(entry_t{.key = key, .value = value});
+  sec->entries.emplace_back(entry_t{.key = key, .value = value_no_newline});
 }
 
 bool config_remove_section(config_t* config, const std::string& section) {
diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc
index d48b721..7c30642 100644
--- a/stack/avrc/avrc_pars_ct.cc
+++ b/stack/avrc/avrc_pars_ct.cc
@@ -22,6 +22,7 @@
 #include "avrc_int.h"
 #include "bt_common.h"
 #include "bt_utils.h"
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 /*****************************************************************************
@@ -457,6 +458,12 @@
       BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
                        p_result->list_app_attr.num_attr);
+
+      if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
+        android_errorWriteLog(0x534e4554, "63146237");
+        p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
+      }
+
       for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
         BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
       }
@@ -485,6 +492,12 @@
           p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
                        p_result->get_cur_app_val.num_val);
+
+      if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
+        android_errorWriteLog(0x534e4554, "63146237");
+        p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
+      }
+
       for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
         BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
         BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
@@ -493,7 +506,6 @@
     } break;
 
     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
-      tAVRC_APP_SETTING_TEXT* p_setting_text;
       uint8_t num_attrs;
 
       if (len == 0) {
@@ -501,10 +513,14 @@
         break;
       }
       BE_STREAM_TO_UINT8(num_attrs, p);
+      if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
+        num_attrs = AVRC_MAX_APP_ATTR_SIZE;
+      }
       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
                        p_result->get_app_attr_txt.num_attr);
       p_result->get_app_attr_txt.num_attr = num_attrs;
-      p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
+
+      p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
           num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
       for (int xx = 0; xx < num_attrs; xx++) {
         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
@@ -524,7 +540,6 @@
     } break;
 
     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
-      tAVRC_APP_SETTING_TEXT* p_setting_text;
       uint8_t num_vals;
 
       if (len == 0) {
@@ -532,11 +547,14 @@
         break;
       }
       BE_STREAM_TO_UINT8(num_vals, p);
+      if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
+        num_vals = AVRC_MAX_APP_ATTR_SIZE;
+      }
       p_result->get_app_val_txt.num_attr = num_vals;
       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
                        p_result->get_app_val_txt.num_attr);
 
-      p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
+      p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
           num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
       for (int i = 0; i < num_vals; i++) {
         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index 871dddf..c0504ee 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
@@ -157,6 +158,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 */
@@ -212,6 +219,11 @@
               p_result->get_app_val_txt.num_val)
             status = AVRC_STS_INTERNAL_ERR;
           else {
+            if (p_result->get_app_val_txt.num_val > AVRC_MAX_APP_ATTR_SIZE) {
+              android_errorWriteLog(0x534e4554, "63146237");
+              p_result->get_app_val_txt.num_val = AVRC_MAX_APP_ATTR_SIZE;
+            }
+
             p_u8 = p_result->get_app_val_txt.vals;
             for (xx = 0; xx < p_result->get_app_val_txt.num_val; xx++) {
               p_u8[xx] = *p++;
@@ -484,8 +496,11 @@
       BE_STREAM_TO_UINT16(p_result->search.string.str_len, p);
       p_result->search.string.p_str = p_buf;
       if (p_buf) {
-        if (buf_len > p_result->search.string.str_len)
-          buf_len = p_result->search.string.str_len;
+        if (p_result->search.string.str_len > buf_len) {
+          p_result->search.string.str_len = buf_len;
+        } else {
+          android_errorWriteLog(0x534e4554, "63146237");
+        }
         BE_STREAM_TO_ARRAY(p, p_buf, p_result->search.string.str_len);
       } else {
         status = AVRC_STS_INTERNAL_ERR;
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index e3b8c7f..5dcb827 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"
@@ -445,6 +446,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);
@@ -473,18 +480,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);
@@ -529,6 +538,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;
 
@@ -595,6 +606,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 28fbcb4..48fd5d1 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"
@@ -760,6 +762,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(
@@ -785,6 +794,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(
@@ -810,6 +826,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 7920e0f..b2016da 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 20a00c2..c8521b1 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"
 
@@ -45,9 +46,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);
@@ -190,7 +194,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   */
@@ -224,6 +228,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);
 
@@ -232,21 +237,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;
@@ -269,7 +274,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;
@@ -301,6 +307,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 {
@@ -308,7 +319,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);
   }
 }
 
@@ -378,7 +389,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;
@@ -477,8 +489,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);
 
@@ -510,7 +526,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;
@@ -607,8 +624,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 32c9a85..2ee310b 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 51b0933..733f1a3 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -23,6 +23,7 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -52,7 +53,7 @@
 /******************************************************************************/
 static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
                                    uint16_t param_len, uint8_t* p_req,
-                                   UNUSED_ATTR uint8_t* p_req_end);
+                                   uint8_t* p_req_end);
 
 static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                      uint16_t param_len, uint8_t* p_req,
@@ -60,7 +61,7 @@
 
 static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                             uint16_t param_len, uint8_t* p_req,
-                                            UNUSED_ATTR uint8_t* p_req_end);
+                                            uint8_t* p_req_end);
 
 /******************************************************************************/
 /*                E R R O R   T E X T   S T R I N G S                         */
@@ -121,11 +122,25 @@
   alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
                      sdp_conn_timer_timeout, p_ccb);
 
+  if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
+    android_errorWriteLog(0x534e4554, "69384124");
+    trans_num = 0;
+    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+                            SDP_TEXT_BAD_HEADER);
+  }
+
   /* The first byte in the message is the pdu type */
   pdu_id = *p_req++;
 
   /* Extract the transaction number and parameter length */
   BE_STREAM_TO_UINT16(trans_num, p_req);
+
+  if (p_req + sizeof(param_len) > p_req_end) {
+    android_errorWriteLog(0x534e4554, "69384124");
+    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+                            SDP_TEXT_BAD_HEADER);
+  }
+
   BE_STREAM_TO_UINT16(param_len, p_req);
 
   if ((p_req + param_len) != p_req_end) {
@@ -169,7 +184,7 @@
  ******************************************************************************/
 static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
                                    uint16_t param_len, uint8_t* p_req,
-                                   UNUSED_ATTR uint8_t* p_req_end) {
+                                   uint8_t* p_req_end) {
   uint16_t max_replies, cur_handles, rem_handles, cont_offset;
   tSDP_UUID_SEQ uid_seq;
   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
@@ -187,15 +202,15 @@
   }
 
   /* Get the max replies we can send. Cap it at our max anyways. */
-  BE_STREAM_TO_UINT16(max_replies, p_req);
-
-  if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
-
-  if ((!p_req) || (p_req > p_req_end)) {
+  if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
+    android_errorWriteLog(0x534e4554, "69384124");
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_MAX_RECORDS_LIST);
     return;
   }
+  BE_STREAM_TO_UINT16(max_replies, p_req);
+
+  if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
 
   /* Get a list of handles that match the UUIDs given to us */
   for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
@@ -209,7 +224,8 @@
 
   /* Check if this is a continuation request */
   if (*p_req) {
-    if (*p_req++ != SDP_CONTINUATION_LEN || (p_req >= p_req_end)) {
+    if (*p_req++ != SDP_CONTINUATION_LEN ||
+        (p_req + sizeof(cont_offset) > p_req_end)) {
       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                               SDP_TEXT_BAD_CONT_LEN);
       return;
@@ -308,15 +324,16 @@
   bool is_cont = false;
   uint16_t attr_len;
 
-  /* Extract the record handle */
-  BE_STREAM_TO_UINT32(rec_handle, p_req);
-
-  if (p_req > p_req_end) {
+  if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
+    android_errorWriteLog(0x534e4554, "69384124");
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
                             SDP_TEXT_BAD_HANDLE);
     return;
   }
 
+  /* Extract the record handle */
+  BE_STREAM_TO_UINT32(rec_handle, p_req);
+
   /* Get the max list length we can send. Cap it at MTU size minus overhead */
   BE_STREAM_TO_UINT16(max_list_len, p_req);
 
@@ -325,7 +342,8 @@
 
   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
 
-  if ((!p_req) || (!attr_seq.num_attr) || (p_req > p_req_end)) {
+  if ((!p_req) || (!attr_seq.num_attr) ||
+      (p_req + sizeof(uint8_t) > p_req_end)) {
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_ATTR_LIST);
     return;
@@ -341,13 +359,20 @@
     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);
 
   /* Check if this is a continuation request */
   if (*p_req) {
-    if (*p_req++ != SDP_CONTINUATION_LEN) {
+    if (*p_req++ != SDP_CONTINUATION_LEN ||
+        (p_req + sizeof(cont_offset) > p_req_end)) {
       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                               SDP_TEXT_BAD_CONT_LEN);
       return;
@@ -512,7 +537,7 @@
  ******************************************************************************/
 static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                             uint16_t param_len, uint8_t* p_req,
-                                            UNUSED_ATTR uint8_t* p_req_end) {
+                                            uint8_t* p_req_end) {
   uint16_t max_list_len;
   int16_t rem_len;
   uint16_t len_to_send, cont_offset;
@@ -529,7 +554,8 @@
   /* Extract the UUID sequence to search for */
   p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
 
-  if ((!p_req) || (!uid_seq.num_uids)) {
+  if ((!p_req) || (!uid_seq.num_uids) ||
+      (p_req + sizeof(uint16_t) > p_req_end)) {
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_UUID_LIST);
     return;
@@ -543,7 +569,8 @@
 
   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
 
-  if ((!p_req) || (!attr_seq.num_attr)) {
+  if ((!p_req) || (!attr_seq.num_attr) ||
+      (p_req + sizeof(uint8_t) > p_req_end)) {
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_ATTR_LIST);
     return;
@@ -551,13 +578,20 @@
 
   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);
 
   /* Check if this is a continuation request */
   if (*p_req) {
-    if (*p_req++ != SDP_CONTINUATION_LEN) {
+    if (*p_req++ != SDP_CONTINUATION_LEN ||
+        (p_req + sizeof(uint16_t) > p_req_end)) {
       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                               SDP_TEXT_BAD_CONT_LEN);
       return;
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index 5529a46..c57a499 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -109,8 +109,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);
     }
   }
@@ -130,8 +131,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;
@@ -333,6 +333,8 @@
   p_seq->num_uids = 0;
 
   /* A UID sequence is composed of a bunch of UIDs. */
+  if (sizeof(descr) > param_len) return (NULL);
+  param_len -= sizeof(descr);
 
   BE_STREAM_TO_UINT8(descr, p);
   type = descr >> 3;
@@ -351,19 +353,25 @@
       seq_len = 16;
       break;
     case SIZE_IN_NEXT_BYTE:
+      if (sizeof(uint8_t) > param_len) return (NULL);
+      param_len -= sizeof(uint8_t);
       BE_STREAM_TO_UINT8(seq_len, p);
       break;
     case SIZE_IN_NEXT_WORD:
+      if (sizeof(uint16_t) > param_len) return (NULL);
+      param_len -= sizeof(uint16_t);
       BE_STREAM_TO_UINT16(seq_len, p);
       break;
     case SIZE_IN_NEXT_LONG:
+      if (sizeof(uint32_t) > param_len) return (NULL);
+      param_len -= sizeof(uint32_t);
       BE_STREAM_TO_UINT32(seq_len, p);
       break;
     default:
       return (NULL);
   }
 
-  if (seq_len >= param_len) return (NULL);
+  if (seq_len > param_len) return (NULL);
 
   p_seq_end = p + seq_len;
 
@@ -386,12 +394,15 @@
         uuid_len = 16;
         break;
       case SIZE_IN_NEXT_BYTE:
+        if (p + sizeof(uint8_t) > p_seq_end) return NULL;
         BE_STREAM_TO_UINT8(uuid_len, p);
         break;
       case SIZE_IN_NEXT_WORD:
+        if (p + sizeof(uint16_t) > p_seq_end) return NULL;
         BE_STREAM_TO_UINT16(uuid_len, p);
         break;
       case SIZE_IN_NEXT_LONG:
+        if (p + sizeof(uint32_t) > p_seq_end) return NULL;
         BE_STREAM_TO_UINT32(uuid_len, p);
         break;
       default:
@@ -399,7 +410,8 @@
     }
 
     /* If UUID length is valid, copy it across */
-    if ((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) {
+    if (((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) &&
+        (p + uuid_len <= p_seq_end)) {
       p_seq->uuid_entry[p_seq->num_uids].len = (uint16_t)uuid_len;
       BE_STREAM_TO_ARRAY(p, p_seq->uuid_entry[p_seq->num_uids].value,
                          (int)uuid_len);
@@ -436,30 +448,38 @@
   p_seq->num_attr = 0;
 
   /* Get attribute sequence info */
+  if (param_len < sizeof(descr)) return NULL;
+  param_len -= sizeof(descr);
   BE_STREAM_TO_UINT8(descr, p);
   type = descr >> 3;
   size = descr & 7;
 
-  if (type != DATA_ELE_SEQ_DESC_TYPE) return (p);
+  if (type != DATA_ELE_SEQ_DESC_TYPE) return NULL;
 
   switch (size) {
     case SIZE_IN_NEXT_BYTE:
+      if (param_len < sizeof(uint8_t)) return NULL;
+      param_len -= sizeof(uint8_t);
       BE_STREAM_TO_UINT8(list_len, p);
       break;
 
     case SIZE_IN_NEXT_WORD:
+      if (param_len < sizeof(uint16_t)) return NULL;
+      param_len -= sizeof(uint16_t);
       BE_STREAM_TO_UINT16(list_len, p);
       break;
 
     case SIZE_IN_NEXT_LONG:
+      if (param_len < sizeof(uint32_t)) return NULL;
+      param_len -= sizeof(uint32_t);
       BE_STREAM_TO_UINT32(list_len, p);
       break;
 
     default:
-      return (p);
+      return NULL;
   }
 
-  if (list_len > param_len) return (p);
+  if (list_len > param_len) return NULL;
 
   p_end_list = p + list_len;
 
@@ -469,7 +489,7 @@
     type = descr >> 3;
     size = descr & 7;
 
-    if (type != UINT_DESC_TYPE) return (p);
+    if (type != UINT_DESC_TYPE) return NULL;
 
     switch (size) {
       case SIZE_TWO_BYTES:
@@ -479,20 +499,24 @@
         attr_len = 4;
         break;
       case SIZE_IN_NEXT_BYTE:
+        if (p + sizeof(uint8_t) > p_end_list) return NULL;
         BE_STREAM_TO_UINT8(attr_len, p);
         break;
       case SIZE_IN_NEXT_WORD:
+        if (p + sizeof(uint16_t) > p_end_list) return NULL;
         BE_STREAM_TO_UINT16(attr_len, p);
         break;
       case SIZE_IN_NEXT_LONG:
+        if (p + sizeof(uint32_t) > p_end_list) return NULL;
         BE_STREAM_TO_UINT32(attr_len, p);
         break;
       default:
-        return (NULL);
+        return NULL;
         break;
     }
 
     /* Attribute length must be 2-bytes or 4-bytes for a paired entry. */
+    if (p + attr_len > p_end_list) return NULL;
     if (attr_len == 2) {
       BE_STREAM_TO_UINT16(p_seq->attr_entry[p_seq->num_attr].start, p);
       p_seq->attr_entry[p_seq->num_attr].end =
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index 612a762..0d44c9d 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -223,6 +223,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)