diff --git a/SPECS/hdf5/CVE-2025-44904.patch b/SPECS/hdf5/CVE-2025-44904.patch new file mode 100644 index 00000000000..d8ceae88c10 --- /dev/null +++ b/SPECS/hdf5/CVE-2025-44904.patch @@ -0,0 +1,125 @@ +From d069f15269509d14f86479f760b2edc62c0c6e9b Mon Sep 17 00:00:00 2001 +From: Neil Fortner +Date: Mon, 2 Feb 2026 16:10:04 -0600 +Subject: [PATCH] Fix CVE-2025-44904 (#6179) + +Fix potential buffer overflow due to invalid chunk size reported by chunk index +(CVE-2025-44904) + +Upstream Patch reference: https://github.com/HDFGroup/hdf5/commit/d069f15269509d14f86479f760b2edc62c0c6e9b.patch +--- + src/H5Dchunk.c | 48 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c +index 5cba7c5..93ee9df 100644 +--- a/src/H5Dchunk.c ++++ b/src/H5Dchunk.c +@@ -4453,12 +4453,12 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + } /* end if */ + } /* end if */ + else { +- haddr_t chunk_addr; /* Address of chunk on disk */ +- hsize_t chunk_alloc; /* Length of chunk on disk */ ++ haddr_t chunk_addr; /* Address of chunk on disk */ ++ hsize_t chunk_disk_size; /* Length of chunk on disk */ + + /* Save the chunk info so the cache stays consistent */ +- chunk_addr = udata->chunk_block.offset; +- chunk_alloc = udata->chunk_block.length; ++ chunk_addr = udata->chunk_block.offset; ++ chunk_disk_size = udata->chunk_block.length; + + /* Check if we should disable filters on this chunk */ + if (pline->nused) { +@@ -4490,6 +4490,12 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + } /* end if */ + } /* end if */ + ++ /* If the chunk on disk is unfiltered, verify the index returned the correct size for the chunk */ ++ if (H5_UNLIKELY((chunk_disk_size != (hsize_t)chunk_size) && H5_addr_defined(chunk_addr) && ++ (!old_pline || !old_pline->nused))) ++ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, ++ "incorrect chunk size returned from index for unfiltered chunk"); ++ + if (relax) { + /* + * Not in the cache, but we're about to overwrite the whole thing +@@ -4514,19 +4520,29 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + + /* Check if the chunk exists on disk */ + if (H5_addr_defined(chunk_addr)) { +- size_t my_chunk_alloc = chunk_alloc; /* Allocated buffer size */ +- size_t buf_alloc = chunk_alloc; /* [Re-]allocated buffer size */ ++ size_t chunk_nbytes; /* Length of the chunk in memory */ ++ size_t buf_alloc; /* [Re-]allocated chunk buffer size */ ++ ++ /* Assign above variables and check for overflow */ ++ H5_CHECKED_ASSIGN(chunk_nbytes, size_t, chunk_disk_size, hsize_t); ++ H5_CHECKED_ASSIGN(buf_alloc, size_t, chunk_disk_size, hsize_t); ++ ++ /* Ideally we should allocate a buffer at least as large as chunk_size, to give the filter the ++ * opportunity to avoid doing a realloc when uncompressing. This causes problems now, however, ++ * and needs more investigation. -NAF */ + +- /* Chunk size on disk isn't [likely] the same size as the final chunk +- * size in memory, so allocate memory big enough. */ +- if (NULL == (chunk = H5D__chunk_mem_alloc(my_chunk_alloc, +- (udata->new_unfilt_chunk ? old_pline : pline)))) ++ /* Allocate chunk buffer */ ++ if (NULL == ++ (chunk = H5D__chunk_mem_alloc(buf_alloc, (udata->new_unfilt_chunk ? old_pline : pline)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for raw data chunk"); ++ ++ /* Read chunk from disk */ + if (H5F_shared_block_read(H5F_SHARED(dset->oloc.file), H5FD_MEM_DRAW, chunk_addr, +- my_chunk_alloc, chunk) < 0) ++ chunk_disk_size, chunk) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk"); + ++ /* Unfilter chunk */ + if (old_pline && old_pline->nused) { + H5Z_EDC_t err_detect; /* Error detection info */ + H5Z_cb_t filter_cb; /* I/O filter callback function */ +@@ -4537,15 +4553,16 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + if (H5CX_get_filter_cb(&filter_cb) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get I/O filter callback function"); + ++ /* Perform filter pipeline */ + if (H5Z_pipeline(old_pline, H5Z_FLAG_REVERSE, &(udata->filter_mask), err_detect, +- filter_cb, &my_chunk_alloc, &buf_alloc, &chunk) < 0) ++ filter_cb, &chunk_nbytes, &buf_alloc, &chunk) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFILTER, NULL, "data pipeline read failed"); + + /* Reallocate chunk if necessary */ + if (udata->new_unfilt_chunk) { + void *tmp_chunk = chunk; + +- if (NULL == (chunk = H5D__chunk_mem_alloc(my_chunk_alloc, pline))) { ++ if (NULL == (chunk = H5D__chunk_mem_alloc(chunk_nbytes, pline))) { + (void)H5D__chunk_mem_xfree(tmp_chunk, old_pline); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for raw data chunk"); +@@ -4564,8 +4581,7 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + /* Sanity check */ + assert(fill->alloc_time != H5D_ALLOC_TIME_EARLY); + +- /* Chunk size on disk isn't [likely] the same size as the final chunk +- * size in memory, so allocate memory big enough. */ ++ /* Allocate chunk buffer large enough to hold an unfiltered (in cache) chunk */ + if (NULL == (chunk = H5D__chunk_mem_alloc(chunk_size, pline))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for raw data chunk"); +@@ -4629,7 +4645,7 @@ H5D__chunk_lock(const H5D_io_info_t H5_ATTR_NDEBUG_UNUSED *io_info, const H5D_ds + + /* Initialize the new entry */ + ent->chunk_block.offset = chunk_addr; +- ent->chunk_block.length = chunk_alloc; ++ ent->chunk_block.length = chunk_disk_size; + ent->chunk_idx = udata->chunk_idx; + H5MM_memcpy(ent->scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims); + H5_CHECKED_ASSIGN(ent->rd_count, uint32_t, chunk_size, size_t); +-- +2.43.0 + diff --git a/SPECS/hdf5/hdf5.spec b/SPECS/hdf5/hdf5.spec index 963501f50b5..5670ac26d5b 100644 --- a/SPECS/hdf5/hdf5.spec +++ b/SPECS/hdf5/hdf5.spec @@ -12,7 +12,7 @@ Summary: A general purpose library and file format for storing scientific data Name: hdf5 Version: 1.14.6 -Release: 2%{?dist} +Release: 3%{?dist} License: BSD Vendor: Microsoft Corporation Distribution: Azure Linux @@ -39,6 +39,7 @@ Patch13: CVE-2025-6858.patch Patch14: CVE-2025-7067.patch Patch15: CVE-2025-7068.patch Patch16: CVE-2025-2915.patch +Patch17: CVE-2025-44904.patch # For patches/rpath BuildRequires: automake @@ -410,6 +411,9 @@ done %changelog +* Fri Jul 10 2026 Azure Linux Security Servicing Account - 1.14.6-3 +- Patch for CVE-2025-44904 + * Tue Jan 20 2026 Aditya Singh - 1.14.6-2 - Patch for CVE-2025-2915 - Skipping failing test cases after applying this patch.