dhcp_invalidate was freeing dhcp and duplicating network unref
(reported by Tomasz Bursztyka), thus causinhg invalid reads,
when ipv4ll_announce_timeout was triggered. The patch consists
of freeing dhcp only when dhcp is stopped and network removal
and unref are previously checked against network_list.
---
 src/dhcp.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index e4bac67..eb37cfe 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -86,7 +86,6 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, bool 
callback)
 {
        struct connman_service *service;
        struct connman_ipconfig *ipconfig;
-       bool network_removed = false;
        int i;
 
        DBG("dhcp %p callback %u", dhcp, callback);
@@ -132,18 +131,14 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, 
bool callback)
        __connman_ipconfig_set_gateway(ipconfig, NULL);
        __connman_ipconfig_set_prefixlen(ipconfig, 0);
 
-       if (dhcp->callback && callback) {
-               g_hash_table_remove(network_table, dhcp->network);
-               network_removed = true;
+       if (dhcp->callback && callback)
                dhcp->callback(dhcp->network, false, NULL);
-       }
 
 out:
-       if (!network_removed)
+       if (g_hash_table_contains(network_table, dhcp->network)) {
                g_hash_table_remove(network_table, dhcp->network);
-
-       connman_network_unref(dhcp->network);
-       dhcp_free(dhcp);
+               connman_network_unref(dhcp->network);
+       }
 }
 
 static void dhcp_valid(struct connman_dhcp *dhcp)
@@ -627,6 +622,7 @@ void __connman_dhcp_stop(struct connman_network *network)
        if (dhcp) {
                dhcp_release(dhcp);
                dhcp_invalidate(dhcp, false);
+               dhcp_free(dhcp);
        }
 }
 
-- 
1.8.3.2

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to