From 65eff22348634144cd5a6e77159c27eb895d54b4 Mon Sep 17 00:00:00 2001 From: bmribler <39579120+bmribler@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:35:45 -0400 Subject: 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. --- release_docs/RELEASE.txt | 12 ++++++++++-- src/H5Olinfo.c | 28 ++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index f64fdd4..2dcb057 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -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 diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index d4ac3bb..11138df 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -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; -- cgit v0.12