From 2fa26e646e1cfdba15d02ce3428ed72e93d73a09 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 15 Dec 2011 12:40:56 +0000 Subject: [PATCH] extra error checking in Bloom filter to check that the size of the file on disk corresponds to the expected size for the given filter --- src/include/gnunet_disk_lib.h | 13 +++++++++++++ src/util/container_bloomfilter.c | 23 ++++++++++++++++++++++- src/util/disk.c | 20 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 5f6a37840..d0a9dfdb7 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -368,6 +368,19 @@ struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm); + +/** + * Get the size of an open file. + * + * @param fh open file handle + * @param size where to write size of the file + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, + off_t *size); + + /** * Creates an interprocess channel * @param blocking creates an asynchronous pipe if set to GNUNET_NO diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index 31e777dc3..0349c32ac 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c @@ -456,6 +456,7 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, off_t pos; int i; size_t ui; + off_t fsize; GNUNET_assert (NULL != filename); if ((k == 0) || (size == 0)) @@ -481,6 +482,21 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, GNUNET_free (bf); return NULL; } + if (GNUNET_OK != + GNUNET_DISK_file_handle_size (bf->fh, &fsize)) + { + GNUNET_DISK_file_close (bf->fh); + GNUNET_free (bf); + return NULL; + } + if (fsize != size * 8LL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Size of file on disk is incorrect for this Bloom filter\n")); + GNUNET_DISK_file_close (bf->fh); + GNUNET_free (bf); + return NULL; + } bf->filename = GNUNET_strdup (filename); /* Alloc block */ bf->bitArray = GNUNET_malloc_large (size); @@ -499,7 +515,7 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, /* Read from the file what bits we can */ rbuff = GNUNET_malloc (BUFFSIZE); pos = 0; - while (pos < size * 8) + while (pos < size * 8LL) { int res; @@ -507,6 +523,11 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, if (res == -1) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "read", bf->filename); + GNUNET_free (rbuff); + GNUNET_free (bf->filename); + GNUNET_DISK_file_close (bf->fh); + GNUNET_free (bf); + return NULL; } if (res == 0) break; /* is ok! we just did not use that many bits yet */ diff --git a/src/util/disk.c b/src/util/disk.c index 2bdcf3262..ba5d159e4 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -205,6 +205,26 @@ GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h) } +/** + * Get the size of an open file. + * + * @param fh open file handle + * @param size where to write size of the file + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, + off_t *size) +{ + struct stat sbuf; + + if (0 != FSTAT (fh->fd, &sbuf)) + return GNUNET_SYSERR; + *size = sbuf.st_size; + return GNUNET_OK; +} + + /** * Move the read/write pointer in a file * -- 2.25.1