summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-05-18 10:56:45 +0000
committerJakub Jelinek <jakub@redhat.com>2008-05-18 10:56:45 +0000
commit21032d9230e840a1f8b89d43e1e8d63ccf7c6eae (patch)
tree4d32b089580a63a332024e526938eb40613e7b27
parent4681f435969ca9806da160d3ae564668ddfecfe2 (diff)
Updated to fedora-glibc-20080518T1017cvs/fedora-glibc-2_8_90-3
-rw-r--r--ChangeLog30
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in10
-rw-r--r--nscd/aicache.c37
-rw-r--r--nscd/mem.c53
-rw-r--r--nscd/nscd.h2
-rw-r--r--resolv/nss_dns/dns-host.c16
-rw-r--r--sysdeps/posix/getaddrinfo.c5
8 files changed, 108 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index abca0a60d2..671ec52f3f 100644
--- 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.
@@ -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@redhat.com>
diff --git a/fedora/branch.mk b/fedora/branch.mk
index ba57c390b3..c88650ca1d 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -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
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index b46ffdb70d..648e8eba09 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -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)
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 918efc9f39..7ae5a1645c 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -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)
diff --git a/nscd/mem.c b/nscd/mem.c
index 14928d633c..96ff03f0df 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -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);
diff --git a/nscd/nscd.h b/nscd/nscd.h
index 66813e7480..b024017fd4 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -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;
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index c52f9f7f84..d998ebf4f5 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -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);
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 2515d23c26..5c82b5274a 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -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;