summaryrefslogtreecommitdiff
path: root/nscd
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-10-10 21:00:50 +0000
committerJakub Jelinek <jakub@redhat.com>2007-10-10 21:00:50 +0000
commitfc2a4f5f837f259c239fbd15911f80ca8c6907e3 (patch)
tree2be478cfcb93051f657027d6fafd96778aa49317 /nscd
parent75cb5a0d471729d28a59b693441e2d527c9e962e (diff)
Updated to fedora-glibc-20071010T2047cvs/fedora-glibc-2_6_90-18
Diffstat (limited to 'nscd')
-rw-r--r--nscd/connections.c26
-rw-r--r--nscd/nscd_helper.c22
2 files changed, 39 insertions, 9 deletions
diff --git a/nscd/connections.c b/nscd/connections.c
index 72a6f3419d..89a1ea4967 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -379,7 +379,9 @@ verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
nscd_ssize_t he_cnt = 0;
for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
{
- ref_t work = head->array[cnt];
+ ref_t trail = head->array[cnt];
+ ref_t work = trail;
+ int tick = 0;
while (work != ENDREF)
{
@@ -438,6 +440,13 @@ verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
}
work = here->next;
+
+ if (work == trail)
+ /* A circular list, this must not happen. */
+ goto fail;
+ if (tick)
+ trail = ((struct hashentry *) (data + trail))->next;
+ tick = 1 - tick;
}
}
@@ -1285,14 +1294,15 @@ cannot change to old working directory: %s; disabling paranoia mode"),
/* Synchronize memory. */
for (int cnt = 0; cnt < lastdb; ++cnt)
- {
- /* Make sure nobody keeps using the database. */
- dbs[cnt].head->timestamp = 0;
+ if (!dbs[cnt].enabled)
+ {
+ /* Make sure nobody keeps using the database. */
+ dbs[cnt].head->timestamp = 0;
- if (dbs[cnt].persistent)
- // XXX async OK?
- msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
- }
+ if (dbs[cnt].persistent)
+ // XXX async OK?
+ msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
+ }
/* The preparations are done. */
execv ("/proc/self/exe", argv);
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 5f3d54efcf..6718d922f3 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -416,7 +416,10 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
size_t datasize = mapped->datasize;
- ref_t work = mapped->head->array[hash];
+ ref_t trail = mapped->head->array[hash];
+ ref_t work = trail;
+ int tick = 0;
+
while (work != ENDREF && work + sizeof (struct hashentry) <= datasize)
{
struct hashentry *here = (struct hashentry *) (mapped->data + work);
@@ -454,6 +457,23 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
}
work = here->next;
+ /* Prevent endless loops. This should never happen but perhaps
+ the database got corrupted, accidentally or deliberately. */
+ if (work == trail)
+ break;
+ if (tick)
+ {
+ struct hashentry *trailelem;
+ trailelem = (struct hashentry *) (mapped->data + trail);
+
+#ifndef _STRING_ARCH_unaligned
+ /* We have to redo the checks. Maybe the data changed. */
+ if ((uintptr_t) trailelem & (__alignof__ (*trailelem) - 1))
+ return NULL;
+#endif
+ trail = trailelem->next;
+ }
+ tick = 1 - tick;
}
return NULL;