diff options
author | mattjala <124107509+mattjala@users.noreply.github.com> | 2023-04-11 20:22:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-11 20:22:11 (GMT) |
commit | 2eedc8e8f7c4d70829c6afd5a048fb38f50917c6 (patch) | |
tree | bc7100fe6691d073cb4044efb42ef81ccfc39f29 /src | |
parent | bc8fa3a477e46d1fd3661666e4de79f455d41e19 (diff) | |
download | hdf5-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.c | 17 | ||||
-rw-r--r-- | src/H5private.h | 5 |
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 |