+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.
/* 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.
{
/* 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)
{
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;
/* 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);
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
/* 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;
}