aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-08-19 09:50:22 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-08-19 09:56:14 +0300
commit64ef7e827406f91d31bffdcad9f4b8aaad1f874c (patch)
tree8eb3da77ef771507f07b68172e7af8cd3d8bd36c
parent4e23fa7b90b56408d480ba8c7556b190757ea2c7 (diff)
downloadgdbm-64ef7e827406f91d31bffdcad9f4b8aaad1f874c.tar.gz
gdbm-64ef7e827406f91d31bffdcad9f4b8aaad1f874c.tar.bz2
Fix directory entry validation.
Bug reported by Miroslav Lichvar and Marek Skalický * src/bucket.c (gdbm_dir_entry_valid_p): Fix lower limit for the allowed bucket address. Initial allocation of second block for the directory can be eventually returned to the available list when the directory is expanded during bucket splitting.
-rw-r--r--src/bucket.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/bucket.c b/src/bucket.c
index 0597965..3d267e2 100644
--- a/src/bucket.c
+++ b/src/bucket.c
@@ -33,49 +33,49 @@ _gdbm_new_bucket (GDBM_FILE dbf, hash_bucket *bucket, int bits)
/* Initialize the avail block. */
bucket->av_count = 0;
/* Set the information fields first. */
bucket->bucket_bits = bits;
bucket->count = 0;
/* Initialize all bucket elements. */
for (index = 0; index < dbf->header->bucket_elems; index++)
bucket->h_table[index].hash_value = -1;
}
/* Return true if the directory entry at DIR_INDEX can be considered
valid. This means that DIR_INDEX is in the valid range for addressing
the dir array, and the offset stored in dir[DIR_INDEX] points past
first two blocks in file. This does not necessarily mean that there's
a valid bucket or data block at that offset. All this implies is that
it is safe to use the offset for look up in the bucket cache and to
attempt to read a block at that offset. */
int
gdbm_dir_entry_valid_p (GDBM_FILE dbf, int dir_index)
{
return dir_index >= 0
&& dir_index < GDBM_DIR_COUNT (dbf)
- && dbf->dir[dir_index] >= 2*dbf->header->block_size;
+ && dbf->dir[dir_index] >= dbf->header->block_size;
}
/* Find a bucket for DBF that is pointed to by the bucket directory from
location DIR_INDEX. The bucket cache is first checked to see if it
is already in memory. If not, a bucket may be tossed to read the new
bucket. On success, the requested bucket becomes the "current" bucket
and dbf->bucket points to the correct bucket. On error, the current
bucket remains unchanged. */
int
_gdbm_get_bucket (GDBM_FILE dbf, int dir_index)
{
int rc;
off_t bucket_adr; /* The address of the correct hash bucket. */
off_t file_pos; /* The return address for lseek. */
int index; /* Loop index. */
if (!gdbm_dir_entry_valid_p (dbf, dir_index))
{
/* FIXME: negative caching? */
GDBM_SET_ERRNO (dbf, GDBM_BAD_DIR_ENTRY, TRUE);
return -1;
}

Return to:

Send suggestions and report system problems to the System administrator.