Fixed GH-2603, heap-buffer-overflow in H5O__linfo_decode (#2697)

* Fixed GH-2603, heap-buffer-overflow in H5O__linfo_decode

Verified with valgrind -v --tool=memcheck --leak-check=full h5dump POV-GH-2603
The several invalid reads shown originally are now gone.
This commit is contained in:
bmribler 2023-04-13 17:35:45 -04:00 committed by GitHub
parent d6243791d4
commit 65eff22348
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 8 deletions

View File

@ -147,7 +147,7 @@ Support for new platforms, languages and compilers
==================================================
-
Bug Fixes since HDF5-1.13.3 release
Bug Fixes since HDF5-1.14.0 release
===================================
Library
-------
@ -162,6 +162,15 @@ Bug Fixes since HDF5-1.13.3 release
(DER - 2023/04/13 GH-2605)
- Fixed potential heap buffer overflow in decoding of link info message
Detections of buffer overflow were added for decoding version, index
flags, link creation order value, and the next three addresses. The
checkings will remove the potential invalid read of any of these
values that could be triggered by a malformed file.
(BMR - 2023/04/12 GH-2603)
- Memory leak
Memory leak was detected when running h5dump with "pov". The memory was allocated
@ -175,7 +184,6 @@ Bug Fixes since HDF5-1.13.3 release
(VC - 2023/04/11 GH-2599)
- Fixed memory leaks that could occur when reading a dataset from a
malformed file

View File

@ -105,11 +105,13 @@ H5FL_DEFINE_STATIC(H5O_linfo_t);
*/
static void *
H5O__linfo_decode(H5F_t *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_linfo_t *linfo = NULL; /* Link info */
unsigned char index_flags; /* Flags for encoding link index info */
void *ret_value = NULL; /* Return value */
const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */
H5O_linfo_t *linfo = NULL; /* Link info */
unsigned char index_flags; /* Flags for encoding link index info */
uint8_t addr_size = H5F_SIZEOF_ADDR(f); /* Temp var */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE
@ -117,6 +119,10 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
HDassert(f);
HDassert(p);
/* Check input buffer before decoding version and index flags */
if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end))
HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding")
/* Version of message */
if (*p++ != H5O_LINFO_VERSION)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
@ -136,11 +142,18 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
linfo->nlinks = HSIZET_MAX;
/* Max. link creation order value for the group, if tracked */
if (linfo->track_corder)
if (linfo->track_corder) {
if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end))
HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding")
INT64DECODE(p, linfo->max_corder)
}
else
linfo->max_corder = 0;
/* Check input buffer before decoding the next two addresses */
if (H5_IS_BUFFER_OVERFLOW(p, addr_size + addr_size, p_end))
HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding")
/* Address of fractal heap to store "dense" links */
H5F_addr_decode(f, &p, &(linfo->fheap_addr));
@ -148,8 +161,11 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
H5F_addr_decode(f, &p, &(linfo->name_bt2_addr));
/* Address of v2 B-tree to index creation order of links, if there is one */
if (linfo->index_corder)
if (linfo->index_corder) {
if (H5_IS_BUFFER_OVERFLOW(p, addr_size, p_end))
HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding")
H5F_addr_decode(f, &p, &(linfo->corder_bt2_addr));
}
else
linfo->corder_bt2_addr = HADDR_UNDEF;