summaryrefslogtreecommitdiffstats
path: root/meta-oe
diff options
context:
space:
mode:
authorLibo Chen <libo.chen.cn@windriver.com>2026-04-17 16:45:46 +0800
committerAnuj Mittal <anuj.mittal@oss.qualcomm.com>2026-04-29 10:14:29 +0530
commit4ab556ad1e14955ffd414b1716eaeaa5ca719cc1 (patch)
treef099b4f3f307aa5e985479b9bcb401c539c2c840 /meta-oe
parenta26a769011ca88a8756b412fb11f6456ca334284 (diff)
downloadmeta-openembedded-4ab556ad1e14955ffd414b1716eaeaa5ca719cc1.tar.gz
hdf5: fix CVE-2025-2308
According to [1], A vulnerability, which was classified as critical, was found in HDF5 1.14.6. This affects the function H5Z__scaleoffset_decompress_one_byte of the component Scale-Offset Filter. The manipulation leads to heap-based buffer overflow. An attack has to be approached locally. The exploit has been disclosed to the public and may be used. The vendor plans to fix this issue in an upcoming release. Backport patch [2] from upstream to fix CVE-2025-2308 [1] https://nvd.nist.gov/vuln/detail/CVE-2025-2308 [2] https://github.com/HDFGroup/hdf5/commit/2ce7fdc4cf147d280aa6d49686297faacc250e40 Signed-off-by: Libo Chen <libo.chen.cn@windriver.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
Diffstat (limited to 'meta-oe')
-rw-r--r--meta-oe/recipes-support/hdf5/files/CVE-2025-2308.patch333
-rw-r--r--meta-oe/recipes-support/hdf5/hdf5_1.14.4-3.bb1
2 files changed, 334 insertions, 0 deletions
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 @@
1From cbce4c2ecf6f5557605890eec125ecfaa4371131 Mon Sep 17 00:00:00 2001
2From: Libo Chen <libo.chen.cn@windriver.com>
3Date: Fri, 30 Jan 2026 16:43:04 +0800
4Subject: [PATCH] Fix CVE-2025-2308 (#5960)
5
6A 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.
7
8This PR fixes CVE-2025-2308.
9
10CVE: CVE-2025-2308
11
12Upstream-Status: Backport [https://github.com/HDFGroup/hdf5/commit/2ce7fdc4cf147d280aa6d49686297faacc250e40]
13
14Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
15---
16 src/H5Zscaleoffset.c | 177 ++--
17 src/H5Zscaleoffset.c.orig | 1781 +++++++++++++++++++++++++++++++++++++
18 1 files changed, 105 insertions(+), 72 deletions(-)
19 create mode 100644 src/H5Zscaleoffset.c.orig
20
21diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
22index fbf12d6..8355b13 100644
23--- a/src/H5Zscaleoffset.c
24+++ b/src/H5Zscaleoffset.c
25@@ -69,21 +69,22 @@ static herr_t H5Z__scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enu
26 static herr_t H5Z__scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type,
27 unsigned filavail, const unsigned cd_values[],
28 uint32_t minbits, unsigned long long minval, double D_val);
29-static void H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len);
30-static void H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
31- unsigned begin_i, const unsigned char *buffer, size_t *j,
32- unsigned *buf_len, parms_atomic p, unsigned dtype_len);
33+static void H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill);
34+static herr_t H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
35+ unsigned begin_i, const unsigned char *buffer,
36+ size_t buf_size, size_t *j, unsigned *bits_to_fill,
37+ parms_atomic p, unsigned dtype_len);
38 static void H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
39 unsigned begin_i, unsigned char *buffer, size_t *j,
40- unsigned *buf_len, parms_atomic p, unsigned dtype_len);
41-static void H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
42- unsigned char *buffer, size_t *j, unsigned *buf_len,
43- parms_atomic p);
44+ unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len);
45+static herr_t H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
46+ unsigned char *buffer, size_t buf_size, size_t *j,
47+ unsigned *bits_to_fill, parms_atomic p);
48 static void H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset,
49- unsigned char *buffer, size_t *j, unsigned *buf_len,
50+ unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
51 parms_atomic p);
52-static void H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
53- parms_atomic p);
54+static herr_t H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
55+ size_t buf_size, parms_atomic p);
56 static void H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
57 size_t buffer_size, parms_atomic p);
58
59@@ -1261,8 +1262,11 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
60 }
61
62 /* decompress the buffer if minbits not equal to zero */
63- if (minbits != 0)
64- H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset, p);
65+ if (minbits != 0) {
66+ if (H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset,
67+ *buf_size - buf_offset, p))
68+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Scaleoffset decompression failed");
69+ }
70 else {
71 /* fill value is not defined and all data elements have the same value */
72 for (i = 0; i < size_out; i++)
73@@ -1603,55 +1607,69 @@ done:
74 }
75
76 static void
77-H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len)
78+H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill)
79 {
80 ++(*j);
81- *buf_len = 8 * sizeof(unsigned char);
82+ *bits_to_fill = 8 * sizeof(unsigned char);
83 }
84
85-static void
86+static herr_t
87 H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k, unsigned begin_i,
88- const unsigned char *buffer, size_t *j, unsigned *buf_len,
89- parms_atomic p, unsigned dtype_len)
90+ const unsigned char *buffer, size_t buf_size, size_t *j,
91+ unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len)
92 {
93- unsigned dat_len; /* dat_len is the number of bits to be copied in each data byte */
94- unsigned char val; /* value to be copied in each data byte */
95+ unsigned bits_to_copy; /* bits_to_copy is the number of bits to be copied in each data byte */
96+ unsigned char val; /* value to be copied in each data byte */
97+ herr_t ret_value = SUCCEED; /* Return value */
98+
99+ FUNC_ENTER_PACKAGE
100+
101+ if (*j >= buf_size)
102+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");
103
104 /* initialize value and bits of unsigned char to be copied */
105 val = buffer[*j];
106 if (k == begin_i)
107- dat_len = 8 - (dtype_len - p.minbits) % 8;
108+ bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
109 else
110- dat_len = 8;
111+ bits_to_copy = 8;
112
113- if (*buf_len > dat_len) {
114- data[data_offset + k] =
115- (unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & (unsigned)(~((unsigned)~0 << dat_len)));
116- *buf_len -= dat_len;
117+ if (*bits_to_fill > bits_to_copy) {
118+ data[data_offset + k] = (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
119+ (unsigned)(~((unsigned)~0 << bits_to_copy)));
120+ *bits_to_fill -= bits_to_copy;
121 } /* end if */
122 else {
123 data[data_offset + k] =
124- (unsigned char)((val & ~((unsigned)(~0) << *buf_len)) << (dat_len - *buf_len));
125- dat_len -= *buf_len;
126- H5Z__scaleoffset_next_byte(j, buf_len);
127- if (dat_len == 0)
128- return;
129+ (unsigned char)((val & ~((unsigned)(~0) << *bits_to_fill)) << (bits_to_copy - *bits_to_fill));
130+ bits_to_copy -= *bits_to_fill;
131+ H5Z__scaleoffset_next_byte(j, bits_to_fill);
132+ if (bits_to_copy == 0)
133+ goto done;
134+ else if (*j >= buf_size)
135+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");
136
137 val = buffer[*j];
138- data[data_offset + k] |=
139- (unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & ~((unsigned)(~0) << dat_len));
140- *buf_len -= dat_len;
141+ data[data_offset + k] |= (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
142+ ~((unsigned)(~0) << bits_to_copy));
143+ *bits_to_fill -= bits_to_copy;
144 } /* end else */
145+
146+done:
147+ FUNC_LEAVE_NOAPI(ret_value)
148 }
149
150-static void
151+static herr_t
152 H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
153- size_t *j, unsigned *buf_len, parms_atomic p)
154+ size_t buf_size, size_t *j, unsigned *bits_to_fill, parms_atomic p)
155 {
156 /* begin_i: the index of byte having first significant bit */
157 unsigned begin_i;
158 unsigned dtype_len;
159 int k;
160+ herr_t ret_value = SUCCEED; /* Return value */
161+
162+ FUNC_ENTER_PACKAGE
163
164 assert(p.minbits > 0);
165
166@@ -1661,8 +1679,9 @@ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
167 begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;
168
169 for (k = (int)begin_i; k >= 0; k--)
170- H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
171- p, dtype_len);
172+ if (H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer,
173+ buf_size, j, bits_to_fill, p, dtype_len))
174+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Atomic decompression failed");
175 }
176 else { /* big endian */
177 assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);
178@@ -1670,67 +1689,81 @@ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
179 begin_i = (dtype_len - p.minbits) / 8;
180
181 for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
182- H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
183- p, dtype_len);
184+ if (H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer,
185+ buf_size, j, bits_to_fill, p, dtype_len))
186+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Atomic decompression failed");
187 }
188+
189+done:
190+ FUNC_LEAVE_NOAPI(ret_value)
191 }
192
193-static void
194-H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, parms_atomic p)
195+static herr_t
196+H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, size_t buf_size,
197+ parms_atomic p)
198 {
199 /* i: index of data, j: index of buffer,
200- buf_len: number of bits to be filled in current byte */
201+ bits_to_fill: number of bits to be filled in current byte */
202 size_t i, j;
203- unsigned buf_len;
204+ unsigned bits_to_fill;
205+ herr_t ret_value = SUCCEED; /* Return value */
206+
207+ FUNC_ENTER_PACKAGE
208
209 /* must initialize to zeros */
210 for (i = 0; i < d_nelmts * (size_t)p.size; i++)
211 data[i] = 0;
212
213 /* initialization before the loop */
214- j = 0;
215- buf_len = sizeof(unsigned char) * 8;
216+ j = 0;
217+ bits_to_fill = sizeof(unsigned char) * 8;
218
219 /* decompress */
220 for (i = 0; i < d_nelmts; i++)
221- H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
222+ if (H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, buf_size, &j, &bits_to_fill, p))
223+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Scaleoffset decompression failed");
224+
225+done:
226+ FUNC_LEAVE_NOAPI(ret_value)
227 }
228
229 static void
230 H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
231- unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *buf_len,
232+ unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
233 parms_atomic p, unsigned dtype_len)
234 {
235- unsigned dat_len; /* dat_len is the number of bits to be copied in each data byte */
236- unsigned char val; /* value to be copied in each data byte */
237+ unsigned bits_to_copy; /* bits_to_copy is the number of bits to be copied in each data byte */
238+ unsigned char val; /* value to be copied in each data byte */
239
240 /* initialize value and bits of unsigned char to be copied */
241 val = data[data_offset + k];
242 if (k == begin_i)
243- dat_len = 8 - (dtype_len - p.minbits) % 8;
244+ bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
245 else
246- dat_len = 8;
247+ bits_to_copy = 8;
248
249- if (*buf_len > dat_len) {
250- buffer[*j] |= (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
251- *buf_len -= dat_len;
252+ if (*bits_to_fill > bits_to_copy) {
253+ buffer[*j] |=
254+ (unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
255+ *bits_to_fill -= bits_to_copy;
256 }
257 else {
258- buffer[*j] |=
259- (unsigned char)((unsigned)(val >> (dat_len - *buf_len)) & ~((unsigned)(~0) << *buf_len));
260- dat_len -= *buf_len;
261- H5Z__scaleoffset_next_byte(j, buf_len);
262- if (dat_len == 0)
263+ buffer[*j] |= (unsigned char)((unsigned)(val >> (bits_to_copy - *bits_to_fill)) &
264+ ~((unsigned)(~0) << *bits_to_fill));
265+ bits_to_copy -= *bits_to_fill;
266+ H5Z__scaleoffset_next_byte(j, bits_to_fill);
267+ if (bits_to_copy == 0)
268 return;
269
270- buffer[*j] = (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
271- *buf_len -= dat_len;
272+ buffer[*j] =
273+ (unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
274+ *bits_to_fill -= bits_to_copy;
275 } /* end else */
276 }
277
278 static void
279 H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
280- size_t *j, unsigned *buf_len, parms_atomic p)
281+ size_t *j, unsigned *bits_to_fill, parms_atomic p)
282 {
283 /* begin_i: the index of byte having first significant bit */
284 unsigned begin_i;
285@@ -1745,16 +1778,16 @@ H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, un
286 begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;
287
288 for (k = (int)begin_i; k >= 0; k--)
289- H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
290- dtype_len);
291+ H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
292+ bits_to_fill, p, dtype_len);
293 }
294 else { /* big endian */
295 assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);
296 begin_i = (dtype_len - p.minbits) / 8;
297
298 for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
299- H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
300- dtype_len);
301+ H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
302+ bits_to_fill, p, dtype_len);
303 }
304 }
305
306@@ -1763,19 +1796,19 @@ H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char
307 parms_atomic p)
308 {
309 /* i: index of data, j: index of buffer,
310- buf_len: number of bits to be filled in current byte */
311+ bits_to_fill: number of bits to be filled in current byte */
312 size_t i, j;
313- unsigned buf_len;
314+ unsigned bits_to_fill;
315
316 /* must initialize buffer to be zeros */
317 for (j = 0; j < buffer_size; j++)
318 buffer[j] = 0;
319
320 /* initialization before the loop */
321- j = 0;
322- buf_len = sizeof(unsigned char) * 8;
323+ j = 0;
324+ bits_to_fill = sizeof(unsigned char) * 8;
325
326 /* compress */
327 for (i = 0; i < d_nelmts; i++)
328- H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
329+ H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &bits_to_fill, p);
330 }
331--
3322.34.1
333
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 = " \
28 file://CVE-2025-2310.patch \ 28 file://CVE-2025-2310.patch \
29 file://CVE-2025-44905.patch \ 29 file://CVE-2025-44905.patch \
30 file://CVE-2025-2309.patch \ 30 file://CVE-2025-2309.patch \
31 file://CVE-2025-2308.patch \
31" 32"
32SRC_URI[sha256sum] = "019ac451d9e1cf89c0482ba2a06f07a46166caf23f60fea5ef3c37724a318e03" 33SRC_URI[sha256sum] = "019ac451d9e1cf89c0482ba2a06f07a46166caf23f60fea5ef3c37724a318e03"
33 34