memoryleak: ipconfig was not unreferenced properly
authorJukka Rissanen <jukka.rissanen@nokia.com>
Wed, 5 Jan 2011 13:14:12 +0000 (15:14 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 6 Jan 2011 02:51:30 +0000 (18:51 -0800)
The service creates ipconfig and then enables it which means that
ref count goes to 2. At some point it then disables ipconfig but
does not do unref which means there is a memory leak as ref count
never goes to 0.

src/service.c

index 09cc4eb..0002609 100644 (file)
@@ -2232,13 +2232,15 @@ static gboolean connect_timeout(gpointer user_data)
        if (service->network != NULL)
                __connman_network_disconnect(service->network);
 
-       if (service->ipconfig_ipv4)
-               if (__connman_ipconfig_disable(service->ipconfig_ipv4) == 0)
-                       service->ipconfig_ipv4 = NULL;
+       if (__connman_ipconfig_disable(service->ipconfig_ipv4) == 0) {
+               connman_ipconfig_unref(service->ipconfig_ipv4);
+               service->ipconfig_ipv4 = NULL;
+       }
 
-       if (service->ipconfig_ipv6)
-               if (__connman_ipconfig_disable(service->ipconfig_ipv6) == 0)
-                       service->ipconfig_ipv6 = NULL;
+       if (__connman_ipconfig_disable(service->ipconfig_ipv6) == 0) {
+               connman_ipconfig_unref(service->ipconfig_ipv6);
+               service->ipconfig_ipv6 = NULL;
+       }
 
        __connman_stats_service_unregister(service);
 
@@ -3351,15 +3353,17 @@ int __connman_service_connect(struct connman_service *service)
 
        if (err < 0) {
                if (err != -EINPROGRESS) {
-                       if (service->ipconfig_ipv4)
-                               if (__connman_ipconfig_disable(
-                                               service->ipconfig_ipv4) == 0)
-                                       service->ipconfig_ipv4 = NULL;
+                       if (__connman_ipconfig_disable(
+                                       service->ipconfig_ipv4) == 0) {
+                               connman_ipconfig_unref(service->ipconfig_ipv4);
+                               service->ipconfig_ipv4 = NULL;
+                       }
 
-                       if (service->ipconfig_ipv6)
-                               if (__connman_ipconfig_disable(
-                                               service->ipconfig_ipv6) == 0)
-                                       service->ipconfig_ipv6 = NULL;
+                       if (__connman_ipconfig_disable(
+                                       service->ipconfig_ipv6) == 0) {
+                               connman_ipconfig_unref(service->ipconfig_ipv6);
+                               service->ipconfig_ipv6 = NULL;
+                       }
 
                        __connman_stats_service_unregister(service);
                        if (service->userconnect == TRUE)
@@ -3406,11 +3410,15 @@ int __connman_service_disconnect(struct connman_service *service)
        __connman_ipconfig_clear_address(service->ipconfig_ipv4);
        __connman_ipconfig_clear_address(service->ipconfig_ipv6);
 
-       if (__connman_ipconfig_disable(service->ipconfig_ipv4) == 0)
+       if (__connman_ipconfig_disable(service->ipconfig_ipv4) == 0) {
+               connman_ipconfig_unref(service->ipconfig_ipv4);
                service->ipconfig_ipv4 = NULL;
+       }
 
-       if (__connman_ipconfig_disable(service->ipconfig_ipv6) == 0)
+       if (__connman_ipconfig_disable(service->ipconfig_ipv6) == 0) {
+               connman_ipconfig_unref(service->ipconfig_ipv6);
                service->ipconfig_ipv6 = NULL;
+       }
 
        __connman_stats_service_unregister(service);