From f33bb733be2da42672b4b0264cd4c6318ba35e9a Mon Sep 17 00:00:00 2001 From: vchoi Date: Thu, 12 Mar 2020 17:20:23 -0500 Subject: Fix issues when deserializing point/all/none 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/H5Rint.c | 14 +++++++++++--- src/H5Sall.c | 3 +++ src/H5Snone.c | 3 +++ src/H5Spkg.h | 9 ++++++--- src/H5Spoint.c | 3 +++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/H5Rint.c b/src/H5Rint.c index 159bcca..4334faa 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -539,7 +539,8 @@ H5R__get_region(H5F_t *file, 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; /* Return value */ + H5S_t *ds = NULL; /* Temporary pointer to dataspace */ + H5S_t *ret_value = NULL; /* Return value */ FUNC_ENTER_PACKAGE @@ -564,18 +565,25 @@ H5R__get_region(H5F_t *file, const void *_ref) H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Open and copy the dataset's dataspace */ - if(NULL == (ret_value = H5S_read(&oloc))) + if(NULL == (ds = H5S_read(&oloc))) 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/H5Sall.c b/src/H5Sall.c index 1738615..8262f9b 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -580,6 +580,9 @@ H5S__all_deserialize(H5S_t **space, const uint8_t **p) /* Decode version */ UINT32DECODE(*p, version); + if(version < H5S_ALL_VERSION_1 || version > H5S_ALL_VERSION_LATEST) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "bad version number for all selection") + /* Skip over the remainder of the header */ *p += 8; diff --git a/src/H5Snone.c b/src/H5Snone.c index aa98035..0a9814c 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -555,6 +555,9 @@ H5S_none_deserialize(H5S_t **space, const uint8_t **p) /* Decode version */ UINT32DECODE(*p, version); + if(version < H5S_NONE_VERSION_1 || version > H5S_NONE_VERSION_LATEST) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "bad version number for none selection") + /* Skip over the remainder of the header */ *p += 8; diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 518c495..fc78cb6 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -42,13 +42,16 @@ #define H5S_HYPER_VERSION_LATEST H5S_HYPER_VERSION_2 /* Versions for H5S_SEL_POINTS selection info */ -#define H5S_POINT_VERSION_1 1 +#define H5S_POINT_VERSION_1 1 +#define H5S_POINT_VERSION_LATEST H5S_POINT_VERSION_1 /* Versions for H5S_SEL_NONE selection info */ -#define H5S_NONE_VERSION_1 1 +#define H5S_NONE_VERSION_1 1 +#define H5S_NONE_VERSION_LATEST H5S_NONE_VERSION_1 /* Versions for H5S_SEL_ALL selection info */ -#define H5S_ALL_VERSION_1 1 +#define H5S_ALL_VERSION_1 1 +#define H5S_ALL_VERSION_LATEST H5S_ALL_VERSION_1 /* Size of point/offset info for H5S_SEL_POINTS/H5S_SEL_HYPER */ #define H5S_SELECT_INFO_ENC_SIZE_4 0x04 /* 4 bytes: 32 bits */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 04d829f..e7e5725 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -1017,6 +1017,9 @@ H5S_point_deserialize(H5S_t **space, const uint8_t **p) /* Decode version */ UINT32DECODE(pp, 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") + /* Skip over the remainder of the header */ pp += 8; -- cgit v0.12