summaryrefslogtreecommitdiffstats
path: root/src/H5Fsuper_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Fsuper_cache.c')
-rw-r--r--src/H5Fsuper_cache.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c
index 5d9b628..467e287 100644
--- a/src/H5Fsuper_cache.c
+++ b/src/H5Fsuper_cache.c
@@ -433,6 +433,8 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
if (H5F__superblock_prefix_decode(sblock, &image, udata, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode file superblock prefix")
+ const uint8_t *image_end = image + len - 1;
+
/* Check for older version of superblock format */
if (sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
uint32_t status_flags; /* File status flags */
@@ -440,10 +442,18 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
unsigned snode_btree_k; /* B-tree symbol table internal node 'K' value */
unsigned chunk_btree_k; /* B-tree chunk internal node 'K' value */
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, 1, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Freespace version (hard-wired) */
if (HDF5_FREESPACE_VERSION != *image++)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, 1, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Root group version number (hard-wired) */
if (HDF5_OBJECTDIR_VERSION != *image++)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")
@@ -451,6 +461,10 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
/* Skip over reserved byte */
image++;
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, 1, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Shared header version number (hard-wired) */
if (HDF5_SHAREDHEADER_VERSION != *image++)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")
@@ -466,12 +480,20 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
/* Skip over reserved byte */
image++;
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, sizeof(uint16_t), image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Various B-tree sizes */
UINT16DECODE(image, sym_leaf_k);
if (sym_leaf_k == 0)
HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
udata->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, sizeof(uint16_t), image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Need 'get' call to set other array values */
UINT16DECODE(image, snode_btree_k);
if (snode_btree_k == 0)
@@ -483,6 +505,10 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
* for the indexed storage B-tree internal 'K' value later.
*/
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, sizeof(uint32_t), image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* File status flags (not really used yet) */
UINT32DECODE(image, status_flags);
HDassert(status_flags <= 255);
@@ -495,16 +521,29 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
* storage B-tree internal 'K' value
*/
if (sblock->super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, sizeof(uint16_t), image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
UINT16DECODE(image, chunk_btree_k);
/* Reserved bytes are present only in version 1 */
- if (sblock->super_vers == HDF5_SUPERBLOCK_VERSION_1)
+ if (sblock->super_vers == HDF5_SUPERBLOCK_VERSION_1) {
image += 2; /* reserved */
- } /* end if */
+
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, 1, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+ }
+ } /* end if */
else
chunk_btree_k = HDF5_BTREE_CHUNK_IK_DEF;
udata->btree_k[H5B_CHUNK_ID] = chunk_btree_k;
+ /* Check whether the image pointer will be out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, H5F_SIZEOF_ADDR(udata->f) * 4, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Remainder of "variable-sized" portion of superblock */
H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr /*out*/);
H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr /*out*/);
@@ -518,7 +557,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
"can't allocate space for root group symbol table entry")
/* decode the root group symbol table entry */
- if (H5G_ent_decode(udata->f, (const uint8_t **)&image, sblock->root_ent) < 0)
+ if (H5G_ent_decode(udata->f, (const uint8_t **)&image, sblock->root_ent, image_end) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")
/* Set the root group address to the correct value */
@@ -544,16 +583,23 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
/* Skip over size of file addresses (already decoded) */
image++;
udata->f->shared->sizeof_addr = sblock->sizeof_addr; /* Keep a local copy also */
-
/* Skip over size of file sizes (already decoded) */
image++;
udata->f->shared->sizeof_size = sblock->sizeof_size; /* Keep a local copy also */
+ /* Check whether the image pointer is out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, 1, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* File status flags (not really used yet) */
sblock->status_flags = *image++;
if (sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")
+ /* Check whether the image pointer will be out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, H5F_SIZEOF_ADDR(udata->f) * 4, image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Base, superblock extension, end of file & root group object header addresses */
H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr /*out*/);
H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr /*out*/);
@@ -562,6 +608,10 @@ H5F__cache_superblock_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUS
/* checksum verification already done in verify_chksum cb */
+ /* Check whether the image pointer will be out of bounds */
+ if (H5_IS_BUFFER_OVERFLOW(image, sizeof(uint32_t), image_end))
+ HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds")
+
/* Decode checksum */
UINT32DECODE(image, read_chksum);