Loading system/osi/src/alarm.cc +11 −5 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ struct alarm_t { // 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; Loading Loading @@ -181,7 +181,8 @@ static alarm_t* alarm_new_internal(const char* name, bool is_periodic) { 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); Loading @@ -198,7 +199,7 @@ void alarm_free(alarm_t* alarm) { if (!alarm) return; alarm_cancel(alarm); delete alarm->callback_mutex; osi_free((void*)alarm->stats.name); alarm->closure.~CancelableClosureInStruct(); osi_free(alarm); Loading Loading @@ -251,13 +252,15 @@ void alarm_cancel(alarm_t* alarm) { 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. Loading Loading @@ -579,7 +582,10 @@ static void alarm_ready_generic(alarm_t* alarm, 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 Loading system/osi/test/alarm_test.cc +14 −0 Original line number Diff line number Diff line Loading @@ -364,3 +364,17 @@ TEST_F(AlarmTest, test_callback_free_race) { } 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(); } system/stack/sdp/sdp_db.cc +5 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,11 @@ static bool find_uuid_in_seq(uint8_t* p, uint32_t seq_len, uint8_t* p_uuid, 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); Loading system/stack/sdp/sdp_discovery.cc +24 −9 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { 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) Loading @@ -366,12 +367,17 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { 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; Loading Loading @@ -699,8 +705,11 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, 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) { Loading Loading @@ -742,9 +751,8 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { 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); } Loading @@ -761,7 +769,11 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { 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); Loading Loading @@ -845,8 +857,11 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, 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; Loading system/stack/sdp/sdp_utils.cc +14 −1 Original line number Diff line number Diff line Loading @@ -543,7 +543,8 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len, * 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; Loading @@ -565,14 +566,26 @@ uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, uint32_t* p_len) { *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; Loading Loading
system/osi/src/alarm.cc +11 −5 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ struct alarm_t { // 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; Loading Loading @@ -181,7 +181,8 @@ static alarm_t* alarm_new_internal(const char* name, bool is_periodic) { 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); Loading @@ -198,7 +199,7 @@ void alarm_free(alarm_t* alarm) { if (!alarm) return; alarm_cancel(alarm); delete alarm->callback_mutex; osi_free((void*)alarm->stats.name); alarm->closure.~CancelableClosureInStruct(); osi_free(alarm); Loading Loading @@ -251,13 +252,15 @@ void alarm_cancel(alarm_t* alarm) { 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. Loading Loading @@ -579,7 +582,10 @@ static void alarm_ready_generic(alarm_t* alarm, 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 Loading
system/osi/test/alarm_test.cc +14 −0 Original line number Diff line number Diff line Loading @@ -364,3 +364,17 @@ TEST_F(AlarmTest, test_callback_free_race) { } 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(); }
system/stack/sdp/sdp_db.cc +5 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,11 @@ static bool find_uuid_in_seq(uint8_t* p, uint32_t seq_len, uint8_t* p_uuid, 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); Loading
system/stack/sdp/sdp_discovery.cc +24 −9 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { 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) Loading @@ -366,12 +367,17 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { 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; Loading Loading @@ -699,8 +705,11 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, 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) { Loading Loading @@ -742,9 +751,8 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { 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); } Loading @@ -761,7 +769,11 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { 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); Loading Loading @@ -845,8 +857,11 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, 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; Loading
system/stack/sdp/sdp_utils.cc +14 −1 Original line number Diff line number Diff line Loading @@ -543,7 +543,8 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len, * 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; Loading @@ -565,14 +566,26 @@ uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t type, uint32_t* p_len) { *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; Loading