avctp: Fix crash when disconnecting 35/204935/1
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 9 Mar 2018 09:26:04 +0000 (11:26 +0200)
committerAmit Purwar <amit.purwar@samsung.com>
Fri, 26 Apr 2019 10:43:38 +0000 (16:13 +0530)
When disconnecting the channel queue shall not be destroyed before
freeeing all requests including those that already have been processed
otherwise the following crash may happen:

4 errors in context 2 of 103:
Invalid read of size 4
   at 0x12A5C2: control_req_destroy (avctp.c:762)
   by 0x12A539: pending_destroy (avctp.c:517)
   by 0x48A0D48: g_slist_foreach (in /usr/lib/libglib-2.0.so.0.3600.0)
   by 0x12A77B: avctp_channel_destroy (avctp.c:553)
   by 0x12A801: avctp_disconnected (avctp.c:570)
   by 0x12A0F1: control_disconnect (control.c:134)
   by 0x1306B9: avrcp_disconnect (avrcp.c:4471)
   by 0x17DAE9: btd_service_disconnect (service.c:307)
   by 0x18437D: dev_disconn_service (device.c:1405)
   by 0x48A0D48: g_slist_foreach (in /usr/lib/libglib-2.0.so.0.3600.0)
   by 0x187D87: device_request_disconnect (device.c:1437)
   by 0x187EC6: dev_disconnect (device.c:1522)
 Address 0x4fde068 is 0 bytes inside a block of size 16 free'd
   at 0x48252B3: free (vg_replace_malloc.c:446)
   by 0x4888172: g_free (in /usr/lib/libglib-2.0.so.0.3600.0)
   by 0x12AB64: avctp_queue_destroy (avctp.c:537)
   by 0x48A0D48: g_slist_foreach (in /usr/lib/libglib-2.0.so.0.3600.0)
   by 0x48A0D91: g_slist_free_full (in /usr/lib/libglib-2.0.so.0.3600.0)
   by 0x12A75E: avctp_channel_destroy (avctp.c:552)
   by 0x12A801: avctp_disconnected (avctp.c:570)
   by 0x12A0F1: control_disconnect (control.c:134)
   by 0x1306B9: avrcp_disconnect (avrcp.c:4471)
   by 0x17DAE9: btd_service_disconnect (service.c:307)
   by 0x18437D: dev_disconn_service (device.c:1405)
   by 0x48A0D48: g_slist_foreach (in /usr/lib/libglib-2.0.so.0.3600.0)

Change-Id: Ida52cd46ad8d1754e8afa84ab52f7e84b68f1065
Signed-off-by: Amit Purwar <amit.purwar@samsung.com>
profiles/audio/avctp.c

index cd7a69d..898b596 100644 (file)
@@ -575,9 +575,9 @@ static void avctp_channel_destroy(struct avctp_channel *chan)
                chan->destroy(chan);
 
        g_free(chan->buffer);
-       g_slist_free_full(chan->queues, avctp_queue_destroy);
        g_slist_foreach(chan->processed, pending_destroy, NULL);
        g_slist_free(chan->processed);
+       g_slist_free_full(chan->queues, avctp_queue_destroy);
        g_slist_free_full(chan->handlers, g_free);
        g_free(chan);
 }