diff mbox series

[meta-oe,7/9] hdf5: patch CVE-2026-120758

Message ID 20261105200552.81303-7-ankur.tyagi85@gmail.com
State New
Headers show
Series [meta-oe,1/9] hdf5: patch CVE-2026-19026, CVE-2026-19027 and CVE-2026-19028 | expand

Commit Message

Ankur Tyagi Nov. 5, 2026, 8:05 p.m. UTC
From: Ankur Tyagi <ankur.tyagi85@gmail.com>

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

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 .../hdf5/files/CVE-2026-120758.patch          | 143 ++++++++++++++++++
 meta-oe/recipes-support/hdf5/hdf5_2.0.0.bb    |   1 +
 2 files changed, 144 insertions(+)
 create mode 100644 meta-oe/recipes-support/hdf5/files/CVE-2026-120758.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-support/hdf5/files/CVE-2026-120758.patch b/meta-oe/recipes-support/hdf5/files/CVE-2026-120758.patch
new file mode 100644
index 0000000000..a8fb5f72ff
--- /dev/null
+++ b/meta-oe/recipes-support/hdf5/files/CVE-2026-120758.patch
@@ -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() */
diff --git a/meta-oe/recipes-support/hdf5/hdf5_2.0.0.bb b/meta-oe/recipes-support/hdf5/hdf5_2.0.0.bb
index 3e978a75ac..1520f8cab8 100644
--- a/meta-oe/recipes-support/hdf5/hdf5_2.0.0.bb
+++ b/meta-oe/recipes-support/hdf5/hdf5_2.0.0.bb
@@ -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"