summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ernberg <john.ernberg@actia.se>2016-01-07 10:46:21 +0000
committerDenis Kenzior <denkenz@gmail.com>2016-01-07 10:31:10 -0600
commitc331d72d1d8bce1c471209c3accf117fc7cd9dbc (patch)
treebb7f8e70215196f7e3aa52f5d866c58c038a59f6
parent6df0655aa3e2137e8baef33b1d58112542ce2eac (diff)
downloadofono-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.
-rw-r--r--src/network.c16
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);