Skip to content

Commit

Permalink
H4O_fsinfo_decode() Make more resilient to out-of-bounds read
Browse files Browse the repository at this point in the history
Malformed hdf5 files may have trunkated content which does not match
the expected size. This function attempts to decode these it will read
past the end of the allocated space which may lead to a crash. Make sure
each element is within bounds before reading.

This fixes CVE-2021-45830 / Bug HDFGroup#2228.

Signed-off-by: Egbert Eich <eich@suse.com>

Additions
  • Loading branch information
e4t committed Nov 9, 2022
1 parent 0f30852 commit 854cb88
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
12 changes: 10 additions & 2 deletions release_docs/RELEASE.txt
Expand Up @@ -149,8 +149,16 @@ Bug Fixes since HDF5-1.13.3 release
===================================
Library
-------
-

- Fix CVE-2021-45830 / GHSA-5h2h-fjjr-x9m2 / Bug #2228

Malformed hdf5 files may have trunkated content which does not match
the expected data size. When H5O_fsinfo_decode() attempted to decode
these it read past the end of the allocated space which may have lead
to a crash.
Make sure each element is within bounds before reading.

(EFE - 2022/10/05 GH-2229)


Java Library
------------
Expand Down
16 changes: 13 additions & 3 deletions src/H5Ofsinfo.c
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -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 */

Expand Down Expand Up @@ -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 */
Expand All @@ -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;
}

Expand Down

0 comments on commit 854cb88

Please sign in to comment.