Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions release_docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ Fixes GitHub issue #6679.

Fixes CVE-2026-19025

### Fixed a division by zero when opening a chunked dataset with a zero-sized chunk dimension

`H5D__chunk_set_info_real()` computed the number of chunks in each dimension by dividing by the chunk dimension before validating that it was non-zero, and the existing validation was only reached in the branch where the maximum dimension was not `H5S_UNLIMITED`. A corrupted file that encoded a zero-sized chunk dimension therefore triggered an integer division by zero (a floating point exception) while the dataset was being opened. The dimension is now validated before the divisions, covering both the limited and unlimited cases, so such a dataset is rejected with an error instead of crashing. One-dimensional datasets were reachable because `H5D__chunk_init()` validates the chunk dimensions only for datasets with more than one dimension.

See also GitHub issues #578 and #583.

### Fixed a crash when reading a dataset with a malformed fill value

An old-style (either version 1 or version 2) fill value message that is marked "defined" but encodes a negative size leaves the fill value with a negative size and no datatype; `H5Pget_fill_value()` then passed that NULL datatype to `H5T_path_find()` and dereferenced it. `H5P_get_fill_value()` now rejects a fill value that has no datatype and returns an error, so the dataset itself remains readable while the corrupt fill value is reported cleanly.
Expand Down
12 changes: 6 additions & 6 deletions src/H5Dchunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,17 +778,17 @@ H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize
layout->nchunks = 1;
layout->max_nchunks = 1;
for (unsigned u = 0; u < ndims; u++) {
/* Sanity check - a corrupt file can encode zero-sized chunk dimensions,
* which would cause a division by zero below */
if (layout->dim[u] == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimension size must be > 0, dim = %u ", u);

/* Round up to the next integer # of chunks, to accommodate partial chunks */
layout->chunks[u] = ((curr_dims[u] + layout->dim[u]) - 1) / layout->dim[u];
if (H5S_UNLIMITED == max_dims[u])
layout->max_chunks[u] = H5S_UNLIMITED;
else {
/* Sanity check */
if (layout->dim[u] == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimension size must be > 0, dim = %u ", u);

else
layout->max_chunks[u] = ((max_dims[u] + layout->dim[u]) - 1) / layout->dim[u];
}

/* Accumulate the # of chunks */
layout->nchunks *= layout->chunks[u];
Expand Down
Loading