diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2014-08-11 10:50:44 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-09-08 05:48:48 +0200 |
commit | 8a4c29ca74b622d3ff95c1dd2bef31aa62892024 (patch) | |
tree | a17cdc265fc4ffeed6efe54cdaa4e8354f94fc1b /gdbus | |
parent | 9aeea028edab0f7b93ef18ab1305bc21267e7ec9 (diff) | |
download | ofono-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.c | 11 |
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; } |