Updated to fedora-glibc-20080518T1017 fedora-glibc-2_8_90-3
authorjakub <jakub>
Sun, 18 May 2008 10:56:44 +0000 (10:56 +0000)
committerjakub <jakub>
Sun, 18 May 2008 10:56:44 +0000 (10:56 +0000)
ChangeLog
fedora/branch.mk
fedora/glibc.spec.in
nscd/aicache.c
nscd/mem.c
nscd/nscd.h
resolv/nss_dns/dns-host.c
sysdeps/posix/getaddrinfo.c

index abca0a6..671ec52 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2008-05-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * 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@redhat.com>
 
        * string/strcasestr.c (CMP_FUNC): Use __strncasecmp, not strncasecmp.
        * 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@redhat.com>
 
index ba57c39..c88650c 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2008-05-16 21:52 UTC
-fedora-sync-tag := fedora-glibc-20080516T2152
+fedora-sync-date := 2008-05-18 10:17 UTC
+fedora-sync-tag := fedora-glibc-20080518T1017
index b46ffdb..648e8eb 100644 (file)
@@ -19,7 +19,7 @@
 Summary: The GNU libc libraries
 Name: glibc
 Version: @glibcversion@
-Release: 2
+Release: 3
 # GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
 # Things that are linked directly into dynamically linked programs
 # and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -281,8 +281,8 @@ GCC="gcc -m64"
 GXX="g++ -m64"
 %endif
 
-BuildFlags="$BuildFlags -DNDEBUG=1 -fasynchronous-unwind-tables"
-#BuildFlags="$BuildFlags -fasynchronous-unwind-tables"
+#BuildFlags="$BuildFlags -DNDEBUG=1 -fasynchronous-unwind-tables"
+BuildFlags="$BuildFlags -fasynchronous-unwind-tables"
 EnableKernel="--enable-kernel=%{enablekernel}"
 echo "$GCC" > Gcc
 AddOns=`echo */configure | sed -e 's!/configure!!g;s!\(linuxthreads\|nptl\|rtkaio\|powerpc-cpu\)\( \|$\)!!g;s! \+$!!;s! !,!g;s!^!,!;/^,\*$/d'`
@@ -976,6 +976,10 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Sun May 18 2008 Jakub Jelinek <jakub@redhat.com> 2.8.90-3
+- getaddrinfo and nscd fixes
+- reenable assertion checking in rawhide
+
 * Fri May 16 2008 Jakub Jelinek <jakub@redhat.com> 2.8.90-2
 - fix getaddrinfo (#446801, #446808)
 
index 918efc9..7ae5a16 100644 (file)
@@ -114,7 +114,6 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
   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 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
       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 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
          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 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
          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 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
            }
 
          /* 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 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
            }
 
          /* 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)
@@ -411,6 +410,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
 
       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.  */
       if (he != NULL)
index 14928d6..96ff03f 100644 (file)
@@ -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 @@ static void
 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 @@ markrange (BITMAP_T *mark, ref_t start, size_t len)
          return;
        }
 
-      mark[elem++] |= 0xff << (start % BITS);
+      mark[elem++] |= ALLBITS << (start % BITS);
       len -= BITS - (start % BITS);
     }
 
@@ -130,14 +132,14 @@ gc (struct database_dyn *db)
   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 @@ gc (struct database_dyn *db)
       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 @@ gc (struct database_dyn *db)
       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 @@ gc (struct database_dyn *db)
   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 @@ gc (struct database_dyn *db)
     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 @@ gc (struct database_dyn *db)
         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 @@ gc (struct database_dyn *db)
     free (he);
   if (mark_use_malloc)
     free (mark);
+
+  obstack_free (&ob, NULL);
 }
 
 
@@ -589,15 +605,16 @@ mempool_alloc (struct database_dyn *db, size_t len, enum in_flight idx)
     }
   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);
index 66813e7..b024017 100644 (file)
@@ -197,7 +197,7 @@ extern __thread struct mem_in_flight
   {
     int dbidx;
     nscd_ssize_t blocklen;
-    void *blockaddr;
+    nscd_ssize_t blockoff;
   } block[IDX_last];
 
   struct mem_in_flight *next;
index c52f9f7..d998ebf 100644 (file)
@@ -990,6 +990,9 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
   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 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
 {
   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);
index 2515d23..5c82b52 100644 (file)
@@ -660,7 +660,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
                  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;