summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authormattjala <124107509+mattjala@users.noreply.github.com>2023-04-11 20:22:11 (GMT)
committerGitHub <noreply@github.com>2023-04-11 20:22:11 (GMT)
commit2eedc8e8f7c4d70829c6afd5a048fb38f50917c6 (patch)
treebc7100fe6691d073cb4044efb42ef81ccfc39f29 /src
parentbc8fa3a477e46d1fd3661666e4de79f455d41e19 (diff)
downloadhdf5-2eedc8e8f7c4d70829c6afd5a048fb38f50917c6.zip
hdf5-2eedc8e8f7c4d70829c6afd5a048fb38f50917c6.tar.gz
hdf5-2eedc8e8f7c4d70829c6afd5a048fb38f50917c6.tar.bz2
Fix invalid memory access in H5O__ginfo_decode (#2663)
Diffstat (limited to 'src')
-rw-r--r--src/H5Oginfo.c17
-rw-r--r--src/H5private.h5
2 files changed, 21 insertions, 1 deletions
diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c
index 0f9628b..54d8b8b 100644
--- a/src/H5Oginfo.c
+++ b/src/H5Oginfo.c
@@ -89,7 +89,7 @@ H5FL_DEFINE_STATIC(H5O_ginfo_t);
*/
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 H5_ATTR_UNUSED p_size, const uint8_t *p)
+ 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 */
@@ -100,7 +100,15 @@ H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign
/* check args */
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")
if (*p++ != H5O_GINFO_VERSION)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
@@ -109,6 +117,9 @@ H5O__ginfo_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")
/* Get the flags for the group */
+ 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++;
if (flags & ~H5O_GINFO_ALL_FLAGS)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message")
@@ -117,6 +128,8 @@ H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign
/* Get the max. # of links to store compactly & the min. # of links to store densely */
if (ginfo->store_link_phase_change) {
+ if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end))
+ 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 */
@@ -127,6 +140,8 @@ H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign
/* Get the estimated # of entries & name lengths */
if (ginfo->store_est_entry_info) {
+ if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end))
+ 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 */
diff --git a/src/H5private.h b/src/H5private.h
index eb7d8e0..d92f7f6 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2436,6 +2436,11 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define HDcompile_assert(e) do { typedef struct { unsigned int b: (e); } x; } while(0)
*/
+/* Check if a read of size bytes starting at ptr would overflow past
+ * the last valid byte, pointed to by buffer_end .
+ */
+#define H5_IS_BUFFER_OVERFLOW(ptr, size, buffer_end) (((ptr) + (size)-1) > (buffer_end))
+
/* Private typedefs */
/* Union for const/non-const pointer for use by functions that manipulate