summaryrefslogtreecommitdiff
path: root/nscd
diff options
context:
space:
mode:
authorAndreas Schwab <aschwab@redhat.com>2009-06-10 14:04:22 +0200
committerAndreas Schwab <aschwab@redhat.com>2009-06-10 14:04:22 +0200
commit0d02cb10e8dd8639b86450cf8e597cf5e2e09894 (patch)
tree0f2174db43a501b946f0600d1b91ae4117977b04 /nscd
parentdfbbe67270efa9c03f9444d50d2f98a7a64622b4 (diff)
parent88ea382fda5af7717f85bb19837c9c99094f3df4 (diff)
Merge commit 'origin/master' into fedora/master
Conflicts: ChangeLog sysdeps/unix/sysv/linux/i386/sysconf.c sysdeps/x86_64/cacheinfo.c version.h
Diffstat (limited to 'nscd')
-rw-r--r--nscd/nscd-client.h7
-rw-r--r--nscd/nscd.c4
-rw-r--r--nscd/nscd_getai.c5
-rw-r--r--nscd/nscd_getgr_r.c5
-rw-r--r--nscd/nscd_gethst_r.c6
-rw-r--r--nscd/nscd_getpw_r.c5
-rw-r--r--nscd/nscd_getserv_r.c5
-rw-r--r--nscd/nscd_helper.c42
-rw-r--r--nscd/nscd_initgroups.c5
-rw-r--r--nscd/selinux.c13
-rw-r--r--nscd/selinux.h5
11 files changed, 57 insertions, 45 deletions
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index 3c9688fd30..c6c09cbddd 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007
+/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -44,7 +44,7 @@
/* Path for the configuration file. */
#define _PATH_NSCDCONF "/etc/nscd.conf"
-/* Maximu allowed length for the key. */
+/* Maximum allowed length for the key. */
#define MAXKEYLEN 1024
@@ -329,7 +329,8 @@ static inline int __nscd_drop_map_ref (struct mapped_database *map,
extern struct datahead *__nscd_cache_search (request_type type,
const char *key,
size_t keylen,
- const struct mapped_database *mapped);
+ const struct mapped_database *mapped,
+ size_t datalen);
/* Wrappers around read, readv and write that only read/write less than LEN
bytes on error or EOF. */
diff --git a/nscd/nscd.c b/nscd/nscd.c
index 3265ea8973..b9035f2131 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -488,10 +488,6 @@ termination_handler (int signum)
msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
}
- /* Shutdown the SELinux AVC. */
- if (selinux_enabled)
- nscd_avc_destroy ();
-
_exit (EXIT_SUCCESS);
}
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index 674a5e7514..d1c5cd14e9 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -75,7 +76,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
if (mapped != NO_MAPPING)
{
struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
- mapped);
+ mapped, sizeof ai_resp);
if (found != NULL)
{
respdata = (char *) (&found->data[0].aidata + 1);
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index b84b06b3ce..c2d204c3c8 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2000, 2002-2005, 2006, 2007
+/* Copyright (C) 1998-2000, 2002-2005, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -107,7 +107,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
if (mapped != NO_MAPPING)
{
- struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped,
+ sizeof gr_resp);
if (found != NULL)
{
len = (const uint32_t *) (&found->data[0].grdata + 1);
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index aea8288594..70631fa961 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -137,7 +138,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
if (mapped != NO_MAPPING)
{
/* No const qualifier, as it can change during garbage collection. */
- struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped,
+ sizeof hst_resp);
if (found != NULL)
{
h_name = (char *) (&found->data[0].hstdata + 1);
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index 21f792bb4e..8a4449d186 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2003, 2004, 2005, 2007
+/* Copyright (C) 1998, 1999, 2003, 2004, 2005, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -104,7 +104,8 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
if (mapped != NO_MAPPING)
{
- struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped,
+ sizeof pw_resp);
if (found != NULL)
{
pw_name = (const char *) (&found->data[0].pwdata + 1);
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
index b1ad7e2e43..dce4165482 100644
--- a/nscd/nscd_getserv_r.c
+++ b/nscd/nscd_getserv_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
@@ -104,7 +104,8 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
if (mapped != NO_MAPPING)
{
- struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped,
+ sizeof serv_resp);
if (found != NULL)
{
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index cd3fa24196..fe63f9a7fe 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
+#include <stddef.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@@ -467,23 +468,36 @@ __nscd_get_map_ref (request_type type, const char *name,
}
+/* Using sizeof (hashentry) is not always correct to determine the size of
+ the data structure as found in the nscd cache. The program could be
+ a 64-bit process and nscd could be a 32-bit process. In this case
+ sizeof (hashentry) would overestimate the size. The following is
+ the minimum size of such an entry, good enough for our tests here. */
+#define MINIMUM_HASHENTRY_SIZE \
+ (offsetof (struct hashentry, dellist) + sizeof (int32_t))
+
+
/* 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)
+ const struct mapped_database *mapped, size_t datalen)
{
unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
size_t datasize = mapped->datasize;
ref_t trail = mapped->head->array[hash];
+ trail = atomic_forced_read (trail);
ref_t work = trail;
+ size_t loop_cnt = datasize / (MINIMUM_HASHENTRY_SIZE
+ + offsetof (struct datahead, data) / 2);
int tick = 0;
- while (work != ENDREF && work + sizeof (struct hashentry) <= datasize)
+ while (work != ENDREF && work + MINIMUM_HASHENTRY_SIZE <= datasize)
{
struct hashentry *here = (struct hashentry *) (mapped->data + work);
+ ref_t here_key, here_packet;
#ifndef _STRING_ARCH_unaligned
/* Although during garbage collection when moving struct hashentry
@@ -498,13 +512,14 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
if (type == here->type
&& keylen == here->len
- && here->key + keylen <= datasize
- && memcmp (key, mapped->data + here->key, keylen) == 0
- && here->packet + sizeof (struct datahead) <= datasize)
+ && (here_key = atomic_forced_read (here->key)) + keylen <= datasize
+ && memcmp (key, mapped->data + here_key, keylen) == 0
+ && ((here_packet = atomic_forced_read (here->packet))
+ + sizeof (struct datahead) <= datasize))
{
/* We found the entry. Increment the appropriate counter. */
struct datahead *dh
- = (struct datahead *) (mapped->data + here->packet);
+ = (struct datahead *) (mapped->data + here_packet);
#ifndef _STRING_ARCH_unaligned
if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
@@ -513,14 +528,17 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
/* 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)
+ if (dh->usable
+ && here_packet + dh->allocsize <= datasize
+ && (here_packet + offsetof (struct datahead, data) + datalen
+ <= datasize))
return dh;
}
- work = here->next;
+ work = atomic_forced_read (here->next);
/* Prevent endless loops. This should never happen but perhaps
the database got corrupted, accidentally or deliberately. */
- if (work == trail)
+ if (work == trail || loop_cnt-- == 0)
break;
if (tick)
{
@@ -532,7 +550,11 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
if ((uintptr_t) trailelem & (__alignof__ (*trailelem) - 1))
return NULL;
#endif
- trail = trailelem->next;
+
+ if (trail + MINIMUM_HASHENTRY_SIZE > datasize)
+ return NULL;
+
+ trail = atomic_forced_read (trailelem->next);
}
tick = 1 - tick;
}
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index 866455a96c..5ff60c080c 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -55,7 +55,8 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
if (mapped != NO_MAPPING)
{
struct datahead *found = __nscd_cache_search (INITGROUPS, user,
- userlen, mapped);
+ userlen, mapped,
+ sizeof initgr_resp);
if (found != NULL)
{
respdata = (char *) (&found->data[0].initgrdata + 1);
diff --git a/nscd/selinux.c b/nscd/selinux.c
index 9a167ec14d..e07a454bf8 100644
--- a/nscd/selinux.c
+++ b/nscd/selinux.c
@@ -1,5 +1,5 @@
/* SELinux access controls for nscd.
- Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
@@ -418,15 +418,4 @@ nscd_avc_print_stats (struct avc_cache_stats *cstats)
cstats->cav_probes, cstats->cav_misses);
}
-
-/* Clean up the AVC before exiting. */
-void
-nscd_avc_destroy (void)
-{
- avc_destroy ();
-#ifdef HAVE_LIBAUDIT
- audit_close (audit_fd);
-#endif
-}
-
#endif /* HAVE_SELINUX */
diff --git a/nscd/selinux.h b/nscd/selinux.h
index 27afcd6e86..67d981bb06 100644
--- a/nscd/selinux.h
+++ b/nscd/selinux.h
@@ -1,5 +1,5 @@
/* Header for nscd SELinux access controls.
- Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
@@ -35,8 +35,6 @@ struct avc_cache_stats;
/* Initialize the userspace AVC. */
extern void nscd_avc_init (void);
-/* Destroy the userspace AVC. */
-extern void nscd_avc_destroy (void);
/* Determine if we are running on an SELinux kernel. */
extern void nscd_selinux_enabled (int *selinux_enabled);
/* Check if the client has permission for the request type. */
@@ -55,7 +53,6 @@ extern void install_real_capabilities (cap_t new_caps);
#else
# define selinux_enabled 0
# define nscd_avc_init() (void) 0
-# define nscd_avc_destroy() (void) 0
# define nscd_selinux_enabled(selinux_enabled) (void) 0
# define nscd_request_avc_has_perm(fd, req) 0
# define nscd_avc_cache_stats(cstats) (void) 0