Fix NULL pointer access when H5A_operator2_t is NULL (#6541)

* Fix NULL pointer access when H5A_operator2_t is NULL

Passing NULL for the callback function pointer to H5Aiterate2 and
H5Aiterate_by_name was not detected, leading to a subsequent access
of an uninitialized pointer. Add a check for this "no operator
specified" case in both functions so they fail gracefully instead.

Fixes GHSA-r7g4-hv2f-5c66 - CVE-2025-9274

* Fix format

* Fix Java test to handle NULL callback to H5Aiterate2
This commit is contained in:
bmribler
2026-07-21 14:21:38 -04:00
committed by GitHub
parent 9eaec3e81a
commit 8a48c7ced8
5 changed files with 29 additions and 3 deletions
+3 -3
View File
@@ -1027,7 +1027,7 @@ public class TestH5Affm {
}
@Test
public void testH5Aiterate()
public void testH5Aiterate_nullCallback()
{
System.out.print(testname.getMethodName());
@@ -1035,10 +1035,10 @@ public class TestH5Affm {
MemorySegment idx = allocateLongArray(arena, 1);
copyToSegment(idx, new long[] {0});
// Just verify the API works, iteration callback complex for FFM
// NULL callback must be rejected gracefully (H5E_BADVALUE), not crash
long result = hdf5_h.H5Aiterate2(H5did, hdf5_h.H5_INDEX_NAME(), hdf5_h.H5_ITER_INC(), idx,
MemorySegment.NULL, MemorySegment.NULL);
assertTrue("H5Aiterate2 should complete", result >= 0);
assertTrue("H5Aiterate2 should fail when callback is NULL", result < 0);
}
}
}
+6
View File
@@ -155,6 +155,12 @@ The `h5repack` tool now obtains its default low and high library version bounds
Previously the error stack would be cleared when exiting a data filter, even an internal library filter, so the user could not see what caused the filter to fail. This has been fixed by not treating internal data filters like a user callback. Note that user-defined or third-party filters that use the default error stack will need to print that stack before returning from their callbacks.
### Fixed error when reading variable-length chunked datasets in read-only mode
Passing NULL for the callback function pointer to H5Aiterate2 and H5Aiterate_by_name was not detected, leading to a subsequent access of an uninitialized pointer. This is now fixed.
Fixes CVE-2025-9274
### Fixed error when reading variable-length chunked datasets in read-only mode
When reading from a chunked dataset with a variable-length type, a non-default fill value, and unwritten chunks, the library would internally try to write data to the file and fail due to writing to a read-only file. Reworked the I/O code to avoid these writes in this case. This may also improve performance and file space usage in similar cases with files open with write access.
+4
View File
@@ -1869,6 +1869,8 @@ H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *i
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
if (op == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
/* Get the loc object */
if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
@@ -1958,6 +1960,8 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
if (op == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
/* Verify access property list and set up collective metadata if appropriate */
if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, false) < 0)
+8
View File
@@ -7608,6 +7608,14 @@ attr_iterate_check(hid_t fid, const char *dsetname, hid_t obj_id, H5_index_t idx
H5E_END_TRY
VERIFY(ret, FAIL, "H5Aiterate_by_name");
/* Test passing null pointer for callback */
H5E_BEGIN_TRY
{
ret = H5Aiterate_by_name(obj_id, ".", idx_type, order, &skip, NULL, NULL, H5P_DEFAULT);
}
H5E_END_TRY
VERIFY(ret, FAIL, "H5Aiterate_by_name");
/* Retrieve current # of errors */
if (old_nerrs == GetTestNumErrs())
return (0);
+8
View File
@@ -539,6 +539,14 @@ test_iter_attr(hid_t fapl, bool new_format)
H5E_END_TRY
VERIFY(ret, FAIL, "H5Aiterate2");
/* Test passing null pointer for callback */
H5E_BEGIN_TRY
{
ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, NULL, &info);
}
H5E_END_TRY
VERIFY(ret, FAIL, "H5Aiterate2");
/* Test all attributes on dataset, when callback always returns 0 */
info.command = RET_ZERO;
idx = 0;