Skip to content

Commit

Permalink
H5O_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 7, 2022
1 parent 81a6f68 commit 9a500cd
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/H5Ofsinfo.c
Original file line number Diff line number Diff line change
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 9a500cd

Please sign in to comment.