diff options
author | Binh-Minh Ribler <bmribler@hdfgroup.org> | 2020-07-06 07:55:14 (GMT) |
---|---|---|
committer | Binh-Minh Ribler <bmribler@hdfgroup.org> | 2020-07-06 07:55:14 (GMT) |
commit | 55377dc855d1431991d996de13a52bf562a5f2fe (patch) | |
tree | 824b6d2f4d356808bd9311dfe7d8730e521782f2 /src | |
parent | 6c615b88035361fcc4e79a40dd2ffba0af306ad0 (diff) | |
download | hdf5-55377dc855d1431991d996de13a52bf562a5f2fe.zip hdf5-55377dc855d1431991d996de13a52bf562a5f2fe.tar.gz hdf5-55377dc855d1431991d996de13a52bf562a5f2fe.tar.bz2 |
Fix HDFFV-10591
Description:
h52gif produced a segfault when a buffer overflow occurred because
the data size was corrupted and became very large. This commit added
a check on the data size against the buffer size to prevent the segfault.
It also added error reporting to h52gif to display an error message
instead of silently exiting when the failure occurred.
Platforms tested:
Linux/64 (jelly)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Oattr.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 4d703f6..195b508 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -110,7 +110,10 @@ H5FL_EXTERN(H5S_extent_t); void *H5O_attr_decode(f, dxpl_id, mesg_flags, p) H5F_t *f; IN: pointer to the HDF5 file struct hid_t dxpl_id; IN: DXPL for any I/O + H5O_t *open_oh; IN: pointer to the object header unsigned mesg_flags; IN: Message flags to influence decoding + unsigned *ioflags; IN: flags for decoding + size_t p_size; IN: size of buffer *p const uint8_t *p; IN: the raw information buffer RETURNS Pointer to the new message in native order on success, NULL on failure @@ -121,13 +124,13 @@ H5FL_EXTERN(H5S_extent_t); --------------------------------------------------------------------------*/ static void * H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned *ioflags, size_t p_size, const uint8_t *p) { - H5A_t *attr = NULL; - H5S_extent_t *extent; /*extent dimensionality information */ - size_t name_len; /*attribute name length */ - unsigned flags = 0; /* Attribute flags */ - H5A_t *ret_value; /* Return value */ + H5A_t *attr = NULL; + H5S_extent_t *extent; /*extent dimensionality information */ + size_t name_len; /*attribute name length */ + unsigned flags = 0; /* Attribute flags */ + H5A_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -136,7 +139,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED HDassert(p); if(NULL == (attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t))) HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure") @@ -144,7 +147,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED /* Version number */ attr->shared->version = *p++; if(attr->shared->version < H5O_ATTR_VERSION_1 || attr->shared->version > H5O_ATTR_VERSION_LATEST) - HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message") + HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message") /* Get the flags byte if we have a later version of the attribute */ if(attr->shared->version >= H5O_ATTR_VERSION_2) { @@ -174,7 +177,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED /* Decode and store the name */ if(NULL == (attr->shared->name = H5MM_strdup((const char *)p))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(attr->shared->version < H5O_ATTR_VERSION_2) p += H5O_ALIGN_OLD(name_len); /* advance the memory pointer */ else @@ -193,7 +196,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED * What's actually shared, though, is only the extent. */ if(NULL == (attr->shared->ds = H5FL_CALLOC(H5S_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Decode attribute's dataspace extent */ if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, open_oh, @@ -220,6 +223,11 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED /* Go get the data */ if(attr->shared->data_size) { + /* Ensure that data size doesn't exceed buffer size, in case of + it's being corrupted in the file */ + if(attr->shared->data_size > p_size) + HGOTO_ERROR(H5E_RESOURCE, H5E_OVERFLOW, NULL, "data size exceeds buffer size") + if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, attr->shared->data_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemcpy(attr->shared->data, p, attr->shared->data_size); |