summaryrefslogtreecommitdiffstats
path: root/gdbus
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2014-08-11 10:50:44 +0300
committerMarcel Holtmann <marcel@holtmann.org>2014-09-08 05:48:48 +0200
commit8a4c29ca74b622d3ff95c1dd2bef31aa62892024 (patch)
treea17cdc265fc4ffeed6efe54cdaa4e8354f94fc1b /gdbus
parent9aeea028edab0f7b93ef18ab1305bc21267e7ec9 (diff)
downloadofono-8a4c29ca74b622d3ff95c1dd2bef31aa62892024.tar.bz2
gdbus: Fix use after free
Refactor filter_data_remove_callback so that we do not iterate over freed pointer.
Diffstat (limited to 'gdbus')
-rw-r--r--gdbus/watch.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/gdbus/watch.c b/gdbus/watch.c
index 0f99f4f1..474d3d4c 100644
--- a/gdbus/watch.c
+++ b/gdbus/watch.c
@@ -362,6 +362,7 @@ static void service_data_free(struct service_data *data)
callback->data = NULL;
}
+/* Returns TRUE if data is freed */
static gboolean filter_data_remove_callback(struct filter_data *data,
struct filter_callback *cb)
{
@@ -383,7 +384,7 @@ static gboolean filter_data_remove_callback(struct filter_data *data,
/* Don't remove the filter if other callbacks exist or data is lock
* processing callbacks */
if (data->callbacks || data->lock)
- return TRUE;
+ return FALSE;
if (data->registered && !remove_match(data))
return FALSE;
@@ -405,7 +406,9 @@ static DBusHandlerResult signal_filter(DBusConnection *connection,
if (cb->signal_func && !cb->signal_func(connection, message,
cb->user_data)) {
- filter_data_remove_callback(data, cb);
+ if (filter_data_remove_callback(data, cb))
+ break;
+
continue;
}
@@ -489,7 +492,9 @@ static DBusHandlerResult service_filter(DBusConnection *connection,
/* Only auto remove if it is a bus name watch */
if (data->argument[0] == ':' &&
(cb->conn_func == NULL || cb->disc_func == NULL)) {
- filter_data_remove_callback(data, cb);
+ if (filter_data_remove_callback(data, cb))
+ break;
+
continue;
}