mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user