summaryrefslogtreecommitdiff
path: root/gdbus
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2014-08-12 12:31:24 (GMT)
committerMarcel Holtmann <marcel@holtmann.org>2014-09-08 03:48:48 (GMT)
commit1e0c41889f7e9a79c2fb10844c0d7e41c523b08e (patch)
tree02730be44b1785415bf8afa144e5d8a7d9fba0a5 /gdbus
parent08e673050a4e6b0eb8f4bbf1bbd68176340a54d7 (diff)
downloadofono-1e0c41889f7e9a79c2fb10844c0d7e41c523b08e.tar.gz
ofono-1e0c41889f7e9a79c2fb10844c0d7e41c523b08e.tar.xz
gdbus: Fix crash when watch is toggled or disconnected
This partially reverts 510b32b7156625b9df737c916b7a7a5c6fb285b9 since it still necessary to take a reference before calling dbus_watch_handle since internally it can call watch_info_free as in the following trace: Invalid read of size 8 at 0x121085: watch_func (mainloop.c:105) by 0x4C72694: g_main_context_dispatch (gmain.c:2539) by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146) by 0x4C72DC1: g_main_loop_run (gmain.c:3340) by 0x120541: main (main.c:551) Address 0x5bbcd90 is 16 bytes inside a block of size 24 free'd at 0x4A079AE: free (vg_replace_malloc.c:427) by 0x4C7837E: g_free (gmem.c:252) by 0x4F708BF: dbus_watch_set_data (dbus-watch.c:614) by 0x4F70938: _dbus_watch_unref (dbus-watch.c:132) by 0x4F6E9A7: _dbus_transport_handle_watch (dbus-transport.c:884) by 0x4F59AFB: _dbus_connection_handle_watch (dbus-connection.c:1497) by 0x4F70AF9: dbus_watch_handle (dbus-watch.c:683) by 0x121084: watch_func (mainloop.c:103) by 0x4C72694: g_main_context_dispatch (gmain.c:2539) by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146) by 0x4C72DC1: g_main_loop_run (gmain.c:3340) by 0x120541: main (main.c:551)
Diffstat (limited to 'gdbus')
-rw-r--r--gdbus/mainloop.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/gdbus/mainloop.c b/gdbus/mainloop.c
index 435fb93..3e88eac 100644
--- a/gdbus/mainloop.c
+++ b/gdbus/mainloop.c
@@ -88,16 +88,22 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
struct watch_info *info = data;
unsigned int flags = 0;
DBusDispatchStatus status;
+ DBusConnection *conn;
if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE;
if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
+ /* Protect connection from being destroyed by dbus_watch_handle */
+ conn = dbus_connection_ref(info->conn);
+
dbus_watch_handle(info->watch, flags);
- status = dbus_connection_get_dispatch_status(info->conn);
- queue_dispatch(info->conn, status);
+ status = dbus_connection_get_dispatch_status(conn);
+ queue_dispatch(conn, status);
+
+ dbus_connection_unref(conn);
return TRUE;
}