mirror of
git://git.openembedded.org/meta-openembedded
synced 2026-05-18 21:59:27 +00:00
hdf5: fix CVE-2025-6857
According to [1], A vulnerability has been found in HDF5 1.14.6 and
classified as problematic. Affected by this vulnerability is the function
H5G__node_cmp3 of the file src/H5Gnode.c. The manipulation leads to
stack-based buffer overflow. It is possible to launch the attack on the
local host. The exploit has been disclosed to the public and may be used.
Backport patch [2] from upstream to fix CVE-2025-6857
[1] https://nvd.nist.gov/vuln/detail/CVE-2025-6857
[2] a8ceb1d95b
Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
parent
4ab556ad1e
commit
c40989630d
255
meta-oe/recipes-support/hdf5/files/CVE-2025-6857.patch
Normal file
255
meta-oe/recipes-support/hdf5/files/CVE-2025-6857.patch
Normal file
@ -0,0 +1,255 @@
|
||||
From eb3af284cc0ac8c758c65f492fc693ed50539592 Mon Sep 17 00:00:00 2001
|
||||
From: Libo Chen <libo.chen.cn@windriver.com>
|
||||
Date: Thu, 29 Jan 2026 13:59:39 +0800
|
||||
Subject: [PATCH] Fix CVE-2025-6857
|
||||
|
||||
Add additional checks for v1 B-tree corruption
|
||||
|
||||
An HDF5 file had a corrupted v1 B-tree that would result in a stack overflow when performing a lookup on it. This has been fixed with additional integrity checks.
|
||||
|
||||
CVE: CVE-2025-6857
|
||||
|
||||
Upstream-Status: Backport [https://github.com/HDFGroup/hdf5/commit/a8ceb1d95bb997f548c1129363dad53c18540096]
|
||||
|
||||
In addition to the upstream backport, this patch includes two adaptation
|
||||
changes for HDF5 1.14.4. First, the H5B_UNKNOWN_NODELEVEL macro and the
|
||||
exp_level field are introduced in H5Bpkg.h, as these do not exist in 1.14.4
|
||||
due to differences with the 2.0.0 codebase. Second, the
|
||||
"cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL" statements are added in H5B_*
|
||||
functions to initialize the new field.
|
||||
|
||||
Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
|
||||
---
|
||||
src/H5B.c | 92 +++++++++++++++++++++++++++++++++++++++++++---------
|
||||
src/H5Bpkg.h | 6 ++++
|
||||
2 files changed, 83 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/H5B.c b/src/H5B.c
|
||||
index 5a7a238..4efa679 100644
|
||||
--- a/src/H5B.c
|
||||
+++ b/src/H5B.c
|
||||
@@ -140,6 +140,8 @@ typedef struct H5B_ins_ud_t {
|
||||
/********************/
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
+static herr_t H5B_find_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, int exp_level, bool *found,
|
||||
+ void *udata);
|
||||
static H5B_ins_t H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, uint8_t *lt_key,
|
||||
bool *lt_key_changed, uint8_t *md_key, void *udata, uint8_t *rt_key,
|
||||
bool *rt_key_changed, H5B_ins_ud_t *split_bt_ud /*out*/);
|
||||
@@ -252,26 +254,67 @@ done:
|
||||
} /* end H5B_create() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
- * Function: H5B_find
|
||||
+ * Function: H5B_find
|
||||
*
|
||||
- * Purpose: Locate the specified information in a B-tree and return
|
||||
- * that information by filling in fields of the caller-supplied
|
||||
- * UDATA pointer depending on the type of leaf node
|
||||
- * requested. The UDATA can point to additional data passed
|
||||
- * to the key comparison function.
|
||||
+ * Purpose: Locate the specified information in a B-tree and return
|
||||
+ * that information by filling in fields of the
|
||||
+ * caller-supplied UDATA pointer depending on the type of leaf
|
||||
+ * node requested. The UDATA can point to additional data
|
||||
+ * passed to the key comparison function.
|
||||
*
|
||||
- * Note: This function does not follow the left/right sibling
|
||||
- * pointers since it assumes that all nodes can be reached
|
||||
- * from the parent node.
|
||||
+ * Note: This function does not follow the left/right sibling
|
||||
+ * pointers since it assumes that all nodes can be reached
|
||||
+ * from the parent node.
|
||||
*
|
||||
- * Return: Non-negative (true/false) on success (if found, values returned
|
||||
- * through the UDATA argument). Negative on failure (if not found,
|
||||
- * UDATA is undefined).
|
||||
+ * Return: Non-negative (true/false) on success (if found, values
|
||||
+ * returned through the UDATA argument). Negative on failure
|
||||
+ * (if not found, UDATA is undefined).
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *udata)
|
||||
+{
|
||||
+ herr_t ret_value = SUCCEED;
|
||||
+
|
||||
+ FUNC_ENTER_NOAPI(FAIL)
|
||||
+
|
||||
+ /*
|
||||
+ * Check arguments.
|
||||
+ */
|
||||
+ assert(f);
|
||||
+ assert(type);
|
||||
+ assert(type->decode);
|
||||
+ assert(type->cmp3);
|
||||
+ assert(type->found);
|
||||
+ assert(H5_addr_defined(addr));
|
||||
+
|
||||
+ if ((ret_value = H5B_find_helper(f, type, addr, H5B_UNKNOWN_NODELEVEL, found, udata)) < 0)
|
||||
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key");
|
||||
+
|
||||
+done:
|
||||
+ FUNC_LEAVE_NOAPI(ret_value)
|
||||
+} /* end H5B_find() */
|
||||
+
|
||||
+/*-------------------------------------------------------------------------
|
||||
+ * Function: H5B_find_helper
|
||||
+ *
|
||||
+ * Purpose: Recursive helper routine for H5B_find used to track node
|
||||
+ * levels and attempt to detect B-tree corruption during
|
||||
+ * lookups.
|
||||
+ *
|
||||
+ * Note: This function does not follow the left/right sibling
|
||||
+ * pointers since it assumes that all nodes can be reached
|
||||
+ * from the parent node.
|
||||
+ *
|
||||
+ * Return: Non-negative on success (if found, values returned through
|
||||
+ * the UDATA argument). Negative on failure (if not found,
|
||||
+ * UDATA is undefined).
|
||||
+ *
|
||||
+ *-------------------------------------------------------------------------
|
||||
+ */
|
||||
+static herr_t
|
||||
+H5B_find_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, int exp_level, bool *found, void *udata)
|
||||
{
|
||||
H5B_t *bt = NULL;
|
||||
H5UC_t *rc_shared; /* Ref-counted shared info */
|
||||
@@ -281,7 +324,7 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *uda
|
||||
int cmp = 1; /* Key comparison value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
- FUNC_ENTER_NOAPI(FAIL)
|
||||
+ FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
@@ -306,6 +349,7 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *uda
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = exp_level;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree node");
|
||||
|
||||
@@ -329,7 +373,17 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, bool *found, void *uda
|
||||
assert(idx < bt->nchildren);
|
||||
|
||||
if (bt->level > 0) {
|
||||
- if ((ret_value = H5B_find(f, type, bt->child[idx], found, udata)) < 0)
|
||||
+ /* Sanity check to catch the case where the current node points to
|
||||
+ * itself and the current node was loaded with an expected node level
|
||||
+ * of H5B_UNKNOWN_NODELEVEL, thus bypassing the expected node level
|
||||
+ * check during deserialization and in the future if the node was
|
||||
+ * cached.
|
||||
+ */
|
||||
+ if (bt->child[idx] == addr)
|
||||
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, FAIL, "cyclic B-tree detected");
|
||||
+
|
||||
+ if ((ret_value = H5B_find_helper(f, type, bt->child[idx], (int)(bt->level - 1), found, udata)) <
|
||||
+ 0)
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree");
|
||||
} /* end if */
|
||||
else {
|
||||
@@ -343,7 +397,7 @@ done:
|
||||
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release node");
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
-} /* end H5B_find() */
|
||||
+} /* end H5B_find_helper() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B__split
|
||||
@@ -425,6 +479,7 @@ H5B__split(H5F_t *f, H5B_ins_ud_t *bt_ud, unsigned idx, void *udata, H5B_ins_ud_
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = shared->type;
|
||||
cache_udata.rc_shared = bt_ud->bt->rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (split_bt_ud->bt =
|
||||
(H5B_t *)H5AC_protect(f, H5AC_BT, split_bt_ud->addr, &cache_udata, H5AC__NO_FLAGS_SET)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree");
|
||||
@@ -532,6 +587,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
bt_ud.addr = addr;
|
||||
if (NULL == (bt_ud.bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__NO_FLAGS_SET)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to locate root of B-tree");
|
||||
@@ -789,6 +845,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, uint8
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
|
||||
if (0 == bt->nchildren) {
|
||||
/*
|
||||
@@ -1077,6 +1134,7 @@ H5B__iterate_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, H5B_operato
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5_ITER_ERROR, "unable to load B-tree node");
|
||||
|
||||
@@ -1190,6 +1248,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, u
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__NO_FLAGS_SET)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load B-tree node");
|
||||
|
||||
@@ -1542,6 +1601,7 @@ H5B_delete(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__NO_FLAGS_SET)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree node");
|
||||
|
||||
@@ -1782,6 +1842,7 @@ H5B__get_info_helper(H5F_t *f, const H5B_class_t *type, haddr_t addr, const H5B_
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree node");
|
||||
|
||||
@@ -1923,6 +1984,7 @@ H5B_valid(H5F_t *f, const H5B_class_t *type, haddr_t addr)
|
||||
cache_udata.f = f;
|
||||
cache_udata.type = type;
|
||||
cache_udata.rc_shared = rc_shared;
|
||||
+ cache_udata.exp_level = H5B_UNKNOWN_NODELEVEL;
|
||||
if (NULL == (bt = (H5B_t *)H5AC_protect(f, H5AC_BT, addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree node");
|
||||
|
||||
diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h
|
||||
index d1ad647..f75e857 100644
|
||||
--- a/src/H5Bpkg.h
|
||||
+++ b/src/H5Bpkg.h
|
||||
@@ -39,6 +39,11 @@
|
||||
/* # of bits for node level: 1 byte */
|
||||
#define LEVEL_BITS 8
|
||||
|
||||
+/* Indicates that the level of the current node is unknown. When the level
|
||||
+ * is known, it can be used to detect corrupted level during decoding
|
||||
+ */
|
||||
+#define H5B_UNKNOWN_NODELEVEL -1
|
||||
+
|
||||
/****************************/
|
||||
/* Package Private Typedefs */
|
||||
/****************************/
|
||||
@@ -60,6 +65,7 @@ typedef struct H5B_t {
|
||||
typedef struct H5B_cache_ud_t {
|
||||
H5F_t *f; /* File that B-tree node is within */
|
||||
const struct H5B_class_t *type; /* Type of tree */
|
||||
+ int exp_level; /* Expected level of the current node */
|
||||
H5UC_t *rc_shared; /* Ref-counted shared info */
|
||||
} H5B_cache_ud_t;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@ -29,6 +29,7 @@ SRC_URI = " \
|
||||
file://CVE-2025-44905.patch \
|
||||
file://CVE-2025-2309.patch \
|
||||
file://CVE-2025-2308.patch \
|
||||
file://CVE-2025-6857.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "019ac451d9e1cf89c0482ba2a06f07a46166caf23f60fea5ef3c37724a318e03"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user