From 85f7f418190d54686a8be4d4836db96e025fc590 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 15 Oct 2012 13:21:11 +0300 Subject: [PATCH] gdbus: Fix invalid memory access during interface removal If an interface is removed from the root path during the same mainloop iteration that it was added we need to check for data->added before doing the check for data->parent == NULL in the remove_interface() function. Otherwise the added interface doesn't get removed from the data->added list and will result in accessing freed memory: ==337== Invalid read of size 8 ==337== at 0x4F65AFA: dbus_message_iter_append_basic (in /usr/lib64/libdbus-1.so.3.7.1) ==337== by 0x1247B5: append_interface (object.c:556) ==337== by 0x4C8DC5C: g_slist_foreach (gslist.c:840) ==337== by 0x1261F7: process_changes (object.c:594) ==337== by 0x126372: generic_unregister (object.c:997) ==337== by 0x4F69669: ??? (in /usr/lib64/libdbus-1.so.3.7.1) ==337== by 0x4F5CE51: dbus_connection_unregister_object_path (in /usr/lib64/libdbus-1.so.3.7.1) ==337== by 0x125E81: object_path_unref (object.c:1236) ==337== by 0x126136: g_dbus_unregister_interface (object.c:1361) ==337== by 0x14CDF0: service_exit (service.c:581) ==337== by 0x177556: plugin_cleanup (plugin.c:242) ==337== by 0x12221F: main (main.c:559) ==337== Address 0x5bc1550 is 0 bytes inside a block of size 56 free'd ==337== at 0x4A079AE: free (vg_replace_malloc.c:427) ==337== by 0x4C7850E: g_free (gmem.c:252) ==337== by 0x125DB0: remove_interface (object.c:671) ==337== by 0x125E3B: object_path_unref (object.c:1230) ==337== by 0x126136: g_dbus_unregister_interface (object.c:1361) ==337== by 0x14CDF0: service_exit (service.c:581) ==337== by 0x177556: plugin_cleanup (plugin.c:242) ==337== by 0x12221F: main (main.c:559) --- gdbus/object.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gdbus/object.c b/gdbus/object.c index aa38c07cc..414736135 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -655,12 +655,6 @@ static gboolean remove_interface(struct generic_data *data, const char *name) iface->user_data = NULL; } - if (data->parent == NULL) { - g_free(iface->name); - g_free(iface); - return TRUE; - } - /* * Interface being removed was just added, on the same mainloop * iteration? Don't send any signal @@ -672,6 +666,12 @@ static gboolean remove_interface(struct generic_data *data, const char *name) return TRUE; } + if (data->parent == NULL) { + g_free(iface->name); + g_free(iface); + return TRUE; + } + data->removed = g_slist_prepend(data->removed, iface->name); g_free(iface); -- 2.47.3