]> git.pld-linux.org Git - packages/libxml2.git/blame - libxml2-CVE-2012-2807.patch
- fixes for some integer overflows (CVE-2012-2807)
[packages/libxml2.git] / libxml2-CVE-2012-2807.patch
CommitLineData
a893934d
KK
1From 459eeb9dc752d5185f57ff6b135027f11981a626 Mon Sep 17 00:00:00 2001
2From: Daniel Veillard <veillard@redhat.com>
3Date: Tue, 17 Jul 2012 16:19:17 +0800
4Subject: [PATCH 1/3] Fix parser local buffers size problems
5
6---
7 parser.c | 74 +++++++++++++++++++++++++++++++++++++---------------------------
8 1 file changed, 43 insertions(+), 31 deletions(-)
9
10diff --git a/parser.c b/parser.c
11index 2c38fae..9863275 100644
12--- a/parser.c
13+++ b/parser.c
14@@ -40,6 +40,7 @@
15 #endif
16
17 #include <stdlib.h>
18+#include <limits.h>
19 #include <string.h>
20 #include <stdarg.h>
21 #include <libxml/xmlmemory.h>
22@@ -117,10 +118,10 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
23 * parser option.
24 */
25 static int
26-xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
27+xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
28 xmlEntityPtr ent)
29 {
30- unsigned long consumed = 0;
31+ size_t consumed = 0;
32
33 if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
34 return (0);
35@@ -2589,15 +2590,17 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
36
37 /*
38 * Macro used to grow the current buffer.
39+ * buffer##_size is expected to be a size_t
40+ * mem_error: is expected to handle memory allocation failures
41 */
42 #define growBuffer(buffer, n) { \
43 xmlChar *tmp; \
44- buffer##_size *= 2; \
45- buffer##_size += n; \
46- tmp = (xmlChar *) \
47- xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
48+ size_t new_size = buffer##_size * 2 + n; \
49+ if (new_size < buffer##_size) goto mem_error; \
50+ tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
51 if (tmp == NULL) goto mem_error; \
52 buffer = tmp; \
53+ buffer##_size = new_size; \
54 }
55
56 /**
57@@ -2623,14 +2626,14 @@ xmlChar *
58 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
59 int what, xmlChar end, xmlChar end2, xmlChar end3) {
60 xmlChar *buffer = NULL;
61- int buffer_size = 0;
62+ size_t buffer_size = 0;
63+ size_t nbchars = 0;
64
65 xmlChar *current = NULL;
66 xmlChar *rep = NULL;
67 const xmlChar *last;
68 xmlEntityPtr ent;
69 int c,l;
70- int nbchars = 0;
71
72 if ((ctxt == NULL) || (str == NULL) || (len < 0))
73 return(NULL);
74@@ -2647,7 +2650,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
75 * allocate a translation buffer.
76 */
77 buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
78- buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
79+ buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
80 if (buffer == NULL) goto mem_error;
81
82 /*
83@@ -2667,7 +2670,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
84 if (val != 0) {
85 COPY_BUF(0,buffer,nbchars,val);
86 }
87- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
88+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
89 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
90 }
91 } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
92@@ -2685,7 +2688,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
93 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
94 if (ent->content != NULL) {
95 COPY_BUF(0,buffer,nbchars,ent->content[0]);
96- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
97+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
98 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
99 }
100 } else {
101@@ -2702,8 +2705,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
102 current = rep;
103 while (*current != 0) { /* non input consuming loop */
104 buffer[nbchars++] = *current++;
105- if (nbchars >
106- buffer_size - XML_PARSER_BUFFER_SIZE) {
107+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
108 if (xmlParserEntityCheck(ctxt, nbchars, ent))
109 goto int_error;
110 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
111@@ -2717,7 +2719,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
112 const xmlChar *cur = ent->name;
113
114 buffer[nbchars++] = '&';
115- if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
116+ if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
117 growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
118 }
119 for (;i > 0;i--)
120@@ -2745,8 +2747,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
121 current = rep;
122 while (*current != 0) { /* non input consuming loop */
123 buffer[nbchars++] = *current++;
124- if (nbchars >
125- buffer_size - XML_PARSER_BUFFER_SIZE) {
126+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
127 if (xmlParserEntityCheck(ctxt, nbchars, ent))
128 goto int_error;
129 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
130@@ -2759,8 +2760,8 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
131 } else {
132 COPY_BUF(l,buffer,nbchars,c);
133 str += l;
134- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
135- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
136+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
137+ growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
138 }
139 }
140 if (str < last)
141@@ -3764,8 +3765,8 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
142 xmlChar limit = 0;
143 xmlChar *buf = NULL;
144 xmlChar *rep = NULL;
145- int len = 0;
146- int buf_size = 0;
147+ size_t len = 0;
148+ size_t buf_size = 0;
149 int c, l, in_space = 0;
150 xmlChar *current = NULL;
151 xmlEntityPtr ent;
152@@ -3787,7 +3788,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
153 * allocate a translation buffer.
154 */
155 buf_size = XML_PARSER_BUFFER_SIZE;
156- buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
157+ buf = (xmlChar *) xmlMallocAtomic(buf_size);
158 if (buf == NULL) goto mem_error;
159
160 /*
161@@ -3804,7 +3805,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
162
163 if (val == '&') {
164 if (ctxt->replaceEntities) {
165- if (len > buf_size - 10) {
166+ if (len + 10 > buf_size) {
167 growBuffer(buf, 10);
168 }
169 buf[len++] = '&';
170@@ -3813,7 +3814,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
171 * The reparsing will be done in xmlStringGetNodeList()
172 * called by the attribute() function in SAX.c
173 */
174- if (len > buf_size - 10) {
175+ if (len + 10 > buf_size) {
176 growBuffer(buf, 10);
177 }
178 buf[len++] = '&';
179@@ -3823,7 +3824,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
180 buf[len++] = ';';
181 }
182 } else if (val != 0) {
183- if (len > buf_size - 10) {
184+ if (len + 10 > buf_size) {
185 growBuffer(buf, 10);
186 }
187 len += xmlCopyChar(0, &buf[len], val);
188@@ -3835,7 +3836,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
189 ctxt->nbentities += ent->owner;
190 if ((ent != NULL) &&
191 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
192- if (len > buf_size - 10) {
193+ if (len + 10 > buf_size) {
194 growBuffer(buf, 10);
195 }
196 if ((ctxt->replaceEntities == 0) &&
197@@ -3863,7 +3864,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
198 current++;
199 } else
200 buf[len++] = *current++;
201- if (len > buf_size - 10) {
202+ if (len + 10 > buf_size) {
203 growBuffer(buf, 10);
204 }
205 }
206@@ -3871,7 +3872,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
207 rep = NULL;
208 }
209 } else {
210- if (len > buf_size - 10) {
211+ if (len + 10 > buf_size) {
212 growBuffer(buf, 10);
213 }
214 if (ent->content != NULL)
215@@ -3899,7 +3900,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
216 * Just output the reference
217 */
218 buf[len++] = '&';
219- while (len > buf_size - i - 10) {
220+ while (len + i + 10 > buf_size) {
221 growBuffer(buf, i + 10);
222 }
223 for (;i > 0;i--)
224@@ -3912,7 +3913,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
225 if ((len != 0) || (!normalize)) {
226 if ((!normalize) || (!in_space)) {
227 COPY_BUF(l,buf,len,0x20);
228- while (len > buf_size - 10) {
229+ while (len + 10 > buf_size) {
230 growBuffer(buf, 10);
231 }
232 }
233@@ -3921,7 +3922,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
234 } else {
235 in_space = 0;
236 COPY_BUF(l,buf,len,c);
237- if (len > buf_size - 10) {
238+ if (len + 10 > buf_size) {
239 growBuffer(buf, 10);
240 }
241 }
242@@ -3946,7 +3947,18 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
243 }
244 } else
245 NEXT;
246- if (attlen != NULL) *attlen = len;
247+
248+ /*
249+ * There we potentially risk an overflow, don't allow attribute value of
250+ * lenght more than INT_MAX it is a very reasonnable assumption !
251+ */
252+ if (len >= INT_MAX) {
253+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
254+ "AttValue lenght too long\n");
255+ goto mem_error;
256+ }
257+
258+ if (attlen != NULL) *attlen = (int) len;
259 return(buf);
260
261 mem_error:
262--
2631.7.11.4
264
265From 4f9fdc709c4861c390cd84e2ed1fd878b3442e28 Mon Sep 17 00:00:00 2001
266From: Daniel Veillard <veillard@redhat.com>
267Date: Wed, 18 Jul 2012 11:38:17 +0800
268Subject: [PATCH 2/3] Fix entities local buffers size problems
269
270---
271 entities.c | 36 +++++++++++++++++++++++-------------
272 1 file changed, 23 insertions(+), 13 deletions(-)
273
274diff --git a/entities.c b/entities.c
275index 6aef49f..859ec3b 100644
276--- a/entities.c
277+++ b/entities.c
278@@ -528,13 +528,13 @@ xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
279 * Macro used to grow the current buffer.
280 */
281 #define growBufferReentrant() { \
282- buffer_size *= 2; \
283- buffer = (xmlChar *) \
284- xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
285- if (buffer == NULL) { \
286- xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");\
287- return(NULL); \
288- } \
289+ xmlChar *tmp; \
290+ size_t new_size = buffer_size * 2; \
291+ if (new_size < buffer_size) goto mem_error; \
292+ tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
293+ if (tmp == NULL) goto mem_error; \
294+ buffer = tmp; \
295+ buffer_size = new_size; \
296 }
297
298
299@@ -555,7 +555,7 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
300 const xmlChar *cur = input;
301 xmlChar *buffer = NULL;
302 xmlChar *out = NULL;
303- int buffer_size = 0;
304+ size_t buffer_size = 0;
305 int html = 0;
306
307 if (input == NULL) return(NULL);
308@@ -574,8 +574,8 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
309 out = buffer;
310
311 while (*cur != '\0') {
312- if (out - buffer > buffer_size - 100) {
313- int indx = out - buffer;
314+ size_t indx = out - buffer;
315+ if (indx + 100 > buffer_size) {
316
317 growBufferReentrant();
318 out = &buffer[indx];
319@@ -692,6 +692,11 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
320 }
321 *out = 0;
322 return(buffer);
323+
324+mem_error:
325+ xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");
326+ xmlFree(buffer);
327+ return(NULL);
328 }
329
330 /**
331@@ -709,7 +714,7 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
332 const xmlChar *cur = input;
333 xmlChar *buffer = NULL;
334 xmlChar *out = NULL;
335- int buffer_size = 0;
336+ size_t buffer_size = 0;
337 if (input == NULL) return(NULL);
338
339 /*
340@@ -724,8 +729,8 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
341 out = buffer;
342
343 while (*cur != '\0') {
344- if (out - buffer > buffer_size - 10) {
345- int indx = out - buffer;
346+ size_t indx = out - buffer;
347+ if (indx + 10 > buffer_size) {
348
349 growBufferReentrant();
350 out = &buffer[indx];
351@@ -774,6 +779,11 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
352 }
353 *out = 0;
354 return(buffer);
355+
356+mem_error:
357+ xmlEntitiesErrMemory("xmlEncodeSpecialChars: realloc failed");
358+ xmlFree(buffer);
359+ return(NULL);
360 }
361
362 /**
363--
3641.7.11.4
365
This page took 0.078115 seconds and 4 git commands to generate.