diff options
Diffstat (limited to 'meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch')
-rw-r--r-- | meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch b/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch new file mode 100644 index 0000000000..ad7b87dbc6 --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch | |||
@@ -0,0 +1,348 @@ | |||
1 | From 2554a2408e09f13652049e5ffb0d26196b02ebab Mon Sep 17 00:00:00 2001 | ||
2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
3 | Date: Tue, 8 Mar 2022 20:10:02 +0100 | ||
4 | Subject: [PATCH] [CVE-2022-29824] Fix integer overflows in xmlBuf and | ||
5 | xmlBuffer | ||
6 | |||
7 | In several places, the code handling string buffers didn't check for | ||
8 | integer overflow or used wrong types for buffer sizes. This could | ||
9 | result in out-of-bounds writes or other memory errors when working on | ||
10 | large, multi-gigabyte buffers. | ||
11 | |||
12 | Thanks to Felix Wilhelm for the report. | ||
13 | |||
14 | CVE: CVE-2022-29824 | ||
15 | |||
16 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/2554a2408e09f13652049e5ffb0d26196b02ebab] | ||
17 | |||
18 | Signed-off-by: Riyaz Ahmed Khan <Riyaz.Khan@kpit.com> | ||
19 | |||
20 | --- | ||
21 | buf.c | 86 +++++++++++++++++++++++----------------------------------- | ||
22 | tree.c | 72 ++++++++++++++++++------------------------------ | ||
23 | 2 files changed, 61 insertions(+), 97 deletions(-) | ||
24 | |||
25 | diff --git a/buf.c b/buf.c | ||
26 | index 24368d37..40a5ee06 100644 | ||
27 | --- a/buf.c | ||
28 | +++ b/buf.c | ||
29 | @@ -30,6 +30,10 @@ | ||
30 | #include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */ | ||
31 | #include "buf.h" | ||
32 | |||
33 | +#ifndef SIZE_MAX | ||
34 | +#define SIZE_MAX ((size_t) -1) | ||
35 | +#endif | ||
36 | + | ||
37 | #define WITH_BUFFER_COMPAT | ||
38 | |||
39 | /** | ||
40 | @@ -156,6 +160,8 @@ xmlBufPtr | ||
41 | xmlBufCreateSize(size_t size) { | ||
42 | xmlBufPtr ret; | ||
43 | |||
44 | + if (size == SIZE_MAX) | ||
45 | + return(NULL); | ||
46 | ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf)); | ||
47 | if (ret == NULL) { | ||
48 | xmlBufMemoryError(NULL, "creating buffer"); | ||
49 | @@ -166,8 +172,8 @@ xmlBufCreateSize(size_t size) { | ||
50 | ret->error = 0; | ||
51 | ret->buffer = NULL; | ||
52 | ret->alloc = xmlBufferAllocScheme; | ||
53 | - ret->size = (size ? size+2 : 0); /* +1 for ending null */ | ||
54 | - ret->compat_size = (int) ret->size; | ||
55 | + ret->size = (size ? size + 1 : 0); /* +1 for ending null */ | ||
56 | + ret->compat_size = (ret->size > INT_MAX ? INT_MAX : ret->size); | ||
57 | if (ret->size){ | ||
58 | ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); | ||
59 | if (ret->content == NULL) { | ||
60 | @@ -442,23 +448,17 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { | ||
61 | CHECK_COMPAT(buf) | ||
62 | |||
63 | if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); | ||
64 | - if (buf->use + len < buf->size) | ||
65 | + if (len < buf->size - buf->use) | ||
66 | return(buf->size - buf->use); | ||
67 | + if (len > SIZE_MAX - buf->use) | ||
68 | + return(0); | ||
69 | |||
70 | - /* | ||
71 | - * Windows has a BIG problem on realloc timing, so we try to double | ||
72 | - * the buffer size (if that's enough) (bug 146697) | ||
73 | - * Apparently BSD too, and it's probably best for linux too | ||
74 | - * On an embedded system this may be something to change | ||
75 | - */ | ||
76 | -#if 1 | ||
77 | - if (buf->size > (size_t) len) | ||
78 | - size = buf->size * 2; | ||
79 | - else | ||
80 | - size = buf->use + len + 100; | ||
81 | -#else | ||
82 | - size = buf->use + len + 100; | ||
83 | -#endif | ||
84 | + if (buf->size > (size_t) len) { | ||
85 | + size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2; | ||
86 | + } else { | ||
87 | + size = buf->use + len; | ||
88 | + size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100; | ||
89 | + } | ||
90 | |||
91 | if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { | ||
92 | /* | ||
93 | @@ -744,7 +744,7 @@ xmlBufIsEmpty(const xmlBufPtr buf) | ||
94 | int | ||
95 | xmlBufResize(xmlBufPtr buf, size_t size) | ||
96 | { | ||
97 | - unsigned int newSize; | ||
98 | + size_t newSize; | ||
99 | xmlChar* rebuf = NULL; | ||
100 | size_t start_buf; | ||
101 | |||
102 | @@ -772,9 +772,13 @@ xmlBufResize(xmlBufPtr buf, size_t size) | ||
103 | case XML_BUFFER_ALLOC_IO: | ||
104 | case XML_BUFFER_ALLOC_DOUBLEIT: | ||
105 | /*take care of empty case*/ | ||
106 | - newSize = (buf->size ? buf->size*2 : size + 10); | ||
107 | + if (buf->size == 0) { | ||
108 | + newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | ||
109 | + } else { | ||
110 | + newSize = buf->size; | ||
111 | + } | ||
112 | while (size > newSize) { | ||
113 | - if (newSize > UINT_MAX / 2) { | ||
114 | + if (newSize > SIZE_MAX / 2) { | ||
115 | xmlBufMemoryError(buf, "growing buffer"); | ||
116 | return 0; | ||
117 | } | ||
118 | @@ -782,15 +786,15 @@ xmlBufResize(xmlBufPtr buf, size_t size) | ||
119 | } | ||
120 | break; | ||
121 | case XML_BUFFER_ALLOC_EXACT: | ||
122 | - newSize = size+10; | ||
123 | + newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | ||
124 | break; | ||
125 | case XML_BUFFER_ALLOC_HYBRID: | ||
126 | if (buf->use < BASE_BUFFER_SIZE) | ||
127 | newSize = size; | ||
128 | else { | ||
129 | - newSize = buf->size * 2; | ||
130 | + newSize = buf->size; | ||
131 | while (size > newSize) { | ||
132 | - if (newSize > UINT_MAX / 2) { | ||
133 | + if (newSize > SIZE_MAX / 2) { | ||
134 | xmlBufMemoryError(buf, "growing buffer"); | ||
135 | return 0; | ||
136 | } | ||
137 | @@ -800,7 +804,7 @@ xmlBufResize(xmlBufPtr buf, size_t size) | ||
138 | break; | ||
139 | |||
140 | default: | ||
141 | - newSize = size+10; | ||
142 | + newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | @@ -866,7 +870,7 @@ xmlBufResize(xmlBufPtr buf, size_t size) | ||
147 | */ | ||
148 | int | ||
149 | xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { | ||
150 | - unsigned int needSize; | ||
151 | + size_t needSize; | ||
152 | |||
153 | if ((str == NULL) || (buf == NULL) || (buf->error)) | ||
154 | return -1; | ||
155 | @@ -888,8 +892,10 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { | ||
156 | if (len < 0) return -1; | ||
157 | if (len == 0) return 0; | ||
158 | |||
159 | - needSize = buf->use + len + 2; | ||
160 | - if (needSize > buf->size){ | ||
161 | + if ((size_t) len >= buf->size - buf->use) { | ||
162 | + if ((size_t) len >= SIZE_MAX - buf->use) | ||
163 | + return(-1); | ||
164 | + needSize = buf->use + len + 1; | ||
165 | if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { | ||
166 | /* | ||
167 | * Used to provide parsing limits | ||
168 | @@ -1025,31 +1031,7 @@ xmlBufCat(xmlBufPtr buf, const xmlChar *str) { | ||
169 | */ | ||
170 | int | ||
171 | xmlBufCCat(xmlBufPtr buf, const char *str) { | ||
172 | - const char *cur; | ||
173 | - | ||
174 | - if ((buf == NULL) || (buf->error)) | ||
175 | - return(-1); | ||
176 | - CHECK_COMPAT(buf) | ||
177 | - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; | ||
178 | - if (str == NULL) { | ||
179 | -#ifdef DEBUG_BUFFER | ||
180 | - xmlGenericError(xmlGenericErrorContext, | ||
181 | - "xmlBufCCat: str == NULL\n"); | ||
182 | -#endif | ||
183 | - return -1; | ||
184 | - } | ||
185 | - for (cur = str;*cur != 0;cur++) { | ||
186 | - if (buf->use + 10 >= buf->size) { | ||
187 | - if (!xmlBufResize(buf, buf->use+10)){ | ||
188 | - xmlBufMemoryError(buf, "growing buffer"); | ||
189 | - return XML_ERR_NO_MEMORY; | ||
190 | - } | ||
191 | - } | ||
192 | - buf->content[buf->use++] = *cur; | ||
193 | - } | ||
194 | - buf->content[buf->use] = 0; | ||
195 | - UPDATE_COMPAT(buf) | ||
196 | - return 0; | ||
197 | + return xmlBufCat(buf, (const xmlChar *) str); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | diff --git a/tree.c b/tree.c | ||
202 | index 9d94aa42..86afb7d6 100644 | ||
203 | --- a/tree.c | ||
204 | +++ b/tree.c | ||
205 | @@ -7104,6 +7104,8 @@ xmlBufferPtr | ||
206 | xmlBufferCreateSize(size_t size) { | ||
207 | xmlBufferPtr ret; | ||
208 | |||
209 | + if (size >= UINT_MAX) | ||
210 | + return(NULL); | ||
211 | ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); | ||
212 | if (ret == NULL) { | ||
213 | xmlTreeErrMemory("creating buffer"); | ||
214 | @@ -7111,7 +7113,7 @@ xmlBufferCreateSize(size_t size) { | ||
215 | } | ||
216 | ret->use = 0; | ||
217 | ret->alloc = xmlBufferAllocScheme; | ||
218 | - ret->size = (size ? size+2 : 0); /* +1 for ending null */ | ||
219 | + ret->size = (size ? size + 1 : 0); /* +1 for ending null */ | ||
220 | if (ret->size){ | ||
221 | ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); | ||
222 | if (ret->content == NULL) { | ||
223 | @@ -7171,6 +7173,8 @@ xmlBufferCreateStatic(void *mem, size_t size) { | ||
224 | |||
225 | if ((mem == NULL) || (size == 0)) | ||
226 | return(NULL); | ||
227 | + if (size > UINT_MAX) | ||
228 | + return(NULL); | ||
229 | |||
230 | ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); | ||
231 | if (ret == NULL) { | ||
232 | @@ -7318,28 +7322,23 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) { | ||
233 | */ | ||
234 | int | ||
235 | xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { | ||
236 | - int size; | ||
237 | + unsigned int size; | ||
238 | xmlChar *newbuf; | ||
239 | |||
240 | if (buf == NULL) return(-1); | ||
241 | |||
242 | if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); | ||
243 | - if (len + buf->use < buf->size) return(0); | ||
244 | + if (len < buf->size - buf->use) | ||
245 | + return(0); | ||
246 | + if (len > UINT_MAX - buf->use) | ||
247 | + return(-1); | ||
248 | |||
249 | - /* | ||
250 | - * Windows has a BIG problem on realloc timing, so we try to double | ||
251 | - * the buffer size (if that's enough) (bug 146697) | ||
252 | - * Apparently BSD too, and it's probably best for linux too | ||
253 | - * On an embedded system this may be something to change | ||
254 | - */ | ||
255 | -#if 1 | ||
256 | - if (buf->size > len) | ||
257 | - size = buf->size * 2; | ||
258 | - else | ||
259 | - size = buf->use + len + 100; | ||
260 | -#else | ||
261 | - size = buf->use + len + 100; | ||
262 | -#endif | ||
263 | + if (buf->size > (size_t) len) { | ||
264 | + size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2; | ||
265 | + } else { | ||
266 | + size = buf->use + len; | ||
267 | + size = size > UINT_MAX - 100 ? UINT_MAX : size + 100; | ||
268 | + } | ||
269 | |||
270 | if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { | ||
271 | size_t start_buf = buf->content - buf->contentIO; | ||
272 | @@ -7466,7 +7465,10 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) | ||
273 | case XML_BUFFER_ALLOC_IO: | ||
274 | case XML_BUFFER_ALLOC_DOUBLEIT: | ||
275 | /*take care of empty case*/ | ||
276 | - newSize = (buf->size ? buf->size : size + 10); | ||
277 | + if (buf->size == 0) | ||
278 | + newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10); | ||
279 | + else | ||
280 | + newSize = buf->size; | ||
281 | while (size > newSize) { | ||
282 | if (newSize > UINT_MAX / 2) { | ||
283 | xmlTreeErrMemory("growing buffer"); | ||
284 | @@ -7476,7 +7478,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) | ||
285 | } | ||
286 | break; | ||
287 | case XML_BUFFER_ALLOC_EXACT: | ||
288 | - newSize = size+10; | ||
289 | + newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);; | ||
290 | break; | ||
291 | case XML_BUFFER_ALLOC_HYBRID: | ||
292 | if (buf->use < BASE_BUFFER_SIZE) | ||
293 | @@ -7494,7 +7496,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) | ||
294 | break; | ||
295 | |||
296 | default: | ||
297 | - newSize = size+10; | ||
298 | + newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);; | ||
299 | break; | ||
300 | } | ||
301 | |||
302 | @@ -7580,8 +7582,10 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) { | ||
303 | if (len < 0) return -1; | ||
304 | if (len == 0) return 0; | ||
305 | |||
306 | - needSize = buf->use + len + 2; | ||
307 | - if (needSize > buf->size){ | ||
308 | + if ((unsigned) len >= buf->size - buf->use) { | ||
309 | + if ((unsigned) len >= UINT_MAX - buf->use) | ||
310 | + return XML_ERR_NO_MEMORY; | ||
311 | + needSize = buf->use + len + 1; | ||
312 | if (!xmlBufferResize(buf, needSize)){ | ||
313 | xmlTreeErrMemory("growing buffer"); | ||
314 | return XML_ERR_NO_MEMORY; | ||
315 | @@ -7694,29 +7698,7 @@ xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) { | ||
316 | */ | ||
317 | int | ||
318 | xmlBufferCCat(xmlBufferPtr buf, const char *str) { | ||
319 | - const char *cur; | ||
320 | - | ||
321 | - if (buf == NULL) | ||
322 | - return(-1); | ||
323 | - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; | ||
324 | - if (str == NULL) { | ||
325 | -#ifdef DEBUG_BUFFER | ||
326 | - xmlGenericError(xmlGenericErrorContext, | ||
327 | - "xmlBufferCCat: str == NULL\n"); | ||
328 | -#endif | ||
329 | - return -1; | ||
330 | - } | ||
331 | - for (cur = str;*cur != 0;cur++) { | ||
332 | - if (buf->use + 10 >= buf->size) { | ||
333 | - if (!xmlBufferResize(buf, buf->use+10)){ | ||
334 | - xmlTreeErrMemory("growing buffer"); | ||
335 | - return XML_ERR_NO_MEMORY; | ||
336 | - } | ||
337 | - } | ||
338 | - buf->content[buf->use++] = *cur; | ||
339 | - } | ||
340 | - buf->content[buf->use] = 0; | ||
341 | - return 0; | ||
342 | + return xmlBufferCat(buf, (const xmlChar *) str); | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | -- | ||
347 | GitLab | ||
348 | |||