Skip to content

Commit

Permalink
Make H5O__fsinfo_decode() more resilient to out-of-bound reads.
Browse files Browse the repository at this point in the history
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 HDFGroup#2228.

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

Additions
  • Loading branch information
e4t committed Nov 10, 2022
1 parent 0f30852 commit cc79fe4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
15 changes: 13 additions & 2 deletions release_docs/RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,19 @@ Bug Fixes since HDF5-1.13.3 release
===================================
Library
-------
-

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

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-2229)


Java Library
------------
Expand Down
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 cc79fe4

Please sign in to comment.