diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | nscd/mem.c | 6 | ||||
-rw-r--r-- | nscd/nscd-client.h | 1 | ||||
-rw-r--r-- | nscd/nscd_helper.c | 17 |
4 files changed, 27 insertions, 9 deletions
@@ -1,3 +1,15 @@ +2006-10-02 Jakub Jelinek <jakub@redhat.com> + + * nscd/mem.c (mempool_alloc): Round array size to 16 bytes + in oldtotal and newtotal calculation. + * nscd/nscd-client.h (struct mapped_database): Add datasize + field. + * nscd/nscd_helper.c (get_mapping): Initialize datasize field. + (__nscd_get_map_ref): Get a new mapping even if mapping's data_size + increased. + (__nscd_cache_search): Add checks to make sure we never reference + data beyond the current mapping. + 2006-10-02 Dmitry V. Levin <ldv@altlinux.org> * io/fts.c (fts_close): Remove redundant checks. @@ -1,5 +1,5 @@ /* Cache memory handling. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -480,12 +480,12 @@ mempool_alloc (struct database_dyn *db, size_t len) { /* Try to resize the database. Grow size of 1/8th. */ size_t oldtotal = (sizeof (struct database_pers_head) - + db->head->module * sizeof (ref_t) + + roundup (db->head->module * sizeof (ref_t), ALIGN) + db->head->data_size); size_t new_data_size = (db->head->data_size + MAX (2 * len, db->head->data_size / 8)); size_t newtotal = (sizeof (struct database_pers_head) - + db->head->module * sizeof (ref_t) + + roundup (db->head->module * sizeof (ref_t), ALIGN) + new_data_size); if (newtotal > db->max_db_size) { diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h index 440697f..0fd2d9f 100644 --- a/nscd/nscd-client.h +++ b/nscd/nscd-client.h @@ -258,6 +258,7 @@ struct mapped_database const char *data; size_t mapsize; int counter; /* > 0 indicates it is usable. */ + size_t datasize; }; #define NO_MAPPING ((struct mapped_database *) -1l) diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c index 1dfe746..7c45981 100644 --- a/nscd/nscd_helper.c +++ b/nscd/nscd_helper.c @@ -290,6 +290,7 @@ get_mapping (request_type type, const char *key, newp->data = ((char *) mapping + head.header_size + roundup (head.module * sizeof (ref_t), ALIGN)); newp->mapsize = size; + newp->datasize = head.data_size; /* Set counter to 1 to show it is usable. */ newp->counter = 1; @@ -340,7 +341,8 @@ __nscd_get_map_ref (request_type type, const char *name, /* If not mapped or timestamp not updated, request new map. */ if (cur == NULL || (cur->head->nscd_certainly_running == 0 - && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL))) + && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL)) + || cur->head->data_size > cur->datasize) cur = get_mapping (type, name, (struct mapped_database **) &mapptr->mapped); @@ -365,14 +367,18 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen, const struct mapped_database *mapped) { unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module; + size_t datasize = mapped->datasize; ref_t work = mapped->head->array[hash]; - while (work != ENDREF) + while (work != ENDREF && work + sizeof (struct hashentry) <= datasize) { struct hashentry *here = (struct hashentry *) (mapped->data + work); - if (type == here->type && keylen == here->len - && memcmp (key, mapped->data + here->key, keylen) == 0) + if (type == here->type + && keylen == here->len + && here->key + here->len <= 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 @@ -380,8 +386,7 @@ __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 && ((char *) dh + dh->allocsize - <= (char *) mapped->head + mapped->mapsize)) + if (dh->usable && here->packet + dh->allocsize <= datasize) return dh; } |