summary refs log tree commit diff
path: root/nscd/nscd_helper.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-01-31 09:14:21 +0000
committerJakub Jelinek <jakub@redhat.com>2007-01-31 09:14:21 +0000
commit1a77d37f9228d51d727f1caff2689137785232b9 (patch)
treed59b0c6fe37e90d5fa0cb1d2ce7e795521ac53cb /nscd/nscd_helper.c
parentee3142006a497a5216aef39ea8277a1c313b9747 (diff)
downloadglibc-1a77d37f9228d51d727f1caff2689137785232b9.tar.gz
glibc-1a77d37f9228d51d727f1caff2689137785232b9.tar.xz
glibc-1a77d37f9228d51d727f1caff2689137785232b9.zip
* nscd/nscd-client.h (__nscd_cache_search): Remove const qualifier
from return value. 
* nscd/nscd_helper.c: Include string.h. 
(__nscd_cache_search): Remove const qualifier from return value. 
On strict alignment architectures check hash entry and data head 
alignment. 
* nscd/nscd_getpw_r.c (nscd_getpw_r): Don't crash or fail because 
mmapped data during GC cycle contains garbage.  If 
__nscd_drop_map_ref fails, decrement mapped->counter when returning 
error or if retrying with NO_MAPPING, only __nscd_unmap if counter 
dropped to 0. 
* nscd/nscd_getgr_r.c (nscd_getgr_r): Likewise. 
* nscd/nscd_initgroups.c (__nscd_getgrouplist): Likewise. 
* nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise. 
* nscd/nscd_getai.c (__nscd_getai): Likewise. 
* nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
2007-01-31  Jakub Jelinek  <jakub@redhat.com>

	* nscd/nscd-client.h (__nscd_cache_search): Remove const qualifier
	from return value.
	* nscd/nscd_helper.c: Include string.h.
	(__nscd_cache_search): Remove const qualifier from return value.
	On strict alignment architectures check hash entry and data head
	alignment.
	* nscd/nscd_getpw_r.c (nscd_getpw_r): Don't crash or fail because
	mmapped data during GC cycle contains garbage.  If
	__nscd_drop_map_ref fails, decrement mapped->counter when returning
	error or if retrying with NO_MAPPING, only __nscd_unmap if counter
	dropped to 0.
	* nscd/nscd_getgr_r.c (nscd_getgr_r): Likewise.
	* nscd/nscd_initgroups.c (__nscd_getgrouplist): Likewise.
	* nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise.
	* nscd/nscd_getai.c (__nscd_getai): Likewise.
	* nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
Diffstat (limited to 'nscd/nscd_helper.c')
-rw-r--r--nscd/nscd_helper.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 7c45981586..336adfee89 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002,2003,2004,2005,2006,2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -21,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
@@ -362,7 +364,10 @@ __nscd_get_map_ref (request_type type, const char *name,
 }
 
 
-const struct datahead *
+/* Don't return const struct datahead *, as eventhough the record
+   is normally constant, it can change arbitrarily during nscd
+   garbage collection.  */
+struct datahead *
 __nscd_cache_search (request_type type, const char *key, size_t keylen,
 		     const struct mapped_database *mapped)
 {
@@ -374,16 +379,32 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
     {
       struct hashentry *here = (struct hashentry *) (mapped->data + work);
 
+#ifndef _STRING_ARCH_unaligned
+      /* Although during garbage collection when moving struct hashentry
+	 records around we first copy from old to new location and then
+	 adjust pointer from previous hashentry to it, there is no barrier
+	 between those memory writes.  It is very unlikely to hit it,
+	 so check alignment only if a misaligned load can crash the
+	 application.  */
+      if ((uintptr_t) here & (__alignof__ (*here) - 1))
+	return NULL;
+#endif
+
       if (type == here->type
 	  && keylen == here->len
-	  && here->key + here->len <= datasize
+	  && here->key + keylen <= datasize
 	  && memcmp (key, mapped->data + here->key, keylen) == 0
 	  && here->packet + sizeof (struct datahead) <= datasize)
 	{
 	  /* We found the entry.  Increment the appropriate counter.  */
-	  const struct datahead *dh
+	  struct datahead *dh
 	    = (struct datahead *) (mapped->data + here->packet);
 
+#ifndef _STRING_ARCH_unaligned
+	  if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
+	    return NULL;
+#endif
+
 	  /* See whether we must ignore the entry or whether something
 	     is wrong because garbage collection is in progress.  */
 	  if (dh->usable && here->packet + dh->allocsize <= datasize)