hdf5: patch CVE-2026-120758

Details:
https://nvd.nist.gov/vuln/detail/cve-2026-120758

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Ankur Tyagi authored and Anuj Mittal committed 2026-11-09 09:10:43 +05:30
1 parent a7e3f1e3c7
commit 0662b78ffb
2 files changed
+144

No files matched your search

@@ -0,0 +1,143 @@
From 277a6bbfdb8e852b7bbd08ae002907fc559e0194 Mon Sep 17 00:00:00 2001
From: tbeu <tbeu@users.noreply.github.com>
Date: Sat, 3 Oct 2026 07:43:53 +0200
Subject: [PATCH] Fix NULL pointer dereferences in H5HL_protect and
H5HL_unprotect (#6377)
* Fix NULL pointer dereferences in H5HL_protect and H5HL_unprotect
When reading corrupted HDF5 files, H5HL_protect can encounter a heap
where prfx->heap is NULL or heap->dblk_image is NULL. Similarly,
H5HL_unprotect can encounter a heap where heap->prfx or heap->dblk has
been set to NULL by H5HL__prfx_dest during cache eviction of corrupted
entries. In both cases, the code proceeded to dereference NULL pointers,
causing a segfault (found by OSS-Fuzz via matio).
Replace the assert in H5HL_unprotect with proper NULL checks and
HGOTO_ERROR, and add equivalent guards in H5HL_protect, so corrupted
files are rejected gracefully instead of crashing.
* Address review: drop speculative H5HL_protect NULL checks, add regression test + changelog
- Remove the NULL checks in H5HL_protect for prfx->heap and heap->dblk_image.
prfx->heap is set in H5HL__prfx_new and only cleared in H5HL__prfx_dest (which
frees the prefix in the same call), so the check is unreachable and could leak
prfx via the done block. heap->dblk_image is NULL by design whenever the data
block is not contiguous with the prefix, so that check was a false positive.
- Keep the H5HL_unprotect NULL checks for heap->prfx and heap->dblk, which are the
actual fix for the reported crash (OSS-Fuzz 504827191).
- Add a regression test (corrupt_heap_unprotect) in test/lheap.c using the
minimized fuzzer file heap_corrupt_prfx.h5, asserting the corrupted file fails
gracefully instead of crashing in H5HL_unprotect.
- Document the fix in release_docs/CHANGELOG.md.
* Improve lheap regression test for H5HL_unprotect NULL deref
Replace the file-based traversal (which does not deterministically reach
the cache-eviction path that nulls heap->prfx) with a white-box check that
protects a local heap, simulates the corrupted/evicted condition by nulling
the heap's prfx/dblk pointers, and verifies H5HL_unprotect() returns an
error instead of dereferencing NULL. Keep a best-effort open/traverse of the
OSS-Fuzz minimized file (issue 504827191) as a smoke test.
Verified: without the fix the test aborts (H5AC_unpin_entry(NULL)); with the
fix it passes.
* Improve lheap regression test to consider review comments
* Fix formatting
* test: improve lheap regression test for reviewer comments
- Use H5L_info2_t in visitor (matches H5L_iterate2_t signature)
- Use H5O_info2_t with H5Oget_info_by_name3
- Replicate matio's exact traversal: H5Literate2 + H5Gopen2/H5Dopen2 +
H5Lvisit2 recursion, H5Aiterate2 attribute reads, skip #refs#/#subsystem#
- Keep white-box deterministic NULL-pointer guard (fuzzer file does not
deterministically crash via public API alone; original crash required
matio fuzzer's specific cache-pressure environment)
- Add CORRUPT_HEAP_TESTFILE define back for white-box test
* Fix formatting
* Reject a local heap unprotect when its pinned cache entry is gone
H5HL_unprotect() now reports an error instead of dereferencing NULL when the
cache entry that H5HL_protect() pinned is no longer linked to the heap, and it
checks for that before decrementing the protect count so a rejected call leaves
the heap unchanged. The regression test as written couldn't fail, since its cleanup
label was after passed and every failure path still returned 0 (success).
It also only ever built single-cache-object heaps, and didn't reach the branch the crash
came from. It now grows a heap into a separate data block to cover both
branches and uses the standard error reporting.
---------
Co-authored-by: Matthew Larson <mlarson@hdfgroup.org>
Co-authored-by: Matt L <124107509+mattjala@users.noreply.github.com>
Co-authored-by: Larry Knox <lrknox@hdfgroup.org>
CVE: CVE-2026-120758
Upstream-Status: Backport [https://github.com/HDFGroup/hdf5/commit/91fc37c3325264e67699408e3a190fe4f329bf85]
Dropped changes to the test and CHANGELOG file.
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
src/H5HL.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/src/H5HL.c b/src/H5HL.c
index b55b3690617..838426406a9 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -416,28 +416,36 @@ H5HL_unprotect(H5HL_t *heap)
/* Check arguments */
assert(heap);
- /* Decrement # of times heap is protected */
- heap->prots--;
-
/* Check for last unprotection of heap */
- if (heap->prots == 0) {
- /* Check for separate heap data block */
+ if (heap->prots == 1) {
+ void *pin_obj; /* Pointer to local heap object to unpin */
+
+ /* Get the object that H5HL_protect() pinned. It is unlinked from the
+ * heap when the cache destroys it, which a damaged file can provoke,
+ * so check for it before the protect count is decremented.
+ */
if (heap->single_cache_obj) {
- /* Mark local heap prefix as evictable again */
- if (FAIL == H5AC_unpin_entry(heap->prfx))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin local heap data block");
+ if (NULL == heap->prfx)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "local heap prefix is not in the cache");
+
+ pin_obj = heap->prfx;
}
else {
- /* Sanity check */
- assert(heap->dblk);
+ if (NULL == heap->dblk)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "local heap data block is not in the cache");
- /* Mark local heap data block as evictable again */
/* (data block still pins prefix) */
- if (FAIL == H5AC_unpin_entry(heap->dblk))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin local heap data block");
+ pin_obj = heap->dblk;
}
+
+ /* Mark local heap object as evictable again */
+ if (FAIL == H5AC_unpin_entry(pin_obj))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin local heap object");
}
+ /* Decrement # of times heap is protected */
+ heap->prots--;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HL_unprotect() */
@@ -28,6 +28,7 @@ SRC_URI = "https://support.hdfgroup.org/releases/hdf5/v2_0/v2_0_0/downloads/${BP
file://CVE-2026-120754-CVE-2026-120755.patch \
file://CVE-2026-120756.patch \
file://CVE-2026-120757.patch \
file://CVE-2026-120758.patch \
"
SRC_URI[sha256sum] = "f4c2edc5668fb846627182708dbe1e16c60c467e63177a75b0b9f12c19d7efed"