Merge cherrypicks of [7496339, 7495273, 7495624, 7496340, 7496341, 7496342, 7496343, 7495658, 7494789, 7494790, 7494791, 7496344, 7496345, 7496346, 7496347, 7496574, 7496348, 7496575, 7496576, 7496260, 7496349, 7496350, 7496440, 7496577, 7496578, 7496261, 7495625, 7496442, 7496351] into pi-qpr3-release

Change-Id: I7f080180cff0ec6fff34b8da8827cb3095b948b5
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index 83a661d..07d8704 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -92,7 +92,7 @@
   // potentially long-running callback is executing. |alarm_cancel| uses this
   // mutex to provide a guarantee to its caller that the callback will not be
   // in progress when it returns.
-  std::recursive_mutex* callback_mutex;
+  std::shared_ptr<std::recursive_mutex> callback_mutex;
   period_ms_t creation_time;
   period_ms_t period;
   period_ms_t deadline;
@@ -181,7 +181,8 @@
 
   alarm_t* ret = static_cast<alarm_t*>(osi_calloc(sizeof(alarm_t)));
 
-  ret->callback_mutex = new std::recursive_mutex;
+  std::shared_ptr<std::recursive_mutex> ptr(new std::recursive_mutex());
+  ret->callback_mutex = ptr;
   ret->is_periodic = is_periodic;
   ret->stats.name = osi_strdup(name);
 
@@ -198,7 +199,7 @@
   if (!alarm) return;
 
   alarm_cancel(alarm);
-  delete alarm->callback_mutex;
+
   osi_free((void*)alarm->stats.name);
   alarm->closure.~CancelableClosureInStruct();
   osi_free(alarm);
@@ -251,13 +252,15 @@
   CHECK(alarms != NULL);
   if (!alarm) return;
 
+  std::shared_ptr<std::recursive_mutex> local_mutex_ref = alarm->callback_mutex;
   {
     std::lock_guard<std::mutex> lock(alarms_mutex);
+    local_mutex_ref = alarm->callback_mutex;
     alarm_cancel_internal(alarm);
   }
 
   // If the callback for |alarm| is in progress, wait here until it completes.
-  std::lock_guard<std::recursive_mutex> lock(*alarm->callback_mutex);
+  std::lock_guard<std::recursive_mutex> lock(*local_mutex_ref);
 }
 
 // Internal implementation of canceling an alarm.
@@ -579,7 +582,10 @@
     alarm->queue = NULL;
   }
 
-  std::lock_guard<std::recursive_mutex> cb_lock(*alarm->callback_mutex);
+  // Increment the reference count of the mutex so it doesn't get freed
+  // before the callback gets finished executing.
+  std::shared_ptr<std::recursive_mutex> local_mutex_ref = alarm->callback_mutex;
+  std::lock_guard<std::recursive_mutex> cb_lock(*local_mutex_ref);
   lock.unlock();
 
   // Update the statistics
diff --git a/osi/test/alarm_test.cc b/osi/test/alarm_test.cc
index f7f473d..0066e19 100644
--- a/osi/test/alarm_test.cc
+++ b/osi/test/alarm_test.cc
@@ -364,3 +364,17 @@
   }
   alarm_cleanup();
 }
+
+static void remove_cb(void* data) {
+  alarm_free((alarm_t*)data);
+  semaphore_post(semaphore);
+}
+
+TEST_F(AlarmTest, test_delete_during_callback) {
+  for (int i = 0; i < 1000; ++i) {
+    alarm_t* alarm = alarm_new("alarm_test.test_delete_during_callback");
+    alarm_set(alarm, 0, remove_cb, alarm);
+    semaphore_wait(semaphore);
+  }
+  alarm_cleanup();
+}
diff --git a/stack/sdp/sdp_db.cc b/stack/sdp/sdp_db.cc
index d8cee9a..769e7d8 100644
--- a/stack/sdp/sdp_db.cc
+++ b/stack/sdp/sdp_db.cc
@@ -117,7 +117,11 @@
 
   while (p < p_end) {
     type = *p++;
-    p = sdpu_get_len_from_type(p, type, &len);
+    p = sdpu_get_len_from_type(p, p_end, type, &len);
+    if (p == NULL || (p + len) > p_end) {
+      SDP_TRACE_WARNING("%s: bad length", __func__);
+      break;
+    }
     type = type >> 3;
     if (type == UUID_DESC_TYPE) {
       if (sdpu_compare_uuid_arrays(p, len, p_uuid, uuid_len)) return (true);
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index 1ca2ad3..f2e9805 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -349,6 +349,7 @@
   unsigned int cpy_len, rem_len;
   uint32_t list_len;
   uint8_t* p;
+  uint8_t* p_end;
   uint8_t type;
 
 #if (SDP_DEBUG_RAW == TRUE)
@@ -366,12 +367,17 @@
     cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used;
     list_len = p_ccb->list_len;
     p = &p_ccb->rsp_list[0];
+    p_end = &p_ccb->rsp_list[0] + list_len;
 
     if (offset) {
       cpy_len -= 1;
       type = *p++;
       uint8_t* old_p = p;
-      p = sdpu_get_len_from_type(p, type, &list_len);
+      p = sdpu_get_len_from_type(p, p_end, type, &list_len);
+      if (p == NULL || (p + list_len) > p_end) {
+        SDP_TRACE_WARNING("%s: bad length", __func__);
+        return;
+      }
       if ((int)cpy_len < (p - old_p)) {
         SDP_TRACE_WARNING("%s: no bytes left for data", __func__);
         return;
@@ -699,8 +705,11 @@
     SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type);
     return;
   }
-  p = sdpu_get_len_from_type(p, type, &seq_len);
-
+  p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len);
+  if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) {
+    SDP_TRACE_WARNING("%s: bad length", __func__);
+    return;
+  }
   p_end = &p_ccb->rsp_list[p_ccb->list_len];
 
   if ((p + seq_len) != p_end) {
@@ -742,9 +751,8 @@
     SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type);
     return (NULL);
   }
-
-  p = sdpu_get_len_from_type(p, type, &seq_len);
-  if ((p + seq_len) > p_msg_end) {
+  p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len);
+  if (p == NULL || (p + seq_len) > p_msg_end) {
     SDP_TRACE_WARNING("SDP - Bad len in attr_rsp %d", seq_len);
     return (NULL);
   }
@@ -761,7 +769,11 @@
   while (p < p_seq_end) {
     /* First get the attribute ID */
     type = *p++;
-    p = sdpu_get_len_from_type(p, type, &attr_len);
+    p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len);
+    if (p == NULL || (p + attr_len) > p_seq_end) {
+      SDP_TRACE_WARNING("%s: Bad len in attr_rsp %d", __func__, attr_len);
+      return (NULL);
+    }
     if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) {
       SDP_TRACE_WARNING("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type,
                         attr_len);
@@ -845,8 +857,11 @@
   nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
 
   type = *p++;
-  p = sdpu_get_len_from_type(p, type, &attr_len);
-
+  p = sdpu_get_len_from_type(p, p_end, type, &attr_len);
+  if (p == NULL || (p + attr_len) > p_end) {
+    SDP_TRACE_WARNING("%s: bad length in attr_rsp", __func__);
+    return NULL;
+  }
   attr_len &= SDP_DISC_ATTR_LEN_MASK;
   attr_type = (type >> 3) & 0x0f;
 
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index c57a499..c2c6b27 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -543,7 +543,8 @@
  * Returns          void
  *
  ******************************************************************************/
-uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, uint32_t* p_len) {
+uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t* p_end, uint8_t type,
+                                uint32_t* p_len) {
   uint8_t u8;
   uint16_t u16;
   uint32_t u32;
@@ -565,14 +566,26 @@
       *p_len = 16;
       break;
     case SIZE_IN_NEXT_BYTE:
+      if (p + 1 > p_end) {
+        *p_len = 0;
+        return NULL;
+      }
       BE_STREAM_TO_UINT8(u8, p);
       *p_len = u8;
       break;
     case SIZE_IN_NEXT_WORD:
+      if (p + 2 > p_end) {
+        *p_len = 0;
+        return NULL;
+      }
       BE_STREAM_TO_UINT16(u16, p);
       *p_len = u16;
       break;
     case SIZE_IN_NEXT_LONG:
+      if (p + 4 > p_end) {
+        *p_len = 0;
+        return NULL;
+      }
       BE_STREAM_TO_UINT32(u32, p);
       *p_len = (uint16_t)u32;
       break;
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index 0d44c9d..e00a8ca 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -263,7 +263,7 @@
 extern uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
                                      tSDP_UUID_SEQ* p_seq);
 
-extern uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type,
+extern uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t* p_end, uint8_t type,
                                        uint32_t* p_len);
 extern bool sdpu_is_base_uuid(uint8_t* p_uuid);
 extern bool sdpu_compare_uuid_arrays(uint8_t* p_uuid1, uint32_t len1,