[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r6194 - in /fsf/trunk/libc: ./ nscd/ resolv/nss_dns/ sysdeps/posix/



Author: eglibc
Date: Sun May 18 00:07:08 2008
New Revision: 6194

Log:
Import glibc-mainline for 2008-05-18

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/nscd/aicache.c
    fsf/trunk/libc/nscd/mem.c
    fsf/trunk/libc/nscd/nscd.h
    fsf/trunk/libc/resolv/nss_dns/dns-host.c
    fsf/trunk/libc/sysdeps/posix/getaddrinfo.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sun May 18 00:07:08 2008
@@ -1,3 +1,31 @@
+2008-05-17  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* nscd/mem.c (gc): Avoid stack overflow when allocating move list.
+
+	* nscd/mem.c (gc): Correctly determine highest used array element
+	in mark.
+
+	* nscd/mem.c (markrange): Add assert to check entries are all
+	aligned.  Small cleanup in bitmap use.
+
+	* nscd/nscd.h (mem_in_flight): Replace blockaddr field with
+	blockoff of type nscd_ssize_t.
+	* nscd/mem.c (gc): Simplify markrange call for on-flight blocks.
+	(mempoll_alloc): Record block offset and not address.
+
+	* nscd/mem.c (gc): Fix test for stack overuse.
+
+	* nscd/aicache.c (addhstaiX): Fix a few small problems, cleanups,
+	more asserts.
+
+	* sysdeps/posix/getaddrinfo.c (gaih_inet): If nscd reports no
+	entry is available, believe it.
+
+	* resolv/nss_dns/dns-host.c (gaih_getanswer_slice): If there are
+	no answers return NSS_STATUS_NOTFOUND.
+	(gaih_getanswer): Don't call gaih_getanswer_slice if the answer
+	buffer does not have any content.
+
 2008-05-16  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* string/strcasestr.c (CMP_FUNC): Use __strncasecmp, not strncasecmp.
@@ -174,7 +202,7 @@
 	* nscd/hstcache.c: Likewise.
 	* nscd/initgrcache.c: Likewise.
 	* nscd/pwdcache.c: Likewise.
-	* nscd/servicecache.c: Likewise.
+	* nscd/servicescache.c: Likewise.
 
 2008-05-10  Roland McGrath  <roland@xxxxxxxxxx>
 

Modified: fsf/trunk/libc/nscd/aicache.c
==============================================================================
--- fsf/trunk/libc/nscd/aicache.c (original)
+++ fsf/trunk/libc/nscd/aicache.c Sun May 18 00:07:08 2008
@@ -114,7 +114,6 @@
   char *tmpbuf6 = alloca (tmpbuf6len);
   size_t tmpbuf4len = 0;
   char *tmpbuf4 = NULL;
-  char *canon = NULL;
   int32_t ttl = INT32_MAX;
   ssize_t total = 0;
   char *key_copy = NULL;
@@ -126,6 +125,7 @@
       int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
       int naddrs = 0;
       size_t addrslen = 0;
+      char *canon = NULL;
       size_t canonlen;
 
       nss_gethostbyname4_r fct4 = __nss_lookup_function (nip,
@@ -136,9 +136,11 @@
 	  while (1)
 	    {
 	      rc6 = 0;
-	      status[0] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
+	      herrno = 0;
+	      status[1] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
 					      &rc6, &herrno, &ttl));
-	      if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
+	      if (rc6 != ERANGE || (herrno != NETDB_INTERNAL
+				    && herrno != TRY_AGAIN))
 		break;
 	      tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
 	    }
@@ -146,22 +148,21 @@
 	  if (rc6 != 0 && herrno == NETDB_INTERNAL)
 	    goto out;
 
-	  if (status[0] != NSS_STATUS_SUCCESS)
+	  if (status[1] != NSS_STATUS_SUCCESS)
 	    goto next_nip;
 
 	  /* We found the data.  Count the addresses and the size.  */
-	  for (struct gaih_addrtuple *at2 = at; at2 != NULL; at2 = at2->next)
+	  for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
+	       at2 = at2->next)
 	    {
 	      ++naddrs;
-	      /* We handle unknown types here the best we can: assume
-		 the maximum size for the address.  */
+	      /* We do not handle anything other than IPv4 and IPv6
+		 addresses.  The getaddrinfo implementation does not
+		 either so it is not worth trying to do more.  */
 	      if (at2->family == AF_INET)
 		addrslen += INADDRSZ;
-	      else if (at2->family == AF_INET6
-		       && IN6ADDRSZ != sizeof (at2->addr))
+	      else if (at2->family == AF_INET6)
 		addrslen += IN6ADDRSZ;
-	      else
-		addrslen += sizeof (at2->addr);
 	    }
 	  canon = at->name;
 	  canonlen = strlen (canon) + 1;
@@ -191,19 +192,17 @@
 	    }
 
 	  /* Fill in the address and address families.  */
-	  char *addrs = (char *) (&dataset->resp + 1);
+	  char *addrs = dataset->strdata;
 	  uint8_t *family = (uint8_t *) (addrs + addrslen);
 
-	  for (struct gaih_addrtuple *at2 = at; at2 != NULL; at2 = at2->next)
+	  for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
+	       at2 = at2->next)
 	    {
 	      *family++ = at2->family;
 	      if (at2->family == AF_INET)
 		addrs = mempcpy (addrs, at2->addr, INADDRSZ);
-	      else if (at2->family == AF_INET6
-		       && IN6ADDRSZ != sizeof (at2->addr))
+	      else if (at2->family == AF_INET6)
 		addrs = mempcpy (addrs, at2->addr, IN6ADDRSZ);
-	      else
-		addrs = mempcpy (addrs, at2->addr, sizeof (at2->addr));
 	    }
 
 	  cp = family;
@@ -373,7 +372,7 @@
 	    }
 
 	  /* Fill in the address and address families.  */
-	  char *addrs = (char *) (&dataset->resp + 1);
+	  char *addrs = dataset->strdata;
 	  uint8_t *family = (uint8_t *) (addrs + addrslen);
 
 	  for (int j = 0; j < 2; ++j)
@@ -410,6 +409,8 @@
 	cp = mempcpy (cp, canon, canonlen);
 
       key_copy = memcpy (cp, key, req->key_len);
+
+      assert (cp == (char *) dataset + total);
 
       /* Now we can determine whether on refill we have to create a
 	 new record or not.  */

Modified: fsf/trunk/libc/nscd/mem.c
==============================================================================
--- fsf/trunk/libc/nscd/mem.c (original)
+++ fsf/trunk/libc/nscd/mem.c Sun May 18 00:07:08 2008
@@ -24,6 +24,7 @@
 #include <inttypes.h>
 #include <libintl.h>
 #include <limits.h>
+#include <obstack.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -79,6 +80,7 @@
 markrange (BITMAP_T *mark, ref_t start, size_t len)
 {
   /* Adjust parameters for block alignment.  */
+  assert ((start & BLOCK_ALIGN_M1) == 0);
   start /= BLOCK_ALIGN;
   len = (len + BLOCK_ALIGN_M1) / BLOCK_ALIGN;
 
@@ -93,7 +95,7 @@
 	  return;
 	}
 
-      mark[elem++] |= 0xff << (start % BITS);
+      mark[elem++] |= ALLBITS << (start % BITS);
       len -= BITS - (start % BITS);
     }
 
@@ -130,14 +132,14 @@
   size_t stack_used = sizeof (bool) * db->head->module;
   if (__builtin_expect (stack_used > MAX_STACK_USE, 0))
     stack_used = 0;
-  size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1)
-			  / BITS) * sizeof (BITMAP_T);
-  if (memory_needed <= MAX_STACK_USE)
+  size_t nmark = (db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS;
+  size_t memory_needed = nmark * sizeof (BITMAP_T);
+  if (stack_used + memory_needed <= MAX_STACK_USE)
     {
       mark = (BITMAP_T *) alloca (memory_needed);
       mark_use_malloc = false;
       memset (mark, '\0', memory_needed);
-      stack_used = memory_needed;
+      stack_used += memory_needed;
     }
   else
     {
@@ -156,6 +158,7 @@
       he = alloca (db->head->nentries * sizeof (struct hashentry *));
       he_data = alloca (db->head->nentries * sizeof (struct hashentry *));
       he_use_malloc = false;
+      stack_used += memory_needed;
     }
   else
     {
@@ -212,11 +215,12 @@
       for (enum in_flight idx = IDX_result_data;
 	   idx < IDX_last && mrunp->block[idx].dbidx == db - dbs; ++idx)
 	{
-	 assert ((char *) mrunp->block[idx].blockaddr > db->data);
-	 assert ((char *) mrunp->block[idx].blockaddr
-		 + mrunp->block[0].blocklen <= db->data + db->memsize);
-	 markrange (mark, (char *) mrunp->block[idx].blockaddr -  db->data,
-		    mrunp->block[idx].blocklen);
+	  assert (mrunp->block[idx].blockoff >= 0);
+	  assert (mrunp->block[idx].blocklen < db->memsize);
+	  assert (mrunp->block[idx].blockoff
+		  + mrunp->block[0].blocklen <= db->memsize);
+	  markrange (mark, mrunp->block[idx].blockoff,
+		     mrunp->block[idx].blocklen);
 	}
 
       mrunp = mrunp->next;
@@ -232,7 +236,7 @@
   qsort (he, cnt, sizeof (struct hashentry *), sort_he);
 
   /* Determine the highest used address.  */
-  size_t high = sizeof (mark);
+  size_t high = nmark;
   while (high > 0 && mark[high - 1] == 0)
     --high;
 
@@ -303,6 +307,10 @@
     size_t size;
     struct moveinfo *next;
   } *moves = NULL;
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+  struct obstack ob;
+  obstack_init (&ob);
 
   while (byte < high)
     {
@@ -363,8 +371,14 @@
 	 displacement.  */
       ref_t disp = off_alloc - off_free;
 
-      struct moveinfo *new_move
-	= (struct moveinfo *) alloca (sizeof (*new_move));
+      struct moveinfo *new_move;
+      if (stack_used + sizeof (*new_move) <= MAX_STACK_USE)
+	{
+	  new_move = alloca (sizeof (*new_move));
+	  stack_used += sizeof (*new_move);
+	}
+      else
+	new_move = obstack_alloc (&ob, sizeof (*new_move));
       new_move->from = db->data + off_alloc;
       new_move->to = db->data + off_free;
       new_move->size = off_allocend - off_alloc;
@@ -524,6 +538,8 @@
     free (he);
   if (mark_use_malloc)
     free (mark);
+
+  obstack_free (&ob, NULL);
 }
 
 
@@ -589,15 +605,16 @@
     }
   else
     {
-      db->head->first_free += len;
-
-      db->last_alloc_failed = false;
-
       /* Remember that we have allocated this memory.  */
       assert (idx >= 0 && idx < IDX_last);
       mem_in_flight.block[idx].dbidx = db - dbs;
       mem_in_flight.block[idx].blocklen = len;
-      mem_in_flight.block[idx].blockaddr = res;
+      mem_in_flight.block[idx].blockoff = db->head->first_free;
+
+      db->head->first_free += len;
+
+      db->last_alloc_failed = false;
+
     }
 
   pthread_mutex_unlock (&db->memlock);

Modified: fsf/trunk/libc/nscd/nscd.h
==============================================================================
--- fsf/trunk/libc/nscd/nscd.h (original)
+++ fsf/trunk/libc/nscd/nscd.h Sun May 18 00:07:08 2008
@@ -197,7 +197,7 @@
   {
     int dbidx;
     nscd_ssize_t blocklen;
-    void *blockaddr;
+    nscd_ssize_t blockoff;
   } block[IDX_last];
 
   struct mem_in_flight *next;

Modified: fsf/trunk/libc/resolv/nss_dns/dns-host.c
==============================================================================
--- fsf/trunk/libc/resolv/nss_dns/dns-host.c (original)
+++ fsf/trunk/libc/resolv/nss_dns/dns-host.c Sun May 18 00:07:08 2008
@@ -990,6 +990,9 @@
   char *h_name = NULL;
   int h_namelen = 0;
 
+  if (ancount == 0)
+    return NSS_STATUS_NOTFOUND;
+
   while (ancount-- > 0 && cp < end_of_message && had_error == 0)
     {
       n = __ns_name_unpack (answer->buf, end_of_message, cp,
@@ -1164,12 +1167,15 @@
 {
   int first = 1;
 
-  enum nss_status status = gaih_getanswer_slice(answer1, anslen1, qname,
-						&pat, &buffer, &buflen,
-						errnop, h_errnop, ttlp,
-						&first);
+  enum nss_status status = NSS_STATUS_NOTFOUND;
+
+  if (anslen1 > 0)
+    status = gaih_getanswer_slice(answer1, anslen1, qname,
+				  &pat, &buffer, &buflen,
+				  errnop, h_errnop, ttlp,
+				  &first);
   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
-      && answer2 != NULL)
+      && answer2 != NULL && anslen2 > 0)
     status = gaih_getanswer_slice(answer2, anslen2, qname,
 				  &pat, &buffer, &buflen,
 				  errnop, h_errnop, ttlp, &first);

Modified: fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
==============================================================================
--- fsf/trunk/libc/sysdeps/posix/getaddrinfo.c (original)
+++ fsf/trunk/libc/sysdeps/posix/getaddrinfo.c Sun May 18 00:07:08 2008
@@ -660,7 +660,10 @@
 
 		  goto process_list;
 		}
-	      else if (err != 0 && __nss_not_use_nscd_hosts == 0)
+	      else if (err == 0)
+		/* The database contains a negative entry.  */
+		return 0;
+	      else if (__nss_not_use_nscd_hosts == 0)
 		{
 		  if (herrno == NETDB_INTERNAL && errno == ENOMEM)
 		    return -EAI_MEMORY;