diff options
author | John Ernberg <john.ernberg@actia.se> | 2016-01-07 10:46:21 +0000 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2016-01-07 10:31:10 -0600 |
commit | c331d72d1d8bce1c471209c3accf117fc7cd9dbc (patch) | |
tree | bb7f8e70215196f7e3aa52f5d866c58c038a59f6 /src | |
parent | 6df0655aa3e2137e8baef33b1d58112542ce2eac (diff) | |
download | ofono-c331d72d1d8bce1c471209c3accf117fc7cd9dbc.tar.bz2 |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/network.c | 16 |
1 files 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); |