From 9e765b9c43c89ad88971e8f0ecae7d610f2cd463 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 25 Apr 2023 10:02:30 -0700 Subject: Sanitize object header message decode functions (#2795) * Add buffer bounds checks * Convert asserts to real error handling to better detect broken files * General cleanup --- src/H5Obogus.c | 22 ++++----- src/H5Ocache_image.c | 37 +++++++------- src/H5Odrvinfo.c | 42 +++++++++------- src/H5Ofill.c | 104 +++++++++++++++++++++++----------------- src/H5Ofsinfo.c | 70 ++++++++++++++------------- src/H5Oginfo.c | 41 ++++++---------- src/H5Olayout.c | 133 +++++++++++++++++++++++++-------------------------- src/H5Olinfo.c | 15 ++---- src/H5Olink.c | 102 ++++++++++++++++++++------------------- src/H5Opline.c | 96 ++++++++++++++++++------------------- src/H5Orefcount.c | 35 +++++++------- src/H5Osdspace.c | 54 ++++++++++----------- src/H5Oshmesg.c | 31 +++++++----- src/H5Ostab.c | 34 ++++++------- 14 files changed, 407 insertions(+), 409 deletions(-) diff --git a/src/H5Obogus.c b/src/H5Obogus.c index 549c3e9..1b83ed1 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -13,8 +13,6 @@ /*------------------------------------------------------------------------- * * Created: H5Obogus.c - * Jan 21 2003 - * Quincey Koziol * * Purpose: "bogus" message. This message is guaranteed to never * be found in a valid HDF5 file and is only used to @@ -95,25 +93,20 @@ const H5O_msg_class_t H5O_MSG_BOGUS_INVALID[1] = {{ * Purpose: Decode a "bogus" message and return a pointer to a new * native message struct. * - * Return: Success: Ptr to new message in native struct. - * + * Return: Success: Pointer to new message in native struct * Failure: NULL - * - * Programmer: Quincey Koziol - * Jan 21 2003 - * *------------------------------------------------------------------------- */ static void * -H5O__bogus_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) +H5O__bogus_decode(H5F_t *f, H5O_t H5_ATTR_NDEBUG_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_bogus_t *mesg = NULL; - void *ret_value; /* Return value */ + const uint8_t *p_end = p + p_size - 1; + H5O_bogus_t *mesg = NULL; + void *ret_value; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); @@ -121,7 +114,8 @@ H5O__bogus_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS if (NULL == (mesg = (H5O_bogus_t *)H5MM_calloc(sizeof(H5O_bogus_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* decode */ + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); UINT32DECODE(p, mesg->u); /* Validate the bogus info */ diff --git a/src/H5Ocache_image.c b/src/H5Ocache_image.c index bd273ec..a06bebc 100644 --- a/src/H5Ocache_image.c +++ b/src/H5Ocache_image.c @@ -13,14 +13,12 @@ /*------------------------------------------------------------------------- * * Created: H5Ocache_image.c - * June 21, 2015 - * John Mainzer * * Purpose: A message indicating that a metadata cache image block - * of the indicated length exists at the specified offset - * in the HDF5 file. + * of the indicated length exists at the specified offset + * in the HDF5 file. * - * The mdci_msg only appears in the superblock extension. + * The mdci_msg only appears in the superblock extension * *------------------------------------------------------------------------- */ @@ -79,30 +77,28 @@ H5FL_DEFINE(H5O_mdci_t); * Function: H5O__mdci_decode * * Purpose: Decode a metadata cache image message and return a - * pointer to a newly allocated H5O_mdci_t struct. - * - * Return: Success: Ptr to new message in native struct. - * Failure: NULL - * - * Programmer: John Mainzer - * 6/22/15 + * pointer to a newly allocated H5O_mdci_t struct. * + * Return: Success: Pointer to new message in native struct + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_mdci_t *mesg; /* Native message */ - void *ret_value = NULL; /* Return value */ + H5O_mdci_t *mesg = NULL; /* New cache image message */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* Sanity check */ HDassert(f); HDassert(p); /* Version of message */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); if (*p++ != H5O_MDCI_VERSION_0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") @@ -111,14 +107,21 @@ H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for metadata cache image message") - /* Decode */ + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(mesg->addr)); + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, mesg->size); /* Set return value */ ret_value = (void *)mesg; done: + if (!ret_value && mesg) + H5FL_FREE(H5O_mdci_t, mesg); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__mdci_decode() */ diff --git a/src/H5Odrvinfo.c b/src/H5Odrvinfo.c index 923856f..53de66d 100644 --- a/src/H5Odrvinfo.c +++ b/src/H5Odrvinfo.c @@ -60,34 +60,32 @@ const H5O_msg_class_t H5O_MSG_DRVINFO[1] = {{ #define H5O_DRVINFO_VERSION 0 /*------------------------------------------------------------------------- - * Function: H5O__drvinfo_decode + * Function: H5O__drvinfo_decode * - * Purpose: Decode a shared message table message and return a pointer + * Purpose: Decode a shared message table message and return a pointer * to a newly allocated H5O_drvinfo_t struct. * - * Return: Success: Ptr to new message in native struct. - * Failure: NULL - * - * Programmer: Quincey Koziol - * Mar 1, 2007 - * + * Return: Success: Pointer to new message in native struct + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, - unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, - size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, + const uint8_t *p) { - H5O_drvinfo_t *mesg; /* Native message */ - void *ret_value = NULL; /* Return value */ + H5O_drvinfo_t *mesg = NULL; /* Native message */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* Sanity check */ HDassert(f); HDassert(p); /* Version of message */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); if (*p++ != H5O_DRVINFO_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") @@ -96,27 +94,37 @@ H5O__drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message") /* Retrieve driver name */ + if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5MM_memcpy(mesg->name, p, 8); mesg->name[8] = '\0'; p += 8; /* Decode buffer size */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); UINT16DECODE(p, mesg->len); - HDassert(mesg->len); + if (0 == mesg->len) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "message length can't be zero"); /* Allocate space for buffer */ - if (NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) { - mesg = (H5O_drvinfo_t *)H5MM_xfree(mesg); + if (NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer") - } /* end if */ /* Copy encoded driver info into buffer */ + if (H5_IS_BUFFER_OVERFLOW(p, mesg->len, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5MM_memcpy(mesg->buf, p, mesg->len); /* Set return value */ ret_value = (void *)mesg; done: + if (!ret_value && mesg) { + H5MM_xfree(mesg->buf); + H5MM_xfree(mesg); + } + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__drvinfo_decode() */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 45877d2..7b789bc 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -10,11 +10,9 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Programmer: Robb Matzke - * Wednesday, September 30, 1998 - * +/* * Purpose: The fill message indicates a bit pattern to use for - * uninitialized data points of a dataset. + * uninitialized data points of a dataset. */ #include "H5Omodule.h" /* This source code file is part of the H5O module */ @@ -179,16 +177,12 @@ H5FL_BLK_EXTERN(type_conv); /*------------------------------------------------------------------------- * Function: H5O__fill_new_decode * - * Purpose: Decode a new fill value message. The new fill value - * message is fill value plus space allocation time and - * fill value writing time and whether fill value is defined. - * - * Return: Success: Ptr to new message in native struct. - * Failure: NULL - * - * Programmer: Raymond Lu - * Feb 26, 2002 + * Purpose: Decode a new fill value message. The new fill value + * message is fill value plus space allocation time and + * fill value writing time and whether fill value is defined. * + * Return: Success: Pointer to new message in native struct + * Failure: NULL *------------------------------------------------------------------------- */ static void * @@ -209,12 +203,21 @@ H5O__fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message") /* Version */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); fill->version = *p++; if (fill->version < H5O_FILL_VERSION_1 || fill->version > H5O_FILL_VERSION_LATEST) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for fill value message") /* Decode each version */ if (fill->version < H5O_FILL_VERSION_3) { + + /* Versions 1 & 2 */ + + /* Buffer size check for the next three bytes */ + if (H5_IS_BUFFER_OVERFLOW(p, 3, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + /* Space allocation time */ fill->alloc_time = (H5D_alloc_time_t)*p++; @@ -226,26 +229,34 @@ H5O__fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, /* Only decode fill value information if one is defined */ if (fill->fill_defined) { + + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); INT32DECODE(p, fill->size); + if (fill->size > 0) { H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); - /* Ensure that fill size doesn't exceed buffer size, due to possible data corruption */ - if (p + fill->size - 1 > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "fill size exceeds buffer size") + if (H5_IS_BUFFER_OVERFLOW(p, fill->size, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); if (NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") H5MM_memcpy(fill->buf, p, (size_t)fill->size); - } /* end if */ - } /* end if */ + } + } else - fill->size = (-1); - } /* end if */ + fill->size = -1; + } else { + + /* Version 3 */ + unsigned flags; /* Status flags */ /* Flags */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); flags = *p++; /* Check for unknown flags */ @@ -261,39 +272,45 @@ H5O__fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, /* Check for undefined fill value */ if (flags & H5O_FILL_FLAG_UNDEFINED_VALUE) { - /* Sanity check */ - HDassert(!(flags & H5O_FILL_FLAG_HAVE_VALUE)); + + if (flags & (unsigned)~H5O_FILL_FLAG_HAVE_VALUE) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "have value and undefined value flags both set") /* Set value for "undefined" fill value */ - fill->size = (-1); - } /* end if */ + fill->size = -1; + } else if (flags & H5O_FILL_FLAG_HAVE_VALUE) { /* Fill value size */ + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); UINT32DECODE(p, fill->size); /* Fill value */ H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); + + if (H5_IS_BUFFER_OVERFLOW(p, fill->size, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + if (NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") H5MM_memcpy(fill->buf, p, (size_t)fill->size); /* Set the "defined" flag */ fill->fill_defined = TRUE; - } /* end else */ + } else /* Set the "defined" flag */ fill->fill_defined = TRUE; - } /* end else */ + } /* Set return value */ ret_value = (void *)fill; done: if (!ret_value && fill) { - if (fill->buf) - H5MM_xfree(fill->buf); + H5MM_xfree(fill->buf); fill = H5FL_FREE(H5O_fill_t, fill); - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__fill_new_decode() */ @@ -301,14 +318,10 @@ done: /*------------------------------------------------------------------------- * Function: H5O__fill_old_decode * - * Purpose: Decode an old fill value message. - * - * Return: Success: Ptr to new message in native struct. - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, September 30, 1998 + * Purpose: Decode an old fill value message * + * Return: Success: Pointer to new message in native struct + * Failure: NULL *------------------------------------------------------------------------- */ static void * @@ -335,6 +348,8 @@ H5O__fill_old_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flag fill->fill_time = H5D_FILL_TIME_IFSET; /* Fill value size */ + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); UINT32DECODE(p, fill->size); /* Only decode the fill value itself if there is one */ @@ -342,8 +357,8 @@ H5O__fill_old_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flag H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); /* Ensure that fill size doesn't exceed buffer size, due to possible data corruption */ - if (p + fill->size - 1 > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "fill size exceeds buffer size") + if (H5_IS_BUFFER_OVERFLOW(p, fill->size, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); /* Get the datatype message */ if ((exists = H5O_msg_exists_oh(open_oh, H5O_DTYPE_ID)) < 0) @@ -354,15 +369,15 @@ H5O__fill_old_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flag /* Verify size */ if (fill->size != (ssize_t)H5T_GET_SIZE(dt)) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "inconsistent fill value size") - } /* end if */ + } if (NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") H5MM_memcpy(fill->buf, p, (size_t)fill->size); fill->fill_defined = TRUE; - } /* end if */ + } else - fill->size = (-1); + fill->size = -1; /* Set return value */ ret_value = (void *)fill; @@ -372,10 +387,9 @@ done: H5O_msg_free(H5O_DTYPE_ID, dt); if (!ret_value && fill) { - if (fill->buf) - H5MM_xfree(fill->buf); - fill = H5FL_FREE(H5O_fill_t, fill); - } /* end if */ + H5MM_xfree(fill->buf); + H5FL_FREE(H5O_fill_t, fill); + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__fill_old_decode() */ diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c index b376606..eb4ed5e 100644 --- a/src/H5Ofsinfo.c +++ b/src/H5Ofsinfo.c @@ -13,10 +13,8 @@ /*------------------------------------------------------------------------- * * Created: H5Ofsinfo.c - * Feb 2009 - * Vailin Choi * - * Purpose: File space info message. + * Purpose: File space info message * *------------------------------------------------------------------------- */ @@ -82,27 +80,22 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); * * Purpose: Decode a message and return a pointer to a newly allocated one. * - * Return: Success: Ptr to new message in native form. - * Failure: NULL - * - * Programmer: Vailin Choi; Feb 2009 - * + * Return: Success: Pointer to new message in native form + * Failure: NULL *------------------------------------------------------------------------- */ - static void * H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_fsinfo_t *fsinfo = NULL; /* File space info message */ - H5F_mem_page_t ptype; /* Memory type for iteration */ - unsigned vers; /* message version */ - const uint8_t *p_end = p + p_size; - void *ret_value = NULL; /* Return value */ + H5O_fsinfo_t *fsinfo = NULL; /* File space info message */ + H5F_mem_page_t ptype; /* Memory type for iteration */ + unsigned vers; /* Message version */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); @@ -114,8 +107,8 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->fs_addr[ptype - 1] = HADDR_UNDEF; /* Version of message */ - if (p + 1 - 1 > p_end) /* one byte for version */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); vers = *p++; if (vers == H5O_FSINFO_VERSION_0) { @@ -129,8 +122,8 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->pgend_meta_thres = H5F_FILE_SPACE_PGEND_META_THRES; fsinfo->eoa_pre_fsm_fsalloc = HADDR_UNDEF; - if (p + 1 + H5F_SIZEOF_SIZE(f) - 1 > p_end) /* one byte for strategy + sizeof(f) */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") + if (H5_IS_BUFFER_OVERFLOW(p, 1 + H5F_sizeof_size(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); strategy = (H5F_file_space_type_t)*p++; /* File space strategy */ H5F_DECODE_LENGTH(f, p, threshold); /* Free-space section threshold */ @@ -143,9 +136,9 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU if (HADDR_UNDEF == (fsinfo->eoa_pre_fsm_fsalloc = H5F_get_eoa(f, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file size") for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) { - if (p + H5_SIZEOF_HADDR_T > p_end) - HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, - "ran off end of input buffer while decoding") + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, + "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(fsinfo->fs_addr[type - 1])); } break; @@ -167,32 +160,43 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5F_FILE_SPACE_DEFAULT: default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file space strategy") - } /* end switch */ + } fsinfo->version = H5O_FSINFO_VERSION_1; fsinfo->mapped = TRUE; } else { - HDassert(vers >= H5O_FSINFO_VERSION_1); + if (vers < H5O_FSINFO_VERSION_1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "bad version number") fsinfo->version = vers; - /* strategy (1) + persist (1) + sizeof(f) + sizeof(f) + pgend_meta_thres (2) + sizeofaddr(f) */ - if (p + 1 + 1 + 2 * H5F_SIZEOF_SIZE(f) + 2 + H5F_SIZEOF_ADDR(f) - 1 > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") + if (H5_IS_BUFFER_OVERFLOW(p, 1 + 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); fsinfo->strategy = (H5F_fspace_strategy_t)*p++; /* File space strategy */ fsinfo->persist = *p++; /* Free-space persist or not */ - H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* Free-space section threshold */ + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* Free-space section threshold */ + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, fsinfo->page_size); /* File space page size */ - UINT16DECODE(p, fsinfo->pgend_meta_thres); /* Page end metadata threshold */ + + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, fsinfo->pgend_meta_thres); /* Page end metadata threshold */ + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(fsinfo->eoa_pre_fsm_fsalloc)); /* EOA before free-space header and section info */ /* Decode addresses of free space managers, if persisting */ if (fsinfo->persist) for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) { - if (p + H5F_SIZEOF_SIZE(f) - 1 > p_end) /* one byte for sizeof(f) */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(fsinfo->fs_addr[ptype - 1])); } fsinfo->mapped = FALSE; @@ -202,8 +206,8 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU ret_value = fsinfo; done: - if (ret_value == NULL && fsinfo != NULL) - fsinfo = H5FL_FREE(H5O_fsinfo_t, fsinfo); + if (!ret_value && fsinfo) + H5FL_FREE(H5O_fsinfo_t, fsinfo); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__fsinfo_decode() */ diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c index 54d8b8b..df45e53 100644 --- a/src/H5Oginfo.c +++ b/src/H5Oginfo.c @@ -13,10 +13,8 @@ /*------------------------------------------------------------------------- * * Created: H5Oginfo.c - * Aug 23 2005 - * Quincey Koziol * - * Purpose: Group Information messages. + * Purpose: Group Information messages * *------------------------------------------------------------------------- */ @@ -78,34 +76,24 @@ H5FL_DEFINE_STATIC(H5O_ginfo_t); * Purpose: Decode a message and return a pointer to * a newly allocated one. * - * Return: Success: Ptr to new message in native order. - * - * Failure: NULL - * - * Programmer: Quincey Koziol - * Aug 30 2005 - * + * Return: Success: Pointer to new message in native order + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */ - unsigned char flags; /* Flags for encoding group info */ - void *ret_value = NULL; /* Return value */ + H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */ + unsigned char flags; /* Flags for encoding group info */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ + HDassert(f); HDassert(p); - if (p_size == 0) - HGOTO_ERROR(H5E_OHDR, H5E_ARGS, NULL, "size of given ginfo was zero") - - /* Points at last valid byte in buffer */ - const uint8_t *p_end = p + p_size - 1; - /* Version of message */ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") @@ -132,11 +120,11 @@ H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, ginfo->max_compact) UINT16DECODE(p, ginfo->min_dense) - } /* end if */ + } else { ginfo->max_compact = H5G_CRT_GINFO_MAX_COMPACT; ginfo->min_dense = H5G_CRT_GINFO_MIN_DENSE; - } /* end else */ + } /* Get the estimated # of entries & name lengths */ if (ginfo->store_est_entry_info) { @@ -144,19 +132,18 @@ H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, ginfo->est_num_entries) UINT16DECODE(p, ginfo->est_name_len) - } /* end if */ + } else { ginfo->est_num_entries = H5G_CRT_GINFO_EST_NUM_ENTRIES; ginfo->est_name_len = H5G_CRT_GINFO_EST_NAME_LEN; - } /* end if */ + } /* Set return value */ ret_value = ginfo; done: - if (ret_value == NULL) - if (ginfo != NULL) - ginfo = H5FL_FREE(H5O_ginfo_t, ginfo); + if (!ret_value && ginfo) + H5FL_FREE(H5O_ginfo_t, ginfo); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__ginfo_decode() */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index a58fc0c..f784f24 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -10,10 +10,8 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Programmer: Robb Matzke - * Wednesday, October 8, 1997 - * - * Purpose: Messages related to data layout. +/* + * Purpose: Messages related to data layout */ #define H5D_FRIEND /*suppress error about including H5Dpkg */ @@ -78,13 +76,8 @@ H5FL_DEFINE(H5O_layout_t); * Purpose: Decode an data layout message and return a pointer to a * new one created with malloc(). * - * Return: Success: Ptr to new message in native order. - * + * Return: Success: Pointer to new message in native order * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 8, 1997 - * *------------------------------------------------------------------------- */ static void * @@ -94,16 +87,13 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ H5O_layout_t *mesg = NULL; uint8_t *heap_block = NULL; - unsigned u; - void *ret_value = NULL; /* Return value */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); - /* decode */ if (NULL == (mesg = H5FL_CALLOC(H5O_layout_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "memory allocation failed") mesg->storage.type = H5D_LAYOUT_ERROR; @@ -144,33 +134,33 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU /* Address */ if (mesg->type == H5D_CONTIGUOUS) { - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr)); /* Set the layout operations */ mesg->ops = H5D_LOPS_CONTIG; - } /* end if */ + } else if (mesg->type == H5D_CHUNKED) { - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr)); /* Set the layout operations */ mesg->ops = H5D_LOPS_CHUNK; - /* Set the chunk operations */ - /* (Only "btree" indexing type currently supported in this version) */ + /* Set the chunk operations + * (Only "btree" indexing type currently supported in this version) + */ mesg->storage.u.chunk.idx_type = H5D_CHUNK_IDX_BTREE; mesg->storage.u.chunk.ops = H5D_COPS_BTREE; - } /* end if */ - else { - /* Sanity check */ - HDassert(mesg->type == H5D_COMPACT); - + } + else if (mesg->type == H5D_COMPACT) { /* Set the layout operations */ mesg->ops = H5D_LOPS_COMPACT; - } /* end else */ + } + else + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid layout type") /* Read the size */ if (mesg->type != H5D_CHUNKED) { @@ -178,24 +168,24 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU * truncation of the dimension sizes when they were stored in this * version of the layout message. Compute the contiguous storage * size in the dataset code, where we've got the dataspace - * information available also. - QAK 5/26/04 + * information available also. */ - if (H5_IS_BUFFER_OVERFLOW(p, (ndims * sizeof(uint32_t)), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, (ndims * 4), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") p += ndims * sizeof(uint32_t); /* Skip over dimension sizes */ - } /* end if */ + } else { if (ndims < 2) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad dimensions for chunked storage") mesg->u.chunk.ndims = ndims; - if (H5_IS_BUFFER_OVERFLOW(p, (ndims * sizeof(uint32_t)), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, (ndims * 4), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") + for (unsigned u = 0; u < ndims; u++) { - for (u = 0; u < ndims; u++) { UINT32DECODE(p, mesg->u.chunk.dim[u]); - /* Just in case that something goes very wrong, such as file corruption. */ + /* Just in case that something goes very wrong, such as file corruption */ if (mesg->u.chunk.dim[u] == 0) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad chunk dimension value when parsing layout message - chunk dimension " @@ -204,12 +194,13 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU } /* Compute chunk size */ - for (u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < ndims; u++) + mesg->u.chunk.size = mesg->u.chunk.dim[0]; + for (unsigned u = 1; u < ndims; u++) mesg->u.chunk.size *= mesg->u.chunk.dim[u]; - } /* end if */ + } if (mesg->type == H5D_COMPACT) { - if (H5_IS_BUFFER_OVERFLOW(p, sizeof(uint32_t), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(p, mesg->storage.u.compact.size); @@ -223,9 +214,9 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU "memory allocation failed for compact data buffer") H5MM_memcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; - } /* end if */ - } /* end if */ - } /* end if */ + } + } + } else { /* Layout & storage class */ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) @@ -236,7 +227,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU switch (mesg->type) { case H5D_COMPACT: /* Compact data size */ - if (H5_IS_BUFFER_OVERFLOW(p, sizeof(uint16_t), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, mesg->storage.u.compact.size); @@ -254,7 +245,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU /* Compact data */ H5MM_memcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; - } /* end if */ + } /* Set the layout operations */ mesg->ops = H5D_LOPS_COMPACT; @@ -262,12 +253,12 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5D_CONTIGUOUS: /* Contiguous storage address */ - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr)); /* Contiguous storage size */ - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_SIZE(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_DECODE_LENGTH(f, p, mesg->storage.u.contig.size); @@ -292,17 +283,18 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad dimensions for chunked storage") /* B-tree address */ - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr)); - if (H5_IS_BUFFER_OVERFLOW(p, (mesg->u.chunk.ndims * sizeof(uint32_t)), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, (mesg->u.chunk.ndims * 4), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") /* Chunk dimensions */ - for (u = 0; u < mesg->u.chunk.ndims; u++) { + for (unsigned u = 0; u < mesg->u.chunk.ndims; u++) { + UINT32DECODE(p, mesg->u.chunk.dim[u]); /* Just in case that something goes very wrong, such as file corruption. */ @@ -311,17 +303,19 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU "bad chunk dimension value when parsing layout message - chunk " "dimension must be positive: mesg->u.chunk.dim[%u] = %u", u, mesg->u.chunk.dim[u]) - } /* end for */ + } /* Compute chunk size */ - for (u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++) + mesg->u.chunk.size = mesg->u.chunk.dim[0]; + for (unsigned u = 1; u < mesg->u.chunk.ndims; u++) mesg->u.chunk.size *= mesg->u.chunk.dim[u]; - /* Set the chunk operations */ - /* (Only "btree" indexing type supported with v3 of message format) */ + /* Set the chunk operations + * (Only "btree" indexing type supported with v3 of message format) + */ mesg->storage.u.chunk.idx_type = H5D_CHUNK_IDX_BTREE; mesg->storage.u.chunk.ops = H5D_COPS_BTREE; - } /* end if */ + } else { /* Get the chunked layout flags */ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) @@ -360,7 +354,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU "ran off end of input buffer while decoding") /* Chunk dimensions */ - for (u = 0; u < mesg->u.chunk.ndims; u++) { + for (unsigned u = 0; u < mesg->u.chunk.ndims; u++) { UINT64DECODE_VAR(p, mesg->u.chunk.dim[u], mesg->u.chunk.enc_bytes_per_dim); /* Just in case that something goes very wrong, such as file corruption. */ @@ -372,7 +366,8 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU } /* Compute chunk size */ - for (u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++) + mesg->u.chunk.size = mesg->u.chunk.dim[0]; + for (unsigned u = 1; u < mesg->u.chunk.ndims; u++) mesg->u.chunk.size *= mesg->u.chunk.dim[u]; /* Chunk index type */ @@ -397,12 +392,12 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5D_CHUNK_IDX_SINGLE: /* Single Chunk Index */ if (mesg->u.chunk.flags & H5O_LAYOUT_CHUNK_SINGLE_INDEX_WITH_FILTER) { - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_SIZE(f) + sizeof(uint32_t), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f) + 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_DECODE_LENGTH(f, p, mesg->storage.u.chunk.u.single.nbytes); UINT32DECODE(p, mesg->storage.u.chunk.u.single.filter_mask); - } /* end if */ + } /* Set the chunk operations */ mesg->storage.u.chunk.ops = H5D_COPS_SINGLE; @@ -475,7 +470,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU break; case H5D_CHUNK_IDX_BT2: /* v2 B-tree index */ - if (H5_IS_BUFFER_OVERFLOW(p, sizeof(uint32_t), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(p, mesg->u.chunk.u.btree2.cparam.node_size); @@ -511,14 +506,14 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5D_CHUNK_IDX_NTYPES: default: HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "Invalid chunk index type") - } /* end switch */ + } /* Chunk index address */ - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr)); - } /* end else */ + } /* Set the layout operations */ mesg->ops = H5D_LOPS_CHUNK; @@ -530,12 +525,12 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "invalid layout version with virtual layout") /* Heap information */ - if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(mesg->storage.u.virt.serial_list_hobjid.addr)); /* NOTE: virtual mapping global heap entry address could be undefined */ - if (H5_IS_BUFFER_OVERFLOW(p, sizeof(uint32_t), p_end)) + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(p, mesg->storage.u.virt.serial_list_hobjid.idx); @@ -580,7 +575,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU (unsigned)H5O_LAYOUT_VDS_GH_ENC_VERS, (unsigned)heap_vers) /* Number of entries */ - if (H5_IS_BUFFER_OVERFLOW(heap_block_p, H5F_SIZEOF_SIZE(f), heap_block_p_end)) + if (H5_IS_BUFFER_OVERFLOW(heap_block_p, H5F_sizeof_size(f), heap_block_p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_DECODE_LENGTH(f, heap_block_p, tmp_hsize) @@ -679,9 +674,9 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU else mesg->storage.u.virt.list[i].source_dset.dset_name = mesg->storage.u.virt.list[i].source_dset_name; - } /* end if */ + } - /* unlim_dim fields */ + /* Unlim_dim fields */ mesg->storage.u.virt.list[i].unlim_dim_source = H5S_get_select_unlim_dim(mesg->storage.u.virt.list[i].source_select); mesg->storage.u.virt.list[i].unlim_dim_virtual = @@ -697,7 +692,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU mesg->storage.u.virt.list[i].source_select; mesg->storage.u.virt.list[i].source_dset.clipped_virtual_select = mesg->storage.u.virt.list[i].source_dset.virtual_select; - } /* end if */ + } /* Check mapping for validity (do both pre and post * checks here, since we had to allocate the entry list @@ -713,10 +708,10 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU if (H5D_virtual_update_min_dims(mesg, i) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to update virtual dataset minimum dimensions") - } /* end for */ + } /* Read stored checksum */ - if (H5_IS_BUFFER_OVERFLOW(heap_block_p, sizeof(uint32_t), heap_block_p_end)) + if (H5_IS_BUFFER_OVERFLOW(heap_block_p, 4, heap_block_p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(heap_block_p, stored_chksum) @@ -743,8 +738,8 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5D_NLAYOUTS: default: HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "Invalid layout class") - } /* end switch */ - } /* end else */ + } + } /* Set return value */ ret_value = mesg; @@ -755,8 +750,8 @@ done: if (mesg->type == H5D_VIRTUAL) if (H5D__virtual_reset_layout(mesg) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to reset virtual layout") - mesg = H5FL_FREE(H5O_layout_t, mesg); - } /* end if */ + H5FL_FREE(H5O_layout_t, mesg); + } heap_block = (uint8_t *)H5MM_xfree(heap_block); diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 11138df..a82be72 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -13,16 +13,14 @@ /*------------------------------------------------------------------------- * * Created: H5Olinfo.c - * Aug 23 2005 - * Quincey Koziol * - * Purpose: Link Information messages. + * Purpose: Link information messages * *------------------------------------------------------------------------- */ -#define H5G_FRIEND /*suppress error about including H5Gpkg */ -#define H5L_FRIEND /*suppress error about including H5Lpkg */ +#define H5G_FRIEND /* Suppress error about including H5Gpkg */ +#define H5L_FRIEND /* Suppress error about including H5Lpkg */ #include "H5Omodule.h" /* This source code file is part of the H5O module */ #include "H5private.h" /* Generic Functions */ @@ -95,12 +93,8 @@ H5FL_DEFINE_STATIC(H5O_linfo_t); * * Purpose: Decode a message and return a pointer to a newly allocated one. * - * Return: Success: Ptr to new message in native form. + * Return: Success: Pointer to new message in native form * Failure: NULL - * - * Programmer: Quincey Koziol - * Aug 23 2005 - * *------------------------------------------------------------------------- */ static void * @@ -115,7 +109,6 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); diff --git a/src/H5Olink.c b/src/H5Olink.c index dabf87e..160b1d0 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -13,10 +13,8 @@ /*------------------------------------------------------------------------- * * Created: H5Olink.c - * Aug 29 2005 - * Quincey Koziol * - * Purpose: Link messages. + * Purpose: Link messages * *------------------------------------------------------------------------- */ @@ -100,32 +98,27 @@ H5FL_DEFINE_STATIC(H5O_link_t); * Purpose: Decode a message and return a pointer to * a newly allocated one. * - * Return: Success: Ptr to new message in native order. - * - * Failure: NULL - * - * Programmer: Quincey Koziol - * Aug 29 2005 - * + * Return: Success: Pointer to new message in native order + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_link_t *lnk = NULL; /* Pointer to link message */ - size_t len = 0; /* Length of a string in the message */ - unsigned char link_flags; /* Flags for encoding link info */ - const uint8_t *p_end = p + p_size; /* End of the p buffer */ - void *ret_value = NULL; /* Return value */ + H5O_link_t *lnk = NULL; /* Pointer to link message */ + size_t len = 0; /* Length of a string in the message */ + unsigned char link_flags; /* Flags for encoding link info */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); - /* decode */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (*p++ != H5O_LINK_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") @@ -134,6 +127,8 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Get the encoding flags for the link */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") link_flags = *p++; if (link_flags & ~H5O_LINK_ALL_FLAGS) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message") @@ -141,63 +136,74 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE /* Check for non-default link type */ if (link_flags & H5O_LINK_STORE_LINK_TYPE) { /* Get the type of the link */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") lnk->type = (H5L_type_t)*p++; if (lnk->type < H5L_TYPE_HARD || lnk->type > H5L_TYPE_MAX) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type") - } /* end if */ + } else lnk->type = H5L_TYPE_HARD; /* Get the link creation time from the file */ if (link_flags & H5O_LINK_STORE_CORDER) { + if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") INT64DECODE(p, lnk->corder) lnk->corder_valid = TRUE; - } /* end if */ + } else { lnk->corder = 0; lnk->corder_valid = FALSE; - } /* end else */ + } /* Check for non-default name character set */ if (link_flags & H5O_LINK_STORE_NAME_CSET) { /* Get the link name's character set */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") lnk->cset = (H5T_cset_t)*p++; if (lnk->cset < H5T_CSET_ASCII || lnk->cset > H5T_CSET_UTF8) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad cset type") - } /* end if */ + } else lnk->cset = H5T_CSET_ASCII; /* Get the length of the link's name */ switch (link_flags & H5O_LINK_NAME_SIZE) { case 0: /* 1 byte size */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") len = *p++; break; case 1: /* 2 byte size */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, len); break; case 2: /* 4 byte size */ + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(p, len); break; case 3: /* 8 byte size */ + if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT64DECODE(p, len); break; default: - HDassert(0 && "bad size for name"); - } /* end switch */ + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "no appropriate size for name length") + } if (len == 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid name length") - /* Make sure that length doesn't exceed buffer size, which could occur - when the file is corrupted */ - if (p + len > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "name length causes read past end of buffer") - /* Get the link's name */ + if (H5_IS_BUFFER_OVERFLOW(p, len, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (NULL == (lnk->name = (char *)H5MM_malloc(len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") H5MM_memcpy(lnk->name, p, len); @@ -208,20 +214,21 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE switch (lnk->type) { case H5L_TYPE_HARD: /* Get the address of the object the link points to */ + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(lnk->u.hard.addr)); break; case H5L_TYPE_SOFT: /* Get the link value */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, len) if (len == 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid link length") - /* Make sure that length doesn't exceed buffer size, which could occur - when the file is corrupted */ - if (p + len > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "name length causes read past end of buffer") - + if (H5_IS_BUFFER_OVERFLOW(p, len, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (NULL == (lnk->u.soft.name = (char *)H5MM_malloc((size_t)len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") H5MM_memcpy(lnk->u.soft.name, p, len); @@ -238,16 +245,15 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type") /* A UD link. Get the user-supplied data */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, len) if (lnk->type == H5L_TYPE_EXTERNAL && len < 3) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "external link information length < 3") lnk->u.ud.size = len; if (len > 0) { - /* Make sure that length doesn't exceed buffer size, which could - occur when the file is corrupted */ - if (p + len > p_end) - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "name length causes read past end of buffer") - + if (H5_IS_BUFFER_OVERFLOW(p, len, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") H5MM_memcpy(lnk->u.ud.udata, p, len); @@ -255,22 +261,20 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE } else lnk->u.ud.udata = NULL; - } /* end switch */ + } /* Set return value */ ret_value = lnk; done: - if (ret_value == NULL) - if (lnk != NULL) { - if (lnk->name != NULL) - H5MM_xfree(lnk->name); - if (lnk->type == H5L_TYPE_SOFT && lnk->u.soft.name != NULL) - H5MM_xfree(lnk->u.soft.name); - if (lnk->type >= H5L_TYPE_UD_MIN && lnk->u.ud.size > 0 && lnk->u.ud.udata != NULL) - H5MM_xfree(lnk->u.ud.udata); - lnk = H5FL_FREE(H5O_link_t, lnk); - } /* end if */ + if (!ret_value && lnk) { + H5MM_xfree(lnk->name); + if (lnk->type == H5L_TYPE_SOFT && lnk->u.soft.name != NULL) + H5MM_xfree(lnk->u.soft.name); + if (lnk->type >= H5L_TYPE_UD_MIN && lnk->u.ud.size > 0 && lnk->u.ud.udata != NULL) + H5MM_xfree(lnk->u.ud.udata); + H5FL_FREE(H5O_link_t, lnk); + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__link_decode() */ diff --git a/src/H5Opline.c b/src/H5Opline.c index 4ccd96c..711a67b 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -11,10 +11,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - * Purpose: Data filter pipeline message. + * Purpose: Data filter pipeline message */ #include "H5Omodule.h" /* This source code file is part of the H5O module */ @@ -103,12 +100,8 @@ H5FL_DEFINE(H5O_pline_t); * * Purpose: Decodes a filter pipeline message. * - * Return: Success: Ptr to the native message. + * Return: Success: Pointer to a new pipeline message * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * *------------------------------------------------------------------------- */ @@ -121,11 +114,11 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign size_t name_length; /* Length of filter name */ size_t i; /* Local index variable */ const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ - void *ret_value = NULL; /* Return value */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ + HDassert(f); HDassert(p); /* Allocate space for I/O pipeline message */ @@ -133,14 +126,15 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Version */ - if (p + 4 - 1 > p_end) /* 4 byte is minimum for all versions */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off the end of the buffer: current p = %p, p_end = %p", - (const void *)(p + 4), (const void *)p_end) + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") pline->version = *p++; if (pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST) HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message") /* Number of filters */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") pline->nused = *p++; if (pline->nused > H5Z_MAX_NFILTERS) { @@ -153,8 +147,11 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign } /* Reserved */ - if (pline->version == H5O_PLINE_VERSION_1) + if (pline->version == H5O_PLINE_VERSION_1) { + if (H5_IS_BUFFER_OVERFLOW(p, 6, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") p += 6; + } /* Allocate array for filters */ pline->nalloc = pline->nused; @@ -164,94 +161,95 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign /* Decode filters */ for (i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) { /* Filter ID */ - if (p + 6 - 1 > p_end) /* 6 bytes minimum */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, - "ran off the end of the buffer: current p = %p, p_end = %p", (const void *)(p + 6), - (const void *)p_end) + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, filter->id); /* Length of filter name */ if (pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED) name_length = 0; else { + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, name_length); if (pline->version == H5O_PLINE_VERSION_1 && name_length % 8) HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight") - if (p + 4 - 1 > p_end) /* with name_length 4 bytes to go */ - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, - "ran off the end of the buffer: current p = %p, p_end = %p", - (const void *)(p + 4), (const void *)p_end) - } /* end if */ + } /* Filter flags */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, filter->flags); /* Number of filter parameters ("client data elements") */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT16DECODE(p, filter->cd_nelmts); /* Filter name, if there is one */ if (name_length) { - size_t actual_name_length; /* Actual length of name */ - size_t len = (size_t)(p_end - p + 1); + size_t actual_name_length; /* Actual length of name */ + size_t max = (size_t)(p_end - p + 1); /* Max possible name length */ + /* Determine actual name length (without padding, but with null terminator) */ - actual_name_length = HDstrnlen((const char *)p, len); - if (actual_name_length == len) + actual_name_length = HDstrnlen((const char *)p, max); + if (actual_name_length == max) HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "filter name not null terminated") actual_name_length += 1; /* include \0 byte */ - HDassert(actual_name_length <= name_length); /* Allocate space for the filter name, or use the internal buffer */ if (actual_name_length > H5Z_COMMON_NAME_LEN) { filter->name = (char *)H5MM_malloc(actual_name_length); if (NULL == filter->name) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name") - } /* end if */ + } else filter->name = filter->_name; HDstrncpy(filter->name, (const char *)p, actual_name_length); + + if (H5_IS_BUFFER_OVERFLOW(p, name_length, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") p += name_length; - } /* end if */ + } /* Filter parameters */ if (filter->cd_nelmts) { - size_t j; /* Local index variable */ /* Allocate space for the client data elements, or use the internal buffer */ if (filter->cd_nelmts > H5Z_COMMON_CD_VALUES) { filter->cd_values = (unsigned *)H5MM_malloc(filter->cd_nelmts * sizeof(unsigned)); if (NULL == filter->cd_values) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for client data") - } /* end if */ + } else filter->cd_values = filter->_cd_values; - /* - * Read the client data values and the padding - */ - for (j = 0; j < filter->cd_nelmts; j++) { - if (p + 4 - 1 <= p_end) - UINT32DECODE(p, filter->cd_values[j]) - else - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "ran off the end of the buffer: current p = %p, p_size = %zu, p_end = %p", - (const void *)p, p_size, (const void *)p_end) + /* Read the client data values and the padding */ + for (size_t j = 0; j < filter->cd_nelmts; j++) { + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") + UINT32DECODE(p, filter->cd_values[j]) } if (pline->version == H5O_PLINE_VERSION_1) - if (filter->cd_nelmts % 2) - p += 4; /*padding*/ - } /* end if */ - } /* end for */ + if (filter->cd_nelmts % 2) { + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, + "ran off end of input buffer while decoding") + p += 4; /* padding */ + } + } + } /* Set return value */ ret_value = pline; done: - if (NULL == ret_value && pline) { + if (!ret_value && pline) { H5O__pline_reset(pline); H5O__pline_free(pline); - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__pline_decode() */ diff --git a/src/H5Orefcount.c b/src/H5Orefcount.c index 51da22c..f4d3b5c 100644 --- a/src/H5Orefcount.c +++ b/src/H5Orefcount.c @@ -13,10 +13,8 @@ /*------------------------------------------------------------------------- * * Created: H5Orefcount.c - * Mar 10 2007 - * Quincey Koziol * - * Purpose: Object ref. count messages. + * Purpose: Object reference count messages * *------------------------------------------------------------------------- */ @@ -72,31 +70,30 @@ H5FL_DEFINE_STATIC(H5O_refcount_t); /*------------------------------------------------------------------------- * Function: H5O__refcount_decode * - * Purpose: Decode a message and return a pointer to a newly allocated one. - * - * Return: Success: Ptr to new message in native form. - * Failure: NULL - * - * Programmer: Quincey Koziol - * Mar 10 2007 + * Purpose: Decode a message and return a pointer to a newly allocated + * one. * + * Return: Success: Pointer to new message in native form + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__refcount_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, - unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, - size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, + const uint8_t *p) { - H5O_refcount_t *refcount = NULL; /* Reference count */ - void *ret_value = NULL; /* Return value */ + H5O_refcount_t *refcount = NULL; /* Reference count */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); /* Version of message */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (*p++ != H5O_REFCOUNT_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") @@ -104,15 +101,17 @@ H5O__refcount_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, if (NULL == (refcount = H5FL_MALLOC(H5O_refcount_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Get ref. count for object */ + /* Get reference count for object */ + if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") UINT32DECODE(p, *refcount) /* Set return value */ ret_value = refcount; done: - if (ret_value == NULL && refcount != NULL) - refcount = H5FL_FREE(H5O_refcount_t, refcount); + if (!ret_value && refcount) + H5FL_FREE(H5O_refcount_t, refcount); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__refcount_decode() */ diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index e9a0dc6..9bf5d6f 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -115,11 +115,9 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); - /* decode */ if (NULL == (sdim = H5FL_CALLOC(H5S_extent_t))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "dataspace structure allocation failed") sdim->type = H5S_NO_CLASS; @@ -154,9 +152,11 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN if (sdim->type != H5S_SIMPLE && sdim->rank > 0) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid rank for scalar or NULL dataspace") - } /* end if */ + } else { - /* Set the dataspace type to be simple or scalar as appropriate */ + /* Set the dataspace type to be simple or scalar as appropriate + * (version 1 does not allow H5S_NULL) + */ if (sdim->rank > 0) sdim->type = H5S_SIMPLE; else @@ -166,50 +166,46 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") p++; - } /* end else */ - HDassert(sdim->type != H5S_NULL || sdim->version >= H5O_SDSPACE_VERSION_2); + } - /* Only Version 1 has these reserved bytes */ + /* Version 1 has 4 reserved bytes */ if (version == H5O_SDSPACE_VERSION_1) { if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") - p += 4; /*reserved*/ + p += 4; } /* Decode dimension sizes */ if (sdim->rank > 0) { - uint8_t sizeof_size = H5F_SIZEOF_SIZE(f); - /* - * Ensure that decoding doesn't cause reading past buffer's end, - * due to possible data corruption - check that we have space to - * decode a "sdim->rank" number of hsize_t values - */ - if (H5_IS_BUFFER_OVERFLOW(p, (sizeof_size * sdim->rank), p_end)) + /* Sizes */ + + /* Check that we have space to decode sdim->rank values */ + if (H5_IS_BUFFER_OVERFLOW(p, (H5F_sizeof_size(f) * sdim->rank), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") if (NULL == (sdim->size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "memory allocation failed") - for (i = 0; i < sdim->rank; i++) H5F_DECODE_LENGTH(f, p, sdim->size[i]); + /* Max sizes */ + if (flags & H5S_VALID_MAX) { if (NULL == (sdim->max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "memory allocation failed") - /* - * Ensure that decoding doesn't cause reading past buffer's end, - * due to possible data corruption - check that we have space to - * decode a "sdim->rank" number of hsize_t values - */ - if (H5_IS_BUFFER_OVERFLOW(p, (sizeof_size * sdim->rank), p_end)) + /* Check that we have space to decode sdim->rank values */ + if (H5_IS_BUFFER_OVERFLOW(p, (H5F_sizeof_size(f) * sdim->rank), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding") - for (i = 0; i < sdim->rank; i++) H5F_DECODE_LENGTH(f, p, sdim->max[i]); - } /* end if */ - } /* end if */ + } + + /* NOTE: The version 1 permutation indexes were never implemented so + * there is nothing to decode. + */ + } /* Compute the number of elements in the extent */ if (sdim->type == H5S_NULL) @@ -217,16 +213,16 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN else { for (i = 0, sdim->nelem = 1; i < sdim->rank; i++) sdim->nelem *= sdim->size[i]; - } /* end else */ + } /* Set return value */ - ret_value = (void *)sdim; /*success*/ + ret_value = (void *)sdim; done: if (!ret_value && sdim) { H5S__extent_release(sdim); - sdim = H5FL_FREE(H5S_extent_t, sdim); - } /* end if */ + H5FL_FREE(H5S_extent_t, sdim); + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__sdspace_decode() */ diff --git a/src/H5Oshmesg.c b/src/H5Oshmesg.c index 586e2ce..8510c6e 100644 --- a/src/H5Oshmesg.c +++ b/src/H5Oshmesg.c @@ -56,29 +56,25 @@ const H5O_msg_class_t H5O_MSG_SHMESG[1] = {{ }}; /*------------------------------------------------------------------------- - * Function: H5O__shmesg_decode + * Function: H5O__shmesg_decode * - * Purpose: Decode a shared message table message and return a pointer + * Purpose: Decode a shared message table message and return a pointer * to a newly allocated H5O_shmesg_table_t struct. * - * Return: Success: Ptr to new message in native struct. - * Failure: NULL - * - * Programmer: James Laird - * Jan 29, 2007 - * + * Return: Success: Ptr to new message in native struct. + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__shmesg_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_shmesg_table_t *mesg; /* Native message */ - void *ret_value = NULL; /* Return value */ + H5O_shmesg_table_t *mesg; /* New shared message table */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* Sanity check */ HDassert(f); HDassert(p); @@ -87,14 +83,25 @@ H5O__shmesg_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU "memory allocation failed for shared message table message") /* Retrieve version, table address, and number of indexes */ + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); mesg->version = *p++; + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(mesg->addr)); + + if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); mesg->nindexes = *p++; /* Set return value */ ret_value = (void *)mesg; done: + if (!ret_value && mesg) + H5MM_xfree(mesg); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__shmesg_decode() */ diff --git a/src/H5Ostab.c b/src/H5Ostab.c index ae4635e..2428f06 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -13,10 +13,8 @@ /*------------------------------------------------------------------------- * * Created: H5Ostab.c - * Aug 6 1997 - * Robb Matzke * - * Purpose: Symbol table messages. + * Purpose: Symbol table messages * *------------------------------------------------------------------------- */ @@ -78,41 +76,39 @@ H5FL_DEFINE_STATIC(H5O_stab_t); * Purpose: Decode a symbol table message and return a pointer to * a newly allocated one. * - * Return: Success: Ptr to new message in native order. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Aug 6 1997 - * + * Return: Success: Pointer to new message in native order + * Failure: NULL *------------------------------------------------------------------------- */ static void * H5O__stab_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_stab_t *stab = NULL; - void *ret_value = NULL; /* Return value */ + H5O_stab_t *stab = NULL; + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void *ret_value = NULL; FUNC_ENTER_PACKAGE - /* check args */ HDassert(f); HDassert(p); - /* decode */ if (NULL == (stab = H5FL_CALLOC(H5O_stab_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(stab->btree_addr)); + + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_addr_decode(f, &p, &(stab->heap_addr)); - /* Set return value */ ret_value = stab; done: - if (ret_value == NULL) - if (stab != NULL) - stab = H5FL_FREE(H5O_stab_t, stab); + if (!ret_value && stab) + H5FL_FREE(H5O_stab_t, stab); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__stab_decode() */ -- cgit v0.12