From 6cb3afb86c7dc7179af3cf4b5973edcd7baaffb0 Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 21 Feb 2020 12:27:01 -0600 Subject: FIx issues when deserializing hyperslab/point selection with version beyond the library's supported version: (1) Verify the decoded version before proceeding further with deserialization (2) Close the dataspace if errors occurred after opening the dataspace --- src/H5R.c | 14 +++++++++++--- src/H5Shyper.c | 15 ++++++++++++--- src/H5Spkg.h | 9 +++++++++ src/H5Spoint.c | 11 ++++++++++- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/H5R.c b/src/H5R.c index 3be724a..74816f8 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -623,7 +623,8 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref) const uint8_t *p; /* Pointer to OID to store */ H5HG_t hobjid; /* Heap object ID */ uint8_t *buf = NULL; /* Buffer to store serialized selection in */ - H5S_t *ret_value; + H5S_t *ds = NULL; /* Temporary pointer to dataspace */ + H5S_t *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT @@ -648,18 +649,25 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref) H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Open and copy the dataset's dataspace */ - if((ret_value = H5S_read(&oloc, dxpl_id)) == NULL) + if((ds = H5S_read(&oloc, dxpl_id)) == NULL) HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found") /* Unserialize the selection */ - if(H5S_select_deserialize(ret_value, p) < 0) + if(H5S_select_deserialize(ds, p) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") + ret_value = ds; + done: /* Free the buffer allocated in H5HG_read() */ if(buf) H5MM_xfree(buf); + if(ret_value == NULL) { + if(ds && H5S_close(ds) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataspace") + } + FUNC_LEAVE_NOAPI(ret_value) } /* end H5R_get_region() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 09d450f..af37b81 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -2120,7 +2120,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Store the preamble information */ UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ + UINT32ENCODE(buf, (uint32_t)H5S_HYPER_VERSION_1); /* Store the version number */ UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */ lenp = buf; /* keep the pointer to the length location for later */ buf += 4; /* skip over space for length */ @@ -2265,8 +2265,10 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) hsize_t *tstride=NULL; /* temporary hyperslab pointers */ hsize_t *tcount=NULL; /* temporary hyperslab pointers */ hsize_t *tblock=NULL; /* temporary hyperslab pointers */ - unsigned i,j; /* local counting variables */ - herr_t ret_value=FAIL; /* return value */ + unsigned i,j; /* local counting variables */ + uint32_t version; /* decoded version */ + uint8_t *p; /* temporary pointer to buf */ + herr_t ret_value=FAIL; /* return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2274,6 +2276,13 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) HDassert(space); HDassert(buf); + p = buf + 4; + UINT32DECODE(p, version); + + if(version < H5S_HYPER_VERSION_1 || version > H5S_HYPER_VERSION_LATEST) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "bad version number for hyperslab selection") + + /* Deserialize slabs to select */ buf+=16; /* Skip over selection header */ UINT32DECODE(buf,rank); /* decode the rank of the point selection */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 0597994..db633b3 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -32,6 +32,15 @@ #define H5S_VALID_MAX 0x01 #define H5S_VALID_PERM 0x02 +/* Version for hyperslab selection info */ +#define H5S_HYPER_VERSION_1 1 +#define H5S_HYPER_VERSION_LATEST H5S_HYPER_VERSION_1 + +/* Version for point selection info */ +#define H5S_POINT_VERSION_1 1 +#define H5S_POINT_VERSION_LATEST H5S_HYPER_VERSION_1 + + /* Initial version of the dataspace information */ #define H5O_SDSPACE_VERSION_1 1 diff --git a/src/H5Spoint.c b/src/H5Spoint.c index e1dbb4d..59430bb 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -846,7 +846,7 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf) /* Store the preamble information */ UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ + UINT32ENCODE(buf, (uint32_t)H5S_POINT_VERSION_1); /* Store the version number */ UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */ lenp=buf; /* keep the pointer to the length location for later */ buf+=4; /* skip over space for length */ @@ -907,6 +907,8 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf) size_t num_elem=0; /* Number of elements in selection */ hsize_t *coord=NULL, *tcoord; /* Pointer to array of elements */ unsigned i, j; /* local counting variables */ + uint32_t version; /* Decoded version */ + uint8_t *p; /* Temporary pointer to buf */ herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI_NOINIT @@ -915,6 +917,13 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf) HDassert(space); HDassert(buf); + p = buf + 4; + UINT32DECODE(p, version); + + if(version < H5S_POINT_VERSION_1 || version > H5S_POINT_VERSION_LATEST) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "bad version number for point selection") + + /* Deserialize points to select */ buf += 16; /* Skip over selection header */ UINT32DECODE(buf, rank); /* decode the rank of the point selection */ -- cgit v0.12