diff --git a/meta-oe/recipes-support/hdf5/files/CVE-2025-2308.patch b/meta-oe/recipes-support/hdf5/files/CVE-2025-2308.patch
new file mode 100644
index 0000000000..336a0d2697
--- /dev/null
+++ b/meta-oe/recipes-support/hdf5/files/CVE-2025-2308.patch
@@ -0,0 +1,333 @@
+From cbce4c2ecf6f5557605890eec125ecfaa4371131 Mon Sep 17 00:00:00 2001
+From: Libo Chen <libo.chen.cn@windriver.com>
+Date: Fri, 30 Jan 2026 16:43:04 +0800
+Subject: [PATCH] Fix CVE-2025-2308 (#5960)
+
+A malformed file can cause the scale-offset filter to have too little input data causing a heap buffer overflow. Additional checks on the maximum buffer length are required during the decompression.
+
+This PR fixes CVE-2025-2308.
+
+CVE: CVE-2025-2308
+
+Upstream-Status: Backport [https://github.com/HDFGroup/hdf5/commit/2ce7fdc4cf147d280aa6d49686297faacc250e40]
+
+Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
+---
+ src/H5Zscaleoffset.c      |  177 ++--
+ src/H5Zscaleoffset.c.orig | 1781 +++++++++++++++++++++++++++++++++++++
+ 1 files changed, 105 insertions(+), 72 deletions(-)
+ create mode 100644 src/H5Zscaleoffset.c.orig
+
+diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
+index fbf12d6..8355b13 100644
+--- a/src/H5Zscaleoffset.c
++++ b/src/H5Zscaleoffset.c
+@@ -69,21 +69,22 @@ static herr_t H5Z__scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enu
+ static herr_t H5Z__scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type,
+                                                  unsigned filavail, const unsigned cd_values[],
+                                                  uint32_t minbits, unsigned long long minval, double D_val);
+-static void   H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len);
+-static void   H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
+-                                                   unsigned begin_i, const unsigned char *buffer, size_t *j,
+-                                                   unsigned *buf_len, parms_atomic p, unsigned dtype_len);
++static void   H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill);
++static herr_t H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
++                                                   unsigned begin_i, const unsigned char *buffer,
++                                                   size_t buf_size, size_t *j, unsigned *bits_to_fill,
++                                                   parms_atomic p, unsigned dtype_len);
+ static void   H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
+                                                  unsigned begin_i, unsigned char *buffer, size_t *j,
+-                                                 unsigned *buf_len, parms_atomic p, unsigned dtype_len);
+-static void   H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
+-                                                     unsigned char *buffer, size_t *j, unsigned *buf_len,
+-                                                     parms_atomic p);
++                                                 unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len);
++static herr_t H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
++                                                     unsigned char *buffer, size_t buf_size, size_t *j,
++                                                     unsigned *bits_to_fill, parms_atomic p);
+ static void   H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset,
+-                                                   unsigned char *buffer, size_t *j, unsigned *buf_len,
++                                                   unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
+                                                    parms_atomic p);
+-static void   H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
+-                                          parms_atomic p);
++static herr_t H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
++                                          size_t buf_size, parms_atomic p);
+ static void   H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
+                                         size_t buffer_size, parms_atomic p);
+ 
+@@ -1261,8 +1262,11 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
+         }
+ 
+         /* decompress the buffer if minbits not equal to zero */
+-        if (minbits != 0)
+-            H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset, p);
++        if (minbits != 0) {
++            if (H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset,
++                                            *buf_size - buf_offset, p))
++                HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Scaleoffset decompression failed");
++        }
+         else {
+             /* fill value is not defined and all data elements have the same value */
+             for (i = 0; i < size_out; i++)
+@@ -1603,55 +1607,69 @@ done:
+ }
+ 
+ static void
+-H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len)
++H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill)
+ {
+     ++(*j);
+-    *buf_len = 8 * sizeof(unsigned char);
++    *bits_to_fill = 8 * sizeof(unsigned char);
+ }
+ 
+-static void
++static herr_t
+ H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k, unsigned begin_i,
+-                                     const unsigned char *buffer, size_t *j, unsigned *buf_len,
+-                                     parms_atomic p, unsigned dtype_len)
++                                     const unsigned char *buffer, size_t buf_size, size_t *j,
++                                     unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len)
+ {
+-    unsigned      dat_len; /* dat_len is the number of bits to be copied in each data byte */
+-    unsigned char val;     /* value to be copied in each data byte */
++    unsigned      bits_to_copy;        /* bits_to_copy is the number of bits to be copied in each data byte */
++    unsigned char val;                 /* value to be copied in each data byte */
++    herr_t        ret_value = SUCCEED; /* Return value */
++
++    FUNC_ENTER_PACKAGE
++
++    if (*j >= buf_size)
++        HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");
+ 
+     /* initialize value and bits of unsigned char to be copied */
+     val = buffer[*j];
+     if (k == begin_i)
+-        dat_len = 8 - (dtype_len - p.minbits) % 8;
++        bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
+     else
+-        dat_len = 8;
++        bits_to_copy = 8;
+ 
+-    if (*buf_len > dat_len) {
+-        data[data_offset + k] =
+-            (unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & (unsigned)(~((unsigned)~0 << dat_len)));
+-        *buf_len -= dat_len;
++    if (*bits_to_fill > bits_to_copy) {
++        data[data_offset + k] = (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
++                                                (unsigned)(~((unsigned)~0 << bits_to_copy)));
++        *bits_to_fill -= bits_to_copy;
+     } /* end if */
+     else {
+         data[data_offset + k] =
+-            (unsigned char)((val & ~((unsigned)(~0) << *buf_len)) << (dat_len - *buf_len));
+-        dat_len -= *buf_len;
+-        H5Z__scaleoffset_next_byte(j, buf_len);
+-        if (dat_len == 0)
+-            return;
++            (unsigned char)((val & ~((unsigned)(~0) << *bits_to_fill)) << (bits_to_copy - *bits_to_fill));
++        bits_to_copy -= *bits_to_fill;
++        H5Z__scaleoffset_next_byte(j, bits_to_fill);
++        if (bits_to_copy == 0)
++            goto done;
++        else if (*j >= buf_size)
++            HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");
+ 
+         val = buffer[*j];
+-        data[data_offset + k] |=
+-            (unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & ~((unsigned)(~0) << dat_len));
+-        *buf_len -= dat_len;
++        data[data_offset + k] |= (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
++                                                 ~((unsigned)(~0) << bits_to_copy));
++        *bits_to_fill -= bits_to_copy;
+     } /* end else */
++
++done:
++    FUNC_LEAVE_NOAPI(ret_value)
+ }
+ 
+-static void
++static herr_t
+ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
+-                                       size_t *j, unsigned *buf_len, parms_atomic p)
++                                       size_t buf_size, size_t *j, unsigned *bits_to_fill, parms_atomic p)
+ {
+     /* begin_i: the index of byte having first significant bit */
+     unsigned begin_i;
+     unsigned dtype_len;
+     int      k;
++    herr_t   ret_value = SUCCEED; /* Return value */
++
++    FUNC_ENTER_PACKAGE
+ 
+     assert(p.minbits > 0);
+ 
+@@ -1661,8 +1679,9 @@ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
+         begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;
+ 
+         for (k = (int)begin_i; k >= 0; k--)
+-            H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
+-                                                 p, dtype_len);
++            if (H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer,
++                                                     buf_size, j, bits_to_fill, p, dtype_len))
++                HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Atomic decompression failed");
+     }
+     else { /* big endian */
+         assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);
+@@ -1670,67 +1689,81 @@ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
+         begin_i = (dtype_len - p.minbits) / 8;
+ 
+         for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
+-            H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
+-                                                 p, dtype_len);
++            if (H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer,
++                                                     buf_size, j, bits_to_fill, p, dtype_len))
++                HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Atomic decompression failed");
+     }
++
++done:
++    FUNC_LEAVE_NOAPI(ret_value)
+ }
+ 
+-static void
+-H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, parms_atomic p)
++static herr_t
++H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, size_t buf_size,
++                            parms_atomic p)
+ {
+     /* i: index of data, j: index of buffer,
+-       buf_len: number of bits to be filled in current byte */
++       bits_to_fill: number of bits to be filled in current byte */
+     size_t   i, j;
+-    unsigned buf_len;
++    unsigned bits_to_fill;
++    herr_t   ret_value = SUCCEED; /* Return value */
++
++    FUNC_ENTER_PACKAGE
+ 
+     /* must initialize to zeros */
+     for (i = 0; i < d_nelmts * (size_t)p.size; i++)
+         data[i] = 0;
+ 
+     /* initialization before the loop */
+-    j       = 0;
+-    buf_len = sizeof(unsigned char) * 8;
++    j            = 0;
++    bits_to_fill = sizeof(unsigned char) * 8;
+ 
+     /* decompress */
+     for (i = 0; i < d_nelmts; i++)
+-        H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
++        if (H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, buf_size, &j, &bits_to_fill, p))
++            HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Scaleoffset decompression failed");
++
++done:
++    FUNC_LEAVE_NOAPI(ret_value)
+ }
+ 
+ static void
+ H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
+-                                   unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *buf_len,
++                                   unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
+                                    parms_atomic p, unsigned dtype_len)
+ {
+-    unsigned      dat_len; /* dat_len is the number of bits to be copied in each data byte */
+-    unsigned char val;     /* value to be copied in each data byte */
++    unsigned      bits_to_copy; /* bits_to_copy is the number of bits to be copied in each data byte */
++    unsigned char val;          /* value to be copied in each data byte */
+ 
+     /* initialize value and bits of unsigned char to be copied */
+     val = data[data_offset + k];
+     if (k == begin_i)
+-        dat_len = 8 - (dtype_len - p.minbits) % 8;
++        bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
+     else
+-        dat_len = 8;
++        bits_to_copy = 8;
+ 
+-    if (*buf_len > dat_len) {
+-        buffer[*j] |= (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
+-        *buf_len -= dat_len;
++    if (*bits_to_fill > bits_to_copy) {
++        buffer[*j] |=
++            (unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
++        *bits_to_fill -= bits_to_copy;
+     }
+     else {
+-        buffer[*j] |=
+-            (unsigned char)((unsigned)(val >> (dat_len - *buf_len)) & ~((unsigned)(~0) << *buf_len));
+-        dat_len -= *buf_len;
+-        H5Z__scaleoffset_next_byte(j, buf_len);
+-        if (dat_len == 0)
++        buffer[*j] |= (unsigned char)((unsigned)(val >> (bits_to_copy - *bits_to_fill)) &
++                                      ~((unsigned)(~0) << *bits_to_fill));
++        bits_to_copy -= *bits_to_fill;
++        H5Z__scaleoffset_next_byte(j, bits_to_fill);
++        if (bits_to_copy == 0)
+             return;
+ 
+-        buffer[*j] = (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
+-        *buf_len -= dat_len;
++        buffer[*j] =
++            (unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
++        *bits_to_fill -= bits_to_copy;
+     } /* end else */
+ }
+ 
+ static void
+ H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
+-                                     size_t *j, unsigned *buf_len, parms_atomic p)
++                                     size_t *j, unsigned *bits_to_fill, parms_atomic p)
+ {
+     /* begin_i: the index of byte having first significant bit */
+     unsigned begin_i;
+@@ -1745,16 +1778,16 @@ H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, un
+         begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;
+ 
+         for (k = (int)begin_i; k >= 0; k--)
+-            H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
+-                                               dtype_len);
++            H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
++                                               bits_to_fill, p, dtype_len);
+     }
+     else { /* big endian */
+         assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);
+         begin_i = (dtype_len - p.minbits) / 8;
+ 
+         for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
+-            H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
+-                                               dtype_len);
++            H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
++                                               bits_to_fill, p, dtype_len);
+     }
+ }
+ 
+@@ -1763,19 +1796,19 @@ H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char
+                           parms_atomic p)
+ {
+     /* i: index of data, j: index of buffer,
+-       buf_len: number of bits to be filled in current byte */
++       bits_to_fill: number of bits to be filled in current byte */
+     size_t   i, j;
+-    unsigned buf_len;
++    unsigned bits_to_fill;
+ 
+     /* must initialize buffer to be zeros */
+     for (j = 0; j < buffer_size; j++)
+         buffer[j] = 0;
+ 
+     /* initialization before the loop */
+-    j       = 0;
+-    buf_len = sizeof(unsigned char) * 8;
++    j            = 0;
++    bits_to_fill = sizeof(unsigned char) * 8;
+ 
+     /* compress */
+     for (i = 0; i < d_nelmts; i++)
+-        H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
++        H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &bits_to_fill, p);
+ }
+-- 
+2.34.1
+
diff --git a/meta-oe/recipes-support/hdf5/hdf5_1.14.4-3.bb b/meta-oe/recipes-support/hdf5/hdf5_1.14.4-3.bb
index ca1e8d7076..b31a8d8cfa 100644
--- a/meta-oe/recipes-support/hdf5/hdf5_1.14.4-3.bb
+++ b/meta-oe/recipes-support/hdf5/hdf5_1.14.4-3.bb
@@ -28,6 +28,7 @@ SRC_URI = " \
     file://CVE-2025-2310.patch \
     file://CVE-2025-44905.patch \
     file://CVE-2025-2309.patch \
+    file://CVE-2025-2308.patch \
 "
 SRC_URI[sha256sum] = "019ac451d9e1cf89c0482ba2a06f07a46166caf23f60fea5ef3c37724a318e03"
 
