about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--nscd/hstcache.c29
2 files changed, 22 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index ddd4c44b39..6c78c9a264 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2004-07-26  Ulrich Drepper  <drepper@redhat.com>
 
+	* nscd/hstcache.c (cache_addhst): Fix two scenarios which lead to
+	memory leaks.
+
 	* sysdeps/unix/sysv/linux/ifreq.c (__ifreq): Assign pointer for
 	new buffer at the right time.
 	Reported by Jakub Bogusz <qboosh@pld-linux.org>.
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index cf2a98c471..44b76aa7c0 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -199,6 +199,17 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
 	 unnecessarily let the receiver wait.  */
       written = TEMP_FAILURE_RETRY (write (fd, data, total));
 
+      /* If the record contains more than one IP address (used for
+         load balancing etc) don't cache the entry.  This is something
+         the current cache handling cannot handle and it is more than
+         questionable whether it is worthwhile complicating the cache
+         handling just for handling such a special case.  */
+      if (!add_addr && hst->h_addr_list[1] != NULL)
+	{
+	  free (data);
+	  return;
+	}
+
       addr_list_type = (hst->h_length == NS_INADDRSZ
 			? GETHOSTBYADDR : GETHOSTBYADDRv6);
 
@@ -208,13 +219,9 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
       /* Now get the lock to safely insert the records.  */
       pthread_rwlock_rdlock (&db->lock);
 
-      /* First add all the aliases.  If the record contains more than
-         one IP address (used for load balancing etc) don't cache the
-         entry.  This is something the current cache handling cannot
-         handle and it is more than questionable whether it is
-         worthwhile complicating the cache handling just for handling
-         such a special case.  */
-      if (!add_addr && hst->h_addr_list[1] == NULL)
+      /* First add all the aliases.  */
+      assert (add_addr || hst->h_addr_list[1] == NULL);
+      if (!add_addr)
 	for (cnt = 0; cnt < h_aliases_cnt; ++cnt)
 	  {
 	    if (addr_list_type == GETHOSTBYADDR)
@@ -232,7 +239,7 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
 	for (cnt = 0; cnt < h_addr_list_cnt; ++cnt)
 	  {
 	    cache_add (addr_list_type, addresses, hst->h_length, data, total,
-		       data, 0, t, db, owner);
+		       data, cnt + 1 == h_addr_list_cnt, t, db, owner);
 	    addresses += hst->h_length;
 	  }
 
@@ -247,9 +254,11 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
 
       /* Avoid adding names if more than one address is available.  See
 	 above for more info.  */
-      if (!add_addr && hst->h_addr_list[1] == NULL)
+      if (!add_addr)
 	{
-	  /* If necessary add the key for this request.  */
+	  /* If necessary add the key for this request.
+
+	     Note: hst->h_addr_list[1] == NULL.  */
 	  if (req->type == GETHOSTBYNAME || req->type == GETHOSTBYNAMEv6)
 	    {
 	      if (addr_list_type == GETHOSTBYADDR)