system/bt
Revision | ff2742acb20ce2abd86bf6f5980fc310f2013e4e (tree) |
---|---|
Zeit | 2019-10-15 17:47:31 |
Autor | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-8.1.0_r69' into oreo-x86
Android 8.1.0 Release 69 (5794017)
Conflicts:
stack/btu/btu_hcif.cc
stack/sdp/sdp_discovery.cc
@@ -92,7 +92,7 @@ struct alarm_t { | ||
92 | 92 | // potentially long-running callback is executing. |alarm_cancel| uses this |
93 | 93 | // mutex to provide a guarantee to its caller that the callback will not be |
94 | 94 | // in progress when it returns. |
95 | - std::recursive_mutex* callback_mutex; | |
95 | + std::shared_ptr<std::recursive_mutex> callback_mutex; | |
96 | 96 | period_ms_t creation_time; |
97 | 97 | period_ms_t period; |
98 | 98 | period_ms_t deadline; |
@@ -175,7 +175,8 @@ static alarm_t* alarm_new_internal(const char* name, bool is_periodic) { | ||
175 | 175 | |
176 | 176 | alarm_t* ret = static_cast<alarm_t*>(osi_calloc(sizeof(alarm_t))); |
177 | 177 | |
178 | - ret->callback_mutex = new std::recursive_mutex; | |
178 | + std::shared_ptr<std::recursive_mutex> ptr(new std::recursive_mutex()); | |
179 | + ret->callback_mutex = ptr; | |
179 | 180 | ret->is_periodic = is_periodic; |
180 | 181 | ret->stats.name = osi_strdup(name); |
181 | 182 |
@@ -192,7 +193,7 @@ void alarm_free(alarm_t* alarm) { | ||
192 | 193 | if (!alarm) return; |
193 | 194 | |
194 | 195 | alarm_cancel(alarm); |
195 | - delete alarm->callback_mutex; | |
196 | + | |
196 | 197 | osi_free((void*)alarm->stats.name); |
197 | 198 | alarm->closure.~CancelableClosureInStruct(); |
198 | 199 | osi_free(alarm); |
@@ -245,13 +246,15 @@ void alarm_cancel(alarm_t* alarm) { | ||
245 | 246 | CHECK(alarms != NULL); |
246 | 247 | if (!alarm) return; |
247 | 248 | |
249 | + std::shared_ptr<std::recursive_mutex> local_mutex_ref; | |
248 | 250 | { |
249 | 251 | std::lock_guard<std::mutex> lock(alarms_mutex); |
252 | + local_mutex_ref = alarm->callback_mutex; | |
250 | 253 | alarm_cancel_internal(alarm); |
251 | 254 | } |
252 | 255 | |
253 | 256 | // If the callback for |alarm| is in progress, wait here until it completes. |
254 | - std::lock_guard<std::recursive_mutex> lock(*alarm->callback_mutex); | |
257 | + std::lock_guard<std::recursive_mutex> lock(*local_mutex_ref); | |
255 | 258 | } |
256 | 259 | |
257 | 260 | // Internal implementation of canceling an alarm. |
@@ -577,7 +580,10 @@ static void alarm_ready_generic(alarm_t* alarm, | ||
577 | 580 | alarm->queue = NULL; |
578 | 581 | } |
579 | 582 | |
580 | - std::lock_guard<std::recursive_mutex> cb_lock(*alarm->callback_mutex); | |
583 | + // Increment the reference count of the mutex so it doesn't get freed | |
584 | + // before the callback gets finished executing. | |
585 | + std::shared_ptr<std::recursive_mutex> local_mutex_ref = alarm->callback_mutex; | |
586 | + std::lock_guard<std::recursive_mutex> cb_lock(*local_mutex_ref); | |
581 | 587 | lock.unlock(); |
582 | 588 | |
583 | 589 | // Update the statistics |
@@ -363,3 +363,17 @@ TEST_F(AlarmTest, test_callback_free_race) { | ||
363 | 363 | } |
364 | 364 | alarm_cleanup(); |
365 | 365 | } |
366 | + | |
367 | +static void remove_cb(void* data) { | |
368 | + alarm_free((alarm_t*)data); | |
369 | + semaphore_post(semaphore); | |
370 | +} | |
371 | + | |
372 | +TEST_F(AlarmTest, test_delete_during_callback) { | |
373 | + for (int i = 0; i < 1000; ++i) { | |
374 | + alarm_t* alarm = alarm_new("alarm_test.test_delete_during_callback"); | |
375 | + alarm_set(alarm, 0, remove_cb, alarm); | |
376 | + semaphore_wait(semaphore); | |
377 | + } | |
378 | + alarm_cleanup(); | |
379 | +} |
@@ -710,6 +710,15 @@ constexpr uint8_t MIN_KEY_SIZE = 7; | ||
710 | 710 | |
711 | 711 | static void read_encryption_key_size_complete_after_encryption_change( |
712 | 712 | uint8_t status, uint16_t handle, uint8_t key_size) { |
713 | + if (status == HCI_ERR_INSUFFCIENT_SECURITY) { | |
714 | + /* If remote device stop the encryption before we call "Read Encryption Key | |
715 | + * Size", we might receive Insufficient Security, which means that link is | |
716 | + * no longer encrypted. */ | |
717 | + HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__, | |
718 | + handle); | |
719 | + return; | |
720 | + } | |
721 | + | |
713 | 722 | if (status != HCI_SUCCESS) { |
714 | 723 | HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status); |
715 | 724 | btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER); |
@@ -1657,6 +1666,15 @@ static void btu_hcif_enhanced_flush_complete_evt(void) { | ||
1657 | 1666 | |
1658 | 1667 | static void read_encryption_key_size_complete_after_key_refresh( |
1659 | 1668 | uint8_t status, uint16_t handle, uint8_t key_size) { |
1669 | + if (status == HCI_ERR_INSUFFCIENT_SECURITY) { | |
1670 | + /* If remote device stop the encryption before we call "Read Encryption Key | |
1671 | + * Size", we might receive Insufficient Security, which means that link is | |
1672 | + * no longer encrypted. */ | |
1673 | + HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__, | |
1674 | + handle); | |
1675 | + return; | |
1676 | + } | |
1677 | + | |
1660 | 1678 | if (status != HCI_SUCCESS) { |
1661 | 1679 | HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status); |
1662 | 1680 | btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER); |
@@ -117,7 +117,11 @@ static bool find_uuid_in_seq(uint8_t* p, uint32_t seq_len, uint8_t* p_uuid, | ||
117 | 117 | |
118 | 118 | while (p < p_end) { |
119 | 119 | type = *p++; |
120 | - p = sdpu_get_len_from_type(p, type, &len); | |
120 | + p = sdpu_get_len_from_type(p, p_end, type, &len); | |
121 | + if (p == NULL || (p + len) > p_end) { | |
122 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
123 | + break; | |
124 | + } | |
121 | 125 | type = type >> 3; |
122 | 126 | if (type == UUID_DESC_TYPE) { |
123 | 127 | if (sdpu_compare_uuid_arrays(p, len, p_uuid, uuid_len)) return (true); |
@@ -346,6 +346,7 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { | ||
346 | 346 | unsigned int cpy_len, rem_len; |
347 | 347 | uint32_t list_len; |
348 | 348 | uint8_t* p; |
349 | + uint8_t* p_end; | |
349 | 350 | uint8_t type; |
350 | 351 | |
351 | 352 | #if (SDP_DEBUG_RAW == TRUE) |
@@ -363,12 +364,17 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { | ||
363 | 364 | cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used; |
364 | 365 | list_len = p_ccb->list_len; |
365 | 366 | p = &p_ccb->rsp_list[0]; |
367 | + p_end = &p_ccb->rsp_list[0] + list_len; | |
366 | 368 | |
367 | 369 | if (offset) { |
368 | 370 | cpy_len -= 1; |
369 | 371 | type = *p++; |
370 | 372 | uint8_t* old_p = p; |
371 | - p = sdpu_get_len_from_type(p, type, &list_len); | |
373 | + p = sdpu_get_len_from_type(p, p_end, type, &list_len); | |
374 | + if (p == NULL || (p + list_len) > p_end) { | |
375 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
376 | + return; | |
377 | + } | |
372 | 378 | if ((int)cpy_len < (p - old_p)) { |
373 | 379 | SDP_TRACE_WARNING("%s: no bytes left for data", __func__); |
374 | 380 | return; |
@@ -696,8 +702,11 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, | ||
696 | 702 | SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type); |
697 | 703 | return; |
698 | 704 | } |
699 | - p = sdpu_get_len_from_type(p, type, &seq_len); | |
700 | - | |
705 | + p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len); | |
706 | + if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) { | |
707 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
708 | + return; | |
709 | + } | |
701 | 710 | p_end = &p_ccb->rsp_list[p_ccb->list_len]; |
702 | 711 | |
703 | 712 | if ((p + seq_len) != p_end) { |
@@ -739,9 +748,8 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { | ||
739 | 748 | SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type); |
740 | 749 | return (NULL); |
741 | 750 | } |
742 | - | |
743 | - p = sdpu_get_len_from_type(p, type, &seq_len); | |
744 | - if ((p + seq_len) > p_msg_end) { | |
751 | + p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len); | |
752 | + if (p == NULL || (p + seq_len) > p_msg_end) { | |
745 | 753 | SDP_TRACE_WARNING("SDP - Bad len in attr_rsp %d", seq_len); |
746 | 754 | return (NULL); |
747 | 755 | } |
@@ -758,7 +766,11 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { | ||
758 | 766 | while (p < p_seq_end) { |
759 | 767 | /* First get the attribute ID */ |
760 | 768 | type = *p++; |
761 | - p = sdpu_get_len_from_type(p, type, &attr_len); | |
769 | + p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len); | |
770 | + if (p == NULL || (p + attr_len) > p_seq_end) { | |
771 | + SDP_TRACE_WARNING("%s: Bad len in attr_rsp %d", __func__, attr_len); | |
772 | + return (NULL); | |
773 | + } | |
762 | 774 | if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) { |
763 | 775 | SDP_TRACE_WARNING("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, |
764 | 776 | attr_len); |
@@ -842,8 +854,11 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, | ||
842 | 854 | nest_level &= ~(SDP_ADDITIONAL_LIST_MASK); |
843 | 855 | |
844 | 856 | type = *p++; |
845 | - p = sdpu_get_len_from_type(p, type, &attr_len); | |
846 | - | |
857 | + p = sdpu_get_len_from_type(p, p_end, type, &attr_len); | |
858 | + if (p == NULL || (p + attr_len) > p_end) { | |
859 | + SDP_TRACE_WARNING("%s: bad length in attr_rsp", __func__); | |
860 | + return NULL; | |
861 | + } | |
847 | 862 | attr_len &= SDP_DISC_ATTR_LEN_MASK; |
848 | 863 | attr_type = (type >> 3) & 0x0f; |
849 | 864 |
@@ -542,7 +542,8 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len, | ||
542 | 542 | * Returns void |
543 | 543 | * |
544 | 544 | ******************************************************************************/ |
545 | -uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, uint32_t* p_len) { | |
545 | +uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t* p_end, uint8_t type, | |
546 | + uint32_t* p_len) { | |
546 | 547 | uint8_t u8; |
547 | 548 | uint16_t u16; |
548 | 549 | uint32_t u32; |
@@ -564,14 +565,26 @@ uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, uint32_t* p_len) { | ||
564 | 565 | *p_len = 16; |
565 | 566 | break; |
566 | 567 | case SIZE_IN_NEXT_BYTE: |
568 | + if (p + 1 > p_end) { | |
569 | + *p_len = 0; | |
570 | + return NULL; | |
571 | + } | |
567 | 572 | BE_STREAM_TO_UINT8(u8, p); |
568 | 573 | *p_len = u8; |
569 | 574 | break; |
570 | 575 | case SIZE_IN_NEXT_WORD: |
576 | + if (p + 2 > p_end) { | |
577 | + *p_len = 0; | |
578 | + return NULL; | |
579 | + } | |
571 | 580 | BE_STREAM_TO_UINT16(u16, p); |
572 | 581 | *p_len = u16; |
573 | 582 | break; |
574 | 583 | case SIZE_IN_NEXT_LONG: |
584 | + if (p + 4 > p_end) { | |
585 | + *p_len = 0; | |
586 | + return NULL; | |
587 | + } | |
575 | 588 | BE_STREAM_TO_UINT32(u32, p); |
576 | 589 | *p_len = (uint16_t)u32; |
577 | 590 | break; |
@@ -262,7 +262,7 @@ extern uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len, | ||
262 | 262 | extern uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len, |
263 | 263 | tSDP_UUID_SEQ* p_seq); |
264 | 264 | |
265 | -extern uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, | |
265 | +extern uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t* p_end, uint8_t type, | |
266 | 266 | uint32_t* p_len); |
267 | 267 | extern bool sdpu_is_base_uuid(uint8_t* p_uuid); |
268 | 268 | extern bool sdpu_compare_uuid_arrays(uint8_t* p_uuid1, uint32_t len1, |