[PATCH 2/2] Fix __check_pf() memory leak.

Debabrata Banerjee dbanerje@akamai.com
Fri Oct 4 20:29:00 GMT 2013


Tested with valgrind --leak-check=full --show-reachable=yes while calling
getaddrinfo() and subsequent freeaddrinfo() with 64k+ local IPv4 and IPv6 addresses.

Changelog:

2013-10-04  Debabrata Banerjee  <dbanerje@akamai.com>

        * sysdeps/unix/sysv/linux/check_pf.c (__check_pf):
	fix memory leak/locking when not building in NSCD.
        (__free_in6ai): Likewise.

Signed-off-by: Debabrata Banerjee <dbanerje@akamai.com>
---
 sysdeps/unix/sysv/linux/check_pf.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 76bf516..8a86571 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -395,6 +395,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
   struct cached_data *olddata = NULL;
   struct cached_data *data = NULL;
 
+#if defined(IS_IN_nscd) || defined(USE_NSCD)
   __libc_lock_lock (lock);
 
   if (cache_valid_p ())
@@ -403,6 +404,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
       atomic_increment (&cache->usecnt);
     }
   else
+#endif
     {
       int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 
@@ -422,14 +424,21 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
 	  close_not_cancel_no_status (fd);
 	}
 
-      if (data != NULL)
+#if defined(IS_IN_nscd) || defined(USE_NSCD)
+      if (data != cache)
 	{
 	  olddata = cache;
 	  cache = data;
+
+          if (olddata != NULL && atomic_add_zero (&olddata->usecnt, -1))
+            free (olddata);
 	}
     }
 
   __libc_lock_unlock (lock);
+#else
+    }
+#endif
 
   if (data != NULL)
     {
@@ -461,16 +470,16 @@ __free_in6ai (struct in6addrinfo *ai)
       struct cached_data *data =
 	(struct cached_data *) ((char *) ai
 				- offsetof (struct cached_data, in6ai));
-
-      if (atomic_add_zero (&data->usecnt, -1))
-	{
+#if defined(IS_IN_nscd) || defined(USE_NSCD)
 	  __libc_lock_lock (lock);
 
-	  if (data->usecnt == 0)
-	    /* Still unused.  */
+       if (atomic_add_zero (&data->usecnt, -1))
 	    free (data);
 
 	  __libc_lock_unlock (lock);
-	}
+#else
+       if (atomic_add_zero (&data->usecnt, -1))
+         free(data);
+#endif
     }
 }
-- 
1.8.3.4



More information about the Libc-alpha mailing list