This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 3/3] Tested with valgrind --leak-check=full --show-reachable=yes while calling getaddrinfo() and subsequent freeaddrinfo() with 64k+ local IPv4 and IPv6 addresses.
- From: Debabrata Banerjee <dbanerje at akamai dot com>
- To: libc-alpha at sourceware dot org, Carlos O'Donell <carlos at redhat dot com>
- Cc: Debabrata Banerjee <dbanerje at akamai dot com>
- Date: Thu, 31 Oct 2013 21:10:13 -0400
- Subject: [PATCH 3/3] Tested with valgrind --leak-check=full --show-reachable=yes while calling getaddrinfo() and subsequent freeaddrinfo() with 64k+ local IPv4 and IPv6 addresses.
- Authentication-results: sourceware.org; auth=none
- References: <524E4504 dot 6050603 at redhat dot com> <1383268213-14349-1-git-send-email-dbanerje at akamai dot com>
Changelog:
2013-10-04 Debabrata Banerjee <dbanerje@akamai.com>
[BZ #16001]
* sysdeps/unix/sysv/linux/check_pf.c (__check_pf):
Fix memory leak and 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 3f436b3..b82f29c 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -378,6 +378,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 ())
@@ -386,6 +387,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
atomic_increment (&cache->usecnt);
}
else
+#endif
{
int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
@@ -405,14 +407,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)
{
@@ -444,16 +453,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