new file mode 100644
@@ -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"