diff --git a/packages/network/connman/patches/connman-10_dhcp-Fix-further-crashes-when-connected-to-network-w.patch b/packages/network/connman/patches/connman-10_dhcp-Fix-further-crashes-when-connected-to-network-w.patch new file mode 100644 index 0000000000..f83be4f315 --- /dev/null +++ b/packages/network/connman/patches/connman-10_dhcp-Fix-further-crashes-when-connected-to-network-w.patch @@ -0,0 +1,90 @@ +From 88c490b3a743dcfdc0dc071b7a7055f1468719f5 Mon Sep 17 00:00:00 2001 +From: Alexandru Costache +Date: Wed, 2 Jul 2014 09:23:38 -0400 +Subject: [PATCH] dhcp: Fix further crashes when connected to network without + dhcp + +There are several crashing conditions in dhcp_retry_cb() and in +ipv4ll_available_cb(), when service is NULL or dhcp->network is +either NULL or has been freed. Fixed all by removing timeout and +ipv4ll callback when invalidating dhcp. +--- + src/dhcp.c | 40 +++++++++++++++++++++++++--------------- + 1 file changed, 25 insertions(+), 15 deletions(-) + +diff --git a/src/dhcp.c b/src/dhcp.c +index e4bac67..70a7d96 100644 +--- a/src/dhcp.c ++++ b/src/dhcp.c +@@ -70,6 +70,20 @@ static void dhcp_free(struct connman_dhcp *dhcp) + g_free(dhcp); + } + ++static void ipv4ll_stop_client(struct connman_dhcp *dhcp) ++{ ++ if (!dhcp->ipv4ll_client) ++ return; ++ ++ g_dhcp_client_stop(dhcp->ipv4ll_client); ++ g_dhcp_client_unref(dhcp->ipv4ll_client); ++ dhcp->ipv4ll_client = NULL; ++ ipv4ll_running = false; ++ ++ g_free(dhcp->ipv4ll_debug_prefix); ++ dhcp->ipv4ll_debug_prefix = NULL; ++} ++ + /** + * dhcp_invalidate: Invalidate an existing DHCP lease + * @dhcp: pointer to the DHCP lease to invalidate. +@@ -132,6 +146,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->timeout > 0) { ++ g_source_remove(dhcp->timeout); ++ dhcp->timeout = 0; ++ } ++ ++ if (ipv4ll_running) ++ ipv4ll_stop_client(dhcp); ++ + if (dhcp->callback && callback) { + g_hash_table_remove(network_table, dhcp->network); + network_removed = true; +@@ -157,20 +179,6 @@ static void dhcp_debug(const char *str, void *data) + connman_info("%s: %s", (const char *) data, str); + } + +-static void ipv4ll_stop_client(struct connman_dhcp *dhcp) +-{ +- if (!dhcp->ipv4ll_client) +- return; +- +- g_dhcp_client_stop(dhcp->ipv4ll_client); +- g_dhcp_client_unref(dhcp->ipv4ll_client); +- dhcp->ipv4ll_client = NULL; +- ipv4ll_running = false; +- +- g_free(dhcp->ipv4ll_debug_prefix); +- dhcp->ipv4ll_debug_prefix = NULL; +-} +- + static void ipv4ll_lost_cb(GDHCPClient *dhcp_client, gpointer user_data); + static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data); + +@@ -574,8 +582,10 @@ static int dhcp_release(struct connman_dhcp *dhcp) + { + DBG("dhcp %p", dhcp); + +- if (dhcp->timeout > 0) ++ if (dhcp->timeout > 0) { + g_source_remove(dhcp->timeout); ++ dhcp->timeout = 0; ++ } + + if (dhcp->dhcp_client) { + g_dhcp_client_stop(dhcp->dhcp_client); +-- +1.7.10.4 +