diff options
author | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
---|---|---|
committer | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
commit | 0d02cb10e8dd8639b86450cf8e597cf5e2e09894 (patch) | |
tree | 0f2174db43a501b946f0600d1b91ae4117977b04 /nscd | |
parent | dfbbe67270efa9c03f9444d50d2f98a7a64622b4 (diff) | |
parent | 88ea382fda5af7717f85bb19837c9c99094f3df4 (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.h | 7 | ||||
-rw-r--r-- | nscd/nscd.c | 4 | ||||
-rw-r--r-- | nscd/nscd_getai.c | 5 | ||||
-rw-r--r-- | nscd/nscd_getgr_r.c | 5 | ||||
-rw-r--r-- | nscd/nscd_gethst_r.c | 6 | ||||
-rw-r--r-- | nscd/nscd_getpw_r.c | 5 | ||||
-rw-r--r-- | nscd/nscd_getserv_r.c | 5 | ||||
-rw-r--r-- | nscd/nscd_helper.c | 42 | ||||
-rw-r--r-- | nscd/nscd_initgroups.c | 5 | ||||
-rw-r--r-- | nscd/selinux.c | 13 | ||||
-rw-r--r-- | nscd/selinux.h | 5 |
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 |