From 659bc99fd139e16fdf47b31b635f158b72e3f5a4 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Fri, 11 Nov 2022 06:20:09 +0100 Subject: Make H5O__fsinfo_decode() more resilient to out-of-bound reads. (#2229) When decoding a file space info message in H5O__fsinfo_decode() make sure each element to be decoded is still within the message. Malformed hdf5 files may have trunkated content which does not match the expected size. Checking this will prevent attempting to decode unrelated data and heap overflows. So far, only free space manager address data was checked before decoding. This fixes CVE-2021-45830 / Bug #2228. Signed-off-by: Egbert Eich Additions Co-authored-by: Larry Knox --- release_docs/RELEASE.txt | 13 +++++++++++++ src/H5Ofsinfo.c | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 48fcc3b..bc04d93 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -172,6 +172,18 @@ Bug Fixes since HDF5-1.13.3 release =================================== Library ------- + - Fix CVE-2021-45830 / GHSA-5h2h-fjjr-x9m2 + + Make H5O__fsinfo_decode() more resilient to out-of-bound reads. + + When decoding a file space info message in H5O__fsinfo_decode() make + sure each element to be decoded is still within the message. Malformed + hdf5 files may have trunkated content which does not match the + expected size. Checking this will prevent attempting to decode + unrelated data and heap overflows. So far, only free space manager + address data was checked before decoding. + + (EFE - 2022/10/05 GH-2228) - Fix CVE-2018-17439 / GHSA-vcxv-vp43-rch7 @@ -185,6 +197,7 @@ Bug Fixes since HDF5-1.13.3 release (EFE - 2022/09/27 HDFFV-10589, GH-2226) + Java Library ------------ - diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c index f8455e4..4d5934d 100644 --- a/src/H5Ofsinfo.c +++ b/src/H5Ofsinfo.c @@ -88,6 +88,7 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); * *------------------------------------------------------------------------- */ + static void * H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) @@ -112,6 +113,8 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->fs_addr[ptype - 1] = HADDR_UNDEF; /* Version of message */ + if (p + 1 - 1 > p_end) /* one byte for version */ + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") vers = *p++; if (vers == H5O_FSINFO_VERSION_0) { @@ -125,6 +128,8 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->pgend_meta_thres = H5F_FILE_SPACE_PGEND_META_THRES; fsinfo->eoa_pre_fsm_fsalloc = HADDR_UNDEF; + if (p + 1 + H5F_SIZEOF_SIZE(f) - 1 > p_end) /* one byte for strategy + sizeof(f) */ + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") strategy = (H5F_file_space_type_t)*p++; /* File space strategy */ H5F_DECODE_LENGTH(f, p, threshold); /* Free-space section threshold */ @@ -169,7 +174,10 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU else { HDassert(vers >= H5O_FSINFO_VERSION_1); - fsinfo->version = vers; + fsinfo->version = vers; + /* strategy (1) + persist (1) + sizeof(f) + sizeof(f) + pgend_meta_thres (2) + sizeofaddr(f) */ + if (p + 1 + 1 + 2 * H5F_SIZEOF_SIZE(f) + 2 + H5F_SIZEOF_ADDR(f) - 1 > p_end) + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") fsinfo->strategy = (H5F_fspace_strategy_t)*p++; /* File space strategy */ fsinfo->persist = *p++; /* Free-space persist or not */ H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* Free-space section threshold */ @@ -181,9 +189,11 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU /* Decode addresses of free space managers, if persisting */ if (fsinfo->persist) - for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) + for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) { + if (p + H5F_SIZEOF_SIZE(f) - 1 > p_end) /* one byte for sizeof(f) */ + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(fsinfo->fs_addr[ptype - 1])); - + } fsinfo->mapped = FALSE; } -- cgit v0.12