OSDN Git Service

obexd/session: Fix crash while disconnecting
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 7 Oct 2013 15:44:44 +0000 (18:44 +0300)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 7 Oct 2013 16:02:43 +0000 (19:02 +0300)
Requests need to be cancelled when obc_session_shutdown is called
otherwise they can trigger the callback with invalid/freed data as in
the following backtrace:
Invalid read of size 8
   at 0x426684: setpath_cb (session.c:998)
   by 0x412AEB: handle_response (gobex.c:949)
   by 0x413010: incoming_data (gobex.c:1192)
   by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x40D59C: main (main.c:319)
 Address 0x571f598 is 40 bytes inside a block of size 56 free'd
   at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x426EA9: obc_session_shutdown (session.c:555)
   by 0x4254B4: remove_session (manager.c:62)
   by 0x43DC53: process_message.isra.5 (object.c:259)
   by 0x3D4981CE85: ??? (in /usr/lib64/libdbus-1.so.3.7.4)
   by 0x3D4980FA30: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.4)
   by 0x43A9D7: message_dispatch (mainloop.c:76)
   by 0x3D46048962: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)

obexd/client/session.c

index 48016c4..67c2b83 100644 (file)
@@ -177,6 +177,9 @@ static struct pending_request *pending_request_new(struct obc_session *session,
 
 static void pending_request_free(struct pending_request *p)
 {
+       if (p->req_id > 0)
+               g_obex_cancel_req(p->session->obex, p->req_id, TRUE);
+
        if (p->destroy)
                p->destroy(p->data);
 
@@ -1311,6 +1314,8 @@ void obc_session_cancel(struct obc_session *session, guint id,
                return;
 
        g_obex_cancel_req(session->obex, p->req_id, remove);
+       p->req_id = 0;
+
        if (!remove)
                return;