From: Luiz Augusto von Dentz Date: Mon, 22 Jun 2020 16:21:27 +0000 (-0700) Subject: avdtp: Fix possible unbalance ref count X-Git-Tag: submit/tizen/20210606.232858~62 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d5e170e939e62d3a73dcef71ca85bb473ed0d93e;p=platform%2Fupstream%2Fbluez.git avdtp: Fix possible unbalance ref count It has been reported that under some unknown circuntances the reference number of AVDTP sessions can go bellow 0 (loop around) causing a crash: bluetoothd[5633]: profiles/audio/avdtp.c:avdtp_ref() 0x56a882b8a500: ref=-2101995743 bluetoothd[5633]: profiles/audio/a2dp.c:discover_cb() err (nil) WARNING crash_reporter[10707]: [user] Received crash notification for bluetoothd[5633] Signed-off-by: Anuj Jain Signed-off-by: Ayush Garg --- diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c index 23fa047f..9cfe5a1d 100644 --- a/profiles/audio/avdtp.c +++ b/profiles/audio/avdtp.c @@ -1383,9 +1383,15 @@ static void sep_free(gpointer data) static void remove_disconnect_timer(struct avdtp *session) { + if (!session->dc_timer) + return; + g_source_remove(session->dc_timer); session->dc_timer = 0; session->stream_setup = FALSE; + + /* Release disconnect timer reference */ + avdtp_unref(session); } static void avdtp_free(void *data) @@ -1406,9 +1412,6 @@ static void avdtp_free(void *data) session->io_id = 0; } - if (session->dc_timer) - remove_disconnect_timer(session); - if (session->req) pending_req_free(session->req); @@ -1493,13 +1496,13 @@ static gboolean disconnect_timeout(gpointer user_data) service = btd_device_get_service(session->device, A2DP_SINK_UUID); if (service && stream_setup) { sink_setup_stream(service, session); - return FALSE; + goto done; } service = btd_device_get_service(session->device, A2DP_SOURCE_UUID); if (service && stream_setup) { source_setup_stream(service, session); - return FALSE; + goto done; } #ifdef TIZEN_FEATURE_BLUEZ_MODIFY @@ -1515,6 +1518,10 @@ static gboolean disconnect_timeout(gpointer user_data) connection_lost(session, ETIMEDOUT); +done: + /* Release disconnect timer reference */ + avdtp_unref(session); + #ifdef TIZEN_FEATURE_BLUEZ_MODIFY if (device) g_timeout_add(100, @@ -1560,8 +1567,8 @@ static void set_disconnect_timer(struct avdtp *session) #ifdef TIZEN_FEATURE_BLUEZ_MODIFY char name[6]; #endif - if (session->dc_timer) - remove_disconnect_timer(session); + /* Take a ref while disconnect timer is active */ + avdtp_ref(session); #ifdef TIZEN_FEATURE_BLUEZ_MODIFY device_get_name(session->device, name, sizeof(name)); @@ -1630,8 +1637,7 @@ struct avdtp *avdtp_ref(struct avdtp *session) { session->ref++; DBG("%p: ref=%d", session, session->ref); - if (session->dc_timer) - remove_disconnect_timer(session); + remove_disconnect_timer(session); return session; }