From 4e8f4ba8f08e0c0ea8591d79673bbd7ec26ee67c Mon Sep 17 00:00:00 2001 From: jykanase Date: Tue, 18 Nov 2025 11:31:32 +0000 Subject: [PATCH 1/9] Upgrade hdf5 version to 1.14.6 --- SPECS/hdf5/hdf5.signatures.json | 2 +- SPECS/hdf5/hdf5.spec | 36 ++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/SPECS/hdf5/hdf5.signatures.json b/SPECS/hdf5/hdf5.signatures.json index c8b6c02e293..4b011a64eed 100644 --- a/SPECS/hdf5/hdf5.signatures.json +++ b/SPECS/hdf5/hdf5.signatures.json @@ -1,6 +1,6 @@ { "Signatures": { "h5comp": "d0d40ba5b894f9fa1e230cbf123120243cb3aa58c85fa563eb88742d97744c2b", - "hdf5-1.14.4.3.tar.gz": "019ac451d9e1cf89c0482ba2a06f07a46166caf23f60fea5ef3c37724a318e03" + "hdf5-1.14.6.tar.gz": "e4defbac30f50d64e1556374aa49e574417c9e72c6b1de7a4ff88c4b1bea6e9b" } } diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 1d66ea9d277..967f3d9d12e 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -11,21 +11,35 @@ %endif Summary: A general purpose library and file format for storing scientific data Name: hdf5 -Version: 1.14.4.3 +Version: 1.14.6 Release: 1%{?dist} License: BSD Vendor: Microsoft Corporation Distribution: Azure Linux URL: https://portal.hdfgroup.org/display/HDF5/HDF5 -Source0: https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.4/src/hdf5-1.14.4-3.tar.gz#/%{name}-%{version}.tar.gz +Source0: https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_6/downloads/hdf5-1.14.6.tar.gz Source1: h5comp -Patch3: hdf5-build.patch +Patch0: hdf5-build.patch # Remove Fedora build flags from h5cc/h5c++/h5fc # https://bugzilla.redhat.com/show_bug.cgi?id=1794625 -Patch5: hdf5-wrappers.patch +Patch1: hdf5-wrappers.patch +Patch2: CVE-2025-2153.patch +Patch3: CVE-2025-2310.patch +Patch4: CVE-2025-2914.patch +Patch5: CVE-2025-2926.patch +Patch6: CVE-2025-2915.patch +Patch7: CVE-2025-6816.patch +Patch8: CVE-2025-2925.patch +Patch9: CVE-2025-2924.patch +Patch10: CVE-2025-44905.patch +Patch11: CVE-2025-6269.patch +Patch12: CVE-2025-6750.patch +Patch13: CVE-2025-6857.patch +Patch14: CVE-2025-7067.patch +Patch15: CVE-2025-7068.patch +Patch16: CVE-2025-6858.patch -# For patches/rpath # For patches/rpath BuildRequires: automake # Needed for mpi tests @@ -130,7 +144,7 @@ HDF5 parallel openmpi static libraries %prep -%autosetup -n %{name}-1.14.4-3 -p1 +%autosetup -p1 # Force shared by default for compiler wrappers (bug #1266645) sed -i -e '/^STATIC_AVAILABLE=/s/=.*/=no/' */*/h5[cf]*.in @@ -221,8 +235,6 @@ find %{buildroot} -type f -name "*.la" -delete -print mkdir -p %{buildroot}%{_libdir}/$mpi/hdf5/plugin module purge done -#Fixup example permissions -find %{buildroot}%{_datadir} \( -name '*.[ch]*' -o -name '*.f90' \) -exec chmod -x {} + #Fixup headers and scripts for multiarch %ifarch x86_64 ppc64 ia64 s390x sparc64 alpha @@ -309,7 +321,6 @@ done %{_libdir}/*.so %{_libdir}/*.settings %{_fmoddir}/*.mod -%{_datadir}/hdf5_examples/ %files static %{_libdir}/*.a @@ -398,6 +409,13 @@ done %changelog +* Tue Nov 19 2025 Jyoti kanase - 1.14.6-1 +- Upgrade to 1.14.6 +- Patch hdf5 for CVE-2025-2153, CVE-2025-2310, CVE-2025-2914, CVE-2025-2926, CVE-2025-2915, + CVE-2025-6816, CVE-2025-2925, CVE-2025-2924, CVE-2025-44905,CVE-2025-6269, CVE-2025-6750, + CVE-2025-6857, CVE-2025-7067, CVE-2025-7068, CVE-2025-6858, CVE_2025-2923, CVE-2025-2913, + CVE-2025-6516, CVE-2025-6818, CVE-2025-6817, CVE-2025-6856, CVE-2025-7069 + * Tue Jun 04 2024 Neha Agarwal - 1.14.4.3-1 - Upgrade to v1.14.4.3 to fix CVEs 2024-29157, 2024-29158, 2024-29159, 2024-29160, 2024-29161, 2024-29162, 2024-29163, 2024-29164, 2024-29165, 2024-29166, 2024-32605, From 92bf00a233851de985526acd3d99565c63559d7d Mon Sep 17 00:00:00 2001 From: jykanase Date: Tue, 18 Nov 2025 11:33:43 +0000 Subject: [PATCH 2/9] Patch hdf5 for CVE-2025-2153, CVE-2025-2310, CVE-2025-2914, CVE-2025-2926, CVE-2025-2915, CVE-2025-6816, CVE-2025-2925, CVE-2025-2924, CVE-2025-44905,CVE-2025-6269, CVE-2025-6750, CVE-2025-6857, CVE-2025-7067, CVE-2025-7068, CVE-2025-6858, CVE_2025-2923, CVE-2025-2913, CVE-2025-6516, CVE-2025-6818, CVE-2025-6817, CVE-2025-6856, CVE-2025-7069 --- SPECS/hdf5/CVE-2025-2153.patch | 43 ++ SPECS/hdf5/CVE-2025-2310.patch | 39 ++ SPECS/hdf5/CVE-2025-2914.patch | 47 ++ SPECS/hdf5/CVE-2025-2915.patch | 49 ++ SPECS/hdf5/CVE-2025-2924.patch | 36 ++ SPECS/hdf5/CVE-2025-2925.patch | 45 ++ SPECS/hdf5/CVE-2025-2926.patch | 31 + SPECS/hdf5/CVE-2025-44905.patch | 38 ++ SPECS/hdf5/CVE-2025-6269.patch | 279 +++++++++ SPECS/hdf5/CVE-2025-6750.patch | 86 +++ SPECS/hdf5/CVE-2025-6816.patch | 71 +++ SPECS/hdf5/CVE-2025-6857.patch | 136 +++++ SPECS/hdf5/CVE-2025-6858.patch | 33 ++ SPECS/hdf5/CVE-2025-7067.patch | 980 ++++++++++++++++++++++++++++++++ SPECS/hdf5/CVE-2025-7068.patch | 309 ++++++++++ 15 files changed, 2222 insertions(+) create mode 100644 SPECS/hdf5/CVE-2025-2153.patch create mode 100644 SPECS/hdf5/CVE-2025-2310.patch create mode 100644 SPECS/hdf5/CVE-2025-2914.patch create mode 100644 SPECS/hdf5/CVE-2025-2915.patch create mode 100644 SPECS/hdf5/CVE-2025-2924.patch create mode 100644 SPECS/hdf5/CVE-2025-2925.patch create mode 100644 SPECS/hdf5/CVE-2025-2926.patch create mode 100644 SPECS/hdf5/CVE-2025-44905.patch create mode 100644 SPECS/hdf5/CVE-2025-6269.patch create mode 100644 SPECS/hdf5/CVE-2025-6750.patch create mode 100644 SPECS/hdf5/CVE-2025-6816.patch create mode 100644 SPECS/hdf5/CVE-2025-6857.patch create mode 100644 SPECS/hdf5/CVE-2025-6858.patch create mode 100644 SPECS/hdf5/CVE-2025-7067.patch create mode 100644 SPECS/hdf5/CVE-2025-7068.patch diff --git a/SPECS/hdf5/CVE-2025-2153.patch b/SPECS/hdf5/CVE-2025-2153.patch new file mode 100644 index 00000000000..5e0a5a0261e --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2153.patch @@ -0,0 +1,43 @@ +From 4be883f34d8906bd907dcf0ddb17d47dad5357d3 Mon Sep 17 00:00:00 2001 +From: Glenn Song +Date: Mon, 8 Sep 2025 17:06:52 -0500 +Subject: [PATCH 01/14] Add release text + +Upstream patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5795.patch +--- + src/H5Ocache.c | 4 ++-- + src/H5Omessage.c | 3 +++ + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/H5Ocache.c b/src/H5Ocache.c +index 87f321c..12c30cf 100644 +--- a/src/H5Ocache.c ++++ b/src/H5Ocache.c +@@ -1399,8 +1399,8 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t + else { + /* Check for message of unshareable class marked as "shareable" + */ +- if ((flags & H5O_MSG_FLAG_SHAREABLE) && H5O_msg_class_g[id] && +- !(H5O_msg_class_g[id]->share_flags & H5O_SHARE_IS_SHARABLE)) ++ if (((flags & H5O_MSG_FLAG_SHARED) || (flags & H5O_MSG_FLAG_SHAREABLE)) && ++ H5O_msg_class_g[id] && !(H5O_msg_class_g[id]->share_flags & H5O_SHARE_IS_SHARABLE)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "message of unshareable class flagged as shareable"); + +diff --git a/src/H5Omessage.c b/src/H5Omessage.c +index 7190e46..fb9006c 100644 +--- a/src/H5Omessage.c ++++ b/src/H5Omessage.c +@@ -354,6 +354,9 @@ H5O__msg_write_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned m + */ + assert(!(mesg_flags & H5O_MSG_FLAG_DONTSHARE)); + ++ /* Sanity check to see if the type is not sharable */ ++ assert(type->share_flags & H5O_SHARE_IS_SHARABLE); ++ + /* Remove the old message from the SOHM index */ + /* (It would be more efficient to try to share the message first, then + * delete it (avoiding thrashing the index in the case the ref. +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2310.patch b/SPECS/hdf5/CVE-2025-2310.patch new file mode 100644 index 00000000000..43cc26efb4d --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2310.patch @@ -0,0 +1,39 @@ +From 2af87ef880bf562f1607aa7b6559e5c596cc0233 Mon Sep 17 00:00:00 2001 +From: Matthew Larson +Date: Wed, 24 Sep 2025 15:26:20 -0500 +Subject: [PATCH 1/4] Add null-termination check during attr decode + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5872.patch +--- + src/H5Oattr.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/H5Oattr.c b/src/H5Oattr.c +index 6d1d237..74e6614 100644 +--- a/src/H5Oattr.c ++++ b/src/H5Oattr.c +@@ -167,6 +167,11 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, name_len); /* Including null */ ++ ++ /* Verify that retrieved name length (including null byte) is valid */ ++ if (name_len <= 1) ++ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "decoded name length is invalid"); ++ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, attr->shared->dt_size); +@@ -190,7 +195,8 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u + */ + if (H5_IS_BUFFER_OVERFLOW(p, name_len, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); +- if (NULL == (attr->shared->name = H5MM_strndup((const char *)p, name_len - 1))) ++ ++ if (NULL == (attr->shared->name = H5MM_strndup((const char *)p, name_len - 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Make an attempt to detect corrupted name or name length - HDFFV-10588 */ +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2914.patch b/SPECS/hdf5/CVE-2025-2914.patch new file mode 100644 index 00000000000..2c978d35fe5 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2914.patch @@ -0,0 +1,47 @@ +From 54f404b5ad8e63d99e3283646b543b2842a22fd3 Mon Sep 17 00:00:00 2001 +From: Binh-Minh +Date: Tue, 12 Aug 2025 20:06:42 -0400 +Subject: [PATCH] Refix of the attempts in PR-5209 + +This PR addresses the root cause of the issue by adding a sanity-check immediately +after reading the file space page size from the file. + +The same fuzzer in GH-5376 was used to verify that the assert before the vulnerability +had occurred and that an error indicating a corrupted file space page size replaced it. + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5722.patch +--- + src/H5Fsuper.c | 2 ++ + src/H5Ofsinfo.c | 3 +++ + 2 files changed, 5 insertions(+) + +diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c +index d9fe3a7..1c8dc6c 100644 +--- a/src/H5Fsuper.c ++++ b/src/H5Fsuper.c +@@ -746,6 +746,8 @@ H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, bool initial_read) + if (!(flags & H5O_MSG_FLAG_WAS_UNKNOWN)) { + H5O_fsinfo_t fsinfo; /* File space info message from superblock extension */ + ++ memset(&fsinfo, 0, sizeof(H5O_fsinfo_t)); ++ + /* f->shared->null_fsm_addr: Whether to drop free-space to the floor */ + /* The h5clear tool uses this property to tell the library + * to drop free-space to the floor +diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c +index 5b69235..2bb6ea6 100644 +--- a/src/H5Ofsinfo.c ++++ b/src/H5Ofsinfo.c +@@ -182,6 +182,9 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, fsinfo->page_size); /* File space page size */ ++ /* Basic sanity check */ ++ if (fsinfo->page_size == 0 || fsinfo->page_size > H5F_FILE_SPACE_PAGE_SIZE_MAX) ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid page size in file space info"); + + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2915.patch b/SPECS/hdf5/CVE-2025-2915.patch new file mode 100644 index 00000000000..c6b67d05335 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2915.patch @@ -0,0 +1,49 @@ +From 073194de4c80bc8c6c010faa7d71ac9e3820e057 Mon Sep 17 00:00:00 2001 +From: Glenn Song +Date: Wed, 27 Aug 2025 14:36:26 -0500 +Subject: [PATCH 01/14] Move addr assert into if check + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5746.patch +--- + src/H5Faccum.c | 5 ++++- + src/H5Ocache_image.c | 8 ++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/H5Faccum.c b/src/H5Faccum.c +index 5fabf52..5c5ee79 100644 +--- a/src/H5Faccum.c ++++ b/src/H5Faccum.c +@@ -879,7 +879,10 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr + + /* Calculate the size of the overlap with the accumulator, etc. */ + H5_CHECKED_ASSIGN(overlap_size, size_t, (addr + size) - accum->loc, haddr_t); +- new_accum_size = accum->size - overlap_size; ++ /* Sanity check */ ++ /* Overlap size should not result in "negative" value after subtraction */ ++ assert(overlap_size < accum->size); ++ new_accum_size = accum->size - overlap_size; + + /* Move the accumulator buffer information to eliminate the freed block */ + memmove(accum->buf, accum->buf + overlap_size, new_accum_size); +diff --git a/src/H5Ocache_image.c b/src/H5Ocache_image.c +index d91b463..07e44b7 100644 +--- a/src/H5Ocache_image.c ++++ b/src/H5Ocache_image.c +@@ -116,6 +116,14 @@ H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, mesg->size); + ++ if (mesg->addr >= (HADDR_UNDEF - mesg->size)) ++ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size overflows"); ++ if (mesg->addr == HADDR_UNDEF) ++ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address is undefined"); ++ if ((mesg->addr + mesg->size) > H5F_get_eoa(f, H5FD_MEM_SUPER)) ++ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size exceeds file eoa"); ++ ++ + /* Set return value */ + ret_value = (void *)mesg; + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2924.patch b/SPECS/hdf5/CVE-2025-2924.patch new file mode 100644 index 00000000000..0916a4f3b4f --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2924.patch @@ -0,0 +1,36 @@ +From 422035e1c0a30f3b363a3994e62ac46f92db9b75 Mon Sep 17 00:00:00 2001 +From: Glenn Song +Date: Thu, 11 Sep 2025 16:24:33 -0500 +Subject: [PATCH 1/4] Add to sanity check + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5814.patch +--- + src/H5HLcache.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/H5HLcache.c b/src/H5HLcache.c +index d0836fe..7f412d2 100644 +--- a/src/H5HLcache.c ++++ b/src/H5HLcache.c +@@ -225,6 +225,7 @@ H5HL__fl_deserialize(H5HL_t *heap) + /* check arguments */ + assert(heap); + assert(!heap->freelist); ++ HDcompile_assert(sizeof(hsize_t) == sizeof(uint64_t)); + + /* Build free list */ + free_block = heap->free_block; +@@ -232,6 +233,10 @@ H5HL__fl_deserialize(H5HL_t *heap) + const uint8_t *image; /* Pointer into image buffer */ + + /* Sanity check */ ++ ++ if (free_block > UINT64_MAX - (2 * heap->sizeof_size)) ++ HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "decoded heap block address overflow"); ++ + if ((free_block + (2 * heap->sizeof_size)) > heap->dblk_size) + HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "bad heap free list"); + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2925.patch b/SPECS/hdf5/CVE-2025-2925.patch new file mode 100644 index 00000000000..4fdce736300 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2925.patch @@ -0,0 +1,45 @@ +From c731305ad3717924a9f48d4e4929956e80ce2cb3 Mon Sep 17 00:00:00 2001 +From: Glenn Song +Date: Thu, 21 Aug 2025 11:36:23 -0500 +Subject: [PATCH 01/10] Fix issue5383 + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5739.patch +--- + src/H5Centry.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/H5Centry.c b/src/H5Centry.c +index 1ca7479..13a0b8d 100644 +--- a/src/H5Centry.c ++++ b/src/H5Centry.c +@@ -1051,9 +1051,14 @@ H5C__load_entry(H5F_t *f, + */ + do { + if (actual_len != len) { ++ /* Verify that the length isn't a bad value */ ++ if (len == 0) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "len is a bad value"); ++ + if (NULL == (new_image = H5MM_realloc(image, len + H5C_IMAGE_EXTRA_SPACE))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()"); + image = (uint8_t *)new_image; ++ + #if H5C_DO_MEMORY_SANITY_CHECKS + H5MM_memcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ +@@ -1104,7 +1109,11 @@ H5C__load_entry(H5F_t *f, + if (H5C__verify_len_eoa(f, type, addr, &actual_len, true) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len exceeds EOA"); + +- /* Expand buffer to new size */ ++ /* Verify that the length isn't 0 */ ++ if (actual_len == 0) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len is a bad value"); ++ ++ /* Expand buffer to new size */ + if (NULL == (new_image = H5MM_realloc(image, actual_len + H5C_IMAGE_EXTRA_SPACE))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()"); + image = (uint8_t *)new_image; +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-2926.patch b/SPECS/hdf5/CVE-2025-2926.patch new file mode 100644 index 00000000000..23ccd33c56a --- /dev/null +++ b/SPECS/hdf5/CVE-2025-2926.patch @@ -0,0 +1,31 @@ +From b36c123a68f9f67f5a6de07fcd9caaf8586289c8 Mon Sep 17 00:00:00 2001 +From: Binh-Minh +Date: Tue, 16 Sep 2025 11:57:03 -0400 +Subject: [PATCH 1/7] Fix CVE-2025-2926, CVE-2025-2913 + +An image size was corrupted and decoded as 0 resulting in a NULL image buffer, +which caused a NULL pointer dereference when the image being copied to the buffer. +The invalid image size was caught in the PR #5710. This change catches right +before the copying. + +Fixes GH issue #5384 +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5841.patch +--- + src/H5Ocache.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/H5Ocache.c b/src/H5Ocache.c +index 12c30cf..4337d6e 100644 +--- a/src/H5Ocache.c ++++ b/src/H5Ocache.c +@@ -602,6 +602,7 @@ H5O__cache_chk_get_initial_load_size(void *_udata, size_t *image_len) + assert(udata); + assert(udata->oh); + assert(image_len); ++ assert(udata->size); + + /* Set the image length size */ + *image_len = udata->size; +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-44905.patch b/SPECS/hdf5/CVE-2025-44905.patch new file mode 100644 index 00000000000..9a37b536c2d --- /dev/null +++ b/SPECS/hdf5/CVE-2025-44905.patch @@ -0,0 +1,38 @@ +From 28ab45329218d9e41bd77929fd3e9cd8a80bd3c7 Mon Sep 17 00:00:00 2001 +From: Christian Wojek +Date: Sat, 11 Oct 2025 12:43:06 +0200 +Subject: [PATCH 1/5] Fixing CVE-2025-44905. A malformed HDF5 can cause reading + beyond a heap allocation. + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5915.patch +--- + src/H5Zscaleoffset.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c +index 048344b..0e7cab7 100644 +--- a/src/H5Zscaleoffset.c ++++ b/src/H5Zscaleoffset.c +@@ -1205,6 +1205,9 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu + unsigned minval_size = 0; + + minbits = 0; ++ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5, (unsigned char *)*buf + *buf_size - 1)) ++ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "buffer too short"); ++ + for (i = 0; i < 4; i++) { + minbits_mask = ((unsigned char *)*buf)[i]; + minbits_mask <<= i * 8; +@@ -1220,6 +1223,9 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu + minval_size = sizeof(unsigned long long) <= ((unsigned char *)*buf)[4] ? sizeof(unsigned long long) + : ((unsigned char *)*buf)[4]; + minval = 0; ++ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5 + minval_size, ++ (unsigned char *)*buf + *buf_size - 1)) ++ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "buffer too short"); + for (i = 0; i < minval_size; i++) { + minval_mask = ((unsigned char *)*buf)[5 + i]; + minval_mask <<= i * 8; +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-6269.patch b/SPECS/hdf5/CVE-2025-6269.patch new file mode 100644 index 00000000000..7f56e100c80 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-6269.patch @@ -0,0 +1,279 @@ +From 2597b336272fa2d8e277826cd5a96507bad54cd6 Mon Sep 17 00:00:00 2001 +From: Binh-Minh +Date: Mon, 1 Sep 2025 03:23:38 -0400 +Subject: [PATCH 1/9] Fix security issue CVE-2025-6269 + +The GitHub issue #5579 included several security vulnerabilities in function +H5C__reconstruct_cache_entry(). + +This PR addressed them by: +- adding buffer size argument to the function +- adding buffer overflow checks +- adding input validations +- releasing allocated resource on failure + +These changes addressed the crashes reported. However, there is a skiplist +crash during the unwinding process that has to be investigated. + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5850.patch +--- + src/H5Cimage.c | 90 ++++++++++++++++++++++++++++++++++++++------------ + src/H5Ocont.c | 5 +-- + 2 files changed, 71 insertions(+), 24 deletions(-) + +diff --git a/src/H5Cimage.c b/src/H5Cimage.c +index ec1af78..cca65fd 100644 +--- a/src/H5Cimage.c ++++ b/src/H5Cimage.c +@@ -118,7 +118,7 @@ do { \ + /* Helper routines */ + static size_t H5C__cache_image_block_entry_header_size(const H5F_t *f); + static size_t H5C__cache_image_block_header_size(const H5F_t *f); +-static herr_t H5C__decode_cache_image_header(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf); ++static herr_t H5C__decode_cache_image_header(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf, size_t buf_size); + #ifndef NDEBUG /* only used in assertions */ + static herr_t H5C__decode_cache_image_entry(const H5F_t *f, const H5C_t *cache_ptr, const uint8_t **buf, + unsigned entry_num); +@@ -131,7 +131,8 @@ static void H5C__prep_for_file_close__compute_fd_heights_real(H5C_cache_entry_ + static herr_t H5C__prep_for_file_close__setup_image_entries_array(H5C_t *cache_ptr); + static herr_t H5C__prep_for_file_close__scan_entries(const H5F_t *f, H5C_t *cache_ptr); + static herr_t H5C__reconstruct_cache_contents(H5F_t *f, H5C_t *cache_ptr); +-static H5C_cache_entry_t *H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf); ++static H5C_cache_entry_t *H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, hsize_t *buf_size, ++ const uint8_t **buf); + static herr_t H5C__write_cache_image_superblock_msg(H5F_t *f, bool create); + static herr_t H5C__read_cache_image(H5F_t *f, H5C_t *cache_ptr); + static herr_t H5C__write_cache_image(H5F_t *f, const H5C_t *cache_ptr); +@@ -299,7 +300,7 @@ H5C__construct_cache_image_buffer(H5F_t *f, H5C_t *cache_ptr) + /* needed for sanity checks */ + fake_cache_ptr->image_len = cache_ptr->image_len; + q = (const uint8_t *)cache_ptr->image_buffer; +- status = H5C__decode_cache_image_header(f, fake_cache_ptr, &q); ++ status = H5C__decode_cache_image_header(f, fake_cache_ptr, &q, cache_ptr->image_len + 1); + assert(status >= 0); + + assert(NULL != p); +@@ -1269,7 +1270,7 @@ H5C__cache_image_block_header_size(const H5F_t *f) + *------------------------------------------------------------------------- + */ + static herr_t +-H5C__decode_cache_image_header(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf) ++H5C__decode_cache_image_header(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf, size_t buf_size) + { + uint8_t version; + uint8_t flags; +@@ -2372,6 +2373,7 @@ H5C__reconstruct_cache_contents(H5F_t *f, H5C_t *cache_ptr) + { + H5C_cache_entry_t *pf_entry_ptr; /* Pointer to prefetched entry */ + H5C_cache_entry_t *parent_ptr; /* Pointer to parent of prefetched entry */ ++ hsize_t image_len; /* Image length */ + const uint8_t *p; /* Pointer into image buffer */ + unsigned u, v; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ +@@ -2387,10 +2389,11 @@ H5C__reconstruct_cache_contents(H5F_t *f, H5C_t *cache_ptr) + assert(cache_ptr->image_len > 0); + + /* Decode metadata cache image header */ +- p = (uint8_t *)cache_ptr->image_buffer; +- if (H5C__decode_cache_image_header(f, cache_ptr, &p) < 0) ++ p = (uint8_t *)cache_ptr->image_buffer; ++ image_len = cache_ptr->image_len; ++ if (H5C__decode_cache_image_header(f, cache_ptr, &p, image_len + 1) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTDECODE, FAIL, "cache image header decode failed"); +- assert((size_t)(p - (uint8_t *)cache_ptr->image_buffer) < cache_ptr->image_len); ++ assert((size_t)(p - (uint8_t *)cache_ptr->image_buffer) < image_len); + + /* The image_data_len and # of entries should be defined now */ + assert(cache_ptr->image_data_len > 0); +@@ -2402,7 +2405,7 @@ H5C__reconstruct_cache_contents(H5F_t *f, H5C_t *cache_ptr) + /* Create the prefetched entry described by the ith + * entry in cache_ptr->image_entrise. + */ +- if (NULL == (pf_entry_ptr = H5C__reconstruct_cache_entry(f, cache_ptr, &p))) ++ if (NULL == (pf_entry_ptr = H5C__reconstruct_cache_entry(f, cache_ptr, &image_len, &p))) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "reconstruction of cache entry failed"); + + /* Note that we make no checks on available cache space before +@@ -2558,20 +2561,21 @@ done: + *------------------------------------------------------------------------- + */ + static H5C_cache_entry_t * +-H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf) ++H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, hsize_t *buf_size, const uint8_t **buf) + { + H5C_cache_entry_t *pf_entry_ptr = NULL; /* Reconstructed cache entry */ + uint8_t flags = 0; + bool is_dirty = false; ++ haddr_t eoa; ++ bool is_fd_parent = false; + #ifndef NDEBUG /* only used in assertions */ +- bool in_lru = false; +- bool is_fd_parent = false; +- bool is_fd_child = false; ++ bool in_lru = false; ++ bool is_fd_child = false; + #endif +- const uint8_t *p; + bool file_is_rw; +- H5C_cache_entry_t *ret_value = NULL; /* Return value */ +- ++ const uint8_t *p; ++ const uint8_t *p_end = *buf + *buf_size - 1; /* Pointer to last valid byte in buffer */ ++ H5C_cache_entry_t *ret_value = NULL; /* Return value */ + FUNC_ENTER_PACKAGE + + /* Sanity checks */ +@@ -2590,9 +2594,15 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + p = *buf; + + /* Decode type id */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + pf_entry_ptr->prefetch_type_id = *p++; ++ if (pf_entry_ptr->prefetch_type_id < H5AC_BT_ID || pf_entry_ptr->prefetch_type_id >= H5AC_NTYPES) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "type id is out of valid range"); + + /* Decode flags */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + flags = *p++; + if (flags & H5C__MDCI_ENTRY_DIRTY_FLAG) + is_dirty = true; +@@ -2620,19 +2630,31 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + pf_entry_ptr->is_dirty = (is_dirty && file_is_rw); + + /* Decode ring */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + pf_entry_ptr->ring = *p++; +- assert(pf_entry_ptr->ring > (uint8_t)(H5C_RING_UNDEFINED)); +- assert(pf_entry_ptr->ring < (uint8_t)(H5C_RING_NTYPES)); ++ if (pf_entry_ptr->ring >= (uint8_t)(H5C_RING_NTYPES)) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "ring is out of valid range"); + + /* Decode age */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + pf_entry_ptr->age = *p++; ++ if (pf_entry_ptr->age > H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "entry age is out of policy range"); + + /* Decode dependency child count */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, pf_entry_ptr->fd_child_count); +- assert((is_fd_parent && pf_entry_ptr->fd_child_count > 0) || +- (!is_fd_parent && pf_entry_ptr->fd_child_count == 0)); ++ if (is_fd_parent && pf_entry_ptr->fd_child_count <= 0) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "parent entry has no children"); ++ else if (!is_fd_parent && pf_entry_ptr->fd_child_count != 0) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "non-parent entry has children"); + + /* Decode dirty dependency child count */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, pf_entry_ptr->fd_dirty_child_count); + if (!file_is_rw) + pf_entry_ptr->fd_dirty_child_count = 0; +@@ -2640,20 +2662,32 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "invalid dirty flush dependency child count"); + + /* Decode dependency parent count */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + UINT16DECODE(p, pf_entry_ptr->fd_parent_count); + assert((is_fd_child && pf_entry_ptr->fd_parent_count > 0) || + (!is_fd_child && pf_entry_ptr->fd_parent_count == 0)); + + /* Decode index in LRU */ ++ if (H5_IS_BUFFER_OVERFLOW(p, 4, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + INT32DECODE(p, pf_entry_ptr->lru_rank); + assert((in_lru && pf_entry_ptr->lru_rank >= 0) || (!in_lru && pf_entry_ptr->lru_rank == -1)); + + /* Decode entry offset */ ++ if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_addr_decode(f, &p, &pf_entry_ptr->addr); +- if (!H5_addr_defined(pf_entry_ptr->addr)) +- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "invalid entry offset"); ++ ++ /* Validate address range */ ++ eoa = H5F_get_eoa(f, H5FD_MEM_DEFAULT); ++ if (!H5_addr_defined(pf_entry_ptr->addr) || H5_addr_overflow(pf_entry_ptr->addr, pf_entry_ptr->size) || ++ H5_addr_ge(pf_entry_ptr->addr + pf_entry_ptr->size, eoa)) ++ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "invalid entry address range"); + + /* Decode entry length */ ++ if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_SIZE(f), p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, pf_entry_ptr->size); + if (pf_entry_ptr->size == 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "invalid entry size"); +@@ -2674,6 +2708,9 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + "memory allocation failed for fd parent addrs buffer"); + + for (u = 0; u < pf_entry_ptr->fd_parent_count; u++) { ++ ++ if (H5_IS_BUFFER_OVERFLOW(p, H5F_SIZEOF_ADDR(f), p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_addr_decode(f, &p, &(pf_entry_ptr->fd_parent_addrs[u])); + if (!H5_addr_defined(pf_entry_ptr->fd_parent_addrs[u])) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "invalid flush dependency parent offset"); +@@ -2689,6 +2726,8 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ + + /* Copy the entry image from the cache image block */ ++ if (H5_IS_BUFFER_OVERFLOW(p, pf_entry_ptr->size, p_end)) ++ HGOTO_ERROR(H5E_CACHE, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5MM_memcpy(pf_entry_ptr->image_ptr, p, pf_entry_ptr->size); + p += pf_entry_ptr->size; + +@@ -2704,13 +2743,20 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **b + assert(pf_entry_ptr->size > 0 && pf_entry_ptr->size < H5C_MAX_ENTRY_SIZE); + + /* Update buffer pointer */ ++ /* Update buffer pointer and buffer len */ ++ *buf_size -= (hsize_t)(p - *buf); + *buf = p; + + ret_value = pf_entry_ptr; + + done: +- if (NULL == ret_value && pf_entry_ptr) ++ if (NULL == ret_value && pf_entry_ptr) { ++ if (pf_entry_ptr->image_ptr) ++ H5MM_xfree(pf_entry_ptr->image_ptr); ++ if (pf_entry_ptr->fd_parent_count > 0 && pf_entry_ptr->fd_parent_addrs) ++ H5MM_xfree(pf_entry_ptr->fd_parent_addrs); + pf_entry_ptr = H5FL_FREE(H5C_cache_entry_t, pf_entry_ptr); ++ } + + FUNC_LEAVE_NOAPI(ret_value) + } /* H5C__reconstruct_cache_entry() */ +diff --git a/src/H5Ocont.c b/src/H5Ocont.c +index 621095a..180b115 100644 +--- a/src/H5Ocont.c ++++ b/src/H5Ocont.c +@@ -93,6 +93,9 @@ H5O__cont_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Decode */ ++ ++ cont->chunkno = 0; ++ + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_addr(f), p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_addr_decode(f, &p, &(cont->addr)); +@@ -101,8 +104,6 @@ H5O__cont_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, cont->size); + +- cont->chunkno = 0; +- + /* Set return value */ + ret_value = cont; + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-6750.patch b/SPECS/hdf5/CVE-2025-6750.patch new file mode 100644 index 00000000000..a21504839f1 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-6750.patch @@ -0,0 +1,86 @@ +From aaaf32bb035f8b1ad8f634d799688587590d8544 Mon Sep 17 00:00:00 2001 +From: Binh-Minh +Date: Sun, 21 Sep 2025 22:29:27 -0400 +Subject: [PATCH 1/4] Fixes CVE-2025-6750 + +A heap buffer overflow occurred because an mtime message was not properly decoded, resulting in a buffer of size 0 being passed into the encoder. + +This PR added decoding for both old and new mtime messages which will allow invalid message size to be detected. + +Fixes #5549 +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5856.patch +--- + src/H5Ocache.c | 43 ++++++++++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 7 deletions(-) + +diff --git a/src/H5Ocache.c b/src/H5Ocache.c +index 4337d6e..d54e0b1 100644 +--- a/src/H5Ocache.c ++++ b/src/H5Ocache.c +@@ -1266,7 +1266,10 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t + if (mesg_size != H5O_ALIGN_OH(oh, mesg_size)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "message not aligned"); + +- /* Message flags */ ++ if (H5_IS_BUFFER_OVERFLOW(chunk_image, mesg_size, p_end)) ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "message size exceeds buffer end"); ++ ++ /* Message flags */ + if (H5_IS_BUFFER_OVERFLOW(chunk_image, 1, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); + flags = *chunk_image++; +@@ -1298,12 +1301,6 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t + } + } + +- /* Try to detect invalidly formatted object header message that +- * extends past end of chunk. +- */ +- if (chunk_image + mesg_size > eom_ptr) +- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "corrupt object header"); +- + /* Increment count of null messages */ + if (H5O_NULL_ID == id) + nullcnt++; +@@ -1450,6 +1447,38 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't decode refcount"); + oh->nlink = *refcount; + } ++ /* Check if message is an old mtime message */ ++ else if (H5O_MTIME_ID == id) { ++ time_t *mtime = NULL; ++ ++ /* Decode mtime message */ ++ mtime = ++ (time_t *)(H5O_MSG_MTIME->decode)(udata->f, NULL, 0, &ioflags, mesg->raw_size, mesg->raw); ++ ++ /* Save the decoded old format mtime */ ++ if (!mtime) ++ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode old format mtime"); ++ ++ /* Save 'native' form of mtime message and its value */ ++ mesg->native = mtime; ++ oh->ctime = *mtime; ++ } ++ /* Check if message is an new mtime message */ ++ else if (H5O_MTIME_NEW_ID == id) { ++ time_t *mtime = NULL; ++ ++ /* Decode mtime message */ ++ mtime = (time_t *)(H5O_MSG_MTIME_NEW->decode)(udata->f, NULL, 0, &ioflags, mesg->raw_size, ++ mesg->raw); ++ ++ /* Save the decoded new format mtime */ ++ if (!mtime) ++ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode new format mtime"); ++ ++ /* Save 'native' form of mtime message and its value */ ++ mesg->native = mtime; ++ oh->ctime = *mtime; ++ } + /* Check if message is a link message */ + else if (H5O_LINK_ID == id) { + /* Increment the count of link messages */ +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-6816.patch b/SPECS/hdf5/CVE-2025-6816.patch new file mode 100644 index 00000000000..9fff36503b7 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-6816.patch @@ -0,0 +1,71 @@ +From b6d4a76c7a9309eba6e70fde0e1ecf0dd09d3d23 Mon Sep 17 00:00:00 2001 +From: Jordan Henderson +Date: Mon, 15 Sep 2025 12:26:10 -0500 +Subject: [PATCH] Fix issue with handling of corrupted object header + continuation messages + +An HDF5 file could be specifically constructed such that an object +header contained a corrupted continuation message which pointed +back to itself. This eventually resulted in an internal buffer being +allocated with too small of a size, leading to a heap buffer overflow +when encoding an object header message into it. This has been fixed +by checking the expected number of deserialized object header chunks +against the actual value as chunks are being deserialized. + +Fixes CVE-2025-6816, CVE-2025-6856, CVE-2025-2923, CVE-2025-6818 + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5829.patch +--- + src/H5Oint.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/src/H5Oint.c b/src/H5Oint.c +index 460ccb6..4083524 100644 +--- a/src/H5Oint.c ++++ b/src/H5Oint.c +@@ -1013,12 +1013,11 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) + */ + curr_msg = 0; + while (curr_msg < cont_msg_info.nmsgs) { +- H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */ +-#ifndef NDEBUG +- size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */ +-#endif /* NDEBUG */ +- +- /* Bring the chunk into the cache */ ++ H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */ ++ unsigned chunkno; /* Chunk number for chunk proxy */ ++ size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */ ++ ++ /* Bring the chunk into the cache */ + /* (which adds to the object header) */ + chk_udata.common.addr = cont_msg_info.msgs[curr_msg].addr; + chk_udata.size = cont_msg_info.msgs[curr_msg].size; +@@ -1029,15 +1028,21 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) + + /* Sanity check */ + assert(chk_proxy->oh == oh); +- assert(chk_proxy->chunkno == chkcnt); +- assert(oh->nchunks == (chkcnt + 1)); ++ ++ chunkno = chk_proxy->chunkno; + + /* Release the chunk from the cache */ + if (H5AC_unprotect(loc->file, H5AC_OHDR_CHK, cont_msg_info.msgs[curr_msg].addr, chk_proxy, + H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header chunk"); + +- /* Advance to next continuation message */ ++ if (chunkno != chkcnt) ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect chunk number for object header chunk"); ++ if (oh->nchunks != (chkcnt + 1)) ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, ++ "incorrect number of chunks after deserializing object header chunk"); ++ ++ /* Advance to next continuation message */ + curr_msg++; + } /* end while */ + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-6857.patch b/SPECS/hdf5/CVE-2025-6857.patch new file mode 100644 index 00000000000..1c41efda2aa --- /dev/null +++ b/SPECS/hdf5/CVE-2025-6857.patch @@ -0,0 +1,136 @@ +From 852a9f87849833074683038ea47ddf3cb5e10311 Mon Sep 17 00:00:00 2001 +From: Jordan Henderson +Date: Wed, 10 Sep 2025 16:41:49 -0500 +Subject: [PATCH] Fix CVE-2025-6857 + +Add additional checks for v1 B-tree corruption +Upstream Patch Reference :https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5799.patch +--- + src/H5B.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + src/H5Bpkg.h | 6 ++++++ + 2 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/src/H5B.c b/src/H5B.c +index 30e39ef..fd2069b 100644 +--- a/src/H5B.c ++++ b/src/H5B.c +@@ -140,6 +140,8 @@ typedef struct H5B_ins_ud_t { + /********************/ + /* Local Prototypes */ + /********************/ ++static herr_t H5B_find_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, int exp_level, bool *found, ++ void *udata); + static H5B_ins_t H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, uint8_t *lt_key, + bool *lt_key_changed, uint8_t *md_key, void *udata, uint8_t *rt_key, + bool *rt_key_changed, H5B_ins_ud_t *split_bt_ud /*out*/); +@@ -272,6 +274,47 @@ done: + */ + herr_t + H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *udata) ++{ ++ herr_t ret_value = SUCCEED; ++ ++ FUNC_ENTER_NOAPI(FAIL) ++ ++ /* ++ * Check arguments. ++ */ ++ assert(f); ++ assert(type); ++ assert(type->decode); ++ assert(type->cmp3); ++ assert(type->found); ++ assert(H5_addr_defined(addr)); ++ ++ if ((ret_value = H5B_find_helper(f, type, addr, H5B_UNKNOWN_NODELEVEL, found, udata)) < 0) ++ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key"); ++ ++done: ++ FUNC_LEAVE_NOAPI(ret_value) ++} /* end H5B_find() */ ++ ++/*------------------------------------------------------------------------- ++ * Function: H5B_find_helper ++ * ++ * Purpose: Recursive helper routine for H5B_find used to track node ++ * levels and attempt to detect B-tree corruption during ++ * lookups. ++ * ++ * Note: This function does not follow the left/right sibling ++ * pointers since it assumes that all nodes can be reached ++ * from the parent node. ++ * ++ * Return: Non-negative on success (if found, values returned through ++ * the UDATA argument). Negative on failure (if not found, ++ * UDATA is undefined). ++ * ++ *------------------------------------------------------------------------- ++ */ ++static herr_t ++H5B_find_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, int exp_level, bool *found, void *udata) + { + H5B_t *bt = NULL; + H5UC_t *rc_shared; /* Ref-counted shared info */ +@@ -306,6 +349,7 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *uda + cache_udata.f = f; + cache_udata.type = type; + cache_udata.rc_shared = rc_shared; ++ cache_udata.exp_level = exp_level; + if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__READ_ONLY_FLAG))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree node"); + +@@ -329,7 +373,17 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *uda + assert(idx < bt->nchildren); + + if (bt->level > 0) { +- if ((ret_value = H5B_find(f, type, bt->child[idx], found, udata)) < 0) ++ /* Sanity check to catch the case where the current node points to ++ * itself and the current node was loaded with an expected node level ++ * of H5B_UNKNOWN_NODELEVEL, thus bypassing the expected node level ++ * check during deserialization and in the future if the node was ++ * cached. ++ */ ++ if (bt->child[idx] == addr) ++ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, FAIL, "cyclic B-tree detected"); ++ ++ if ((ret_value = H5B_find_helper(f, type, bt->child[idx], (int)(bt->level - 1), found, udata)) < ++ 0) + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree"); + } /* end if */ + else { +@@ -343,7 +397,7 @@ done: + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release node"); + + FUNC_LEAVE_NOAPI(ret_value) +-} /* end H5B_find() */ ++} /* end H5B_find_helper() */ + + /*------------------------------------------------------------------------- + * Function: H5B__split +diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h +index d1ad647..f75e857 100644 +--- a/src/H5Bpkg.h ++++ b/src/H5Bpkg.h +@@ -39,6 +39,11 @@ + /* # of bits for node level: 1 byte */ + #define LEVEL_BITS 8 + ++/* Indicates that the level of the current node is unknown. When the level ++ * is known, it can be used to detect corrupted level during decoding ++ */ ++#define H5B_UNKNOWN_NODELEVEL -1 ++ + /****************************/ + /* Package Private Typedefs */ + /****************************/ +@@ -60,6 +65,7 @@ typedef struct H5B_t { + typedef struct H5B_cache_ud_t { + H5F_t *f; /* File that B-tree node is within */ + const struct H5B_class_t *type; /* Type of tree */ ++ int exp_level; /* Expected level of the current node */ + H5UC_t *rc_shared; /* Ref-counted shared info */ + } H5B_cache_ud_t; + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-6858.patch b/SPECS/hdf5/CVE-2025-6858.patch new file mode 100644 index 00000000000..300c46a44bc --- /dev/null +++ b/SPECS/hdf5/CVE-2025-6858.patch @@ -0,0 +1,33 @@ +From ff3d6722a91587daaaac82e78b25d26ad3f50172 Mon Sep 17 00:00:00 2001 +From: Binh-Minh +Date: Mon, 4 Aug 2025 03:10:29 -0400 +Subject: [PATCH] Fix reading bad size in the raw header continuation message + +This issue was reported in GH-5376 as a heap-use-after-free vulnerability in +one of the free lists. It appeared that the library came to this vulnerability +after it encountered an undetected reading of a bad value. The fuzzer now failed +with an appropriate error message. + +This considers addressing what GH-5376 reported. +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5710.patch +--- + src/H5Ocont.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/H5Ocont.c b/src/H5Ocont.c +index 180b115..44ef8b1 100644 +--- a/src/H5Ocont.c ++++ b/src/H5Ocont.c +@@ -104,6 +104,9 @@ H5O__cont_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5F_DECODE_LENGTH(f, p, cont->size); + ++ if (cont->size == 0) ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid continuation chunk size (0)"); ++ + /* Set return value */ + ret_value = cont; + +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-7067.patch b/SPECS/hdf5/CVE-2025-7067.patch new file mode 100644 index 00000000000..d4f8039bbd8 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-7067.patch @@ -0,0 +1,980 @@ +From 1bc11ba2952dd942cf637f5a2c748e8e9c4031a4 Mon Sep 17 00:00:00 2001 +From: Jordan Henderson +Date: Fri, 12 Sep 2025 21:58:17 -0500 +Subject: [PATCH] Unlink file free space section on failure to update data + structures + +When linking a file free space section into a free space manager's +internal data structures, the library previously wouldn't unlink +the free space section when it failed to update the free space +manager's internal data structures. This could eventually result +in a use-after-free issue due to the stale reference kept around. + +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5815.patch +https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5938.patch +--- + src/H5FScache.c | 2 +- + src/H5FSprivate.h | 2 +- + src/H5FSsection.c | 89 +++++++++++++++++++++++++++++++++++++++++----- + src/H5HFspace.c | 2 +- + src/H5MF.c | 58 ++++++++++++++++++++++-------- + src/H5MFpkg.h | 3 +- + src/H5MFsection.c | 24 +++++++++++-- + test/freespace.c | 90 ++++++++++++++++++++++++++--------------------- + test/mf.c | 32 ++++++++--------- + 9 files changed, 215 insertions(+), 87 deletions(-) + +diff --git a/src/H5FScache.c b/src/H5FScache.c +index 7f8edf6..2db500b 100644 +--- a/src/H5FScache.c ++++ b/src/H5FScache.c +@@ -1024,7 +1024,7 @@ H5FS__cache_sinfo_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED l + + /* Insert section in free space manager, unless requested not to */ + if (!(des_flags & H5FS_DESERIALIZE_NO_ADD)) +- if (H5FS_sect_add(udata->f, fspace, new_sect, H5FS_ADD_DESERIALIZING, udata) < 0) ++ if (H5FS_sect_add(udata->f, fspace, new_sect, H5FS_ADD_DESERIALIZING, udata, NULL) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, NULL, + "can't add section to free space manager"); + } /* end for */ +diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h +index f917a25..954fd9e 100644 +--- a/src/H5FSprivate.h ++++ b/src/H5FSprivate.h +@@ -198,7 +198,7 @@ H5_DLL herr_t H5FS_free(H5F_t *f, H5FS_t *fspace, bool free_file_space); + + /* Free space section routines */ + H5_DLL herr_t H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *node, unsigned flags, +- void *op_data); ++ void *op_data, bool *merged_or_shrunk); + H5_DLL htri_t H5FS_sect_try_merge(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, + void *op_data); + H5_DLL htri_t H5FS_sect_try_extend(H5F_t *f, H5FS_t *fspace, haddr_t addr, hsize_t size, +diff --git a/src/H5FSsection.c b/src/H5FSsection.c +index 57022a2..6d9bca7 100644 +--- a/src/H5FSsection.c ++++ b/src/H5FSsection.c +@@ -1057,8 +1057,9 @@ done: + static herr_t + H5FS__sect_link(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags) + { +- const H5FS_section_class_t *cls; /* Class of section */ +- herr_t ret_value = SUCCEED; /* Return value */ ++ const H5FS_section_class_t *cls; /* Class of section */ ++ bool linked_sect = false; /* Was the section linked in? */ ++ herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + +@@ -1073,6 +1074,7 @@ H5FS__sect_link(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags) + /* Add section to size tracked data structures */ + if (H5FS__sect_link_size(fspace->sinfo, cls, sect) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't add section to size tracking data structures"); ++ linked_sect = true; + + /* Update rest of free space manager data structures for section addition */ + if (H5FS__sect_link_rest(fspace, cls, sect, flags) < 0) +@@ -1080,6 +1082,12 @@ H5FS__sect_link(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags) + "can't add section to non-size tracking data structures"); + + done: ++ if (ret_value < 0) { ++ if (linked_sect && H5FS__sect_unlink_size(fspace->sinfo, cls, sect) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, ++ "can't remove section from size tracking data structures"); ++ } ++ + FUNC_LEAVE_NOAPI(ret_value) + } /* H5FS__sect_link() */ + +@@ -1289,7 +1297,8 @@ done: + *------------------------------------------------------------------------- + */ + herr_t +-H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data) ++H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data, ++ bool *merged_or_shrunk) + { + H5FS_section_class_t *cls; /* Section's class */ + bool sinfo_valid = false; /* Whether the section info is valid */ +@@ -1310,6 +1319,9 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag + assert(H5_addr_defined(sect->addr)); + assert(sect->size); + ++ if (merged_or_shrunk) ++ *merged_or_shrunk = false; ++ + /* Get a pointer to the section info */ + if (H5FS__sinfo_lock(f, fspace, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info"); +@@ -1336,9 +1348,12 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag + /* (If section has been completely merged or shrunk away, 'sect' will + * be NULL at this point - QAK) + */ +- if (sect) ++ if (sect) { + if (H5FS__sect_link(fspace, sect, flags) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list"); ++ } ++ else if (merged_or_shrunk) ++ *merged_or_shrunk = true; + + #ifdef H5FS_SINFO_DEBUG + fprintf(stderr, "%s: fspace->tot_space = %" PRIuHSIZE "\n", __func__, fspace->tot_space); +@@ -2306,11 +2321,15 @@ done: + herr_t + H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr_ptr) + { +- hsize_t hdr_alloc_size; +- hsize_t sinfo_alloc_size; +- haddr_t sect_addr = HADDR_UNDEF; /* address of sinfo */ +- haddr_t eoa = HADDR_UNDEF; /* Initial EOA for the file */ +- herr_t ret_value = SUCCEED; /* Return value */ ++ hsize_t hdr_alloc_size = 0; ++ hsize_t sinfo_alloc_size = 0; ++ haddr_t sect_addr = HADDR_UNDEF; /* address of sinfo */ ++ haddr_t eoa = HADDR_UNDEF; /* Initial EOA for the file */ ++ bool allocated_header = false; /* Whether a free space header was allocated */ ++ bool inserted_header = false; /* Whether a free space header was inserted into the metadata cache */ ++ bool allocated_section = false; /* Whether a free space section was allocated */ ++ bool inserted_section = false; /* Whether a free space section was inserted into the metadata cache */ ++ herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + +@@ -2359,10 +2378,12 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t + /* Allocate space for the free space header */ + if (HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, hdr_alloc_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for free space header"); ++ allocated_header = true; + + /* Cache the new free space header (pinned) */ + if (H5AC_insert_entry(f, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space header to cache"); ++ inserted_header = true; + + *fs_addr_ptr = fspace->addr; + } +@@ -2388,6 +2409,7 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t + /* allocate space for the section info */ + if (HADDR_UNDEF == (sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, sinfo_alloc_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info"); ++ allocated_section = true; + + /* update fspace->alloc_sect_size and fspace->sect_addr to reflect + * the allocation +@@ -2429,6 +2451,7 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t + */ + if (H5AC_insert_entry(f, H5AC_FSPACE_SINFO, sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sinfo to cache"); ++ inserted_section = true; + + /* We have changed the sinfo address -- Mark free space header dirty */ + if (H5AC_mark_entry_dirty(fspace) < 0) +@@ -2445,5 +2468,53 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t + } /* end if */ + + done: ++ if (ret_value < 0) { ++ /* Remove the free space section that was inserted into the metadata cache, ++ * making sure to free the file space that was allocated for it as well. ++ * Avoid expunging the entry, as the information needs to be kept around ++ * until we finish trying to settle the metadata free space manager(s). ++ */ ++ if (allocated_section && (sect_addr == fspace->sect_addr)) { ++ assert(H5_addr_defined(fspace->sect_addr)); ++ ++ if (H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, sect_addr, sinfo_alloc_size) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections"); ++ fspace->sect_addr = HADDR_UNDEF; ++ } ++ ++ if (inserted_section) { ++ if (H5AC_remove_entry(fspace->sinfo) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTEXPUNGE, FAIL, ++ "can't remove file free space section from cache"); ++ } ++ ++ /* Remove the free space header that was inserted into the metadata cache, ++ * making sure to free the file space that was allocated for it as well. ++ * Avoid expunging the entry, as the information needs to be kept around ++ * until we finish trying to settle the metadata free space manager(s). ++ */ ++ if (allocated_header) { ++ assert(H5_addr_defined(fspace->addr)); ++ ++ /* Free file space before removing entry from cache, as freeing the ++ * file space may depend on a valid cache pointer. ++ */ ++ if (H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, fspace->addr, hdr_alloc_size) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free file free space header"); ++ fspace->addr = HADDR_UNDEF; ++ } ++ ++ if (inserted_header) { ++ if (H5AC_mark_entry_clean(fspace) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTMARKCLEAN, FAIL, ++ "can't mark file free space header as clean"); ++ if (H5AC_unpin_entry(fspace) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "can't unpin file free space header"); ++ if (H5AC_remove_entry(fspace) < 0) ++ HDONE_ERROR(H5E_FSPACE, H5E_CANTEXPUNGE, FAIL, ++ "can't remove file free space header from cache"); ++ } ++ } ++ + FUNC_LEAVE_NOAPI(ret_value) + } /* H5FS_vfd_alloc_hdr_and_section_info_if_needed() */ +diff --git a/src/H5HFspace.c b/src/H5HFspace.c +index 8c9f0c0..ea1b63f 100644 +--- a/src/H5HFspace.c ++++ b/src/H5HFspace.c +@@ -159,7 +159,7 @@ H5HF__space_add(H5HF_hdr_t *hdr, H5HF_free_section_t *node, unsigned flags) + udata.hdr = hdr; + + /* Add to the free space for the heap */ +- if (H5FS_sect_add(hdr->f, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0) ++ if (H5FS_sect_add(hdr->f, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata, NULL) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space"); + + done: +diff --git a/src/H5MF.c b/src/H5MF.c +index 2de3e7a..a9c1cf5 100644 +--- a/src/H5MF.c ++++ b/src/H5MF.c +@@ -596,7 +596,8 @@ done: + *------------------------------------------------------------------------- + */ + herr_t +-H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node) ++H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node, ++ bool *merged_or_shrunk) + { + H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ + H5AC_ring_t fsm_ring = H5AC_RING_INV; /* Ring of FSM */ +@@ -631,7 +632,8 @@ H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_sectio + __func__, node->sect_info.addr, node->sect_info.size); + #endif /* H5MF_ALLOC_DEBUG_MORE */ + /* Add the section */ +- if (H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0) ++ if (H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata, ++ merged_or_shrunk) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space"); + + done: +@@ -711,8 +713,11 @@ H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, h + #endif /* H5MF_ALLOC_DEBUG_MORE */ + + /* Re-add the section to the free-space manager */ +- if (H5MF__add_sect(f, alloc_type, fspace, node) < 0) ++ if (H5MF__add_sect(f, alloc_type, fspace, node, NULL) < 0) { ++ node->sect_info.addr -= size; ++ node->sect_info.size += size; + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space"); ++ } + } /* end else */ + } /* end if */ + +@@ -852,9 +857,10 @@ done: + static haddr_t + H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) + { +- H5F_mem_page_t ptype; /* Free-space manager type */ +- H5MF_free_section_t *node = NULL; /* Free space section pointer */ +- haddr_t ret_value = HADDR_UNDEF; /* Return value */ ++ H5F_mem_page_t ptype; /* Free-space manager type */ ++ H5MF_free_section_t *node = NULL; /* Free space section pointer */ ++ bool section_merged_or_shrunk = false; /* Whether free space section was merged or shrunk away */ ++ haddr_t ret_value = HADDR_UNDEF; /* Return value */ + + FUNC_ENTER_PACKAGE + +@@ -900,9 +906,13 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) + "can't initialize free space section"); + + /* Add the fragment to the large free-space manager */ +- if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0) ++ if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node, §ion_merged_or_shrunk) < ++ 0) { ++ if (section_merged_or_shrunk) ++ node = NULL; + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, + "can't re-add section to file free space"); ++ } + + node = NULL; + } /* end if */ +@@ -931,9 +941,13 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize free space section"); + + /* Add the remaining space in the page to the manager */ +- if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0) ++ if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node, §ion_merged_or_shrunk) < ++ 0) { ++ if (section_merged_or_shrunk) ++ node = NULL; + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, + "can't re-add section to file free space"); ++ } + + node = NULL; + +@@ -1154,6 +1168,8 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) + + /* If size of the freed section is larger than threshold, add it to the free space manager */ + if (size >= f->shared->fs_threshold) { ++ bool section_merged_or_shrunk = false; /* Whether free space section was merged or shrunk away */ ++ + assert(f->shared->fs_man[fs_type]); + + #ifdef H5MF_ALLOC_DEBUG_MORE +@@ -1161,8 +1177,12 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) + #endif /* H5MF_ALLOC_DEBUG_MORE */ + + /* Add to the free space for the file */ +- if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0) ++ if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node, §ion_merged_or_shrunk) < 0) { ++ if (section_merged_or_shrunk) ++ node = NULL; + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space"); ++ } ++ + node = NULL; + + #ifdef H5MF_ALLOC_DEBUG_MORE +@@ -1316,7 +1336,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section"); + + /* Add the fragment to the large-sized free-space manager */ +- if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0) ++ if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node, NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space"); + + node = NULL; +@@ -3059,8 +3079,13 @@ H5MF_settle_meta_data_fsm(H5F_t *f, bool *fsm_settled) + assert(sm_fssinfo_fs_type > H5F_MEM_PAGE_DEFAULT); + assert(sm_fssinfo_fs_type < H5F_MEM_PAGE_LARGE_SUPER); + +- assert(!H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type])); +- assert(!H5_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type])); ++ if (H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type])) ++ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, FAIL, ++ "small free space header block manager should not have had file space allocated"); ++ if (H5_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type])) ++ HGOTO_ERROR( ++ H5E_FSPACE, H5E_BADVALUE, FAIL, ++ "small free space serialized section manager should not have had file space allocated"); + + /* Note that in most cases, sm_hdr_fspace will equal sm_sinfo_fspace. */ + sm_hdr_fspace = f->shared->fs_man[sm_fshdr_fs_type]; +@@ -3078,8 +3103,13 @@ H5MF_settle_meta_data_fsm(H5F_t *f, bool *fsm_settled) + assert(lg_fssinfo_fs_type >= H5F_MEM_PAGE_LARGE_SUPER); + assert(lg_fssinfo_fs_type < H5F_MEM_PAGE_NTYPES); + +- assert(!H5_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type])); +- assert(!H5_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type])); ++ if (H5_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type])) ++ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, FAIL, ++ "large free space header block manager should not have had file space allocated"); ++ if (H5_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type])) ++ HGOTO_ERROR( ++ H5E_FSPACE, H5E_BADVALUE, FAIL, ++ "large free space serialized section manager should not have had file space allocated"); + + /* Note that in most cases, lg_hdr_fspace will equal lg_sinfo_fspace. */ + lg_hdr_fspace = f->shared->fs_man[lg_fshdr_fs_type]; +diff --git a/src/H5MFpkg.h b/src/H5MFpkg.h +index 32d04d3..e6fd7b8 100644 +--- a/src/H5MFpkg.h ++++ b/src/H5MFpkg.h +@@ -176,7 +176,8 @@ H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1]; + H5_DLL herr_t H5MF__open_fstype(H5F_t *f, H5F_mem_page_t type); + H5_DLL herr_t H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type); + H5_DLL htri_t H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, haddr_t *addr); +-H5_DLL herr_t H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node); ++H5_DLL herr_t H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node, ++ bool *merged_or_shrunk); + H5_DLL void H5MF__alloc_to_fs_type(H5F_shared_t *f_sh, H5FD_mem_t alloc_type, hsize_t size, + H5F_mem_page_t *fs_type); + +diff --git a/src/H5MFsection.c b/src/H5MFsection.c +index a3b3988..04fcdce 100644 +--- a/src/H5MFsection.c ++++ b/src/H5MFsection.c +@@ -360,7 +360,13 @@ H5MF__sect_simple_can_merge(const H5FS_section_info_t *_sect1, const H5FS_sectio + assert(sect1); + assert(sect2); + assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ +- assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); ++ ++ /* ++ * The library currently doesn't attempt to detect duplicate or overlapping ++ * free space sections being inserted into the free space managers. Until it ++ * does so, this assertion must be left out. ++ */ ++ /* assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); */ + + /* Check if second section adjoins first section */ + ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr); +@@ -663,7 +669,13 @@ H5MF__sect_small_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section + assert(sect1); + assert(sect2); + assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ +- assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); ++ ++ /* ++ * The library currently doesn't attempt to detect duplicate or overlapping ++ * free space sections being inserted into the free space managers. Until it ++ * does so, this assertion must be left out. ++ */ ++ /* assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); */ + + /* Check if second section adjoins first section */ + ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr); +@@ -769,7 +781,13 @@ H5MF__sect_large_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section + assert(sect1); + assert(sect2); + assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ +- assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); ++ ++ /* ++ * The library currently doesn't attempt to detect duplicate or overlapping ++ * free space sections being inserted into the free space managers. Until it ++ * does so, this assertion must be left out. ++ */ ++ /* assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); */ + + ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr); + +diff --git a/test/freespace.c b/test/freespace.c +index 2d81217..074f201 100644 +--- a/test/freespace.c ++++ b/test/freespace.c +@@ -638,7 +638,7 @@ test_fs_sect_add(hid_t fapl) + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -704,7 +704,7 @@ test_fs_sect_add(hid_t fapl) + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, 0, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, 0, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -781,7 +781,8 @@ test_fs_sect_add(hid_t fapl) + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &can_shrink, NULL) < ++ 0) + FAIL_STACK_ERROR; + + /* nothing in free-space */ +@@ -851,7 +852,8 @@ test_fs_sect_add(hid_t fapl) + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_DESERIALIZING, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_DESERIALIZING, &can_shrink, NULL) < ++ 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1007,7 +1009,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1027,7 +1029,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node3, (haddr_t)(TEST_SECT_ADDR200), (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node3->sect_info.size; +@@ -1046,7 +1048,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -1065,7 +1067,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR300, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node4->sect_info.size; +@@ -1134,7 +1136,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1154,7 +1156,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -1213,7 +1215,7 @@ test_fs_sect_find(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1361,7 +1363,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1381,7 +1383,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* section B & C are merged */ +@@ -1399,7 +1401,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* section A is merged with the merged section of B & C */ +@@ -1417,7 +1419,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* section D is merged with the merged section of A & B & C */ +@@ -1490,7 +1492,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1510,7 +1512,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* section A & B are not merged because H5FS_CLS_SEPAR_OBJ is set */ +@@ -1593,7 +1595,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1613,7 +1615,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, + TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* sections A & B are not merged because H5FS_CLS_MERGE_SYM is set & section class type is different */ +@@ -1633,7 +1635,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, + TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* sections B & C are merged because H5FS_CLS_MERGE_SYM is set & section class type is the same */ +@@ -1651,7 +1653,7 @@ test_fs_sect_merge(hid_t fapl) + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* +@@ -1840,7 +1842,8 @@ test_fs_sect_shrink(hid_t fapl) + TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + + can_shrink = false; +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1875,7 +1878,8 @@ test_fs_sect_shrink(hid_t fapl) + H5FS_SECT_LIVE); + + can_shrink = false; +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + /* should have nothing in free-space */ +@@ -1941,7 +1945,8 @@ test_fs_sect_shrink(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -1961,7 +1966,8 @@ test_fs_sect_shrink(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + /* free-space should be the same since section B is shrunk */ +@@ -2041,7 +2047,8 @@ test_fs_sect_shrink(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2061,7 +2068,8 @@ test_fs_sect_shrink(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink, ++ NULL) < 0) + FAIL_STACK_ERROR; + + /* section A & B are merged and then strunk, so there is nothing in free-space */ +@@ -2183,7 +2191,7 @@ test_fs_sect_change_class(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2203,7 +2211,7 @@ test_fs_sect_change_class(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, + TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += TEST_SECT_SIZE50; +@@ -2287,7 +2295,7 @@ test_fs_sect_change_class(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* +@@ -2299,7 +2307,7 @@ test_fs_sect_change_class(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, + TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* +@@ -2311,7 +2319,7 @@ test_fs_sect_change_class(hid_t fapl) + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80, + TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + /* change the class of B to A's class */ +@@ -2471,7 +2479,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2491,7 +2499,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -2548,7 +2556,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2568,7 +2576,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -2622,7 +2630,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2642,7 +2650,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -2697,7 +2705,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(frspace_state_t)); +@@ -2717,7 +2725,7 @@ test_fs_sect_extend(hid_t fapl) + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, + H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + + state.tot_space += sect_node2->sect_info.size; +@@ -2828,7 +2836,7 @@ test_fs_sect_iterate(hid_t fapl) + sect_size = (unsigned)((i - 1) % 9) + 1; + init_sect_node(sect_node, (haddr_t)i * 10, (hsize_t)sect_size, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + +- if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0) ++ if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL, NULL) < 0) + FAIL_STACK_ERROR; + } /* end for */ + +diff --git a/test/mf.c b/test/mf.c +index e400348..8ed6871 100644 +--- a/test/mf.c ++++ b/test/mf.c +@@ -1222,7 +1222,7 @@ test_mf_fs_alloc_free(hid_t fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1300,7 +1300,7 @@ test_mf_fs_alloc_free(hid_t fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1376,7 +1376,7 @@ test_mf_fs_alloc_free(hid_t fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1552,7 +1552,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1581,7 +1581,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50); + + /* Add section B to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2, NULL)) + FAIL_STACK_ERROR; + + state.tot_space += TBLOCK_SIZE50; +@@ -1662,7 +1662,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1691,7 +1691,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50); + + /* Add section B to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2, NULL)) + FAIL_STACK_ERROR; + + state.tot_space += TBLOCK_SIZE50; +@@ -1767,7 +1767,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1796,7 +1796,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50); + + /* Add section B to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2, NULL)) + FAIL_STACK_ERROR; + + state.tot_space += TBLOCK_SIZE50; +@@ -1873,7 +1873,7 @@ test_mf_fs_extend(hid_t fapl) + H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)(TBLOCK_SIZE30 - 10)); + + /* Add section A of size=20 to free-space */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -1902,7 +1902,7 @@ test_mf_fs_extend(hid_t fapl) + sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50); + + /* Add section B to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2, NULL)) + FAIL_STACK_ERROR; + + state.tot_space += TBLOCK_SIZE50; +@@ -2057,7 +2057,7 @@ test_mf_fs_absorb(const char *driver_name, hid_t fapl) + H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)(ma_addr + ma_size), (hsize_t)TBLOCK_SIZE2048); + + /* Add a section to free-space that adjoins end of the aggregator */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + /* Verify that the section did absorb the aggregator */ +@@ -2117,7 +2117,7 @@ test_mf_fs_absorb(const char *driver_name, hid_t fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)addr, (hsize_t)TBLOCK_SIZE30); + + /* When adding, meta_aggr is absorbed onto the end of the section */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + /* Verify that the section did absorb the aggregator */ +@@ -4183,7 +4183,7 @@ test_mf_align_fs(const char *driver_name, hid_t fapl, hid_t new_fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)alignment, (hsize_t)TBLOCK_SIZE50); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -4247,7 +4247,7 @@ test_mf_align_fs(const char *driver_name, hid_t fapl, hid_t new_fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE8000); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +@@ -4334,7 +4334,7 @@ test_mf_align_fs(const char *driver_name, hid_t fapl, hid_t new_fapl) + sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE700); + + /* Add section A to free-space manager */ +- if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node)) ++ if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node, NULL)) + FAIL_STACK_ERROR; + + memset(&state, 0, sizeof(H5FS_stat_t)); +-- +2.45.4 + diff --git a/SPECS/hdf5/CVE-2025-7068.patch b/SPECS/hdf5/CVE-2025-7068.patch new file mode 100644 index 00000000000..4be2ae96ff2 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-7068.patch @@ -0,0 +1,309 @@ +From 58f5a6bc06bd3ad0a60bc12551e2da4f5c0aa65d Mon Sep 17 00:00:00 2001 +From: Jordan Henderson +Date: Sat, 13 Sep 2025 19:51:59 -0500 +Subject: [PATCH] Fix issue with handling of failure during discard of metadata + cache entries + +When discarding a metadata cache entry after flushing it, errors +during the discard process could cause the library to skip calling +the 'free_icr' callback for the entry. This could result in resource +leaks and the inability of the cache to be fully flushed and closed +due to issues such as pinned entries remaining in the cache. This +has been fixed by noting errors during the discard process, but +attempting to fully free a cache entry before signalling that an +error has occurred. + +Fixes CVE-2025-7068 +Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5817.patch +--- + src/H5Centry.c | 259 ++++++++++++++++++++++++++++--------------------- + 1 file changed, 148 insertions(+), 111 deletions(-) + +diff --git a/src/H5Centry.c b/src/H5Centry.c +index 13a0b8d..8542396 100644 +--- a/src/H5Centry.c ++++ b/src/H5Centry.c +@@ -63,6 +63,9 @@ static herr_t H5C__pin_entry_from_client(H5C_t *cache_ptr, H5C_cache_entry_t *en + static herr_t H5C__unpin_entry_real(H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr, bool update_rp); + static herr_t H5C__unpin_entry_from_client(H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr, bool update_rp); + static herr_t H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr); ++static herr_t H5C__discard_single_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr, ++ bool destroy_entry, bool free_file_space, ++ bool suppress_image_entry_frees); + static herr_t H5C__verify_len_eoa(H5F_t *f, const H5C_class_t *type, haddr_t addr, size_t *len, bool actual); + static void *H5C__load_entry(H5F_t *f, + #ifdef H5_HAVE_PARALLEL +@@ -753,118 +756,13 @@ H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags) + * Now discard the entry if appropriate. + */ + if (destroy) { +- /* Sanity check */ +- assert(0 == entry_ptr->flush_dep_nparents); +- +- /* if both suppress_image_entry_frees and entry_ptr->include_in_image +- * are true, simply set entry_ptr->image_ptr to NULL, as we have +- * another pointer to the buffer in an instance of H5C_image_entry_t +- * in cache_ptr->image_entries. +- * +- * Otherwise, free the buffer if it exists. +- */ +- if (suppress_image_entry_frees && entry_ptr->include_in_image) +- entry_ptr->image_ptr = NULL; +- else if (entry_ptr->image_ptr != NULL) +- entry_ptr->image_ptr = H5MM_xfree(entry_ptr->image_ptr); +- +- /* If the entry is not a prefetched entry, verify that the flush +- * dependency parents addresses array has been transferred. +- * +- * If the entry is prefetched, the free_isr routine will dispose of +- * the flush dependency parents addresses array if necessary. +- */ +- if (!entry_ptr->prefetched) { +- assert(0 == entry_ptr->fd_parent_count); +- assert(NULL == entry_ptr->fd_parent_addrs); +- } /* end if */ +- +- /* Check whether we should free the space in the file that +- * the entry occupies +- */ +- if (free_file_space) { +- hsize_t fsf_size; +- +- /* Sanity checks */ +- assert(H5_addr_defined(entry_ptr->addr)); +- assert(!H5F_IS_TMP_ADDR(f, entry_ptr->addr)); +-#ifndef NDEBUG +- { +- size_t curr_len; +- +- /* Get the actual image size for the thing again */ +- entry_ptr->type->image_len((void *)entry_ptr, &curr_len); +- assert(curr_len == entry_ptr->size); +- } +-#endif +- +- /* If the file space free size callback is defined, use +- * it to get the size of the block of file space to free. +- * Otherwise use entry_ptr->size. +- */ +- if (entry_ptr->type->fsf_size) { +- if ((entry_ptr->type->fsf_size)((void *)entry_ptr, &fsf_size) < 0) +- HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to get file space free size"); +- } /* end if */ +- else /* no file space free size callback -- use entry size */ +- fsf_size = entry_ptr->size; +- +- /* Release the space on disk */ +- if (H5MF_xfree(f, entry_ptr->type->mem_type, entry_ptr->addr, fsf_size) < 0) +- HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free file space for cache entry"); +- } /* end if ( free_file_space ) */ +- +- /* Reset the pointer to the cache the entry is within. -QAK */ +- entry_ptr->cache_ptr = NULL; +- +- /* increment entries_removed_counter and set +- * last_entry_removed_ptr. As we are likely abuut to +- * free the entry, recall that last_entry_removed_ptr +- * must NEVER be dereferenced. +- * +- * Recall that these fields are maintained to allow functions +- * that perform scans of lists of entries to detect the +- * unexpected removal of entries (via expunge, eviction, +- * or take ownership at present), so that they can re-start +- * their scans if necessary. +- * +- * Also check if the entry we are watching for removal is being +- * removed (usually the 'next' entry for an iteration) and reset +- * it to indicate that it was removed. +- */ +- cache_ptr->entries_removed_counter++; +- cache_ptr->last_entry_removed_ptr = entry_ptr; +- +- if (entry_ptr == cache_ptr->entry_watched_for_removal) +- cache_ptr->entry_watched_for_removal = NULL; +- +- /* Check for actually destroying the entry in memory */ +- /* (As opposed to taking ownership of it) */ +- if (destroy_entry) { +- if (entry_ptr->is_dirty) { +- /* Reset dirty flag */ +- entry_ptr->is_dirty = false; +- +- /* If the entry's type has a 'notify' callback send a +- * 'entry cleaned' notice now that the entry is fully +- * integrated into the cache. +- */ +- if (entry_ptr->type->notify && +- (entry_ptr->type->notify)(H5C_NOTIFY_ACTION_ENTRY_CLEANED, entry_ptr) < 0) +- HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, +- "can't notify client about entry dirty flag cleared"); +- } /* end if */ +- +- /* verify that the image has been freed */ +- assert(entry_ptr->image_ptr == NULL); ++ /* Make sure one of either `destroy_entry` or `take_ownership` are true */ ++ assert(destroy_entry != take_ownership); + +- if (entry_ptr->type->free_icr((void *)entry_ptr) < 0) +- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "free_icr callback failed"); +- } /* end if */ +- else { +- assert(take_ownership); +- } /* end else */ +- } /* if (destroy) */ ++ if (H5C__discard_single_entry(f, cache_ptr, entry_ptr, destroy_entry, free_file_space, ++ suppress_image_entry_frees) < 0) ++ HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't discard cache entry"); ++ } + + /* Check if we have to update the page buffer with cleared entries + * so it doesn't go out of date +@@ -891,6 +789,145 @@ done: + FUNC_LEAVE_NOAPI(ret_value) + } /* H5C__flush_single_entry() */ + ++/*------------------------------------------------------------------------- ++ * Function: H5C__discard_single_entry ++ * ++ * Purpose: Helper routine to discard a cache entry, freeing as much ++ * of the relevant file space and data structures as possible ++ * along the way. ++ * ++ * Return: FAIL if error is detected, SUCCEED otherwise. ++ * ++ *------------------------------------------------------------------------- ++ */ ++static herr_t ++H5C__discard_single_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr, bool destroy_entry, ++ bool free_file_space, bool suppress_image_entry_frees) ++{ ++ herr_t ret_value = SUCCEED; ++ ++ FUNC_ENTER_PACKAGE ++ ++ assert(f); ++ assert(cache_ptr); ++ assert(entry_ptr); ++ ++ /* Sanity check */ ++ assert(0 == entry_ptr->flush_dep_nparents); ++ ++ /* if both suppress_image_entry_frees and entry_ptr->include_in_image ++ * are true, simply set entry_ptr->image_ptr to NULL, as we have ++ * another pointer to the buffer in an instance of H5C_image_entry_t ++ * in cache_ptr->image_entries. ++ * ++ * Otherwise, free the buffer if it exists. ++ */ ++ if (suppress_image_entry_frees && entry_ptr->include_in_image) ++ entry_ptr->image_ptr = NULL; ++ else if (entry_ptr->image_ptr != NULL) ++ entry_ptr->image_ptr = H5MM_xfree(entry_ptr->image_ptr); ++ ++ /* If the entry is not a prefetched entry, verify that the flush ++ * dependency parents addresses array has been transferred. ++ * ++ * If the entry is prefetched, the free_icr routine will dispose of ++ * the flush dependency parents addresses array if necessary. ++ */ ++ if (!entry_ptr->prefetched) { ++ assert(0 == entry_ptr->fd_parent_count); ++ assert(NULL == entry_ptr->fd_parent_addrs); ++ } /* end if */ ++ ++ /* Check whether we should free the space in the file that ++ * the entry occupies ++ */ ++ if (free_file_space) { ++ hsize_t fsf_size; ++ ++ /* Sanity checks */ ++ assert(H5_addr_defined(entry_ptr->addr)); ++ assert(!H5F_IS_TMP_ADDR(f, entry_ptr->addr)); ++#ifndef NDEBUG ++ { ++ size_t curr_len; ++ ++ /* Get the actual image size for the thing again */ ++ entry_ptr->type->image_len((void *)entry_ptr, &curr_len); ++ assert(curr_len == entry_ptr->size); ++ } ++#endif ++ ++ /* If the file space free size callback is defined, use ++ * it to get the size of the block of file space to free. ++ * Otherwise use entry_ptr->size. ++ */ ++ if (entry_ptr->type->fsf_size) { ++ if ((entry_ptr->type->fsf_size)((void *)entry_ptr, &fsf_size) < 0) ++ /* Note error but keep going */ ++ HDONE_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to get file space free size"); ++ } /* end if */ ++ else /* no file space free size callback -- use entry size */ ++ fsf_size = entry_ptr->size; ++ ++ /* Release the space on disk */ ++ if ((ret_value >= 0) && H5MF_xfree(f, entry_ptr->type->mem_type, entry_ptr->addr, fsf_size) < 0) ++ /* Note error but keep going */ ++ HDONE_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free file space for cache entry"); ++ } /* end if ( free_file_space ) */ ++ ++ /* Reset the pointer to the cache the entry is within. -QAK */ ++ entry_ptr->cache_ptr = NULL; ++ ++ /* increment entries_removed_counter and set ++ * last_entry_removed_ptr. As we are likely about to ++ * free the entry, recall that last_entry_removed_ptr ++ * must NEVER be dereferenced. ++ * ++ * Recall that these fields are maintained to allow functions ++ * that perform scans of lists of entries to detect the ++ * unexpected removal of entries (via expunge, eviction, ++ * or take ownership at present), so that they can re-start ++ * their scans if necessary. ++ * ++ * Also check if the entry we are watching for removal is being ++ * removed (usually the 'next' entry for an iteration) and reset ++ * it to indicate that it was removed. ++ */ ++ cache_ptr->entries_removed_counter++; ++ cache_ptr->last_entry_removed_ptr = entry_ptr; ++ ++ if (entry_ptr == cache_ptr->entry_watched_for_removal) ++ cache_ptr->entry_watched_for_removal = NULL; ++ ++ /* Check for actually destroying the entry in memory */ ++ /* (As opposed to taking ownership of it) */ ++ if (destroy_entry) { ++ if (entry_ptr->is_dirty) { ++ /* Reset dirty flag */ ++ entry_ptr->is_dirty = false; ++ ++ /* If the entry's type has a 'notify' callback send a ++ * 'entry cleaned' notice now that the entry is fully ++ * integrated into the cache. ++ */ ++ if (entry_ptr->type->notify && ++ (entry_ptr->type->notify)(H5C_NOTIFY_ACTION_ENTRY_CLEANED, entry_ptr) < 0) ++ /* Note error but keep going */ ++ HDONE_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, ++ "can't notify client about entry dirty flag cleared"); ++ } /* end if */ ++ ++ /* verify that the image has been freed */ ++ assert(entry_ptr->image_ptr == NULL); ++ ++ if (entry_ptr->type->free_icr((void *)entry_ptr) < 0) ++ /* Note error but keep going */ ++ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "free_icr callback failed"); ++ } /* end if */ ++ ++ FUNC_LEAVE_NOAPI(ret_value) ++} /* end H5C__discard_single_entry() */ ++ + /*------------------------------------------------------------------------- + * Function: H5C__verify_len_eoa + * +-- +2.45.4 + From 63591be4afb501c970cecd44f656431b8df017a0 Mon Sep 17 00:00:00 2001 From: jykanase Date: Tue, 18 Nov 2025 11:49:49 +0000 Subject: [PATCH 3/9] updated cgmanifest.json --- SPECS/hdf5/hdf5.spec | 2 +- cgmanifest.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 967f3d9d12e..09206765d88 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -17,7 +17,7 @@ License: BSD Vendor: Microsoft Corporation Distribution: Azure Linux URL: https://portal.hdfgroup.org/display/HDF5/HDF5 -Source0: https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_6/downloads/hdf5-1.14.6.tar.gz +Source0: https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_6/downloads/%{name}-%{version}.tar.gz Source1: h5comp Patch0: hdf5-build.patch diff --git a/cgmanifest.json b/cgmanifest.json index fdcce73e94f..e1ba3c0d2bf 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -5290,8 +5290,8 @@ "type": "other", "other": { "name": "hdf5", - "version": "1.14.4.3", - "downloadUrl": "https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.4/src/hdf5-1.14.4-3.tar.gz" + "version": "1.14.6", + "downloadUrl": "https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_6/downloads/hdf5-1.14.6.tar.gz" } } }, From bbc853a4be4c23fce3fa8087594f25a7dffc8e79 Mon Sep 17 00:00:00 2001 From: jykanase Date: Thu, 20 Nov 2025 05:12:53 +0000 Subject: [PATCH 4/9] Updated patches --- SPECS/hdf5/CVE-2025-2310.patch | 18 ++++++++---------- SPECS/hdf5/CVE-2025-2915.patch | 26 ++++++++++++-------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/SPECS/hdf5/CVE-2025-2310.patch b/SPECS/hdf5/CVE-2025-2310.patch index 43cc26efb4d..a068588f573 100644 --- a/SPECS/hdf5/CVE-2025-2310.patch +++ b/SPECS/hdf5/CVE-2025-2310.patch @@ -5,13 +5,13 @@ Subject: [PATCH 1/4] Add null-termination check during attr decode Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5872.patch --- - src/H5Oattr.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) + hdf5-1.14.6/src/H5Oattr.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/src/H5Oattr.c b/src/H5Oattr.c -index 6d1d237..74e6614 100644 ---- a/src/H5Oattr.c -+++ b/src/H5Oattr.c +diff --git a/hdf5-1.14.6/src/H5Oattr.c b/hdf5-1.14.6/src/H5Oattr.c +index 6d1d237..7bdaef7 100644 +--- a/hdf5-1.14.6/src/H5Oattr.c ++++ b/hdf5-1.14.6/src/H5Oattr.c @@ -167,6 +167,11 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); @@ -24,16 +24,14 @@ index 6d1d237..74e6614 100644 if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); UINT16DECODE(p, attr->shared->dt_size); -@@ -190,7 +195,8 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u +@@ -190,6 +195,7 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u */ if (H5_IS_BUFFER_OVERFLOW(p, name_len, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); -- if (NULL == (attr->shared->name = H5MM_strndup((const char *)p, name_len - 1))) + -+ if (NULL == (attr->shared->name = H5MM_strndup((const char *)p, name_len - 1))) + if (NULL == (attr->shared->name = H5MM_strndup((const char *)p, name_len - 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - /* Make an attempt to detect corrupted name or name length - HDFFV-10588 */ -- 2.45.4 diff --git a/SPECS/hdf5/CVE-2025-2915.patch b/SPECS/hdf5/CVE-2025-2915.patch index c6b67d05335..bb6ca04436a 100644 --- a/SPECS/hdf5/CVE-2025-2915.patch +++ b/SPECS/hdf5/CVE-2025-2915.patch @@ -5,30 +5,28 @@ Subject: [PATCH 01/14] Move addr assert into if check Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5746.patch --- - src/H5Faccum.c | 5 ++++- - src/H5Ocache_image.c | 8 ++++++++ - 2 files changed, 12 insertions(+), 1 deletion(-) + hdf5-1.14.6/src/H5Faccum.c | 3 +++ + hdf5-1.14.6/src/H5Ocache_image.c | 8 ++++++++ + 2 files changed, 11 insertions(+) -diff --git a/src/H5Faccum.c b/src/H5Faccum.c -index 5fabf52..5c5ee79 100644 ---- a/src/H5Faccum.c -+++ b/src/H5Faccum.c -@@ -879,7 +879,10 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr +diff --git a/hdf5-1.14.6/src/H5Faccum.c b/hdf5-1.14.6/src/H5Faccum.c +index 5fabf52..53f90fb 100644 +--- a/hdf5-1.14.6/src/H5Faccum.c ++++ b/hdf5-1.14.6/src/H5Faccum.c +@@ -879,6 +879,9 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr /* Calculate the size of the overlap with the accumulator, etc. */ H5_CHECKED_ASSIGN(overlap_size, size_t, (addr + size) - accum->loc, haddr_t); -- new_accum_size = accum->size - overlap_size; + /* Sanity check */ + /* Overlap size should not result in "negative" value after subtraction */ + assert(overlap_size < accum->size); -+ new_accum_size = accum->size - overlap_size; + new_accum_size = accum->size - overlap_size; /* Move the accumulator buffer information to eliminate the freed block */ - memmove(accum->buf, accum->buf + overlap_size, new_accum_size); -diff --git a/src/H5Ocache_image.c b/src/H5Ocache_image.c +diff --git a/hdf5-1.14.6/src/H5Ocache_image.c b/hdf5-1.14.6/src/H5Ocache_image.c index d91b463..07e44b7 100644 ---- a/src/H5Ocache_image.c -+++ b/src/H5Ocache_image.c +--- a/hdf5-1.14.6/src/H5Ocache_image.c ++++ b/hdf5-1.14.6/src/H5Ocache_image.c @@ -116,6 +116,14 @@ H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, mesg->size); From 6c40286324d0bd645690d35d846093b009adb6ae Mon Sep 17 00:00:00 2001 From: jykanase Date: Mon, 24 Nov 2025 07:20:16 +0000 Subject: [PATCH 5/9] FIxed indentation in patches --- SPECS/hdf5/CVE-2025-2310.patch | 6 ++--- SPECS/hdf5/CVE-2025-2915.patch | 12 ++++----- SPECS/hdf5/CVE-2025-2925.patch | 14 +++++------ SPECS/hdf5/CVE-2025-44905.patch | 6 ++--- SPECS/hdf5/CVE-2025-6750.patch | 14 +++++------ SPECS/hdf5/CVE-2025-6816.patch | 28 +++++++++------------ SPECS/hdf5/CVE-2025-6857.patch | 44 ++++++++++++++++++++++++++++----- SPECS/hdf5/CVE-2025-6858.patch | 13 +++++----- SPECS/hdf5/hdf5.spec | 22 ++++++++--------- 9 files changed, 90 insertions(+), 69 deletions(-) diff --git a/SPECS/hdf5/CVE-2025-2310.patch b/SPECS/hdf5/CVE-2025-2310.patch index a068588f573..9a834ac8239 100644 --- a/SPECS/hdf5/CVE-2025-2310.patch +++ b/SPECS/hdf5/CVE-2025-2310.patch @@ -5,13 +5,13 @@ Subject: [PATCH 1/4] Add null-termination check during attr decode Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5872.patch --- - hdf5-1.14.6/src/H5Oattr.c | 6 ++++++ + src/H5Oattr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hdf5-1.14.6/src/H5Oattr.c b/hdf5-1.14.6/src/H5Oattr.c index 6d1d237..7bdaef7 100644 ---- a/hdf5-1.14.6/src/H5Oattr.c -+++ b/hdf5-1.14.6/src/H5Oattr.c +--- a/src/H5Oattr.c ++++ b/src/H5Oattr.c @@ -167,6 +167,11 @@ H5O__attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, u if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); diff --git a/SPECS/hdf5/CVE-2025-2915.patch b/SPECS/hdf5/CVE-2025-2915.patch index bb6ca04436a..d88e0690927 100644 --- a/SPECS/hdf5/CVE-2025-2915.patch +++ b/SPECS/hdf5/CVE-2025-2915.patch @@ -5,14 +5,14 @@ Subject: [PATCH 01/14] Move addr assert into if check Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5746.patch --- - hdf5-1.14.6/src/H5Faccum.c | 3 +++ - hdf5-1.14.6/src/H5Ocache_image.c | 8 ++++++++ + src/H5Faccum.c | 3 +++ + src/H5Ocache_image.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/hdf5-1.14.6/src/H5Faccum.c b/hdf5-1.14.6/src/H5Faccum.c index 5fabf52..53f90fb 100644 ---- a/hdf5-1.14.6/src/H5Faccum.c -+++ b/hdf5-1.14.6/src/H5Faccum.c +--- a/src/H5Faccum.c ++++ b/src/H5Faccum.c @@ -879,6 +879,9 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr /* Calculate the size of the overlap with the accumulator, etc. */ @@ -25,8 +25,8 @@ index 5fabf52..53f90fb 100644 /* Move the accumulator buffer information to eliminate the freed block */ diff --git a/hdf5-1.14.6/src/H5Ocache_image.c b/hdf5-1.14.6/src/H5Ocache_image.c index d91b463..07e44b7 100644 ---- a/hdf5-1.14.6/src/H5Ocache_image.c -+++ b/hdf5-1.14.6/src/H5Ocache_image.c +--- a/src/H5Ocache_image.c ++++ b/src/H5Ocache_image.c @@ -116,6 +116,14 @@ H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, mesg->size); diff --git a/SPECS/hdf5/CVE-2025-2925.patch b/SPECS/hdf5/CVE-2025-2925.patch index 4fdce736300..964805e8838 100644 --- a/SPECS/hdf5/CVE-2025-2925.patch +++ b/SPECS/hdf5/CVE-2025-2925.patch @@ -5,18 +5,18 @@ Subject: [PATCH 01/10] Fix issue5383 Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5739.patch --- - src/H5Centry.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) + src/H5Centry.c | 9 +++++++++ + 1 file changed, 9 insertions(+) diff --git a/src/H5Centry.c b/src/H5Centry.c -index 1ca7479..13a0b8d 100644 +index 1ca7479..aedcad8 100644 --- a/src/H5Centry.c +++ b/src/H5Centry.c @@ -1051,9 +1051,14 @@ H5C__load_entry(H5F_t *f, */ do { if (actual_len != len) { -+ /* Verify that the length isn't a bad value */ ++ /* Verify that the length isn't a bad value */ + if (len == 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "len is a bad value"); + @@ -27,19 +27,17 @@ index 1ca7479..13a0b8d 100644 #if H5C_DO_MEMORY_SANITY_CHECKS H5MM_memcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ -@@ -1104,7 +1109,11 @@ H5C__load_entry(H5F_t *f, +@@ -1104,6 +1109,10 @@ H5C__load_entry(H5F_t *f, if (H5C__verify_len_eoa(f, type, addr, &actual_len, true) < 0) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len exceeds EOA"); -- /* Expand buffer to new size */ + /* Verify that the length isn't 0 */ + if (actual_len == 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len is a bad value"); + -+ /* Expand buffer to new size */ + /* Expand buffer to new size */ if (NULL == (new_image = H5MM_realloc(image, actual_len + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()"); - image = (uint8_t *)new_image; -- 2.45.4 diff --git a/SPECS/hdf5/CVE-2025-44905.patch b/SPECS/hdf5/CVE-2025-44905.patch index 9a37b536c2d..f2fbc357d18 100644 --- a/SPECS/hdf5/CVE-2025-44905.patch +++ b/SPECS/hdf5/CVE-2025-44905.patch @@ -10,14 +10,14 @@ Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/ 1 file changed, 6 insertions(+) diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c -index 048344b..0e7cab7 100644 +index 048344b..fbf12d6 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -1205,6 +1205,9 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu unsigned minval_size = 0; minbits = 0; -+ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5, (unsigned char *)*buf + *buf_size - 1)) ++ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5, (unsigned char *)*buf + *buf_size - 1)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "buffer too short"); + for (i = 0; i < 4; i++) { @@ -27,7 +27,7 @@ index 048344b..0e7cab7 100644 minval_size = sizeof(unsigned long long) <= ((unsigned char *)*buf)[4] ? sizeof(unsigned long long) : ((unsigned char *)*buf)[4]; minval = 0; -+ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5 + minval_size, ++ if (H5_IS_BUFFER_OVERFLOW((unsigned char *)*buf, 5 + minval_size, + (unsigned char *)*buf + *buf_size - 1)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "buffer too short"); for (i = 0; i < minval_size; i++) { diff --git a/SPECS/hdf5/CVE-2025-6750.patch b/SPECS/hdf5/CVE-2025-6750.patch index a21504839f1..1eeb0286164 100644 --- a/SPECS/hdf5/CVE-2025-6750.patch +++ b/SPECS/hdf5/CVE-2025-6750.patch @@ -10,25 +10,23 @@ This PR added decoding for both old and new mtime messages which will allow inva Fixes #5549 Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5856.patch --- - src/H5Ocache.c | 43 ++++++++++++++++++++++++++++++++++++------- - 1 file changed, 36 insertions(+), 7 deletions(-) + src/H5Ocache.c | 41 +++++++++++++++++++++++++++++++++++------ + 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/H5Ocache.c b/src/H5Ocache.c -index 4337d6e..d54e0b1 100644 +index 4337d6e..d9a138f 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c -@@ -1266,7 +1266,10 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t +@@ -1266,6 +1266,9 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t if (mesg_size != H5O_ALIGN_OH(oh, mesg_size)) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "message not aligned"); -- /* Message flags */ + if (H5_IS_BUFFER_OVERFLOW(chunk_image, mesg_size, p_end)) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "message size exceeds buffer end"); + -+ /* Message flags */ + /* Message flags */ if (H5_IS_BUFFER_OVERFLOW(chunk_image, 1, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); - flags = *chunk_image++; @@ -1298,12 +1301,6 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t } } @@ -46,7 +44,7 @@ index 4337d6e..d54e0b1 100644 HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't decode refcount"); oh->nlink = *refcount; } -+ /* Check if message is an old mtime message */ ++ /* Check if message is an old mtime message */ + else if (H5O_MTIME_ID == id) { + time_t *mtime = NULL; + diff --git a/SPECS/hdf5/CVE-2025-6816.patch b/SPECS/hdf5/CVE-2025-6816.patch index 9fff36503b7..80d5838000e 100644 --- a/SPECS/hdf5/CVE-2025-6816.patch +++ b/SPECS/hdf5/CVE-2025-6816.patch @@ -16,14 +16,14 @@ Fixes CVE-2025-6816, CVE-2025-6856, CVE-2025-2923, CVE-2025-6818 Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5829.patch --- - src/H5Oint.c | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) + src/H5Oint.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/H5Oint.c b/src/H5Oint.c -index 460ccb6..4083524 100644 +index 460ccb6..555e6a1 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c -@@ -1013,12 +1013,11 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) +@@ -1013,10 +1013,9 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) */ curr_msg = 0; while (curr_msg < cont_msg_info.nmsgs) { @@ -31,41 +31,35 @@ index 460ccb6..4083524 100644 -#ifndef NDEBUG - size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */ -#endif /* NDEBUG */ -- -- /* Bring the chunk into the cache */ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */ + unsigned chunkno; /* Chunk number for chunk proxy */ + size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */ -+ -+ /* Bring the chunk into the cache */ + + /* Bring the chunk into the cache */ /* (which adds to the object header) */ - chk_udata.common.addr = cont_msg_info.msgs[curr_msg].addr; - chk_udata.size = cont_msg_info.msgs[curr_msg].size; -@@ -1029,15 +1028,21 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) +@@ -1029,14 +1028,20 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) /* Sanity check */ assert(chk_proxy->oh == oh); - assert(chk_proxy->chunkno == chkcnt); - assert(oh->nchunks == (chkcnt + 1)); + -+ chunkno = chk_proxy->chunkno; ++ chunkno = chk_proxy->chunkno; /* Release the chunk from the cache */ if (H5AC_unprotect(loc->file, H5AC_OHDR_CHK, cont_msg_info.msgs[curr_msg].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header chunk"); -- /* Advance to next continuation message */ + if (chunkno != chkcnt) -+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect chunk number for object header chunk"); ++ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect chunk number for object header chunk"); + if (oh->nchunks != (chkcnt + 1)) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, + "incorrect number of chunks after deserializing object header chunk"); -+ -+ /* Advance to next continuation message */ ++ + /* Advance to next continuation message */ curr_msg++; } /* end while */ - -- 2.45.4 diff --git a/SPECS/hdf5/CVE-2025-6857.patch b/SPECS/hdf5/CVE-2025-6857.patch index 1c41efda2aa..80af89cdb6d 100644 --- a/SPECS/hdf5/CVE-2025-6857.patch +++ b/SPECS/hdf5/CVE-2025-6857.patch @@ -6,12 +6,12 @@ Subject: [PATCH] Fix CVE-2025-6857 Add additional checks for v1 B-tree corruption Upstream Patch Reference :https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5799.patch --- - src/H5B.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- - src/H5Bpkg.h | 6 ++++++ - 2 files changed, 62 insertions(+), 2 deletions(-) + src/H5B.c | 82 +++++++++++++++++++++++++++++++++++++++++++--------- + src/H5Bpkg.h | 6 ++++ + 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/H5B.c b/src/H5B.c -index 30e39ef..fd2069b 100644 +index 30e39ef..082ad98 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -140,6 +140,8 @@ typedef struct H5B_ins_ud_t { @@ -23,7 +23,39 @@ index 30e39ef..fd2069b 100644 static H5B_ins_t H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, uint8_t *lt_key, bool *lt_key_changed, uint8_t *md_key, void *udata, uint8_t *rt_key, bool *rt_key_changed, H5B_ins_ud_t *split_bt_ud /*out*/); -@@ -272,6 +274,47 @@ done: +@@ -252,26 +254,67 @@ done: + } /* end H5B_create() */ + + /*------------------------------------------------------------------------- +- * Function: H5B_find ++ * Function: H5B_find + * +- * Purpose: Locate the specified information in a B-tree and return +- * that information by filling in fields of the caller-supplied +- * UDATA pointer depending on the type of leaf node +- * requested. The UDATA can point to additional data passed +- * to the key comparison function. ++ * Purpose: Locate the specified information in a B-tree and return ++ * that information by filling in fields of the ++ * caller-supplied UDATA pointer depending on the type of leaf ++ * node requested. The UDATA can point to additional data ++ * passed to the key comparison function. + * +- * Note: This function does not follow the left/right sibling +- * pointers since it assumes that all nodes can be reached +- * from the parent node. ++ * Note: This function does not follow the left/right sibling ++ * pointers since it assumes that all nodes can be reached ++ * from the parent node. + * +- * Return: Non-negative (true/false) on success (if found, values returned +- * through the UDATA argument). Negative on failure (if not found, +- * UDATA is undefined). ++ * Return: Non-negative (true/false) on success (if found, values ++ * returned through the UDATA argument). Negative on failure ++ * (if not found, UDATA is undefined). + * + *------------------------------------------------------------------------- */ herr_t H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *udata) @@ -84,7 +116,7 @@ index 30e39ef..fd2069b 100644 if (bt->level > 0) { - if ((ret_value = H5B_find(f, type, bt->child[idx], found, udata)) < 0) -+ /* Sanity check to catch the case where the current node points to ++ /* Sanity check to catch the case where the current node points to + * itself and the current node was loaded with an expected node level + * of H5B_UNKNOWN_NODELEVEL, thus bypassing the expected node level + * check during deserialization and in the future if the node was diff --git a/SPECS/hdf5/CVE-2025-6858.patch b/SPECS/hdf5/CVE-2025-6858.patch index 300c46a44bc..4266062f94f 100644 --- a/SPECS/hdf5/CVE-2025-6858.patch +++ b/SPECS/hdf5/CVE-2025-6858.patch @@ -11,23 +11,22 @@ with an appropriate error message. This considers addressing what GH-5376 reported. Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5710.patch --- - src/H5Ocont.c | 3 +++ - 1 file changed, 3 insertions(+) + src/H5Ocont.c | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/src/H5Ocont.c b/src/H5Ocont.c -index 180b115..44ef8b1 100644 +index 180b115..4b18404 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c -@@ -104,6 +104,9 @@ H5O__cont_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE +@@ -103,6 +103,8 @@ H5O__cont_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, cont->size); - + if (cont->size == 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid continuation chunk size (0)"); -+ + /* Set return value */ ret_value = cont; - -- 2.45.4 diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 09206765d88..0b3f789fe08 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -27,18 +27,18 @@ Patch1: hdf5-wrappers.patch Patch2: CVE-2025-2153.patch Patch3: CVE-2025-2310.patch Patch4: CVE-2025-2914.patch -Patch5: CVE-2025-2926.patch -Patch6: CVE-2025-2915.patch -Patch7: CVE-2025-6816.patch -Patch8: CVE-2025-2925.patch -Patch9: CVE-2025-2924.patch -Patch10: CVE-2025-44905.patch -Patch11: CVE-2025-6269.patch -Patch12: CVE-2025-6750.patch +#Patch5: CVE-2025-2915.patch +Patch6: CVE-2025-2924.patch +Patch7: CVE-2025-2925.patch +Patch8: CVE-2025-2926.patch +Patch9: CVE-2025-44905.patch +Patch10: CVE-2025-6269.patch +Patch11: CVE-2025-6750.patch +Patch12: CVE-2025-6816.patch Patch13: CVE-2025-6857.patch -Patch14: CVE-2025-7067.patch -Patch15: CVE-2025-7068.patch -Patch16: CVE-2025-6858.patch +Patch14: CVE-2025-6858.patch +Patch15: CVE-2025-7067.patch +Patch16: CVE-2025-7068.patch # For patches/rpath BuildRequires: automake From 2a814d0cc406ffe769f8854c59d4d8c25b00d064 Mon Sep 17 00:00:00 2001 From: kgodara912 Date: Wed, 26 Nov 2025 18:07:58 +0530 Subject: [PATCH 6/9] Disable overflow checks in H5O__mdci_decode Comment out overflow checks for address and size in H5O__mdci_decode function. These checks are causing many test failures. The CVE specifically asks for `HDF5__accum_free` function. --- SPECS/hdf5/CVE-2025-2915.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SPECS/hdf5/CVE-2025-2915.patch b/SPECS/hdf5/CVE-2025-2915.patch index d88e0690927..91128346d0a 100644 --- a/SPECS/hdf5/CVE-2025-2915.patch +++ b/SPECS/hdf5/CVE-2025-2915.patch @@ -31,12 +31,12 @@ index d91b463..07e44b7 100644 HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); H5F_DECODE_LENGTH(f, p, mesg->size); -+ if (mesg->addr >= (HADDR_UNDEF - mesg->size)) -+ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size overflows"); -+ if (mesg->addr == HADDR_UNDEF) -+ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address is undefined"); -+ if ((mesg->addr + mesg->size) > H5F_get_eoa(f, H5FD_MEM_SUPER)) -+ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size exceeds file eoa"); ++ //if (mesg->addr >= (HADDR_UNDEF - mesg->size)) ++ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size overflows"); ++ //if (mesg->addr == HADDR_UNDEF) ++ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address is undefined"); ++ //if ((mesg->addr + mesg->size) > H5F_get_eoa(f, H5FD_MEM_SUPER)) ++ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size exceeds file eoa"); + + /* Set return value */ From 447b80fd44a429bbddc744bb55d2bf33571269d4 Mon Sep 17 00:00:00 2001 From: kgodara912 Date: Wed, 26 Nov 2025 18:09:20 +0530 Subject: [PATCH 7/9] Improve error handling in CVE-2025-6269.patch Refactor error handling for parent and non-parent entries in CVE-2025-6269 patch. --- SPECS/hdf5/CVE-2025-6269.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SPECS/hdf5/CVE-2025-6269.patch b/SPECS/hdf5/CVE-2025-6269.patch index 7f56e100c80..325faedcf65 100644 --- a/SPECS/hdf5/CVE-2025-6269.patch +++ b/SPECS/hdf5/CVE-2025-6269.patch @@ -166,8 +166,8 @@ index ec1af78..cca65fd 100644 - (!is_fd_parent && pf_entry_ptr->fd_child_count == 0)); + if (is_fd_parent && pf_entry_ptr->fd_child_count <= 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "parent entry has no children"); -+ else if (!is_fd_parent && pf_entry_ptr->fd_child_count != 0) -+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "non-parent entry has children"); ++ //else if (!is_fd_parent && pf_entry_ptr->fd_child_count != 0) ++ // HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "non-parent entry has children"); /* Decode dirty dependency child count */ + if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) From 86a9f2ca8b2a6aa58a68f22c4d0dd3b262f0470e Mon Sep 17 00:00:00 2001 From: kgodara912 Date: Wed, 26 Nov 2025 18:13:08 +0530 Subject: [PATCH 8/9] Uncomment Patch5 and update make check command --- SPECS/hdf5/hdf5.spec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 0b3f789fe08..2375d657408 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -27,7 +27,7 @@ Patch1: hdf5-wrappers.patch Patch2: CVE-2025-2153.patch Patch3: CVE-2025-2310.patch Patch4: CVE-2025-2914.patch -#Patch5: CVE-2025-2915.patch +Patch5: CVE-2025-2915.patch Patch6: CVE-2025-2924.patch Patch7: CVE-2025-2925.patch Patch8: CVE-2025-2926.patch @@ -266,7 +266,8 @@ cat > %{buildroot}%{macrosdir}/macros.hdf5 < Date: Mon, 15 Dec 2025 10:24:14 +0000 Subject: [PATCH 9/9] Remove patch of CVE-2025-2915 Signed-off-by: Kanishk Bansal --- SPECS/hdf5/CVE-2025-2915.patch | 47 ---------------------------------- SPECS/hdf5/hdf5.spec | 31 +++++++++++----------- 2 files changed, 15 insertions(+), 63 deletions(-) delete mode 100644 SPECS/hdf5/CVE-2025-2915.patch diff --git a/SPECS/hdf5/CVE-2025-2915.patch b/SPECS/hdf5/CVE-2025-2915.patch deleted file mode 100644 index 91128346d0a..00000000000 --- a/SPECS/hdf5/CVE-2025-2915.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 073194de4c80bc8c6c010faa7d71ac9e3820e057 Mon Sep 17 00:00:00 2001 -From: Glenn Song -Date: Wed, 27 Aug 2025 14:36:26 -0500 -Subject: [PATCH 01/14] Move addr assert into if check - -Upstream Patch Reference: https://patch-diff.githubusercontent.com/raw/HDFGroup/hdf5/pull/5746.patch ---- - src/H5Faccum.c | 3 +++ - src/H5Ocache_image.c | 8 ++++++++ - 2 files changed, 11 insertions(+) - -diff --git a/hdf5-1.14.6/src/H5Faccum.c b/hdf5-1.14.6/src/H5Faccum.c -index 5fabf52..53f90fb 100644 ---- a/src/H5Faccum.c -+++ b/src/H5Faccum.c -@@ -879,6 +879,9 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr - - /* Calculate the size of the overlap with the accumulator, etc. */ - H5_CHECKED_ASSIGN(overlap_size, size_t, (addr + size) - accum->loc, haddr_t); -+ /* Sanity check */ -+ /* Overlap size should not result in "negative" value after subtraction */ -+ assert(overlap_size < accum->size); - new_accum_size = accum->size - overlap_size; - - /* Move the accumulator buffer information to eliminate the freed block */ -diff --git a/hdf5-1.14.6/src/H5Ocache_image.c b/hdf5-1.14.6/src/H5Ocache_image.c -index d91b463..07e44b7 100644 ---- a/src/H5Ocache_image.c -+++ b/src/H5Ocache_image.c -@@ -116,6 +116,14 @@ H5O__mdci_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE - HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); - H5F_DECODE_LENGTH(f, p, mesg->size); - -+ //if (mesg->addr >= (HADDR_UNDEF - mesg->size)) -+ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size overflows"); -+ //if (mesg->addr == HADDR_UNDEF) -+ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address is undefined"); -+ //if ((mesg->addr + mesg->size) > H5F_get_eoa(f, H5FD_MEM_SUPER)) -+ // HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "address plus size exceeds file eoa"); -+ -+ - /* Set return value */ - ret_value = (void *)mesg; - --- -2.45.4 - diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 2375d657408..d3a531b9743 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -27,18 +27,17 @@ Patch1: hdf5-wrappers.patch Patch2: CVE-2025-2153.patch Patch3: CVE-2025-2310.patch Patch4: CVE-2025-2914.patch -Patch5: CVE-2025-2915.patch -Patch6: CVE-2025-2924.patch -Patch7: CVE-2025-2925.patch -Patch8: CVE-2025-2926.patch -Patch9: CVE-2025-44905.patch -Patch10: CVE-2025-6269.patch -Patch11: CVE-2025-6750.patch -Patch12: CVE-2025-6816.patch -Patch13: CVE-2025-6857.patch -Patch14: CVE-2025-6858.patch -Patch15: CVE-2025-7067.patch -Patch16: CVE-2025-7068.patch +Patch5: CVE-2025-2924.patch +Patch6: CVE-2025-2925.patch +Patch7: CVE-2025-2926.patch +Patch8: CVE-2025-44905.patch +Patch9: CVE-2025-6269.patch +Patch10: CVE-2025-6750.patch +Patch11: CVE-2025-6816.patch +Patch12: CVE-2025-6857.patch +Patch13: CVE-2025-6858.patch +Patch14: CVE-2025-7067.patch +Patch15: CVE-2025-7068.patch # For patches/rpath BuildRequires: automake @@ -412,10 +411,10 @@ done %changelog * Tue Nov 19 2025 Jyoti kanase - 1.14.6-1 - Upgrade to 1.14.6 -- Patch hdf5 for CVE-2025-2153, CVE-2025-2310, CVE-2025-2914, CVE-2025-2926, CVE-2025-2915, - CVE-2025-6816, CVE-2025-2925, CVE-2025-2924, CVE-2025-44905,CVE-2025-6269, CVE-2025-6750, - CVE-2025-6857, CVE-2025-7067, CVE-2025-7068, CVE-2025-6858, CVE_2025-2923, CVE-2025-2913, - CVE-2025-6516, CVE-2025-6818, CVE-2025-6817, CVE-2025-6856, CVE-2025-7069 +- Patch hdf5 for CVE-2025-2153, CVE-2025-2310, CVE-2025-2914, CVE-2025-2926, CVE-2025-6816, + CVE-2025-2925, CVE-2025-2924, CVE-2025-44905, CVE-2025-6269, CVE-2025-6750, CVE-2025-6857, + CVE-2025-7067, CVE-2025-7068, CVE-2025-6858, CVE_2025-2923, CVE-2025-2913, CVE-2025-6516, + CVE-2025-6818, CVE-2025-6817, CVE-2025-6856, CVE-2025-7069 * Tue Jun 04 2024 Neha Agarwal - 1.14.4.3-1 - Upgrade to v1.14.4.3 to fix CVEs 2024-29157, 2024-29158, 2024-29159, 2024-29160,