summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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