This bug related to src/ipconfig.c in function __connman_ipconfig_enable
we are removing the wrong entry in ipconfig_list which caused to leave
etries after services goes away causing the crash becuase we are
touching a gone memory.

I also added some checks for NULL pointer in service_ops callback
pointers.
---
 src/ipconfig.c |    6 ++++--
 src/service.c  |   48 +++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 90b4f16..0518e10 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1218,7 +1218,8 @@ int __connman_ipconfig_enable(struct connman_ipconfig 
*ipconfig)
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
                                        ipdevice->config_ipv4 != NULL) {
-               ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+               ipconfig_list = g_list_remove(ipconfig_list,
+                                                       ipdevice->config_ipv4);
 
                connman_ipaddress_clear(ipdevice->config_ipv4->system);
 
@@ -1227,7 +1228,8 @@ int __connman_ipconfig_enable(struct connman_ipconfig 
*ipconfig)
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
                                        ipdevice->config_ipv6 != NULL) {
-               ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+               ipconfig_list = g_list_remove(ipconfig_list,
+                                                       ipdevice->config_ipv6);
 
                connman_ipaddress_clear(ipdevice->config_ipv6->system);
 
diff --git a/src/service.c b/src/service.c
index cca1ab8..6e9a3f8 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3737,10 +3737,17 @@ static int service_register(struct connman_service 
*service)
 
 static void service_up(struct connman_ipconfig *ipconfig)
 {
-       struct connman_service *service = connman_ipconfig_get_data(ipconfig);
+       struct connman_service *service;
+
+       if (ipconfig == NULL)
+               return;
 
+       service = connman_ipconfig_get_data(ipconfig);
        connman_info("%s up", connman_ipconfig_get_ifname(ipconfig));
 
+       if (service == NULL)
+               return;
+
        link_changed(service);
 
        service->stats.valid = FALSE;
@@ -3749,21 +3756,36 @@ static void service_up(struct connman_ipconfig 
*ipconfig)
 
 static void service_down(struct connman_ipconfig *ipconfig)
 {
+       if (ipconfig == NULL)
+               return;
+
        connman_info("%s down", connman_ipconfig_get_ifname(ipconfig));
 }
 
 static void service_lower_up(struct connman_ipconfig *ipconfig)
 {
-       struct connman_service *service = connman_ipconfig_get_data(ipconfig);
+       struct connman_service *service;
+
+       if (ipconfig == NULL)
+               return;
+
+       service = connman_ipconfig_get_data(ipconfig);
 
        connman_info("%s lower up", connman_ipconfig_get_ifname(ipconfig));
 
-       stats_start(service);
+       if (service != NULL)
+               stats_start(service);
 }
 
 static void service_lower_down(struct connman_ipconfig *ipconfig)
 {
-       struct connman_service *service = connman_ipconfig_get_data(ipconfig);
+       struct connman_service *service = NULL;
+
+       if (ipconfig != NULL)
+               service = connman_ipconfig_get_data(ipconfig);
+
+       if (service == NULL)
+               return;
 
        connman_info("%s lower down", connman_ipconfig_get_ifname(ipconfig));
 
@@ -3773,20 +3795,32 @@ static void service_lower_down(struct connman_ipconfig 
*ipconfig)
 
 static void service_ip_bound(struct connman_ipconfig *ipconfig)
 {
-       struct connman_service *service = connman_ipconfig_get_data(ipconfig);
+       struct connman_service *service;
+
+       if (ipconfig == NULL)
+               return;
+
+       service = connman_ipconfig_get_data(ipconfig);
 
        connman_info("%s ip bound", connman_ipconfig_get_ifname(ipconfig));
 
-       settings_changed(service);
+       if (service != NULL)
+               settings_changed(service);
 }
 
 static void service_ip_release(struct connman_ipconfig *ipconfig)
 {
        struct connman_service *service = connman_ipconfig_get_data(ipconfig);
 
+       if (ipconfig == NULL)
+               return;
+
+       service = connman_ipconfig_get_data(ipconfig);
+
        connman_info("%s ip release", connman_ipconfig_get_ifname(ipconfig));
 
-       settings_changed(service);
+       if (service != NULL)
+               settings_changed(service);
 }
 
 static const struct connman_ipconfig_ops service_ops = {
-- 
1.7.3.3

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to