From 28771e289dc0ea91402bb079b06ea0d7aca7b9bf Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:26:48 -0700 Subject: [PATCH] Fix divide-by-zero when page buf page size is 0 (#4296) If a corrupt file sets the page buffer size in the superblock to zero, the library could attempt to divide by zero when allocating space in the file. The library now checks for valid page buffer sizes when reading the superblock message. Fixes oss-fuzz issue 58762 --- release_docs/RELEASE.txt | 9 +++++++++ src/H5Fsuper.c | 7 +++++-- src/H5MFsection.c | 6 ++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 1013a022c12..50ac630f5c3 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -514,6 +514,15 @@ Bug Fixes since HDF5-1.14.3 release Library ------- + - Fixed a divide-by-zero issue when a corrupt file sets the page size to 0 + + If a corrupt file sets the page buffer size in the superblock to zero, + the library could attempt to divide by zero when allocating space in + the file. The library now checks for valid page buffer sizes when + reading the superblock message. + + Fixes oss-fuzz issue 58762 + - Fixed a bug when using array datatypes with certain parent types Array datatype conversion would never use a background buffer, even if the diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 815a26b77df..3e5bc9a3a2b 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -799,8 +799,11 @@ H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, bool initial_read) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file space strategy"); } /* end if */ - assert(f->shared->fs_page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN); - assert(fsinfo.page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN); + if (f->shared->fs_page_size < H5F_FILE_SPACE_PAGE_SIZE_MIN) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file space page size too small"); + if (fsinfo.page_size < H5F_FILE_SPACE_PAGE_SIZE_MIN) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file space page size too small"); + if (f->shared->fs_page_size != fsinfo.page_size) { f->shared->fs_page_size = fsinfo.page_size; diff --git a/src/H5MFsection.c b/src/H5MFsection.c index 03d1112624e..a3b3988b38c 100644 --- a/src/H5MFsection.c +++ b/src/H5MFsection.c @@ -606,8 +606,10 @@ H5MF__sect_small_add(H5FS_section_info_t **_sect, unsigned *flags, void *_udata) HGOTO_DONE(ret_value); sect_end = (*sect)->sect_info.addr + (*sect)->sect_info.size; - rem = sect_end % udata->f->shared->fs_page_size; - prem = udata->f->shared->fs_page_size - rem; + if (0 == udata->f->shared->fs_page_size) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADVALUE, FAIL, "page size of zero would result in division by zero"); + rem = sect_end % udata->f->shared->fs_page_size; + prem = udata->f->shared->fs_page_size - rem; /* Drop the section if it is at page end and its size is <= pgend threshold */ if (!rem && (*sect)->sect_info.size <= H5F_PGEND_META_THRES(udata->f) &&