From c331d72d1d8bce1c471209c3accf117fc7cd9dbc Mon Sep 17 00:00:00 2001 From: John Ernberg Date: Thu, 7 Jan 2016 10:46:21 +0000 Subject: network: Fix crash caused by empty Scan() results When issuing a Scan() in poor reception while attached to an operator it's fully possible to get no results, which causes the attached operator to be cleaned up. In certain scenarios this would cause a use-after-free as there are still references to this operator. Transfer the attached operator to the new list regardless of removal caused by the Scan() results. --- src/network.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/network.c b/src/network.c index 1dddcacf..8ad11d3f 100644 --- a/src/network.c +++ b/src/network.c @@ -710,6 +710,7 @@ static gboolean update_operator_list(struct ofono_netreg *netreg, int total, GSList *o; GSList *compressed; GSList *c; + struct network_operator_data *current_op = NULL; gboolean changed = FALSE; compressed = compress_operator_list(list, total); @@ -754,8 +755,19 @@ static gboolean update_operator_list(struct ofono_netreg *netreg, int total, if (netreg->operator_list) changed = TRUE; - for (o = netreg->operator_list; o; o = o->next) - network_operator_dbus_unregister(netreg, o->data); + for (o = netreg->operator_list; o; o = o->next) { + struct network_operator_data *op = o->data; + if (op != op->netreg->current_operator) + network_operator_dbus_unregister(netreg, op); + else + current_op = op; + } + + if (current_op) { + n = g_slist_prepend(n, current_op); + netreg->operator_list = + g_slist_remove(netreg->operator_list, current_op); + } g_slist_free(netreg->operator_list); -- cgit v1.2.3