View | Details | Raw Unified | Return to bug 210531
Collapse All | Expand All

(-)textproc/expat2/Makefile (-4 / +2 lines)
Lines 2-9 Link Here
2
# $FreeBSD$
2
# $FreeBSD$
3
3
4
PORTNAME=	expat
4
PORTNAME=	expat
5
PORTVERSION=	2.1.1
5
PORTVERSION=	2.2.0
6
PORTREVISION=	1
7
CATEGORIES=	textproc
6
CATEGORIES=	textproc
8
MASTER_SITES=	SF
7
MASTER_SITES=	SF
9
8
Lines 12-19 COMMENT= XML 1.0 parser written in C Link Here
12
11
13
GNU_CONFIGURE=	yes
12
GNU_CONFIGURE=	yes
14
ALL_TARGET=	default
13
ALL_TARGET=	default
15
USES=		dos2unix libtool pathfix tar:bz2
14
USES=		libtool pathfix tar:bz2
16
DOS2UNIX_GLOB=	*.txt
17
USE_LDCONFIG=	yes
15
USE_LDCONFIG=	yes
18
16
19
post-stage:
17
post-stage:
(-)textproc/expat2/distinfo (-3 / +3 lines)
Lines 1-3 Link Here
1
TIMESTAMP = 1463705024
1
TIMESTAMP = 1466782039
2
SHA256 (expat-2.1.1.tar.bz2) = aff584e5a2f759dcfc6d48671e9529f6afe1e30b0cd6a4cec200cbe3f793de67
2
SHA256 (expat-2.2.0.tar.bz2) = d9e50ff2d19b3538bd2127902a89987474e1a4db8e43a66a4d1a712ab9a504ff
3
SIZE (expat-2.1.1.tar.bz2) = 405103
3
SIZE (expat-2.2.0.tar.bz2) = 414352
(-)textproc/expat2/files/patch-CVE-2016-0718-v2-2-1 (-754 lines)
Lines 1-754 Link Here
1
From cdfcb1b5c95e93b00ae9e9d25708b4a3bee72c15 Mon Sep 17 00:00:00 2001
2
From: Sebastian Pipping <sebastian@pipping.org>
3
Date: Mon, 2 May 2016 00:02:44 +0200
4
Subject: [PATCH] Address CVE-2016-0718 (/patch/ version 2.2.1)
5
6
* Out of bounds memory access when doing text conversion on malformed input
7
* Integer overflow related to memory allocation
8
9
Reported by Gustavo Grieco
10
11
Patch credits go to
12
* Christian Heimes
13
* Karl Waclawek
14
* Gustavo Grieco
15
* Sebastian Pipping
16
* Pascal Cuoq
17
---
18
 expat/lib/xmlparse.c    |  34 +++++++++-----
19
 expat/lib/xmltok.c      | 115 +++++++++++++++++++++++++++++++++++-------------
20
 expat/lib/xmltok.h      |  10 ++++-
21
 expat/lib/xmltok_impl.c |  62 +++++++++++++-------------
22
 4 files changed, 146 insertions(+), 75 deletions(-)
23
24
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
25
index e308c79..13e080d 100644
26
--- lib/xmlparse.c
27
+++ lib/xmlparse.c
28
@@ -2426,11 +2426,11 @@ doContent(XML_Parser parser,
29
           for (;;) {
30
             int bufSize;
31
             int convLen;
32
-            XmlConvert(enc,
33
+            const enum XML_Convert_Result convert_res = XmlConvert(enc,
34
                        &fromPtr, rawNameEnd,
35
                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
36
             convLen = (int)(toPtr - (XML_Char *)tag->buf);
37
-            if (fromPtr == rawNameEnd) {
38
+            if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
39
               tag->name.strLen = convLen;
40
               break;
41
             }
42
@@ -2651,11 +2651,11 @@ doContent(XML_Parser parser,
43
           if (MUST_CONVERT(enc, s)) {
44
             for (;;) {
45
               ICHAR *dataPtr = (ICHAR *)dataBuf;
46
-              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
47
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
48
               *eventEndPP = s;
49
               charDataHandler(handlerArg, dataBuf,
50
                               (int)(dataPtr - (ICHAR *)dataBuf));
51
-              if (s == next)
52
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
53
                 break;
54
               *eventPP = s;
55
             }
56
@@ -3261,11 +3261,11 @@ doCdataSection(XML_Parser parser,
57
           if (MUST_CONVERT(enc, s)) {
58
             for (;;) {
59
               ICHAR *dataPtr = (ICHAR *)dataBuf;
60
-              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
61
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
62
               *eventEndPP = next;
63
               charDataHandler(handlerArg, dataBuf,
64
                               (int)(dataPtr - (ICHAR *)dataBuf));
65
-              if (s == next)
66
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
67
                 break;
68
               *eventPP = s;
69
             }
70
@@ -5342,6 +5342,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
71
               const char *s, const char *end)
72
 {
73
   if (MUST_CONVERT(enc, s)) {
74
+    enum XML_Convert_Result convert_res;
75
     const char **eventPP;
76
     const char **eventEndPP;
77
     if (enc == encoding) {
78
@@ -5354,11 +5355,11 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
79
     }
80
     do {
81
       ICHAR *dataPtr = (ICHAR *)dataBuf;
82
-      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
83
+      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
84
       *eventEndPP = s;
85
       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
86
       *eventPP = s;
87
-    } while (s != end);
88
+    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
89
   }
90
   else
91
     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
92
@@ -6163,8 +6164,8 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc,
93
   if (!pool->ptr && !poolGrow(pool))
94
     return NULL;
95
   for (;;) {
96
-    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
97
-    if (ptr == end)
98
+    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
99
+    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
100
       break;
101
     if (!poolGrow(pool))
102
       return NULL;
103
@@ -6248,8 +6249,13 @@ poolGrow(STRING_POOL *pool)
104
     }
105
   }
106
   if (pool->blocks && pool->start == pool->blocks->s) {
107
-    int blockSize = (int)(pool->end - pool->start)*2;
108
-    BLOCK *temp = (BLOCK *)
109
+    BLOCK *temp;
110
+    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
111
+
112
+    if (blockSize < 0)
113
+      return XML_FALSE;
114
+
115
+    temp = (BLOCK *)
116
       pool->mem->realloc_fcn(pool->blocks,
117
                              (offsetof(BLOCK, s)
118
                               + blockSize * sizeof(XML_Char)));
119
@@ -6264,6 +6270,10 @@ poolGrow(STRING_POOL *pool)
120
   else {
121
     BLOCK *tem;
122
     int blockSize = (int)(pool->end - pool->start);
123
+
124
+    if (blockSize < 0)
125
+      return XML_FALSE;
126
+
127
     if (blockSize < INIT_BLOCK_SIZE)
128
       blockSize = INIT_BLOCK_SIZE;
129
     else
130
diff --git a/expat/lib/xmltok.c b/expat/lib/xmltok.c
131
index bf09dfc..cb98ce1 100644
132
--- lib/xmltok.c
133
+++ lib/xmltok.c
134
@@ -318,39 +318,55 @@ enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
135
   UTF8_cval4 = 0xf0
136
 };
137
 
138
-static void PTRCALL
139
+static enum XML_Convert_Result PTRCALL
140
 utf8_toUtf8(const ENCODING *enc,
141
             const char **fromP, const char *fromLim,
142
             char **toP, const char *toLim)
143
 {
144
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
145
   char *to;
146
   const char *from;
147
   if (fromLim - *fromP > toLim - *toP) {
148
     /* Avoid copying partial characters. */
149
+    res = XML_CONVERT_OUTPUT_EXHAUSTED;
150
     for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
151
       if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
152
         break;
153
   }
154
-  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
155
+  for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
156
     *to = *from;
157
   *fromP = from;
158
   *toP = to;
159
+
160
+  if ((to == toLim) && (from < fromLim))
161
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
162
+  else
163
+    return res;
164
 }
165
 
166
-static void PTRCALL
167
+static enum XML_Convert_Result PTRCALL
168
 utf8_toUtf16(const ENCODING *enc,
169
              const char **fromP, const char *fromLim,
170
              unsigned short **toP, const unsigned short *toLim)
171
 {
172
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
173
   unsigned short *to = *toP;
174
   const char *from = *fromP;
175
-  while (from != fromLim && to != toLim) {
176
+  while (from < fromLim && to < toLim) {
177
     switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
178
     case BT_LEAD2:
179
+      if (fromLim - from < 2) {
180
+        res = XML_CONVERT_INPUT_INCOMPLETE;
181
+        break;
182
+      }
183
       *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
184
       from += 2;
185
       break;
186
     case BT_LEAD3:
187
+      if (fromLim - from < 3) {
188
+        res = XML_CONVERT_INPUT_INCOMPLETE;
189
+        break;
190
+      }
191
       *to++ = (unsigned short)(((from[0] & 0xf) << 12)
192
                                | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
193
       from += 3;
194
@@ -358,8 +374,14 @@ utf8_toUtf16(const ENCODING *enc,
195
     case BT_LEAD4:
196
       {
197
         unsigned long n;
198
-        if (to + 1 == toLim)
199
+        if (toLim - to < 2) {
200
+          res = XML_CONVERT_OUTPUT_EXHAUSTED;
201
           goto after;
202
+        }
203
+        if (fromLim - from < 4) {
204
+          res = XML_CONVERT_INPUT_INCOMPLETE;
205
+          goto after;
206
+        }
207
         n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
208
             | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
209
         n -= 0x10000;
210
@@ -377,6 +399,7 @@ utf8_toUtf16(const ENCODING *enc,
211
 after:
212
   *fromP = from;
213
   *toP = to;
214
+  return res;
215
 }
216
 
217
 #ifdef XML_NS
218
@@ -425,7 +448,7 @@ static const struct normal_encoding internal_utf8_encoding = {
219
   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
220
 };
221
 
222
-static void PTRCALL
223
+static enum XML_Convert_Result PTRCALL
224
 latin1_toUtf8(const ENCODING *enc,
225
               const char **fromP, const char *fromLim,
226
               char **toP, const char *toLim)
227
@@ -433,30 +456,35 @@ latin1_toUtf8(const ENCODING *enc,
228
   for (;;) {
229
     unsigned char c;
230
     if (*fromP == fromLim)
231
-      break;
232
+      return XML_CONVERT_COMPLETED;
233
     c = (unsigned char)**fromP;
234
     if (c & 0x80) {
235
       if (toLim - *toP < 2)
236
-        break;
237
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
238
       *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
239
       *(*toP)++ = (char)((c & 0x3f) | 0x80);
240
       (*fromP)++;
241
     }
242
     else {
243
       if (*toP == toLim)
244
-        break;
245
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
246
       *(*toP)++ = *(*fromP)++;
247
     }
248
   }
249
 }
250
 
251
-static void PTRCALL
252
+static enum XML_Convert_Result PTRCALL
253
 latin1_toUtf16(const ENCODING *enc,
254
                const char **fromP, const char *fromLim,
255
                unsigned short **toP, const unsigned short *toLim)
256
 {
257
-  while (*fromP != fromLim && *toP != toLim)
258
+  while (*fromP < fromLim && *toP < toLim)
259
     *(*toP)++ = (unsigned char)*(*fromP)++;
260
+
261
+  if ((*toP == toLim) && (*fromP < fromLim))
262
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
263
+  else
264
+    return XML_CONVERT_COMPLETED;
265
 }
266
 
267
 #ifdef XML_NS
268
@@ -483,13 +511,18 @@ static const struct normal_encoding latin1_encoding = {
269
   STANDARD_VTABLE(sb_)
270
 };
271
 
272
-static void PTRCALL
273
+static enum XML_Convert_Result PTRCALL
274
 ascii_toUtf8(const ENCODING *enc,
275
              const char **fromP, const char *fromLim,
276
              char **toP, const char *toLim)
277
 {
278
-  while (*fromP != fromLim && *toP != toLim)
279
+  while (*fromP < fromLim && *toP < toLim)
280
     *(*toP)++ = *(*fromP)++;
281
+
282
+  if ((*toP == toLim) && (*fromP < fromLim))
283
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
284
+  else
285
+    return XML_CONVERT_COMPLETED;
286
 }
287
 
288
 #ifdef XML_NS
289
@@ -536,13 +569,14 @@ unicode_byte_type(char hi, char lo)
290
 }
291
 
292
 #define DEFINE_UTF16_TO_UTF8(E) \
293
-static void  PTRCALL \
294
+static enum XML_Convert_Result  PTRCALL \
295
 E ## toUtf8(const ENCODING *enc, \
296
             const char **fromP, const char *fromLim, \
297
             char **toP, const char *toLim) \
298
 { \
299
-  const char *from; \
300
-  for (from = *fromP; from != fromLim; from += 2) { \
301
+  const char *from = *fromP; \
302
+  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \
303
+  for (; from < fromLim; from += 2) { \
304
     int plane; \
305
     unsigned char lo2; \
306
     unsigned char lo = GET_LO(from); \
307
@@ -552,7 +586,7 @@ E ## toUtf8(const ENCODING *enc, \
308
       if (lo < 0x80) { \
309
         if (*toP == toLim) { \
310
           *fromP = from; \
311
-          return; \
312
+          return XML_CONVERT_OUTPUT_EXHAUSTED; \
313
         } \
314
         *(*toP)++ = lo; \
315
         break; \
316
@@ -562,7 +596,7 @@ E ## toUtf8(const ENCODING *enc, \
317
     case 0x4: case 0x5: case 0x6: case 0x7: \
318
       if (toLim -  *toP < 2) { \
319
         *fromP = from; \
320
-        return; \
321
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
322
       } \
323
       *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
324
       *(*toP)++ = ((lo & 0x3f) | 0x80); \
325
@@ -570,7 +604,7 @@ E ## toUtf8(const ENCODING *enc, \
326
     default: \
327
       if (toLim -  *toP < 3)  { \
328
         *fromP = from; \
329
-        return; \
330
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
331
       } \
332
       /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
333
       *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
334
@@ -580,7 +614,11 @@ E ## toUtf8(const ENCODING *enc, \
335
     case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
336
       if (toLim -  *toP < 4) { \
337
         *fromP = from; \
338
-        return; \
339
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
340
+      } \
341
+      if (fromLim - from < 4) { \
342
+        *fromP = from; \
343
+        return XML_CONVERT_INPUT_INCOMPLETE; \
344
       } \
345
       plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
346
       *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
347
@@ -596,20 +634,32 @@ E ## toUtf8(const ENCODING *enc, \
348
     } \
349
   } \
350
   *fromP = from; \
351
+  if (from < fromLim) \
352
+    return XML_CONVERT_INPUT_INCOMPLETE; \
353
+  else \
354
+    return XML_CONVERT_COMPLETED; \
355
 }
356
 
357
 #define DEFINE_UTF16_TO_UTF16(E) \
358
-static void  PTRCALL \
359
+static enum XML_Convert_Result  PTRCALL \
360
 E ## toUtf16(const ENCODING *enc, \
361
              const char **fromP, const char *fromLim, \
362
              unsigned short **toP, const unsigned short *toLim) \
363
 { \
364
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
365
+  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \
366
   /* Avoid copying first half only of surrogate */ \
367
   if (fromLim - *fromP > ((toLim - *toP) << 1) \
368
-      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
369
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
370
     fromLim -= 2; \
371
-  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
372
+    res = XML_CONVERT_INPUT_INCOMPLETE; \
373
+  } \
374
+  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
375
     *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
376
+  if ((*toP == toLim) && (*fromP < fromLim)) \
377
+    return XML_CONVERT_OUTPUT_EXHAUSTED; \
378
+  else \
379
+    return res; \
380
 }
381
 
382
 #define SET2(ptr, ch) \
383
@@ -1288,7 +1338,7 @@ unknown_isInvalid(const ENCODING *enc, const char *p)
384
   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
385
 }
386
 
387
-static void PTRCALL
388
+static enum XML_Convert_Result PTRCALL
389
 unknown_toUtf8(const ENCODING *enc,
390
                const char **fromP, const char *fromLim,
391
                char **toP, const char *toLim)
392
@@ -1299,21 +1349,21 @@ unknown_toUtf8(const ENCODING *enc,
393
     const char *utf8;
394
     int n;
395
     if (*fromP == fromLim)
396
-      break;
397
+      return XML_CONVERT_COMPLETED;
398
     utf8 = uenc->utf8[(unsigned char)**fromP];
399
     n = *utf8++;
400
     if (n == 0) {
401
       int c = uenc->convert(uenc->userData, *fromP);
402
       n = XmlUtf8Encode(c, buf);
403
       if (n > toLim - *toP)
404
-        break;
405
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
406
       utf8 = buf;
407
       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
408
                  - (BT_LEAD2 - 2));
409
     }
410
     else {
411
       if (n > toLim - *toP)
412
-        break;
413
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
414
       (*fromP)++;
415
     }
416
     do {
417
@@ -1322,13 +1372,13 @@ unknown_toUtf8(const ENCODING *enc,
418
   }
419
 }
420
 
421
-static void PTRCALL
422
+static enum XML_Convert_Result PTRCALL
423
 unknown_toUtf16(const ENCODING *enc,
424
                 const char **fromP, const char *fromLim,
425
                 unsigned short **toP, const unsigned short *toLim)
426
 {
427
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
428
-  while (*fromP != fromLim && *toP != toLim) {
429
+  while (*fromP < fromLim && *toP < toLim) {
430
     unsigned short c = uenc->utf16[(unsigned char)**fromP];
431
     if (c == 0) {
432
       c = (unsigned short)
433
@@ -1340,6 +1390,11 @@ unknown_toUtf16(const ENCODING *enc,
434
       (*fromP)++;
435
     *(*toP)++ = c;
436
   }
437
+
438
+  if ((*toP == toLim) && (*fromP < fromLim))
439
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
440
+  else
441
+    return XML_CONVERT_COMPLETED;
442
 }
443
 
444
 ENCODING *
445
@@ -1503,7 +1558,7 @@ initScan(const ENCODING * const *encodingTable,
446
 {
447
   const ENCODING **encPtr;
448
 
449
-  if (ptr == end)
450
+  if (ptr >= end)
451
     return XML_TOK_NONE;
452
   encPtr = enc->encPtr;
453
   if (ptr + 1 == end) {
454
diff --git a/expat/lib/xmltok.h b/expat/lib/xmltok.h
455
index ca867aa..752007e 100644
456
--- lib/xmltok.h
457
+++ lib/xmltok.h
458
@@ -130,6 +130,12 @@ typedef int (PTRCALL *SCANNER)(const ENCODING *,
459
                                const char *,
460
                                const char **);
461
 
462
+enum XML_Convert_Result {
463
+  XML_CONVERT_COMPLETED = 0,
464
+  XML_CONVERT_INPUT_INCOMPLETE = 1,
465
+  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */
466
+};
467
+
468
 struct encoding {
469
   SCANNER scanners[XML_N_STATES];
470
   SCANNER literalScanners[XML_N_LITERAL_TYPES];
471
@@ -158,12 +164,12 @@ struct encoding {
472
                             const char *ptr,
473
                             const char *end,
474
                             const char **badPtr);
475
-  void (PTRCALL *utf8Convert)(const ENCODING *enc,
476
+  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
477
                               const char **fromP,
478
                               const char *fromLim,
479
                               char **toP,
480
                               const char *toLim);
481
-  void (PTRCALL *utf16Convert)(const ENCODING *enc,
482
+  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
483
                                const char **fromP,
484
                                const char *fromLim,
485
                                unsigned short **toP,
486
diff --git a/expat/lib/xmltok_impl.c b/expat/lib/xmltok_impl.c
487
index 9c2895b..6c5a3ba 100644
488
--- lib/xmltok_impl.c
489
+++ lib/xmltok_impl.c
490
@@ -93,13 +93,13 @@ static int PTRCALL
491
 PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
492
                     const char *end, const char **nextTokPtr)
493
 {
494
-  if (ptr != end) {
495
+  if (ptr < end) {
496
     if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
497
       *nextTokPtr = ptr;
498
       return XML_TOK_INVALID;
499
     }
500
     ptr += MINBPC(enc);
501
-    while (ptr != end) {
502
+    while (ptr < end) {
503
       switch (BYTE_TYPE(enc, ptr)) {
504
       INVALID_CASES(ptr, nextTokPtr)
505
       case BT_MINUS:
506
@@ -147,7 +147,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
507
     *nextTokPtr = ptr;
508
     return XML_TOK_INVALID;
509
   }
510
-  while (ptr != end) {
511
+  while (ptr < end) {
512
     switch (BYTE_TYPE(enc, ptr)) {
513
     case BT_PERCNT:
514
       if (ptr + MINBPC(enc) == end)
515
@@ -233,7 +233,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
516
     *nextTokPtr = ptr;
517
     return XML_TOK_INVALID;
518
   }
519
-  while (ptr != end) {
520
+  while (ptr < end) {
521
     switch (BYTE_TYPE(enc, ptr)) {
522
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
523
     case BT_S: case BT_CR: case BT_LF:
524
@@ -242,7 +242,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
525
         return XML_TOK_INVALID;
526
       }
527
       ptr += MINBPC(enc);
528
-      while (ptr != end) {
529
+      while (ptr < end) {
530
         switch (BYTE_TYPE(enc, ptr)) {
531
         INVALID_CASES(ptr, nextTokPtr)
532
         case BT_QUEST:
533
@@ -305,7 +305,7 @@ static int PTRCALL
534
 PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
535
                         const char *end, const char **nextTokPtr)
536
 {
537
-  if (ptr == end)
538
+  if (ptr >= end)
539
     return XML_TOK_NONE;
540
   if (MINBPC(enc) > 1) {
541
     size_t n = end - ptr;
542
@@ -348,7 +348,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
543
     ptr += MINBPC(enc);
544
     break;
545
   }
546
-  while (ptr != end) {
547
+  while (ptr < end) {
548
     switch (BYTE_TYPE(enc, ptr)) {
549
 #define LEAD_CASE(n) \
550
     case BT_LEAD ## n: \
551
@@ -391,11 +391,11 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
552
     *nextTokPtr = ptr;
553
     return XML_TOK_INVALID;
554
   }
555
-  while (ptr != end) {
556
+  while (ptr < end) {
557
     switch (BYTE_TYPE(enc, ptr)) {
558
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
559
     case BT_S: case BT_CR: case BT_LF:
560
-      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
561
+      for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
562
         switch (BYTE_TYPE(enc, ptr)) {
563
         case BT_S: case BT_CR: case BT_LF:
564
           break;
565
@@ -432,7 +432,7 @@ static int PTRCALL
566
 PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
567
                        const char *end, const char **nextTokPtr)
568
 {
569
-  if (ptr != end) {
570
+  if (ptr < end) {
571
     switch (BYTE_TYPE(enc, ptr)) {
572
     case BT_DIGIT:
573
     case BT_HEX:
574
@@ -441,7 +441,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
575
       *nextTokPtr = ptr;
576
       return XML_TOK_INVALID;
577
     }
578
-    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
579
+    for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
580
       switch (BYTE_TYPE(enc, ptr)) {
581
       case BT_DIGIT:
582
       case BT_HEX:
583
@@ -464,7 +464,7 @@ static int PTRCALL
584
 PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
585
                     const char *end, const char **nextTokPtr)
586
 {
587
-  if (ptr != end) {
588
+  if (ptr < end) {
589
     if (CHAR_MATCHES(enc, ptr, ASCII_x))
590
       return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
591
     switch (BYTE_TYPE(enc, ptr)) {
592
@@ -474,7 +474,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
593
       *nextTokPtr = ptr;
594
       return XML_TOK_INVALID;
595
     }
596
-    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
597
+    for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
598
       switch (BYTE_TYPE(enc, ptr)) {
599
       case BT_DIGIT:
600
         break;
601
@@ -506,7 +506,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
602
     *nextTokPtr = ptr;
603
     return XML_TOK_INVALID;
604
   }
605
-  while (ptr != end) {
606
+  while (ptr < end) {
607
     switch (BYTE_TYPE(enc, ptr)) {
608
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
609
     case BT_SEMI:
610
@@ -529,7 +529,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
611
 #ifdef XML_NS
612
   int hadColon = 0;
613
 #endif
614
-  while (ptr != end) {
615
+  while (ptr < end) {
616
     switch (BYTE_TYPE(enc, ptr)) {
617
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
618
 #ifdef XML_NS
619
@@ -716,7 +716,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
620
   hadColon = 0;
621
 #endif
622
   /* we have a start-tag */
623
-  while (ptr != end) {
624
+  while (ptr < end) {
625
     switch (BYTE_TYPE(enc, ptr)) {
626
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
627
 #ifdef XML_NS
628
@@ -740,7 +740,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
629
     case BT_S: case BT_CR: case BT_LF:
630
       {
631
         ptr += MINBPC(enc);
632
-        while (ptr != end) {
633
+        while (ptr < end) {
634
           switch (BYTE_TYPE(enc, ptr)) {
635
           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
636
           case BT_GT:
637
@@ -785,7 +785,7 @@ static int PTRCALL
638
 PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
639
                    const char **nextTokPtr)
640
 {
641
-  if (ptr == end)
642
+  if (ptr >= end)
643
     return XML_TOK_NONE;
644
   if (MINBPC(enc) > 1) {
645
     size_t n = end - ptr;
646
@@ -832,7 +832,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
647
     ptr += MINBPC(enc);
648
     break;
649
   }
650
-  while (ptr != end) {
651
+  while (ptr < end) {
652
     switch (BYTE_TYPE(enc, ptr)) {
653
 #define LEAD_CASE(n) \
654
     case BT_LEAD ## n: \
655
@@ -895,7 +895,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
656
     *nextTokPtr = ptr;
657
     return XML_TOK_INVALID;
658
   }
659
-  while (ptr != end) {
660
+  while (ptr < end) {
661
     switch (BYTE_TYPE(enc, ptr)) {
662
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
663
     case BT_SEMI:
664
@@ -921,7 +921,7 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
665
     *nextTokPtr = ptr;
666
     return XML_TOK_INVALID;
667
   }
668
-  while (ptr != end) {
669
+  while (ptr < end) {
670
     switch (BYTE_TYPE(enc, ptr)) {
671
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
672
     case BT_CR: case BT_LF: case BT_S:
673
@@ -941,7 +941,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
674
                 const char *ptr, const char *end,
675
                 const char **nextTokPtr)
676
 {
677
-  while (ptr != end) {
678
+  while (ptr < end) {
679
     int t = BYTE_TYPE(enc, ptr);
680
     switch (t) {
681
     INVALID_CASES(ptr, nextTokPtr)
682
@@ -973,7 +973,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
683
                   const char **nextTokPtr)
684
 {
685
   int tok;
686
-  if (ptr == end)
687
+  if (ptr >= end)
688
     return XML_TOK_NONE;
689
   if (MINBPC(enc) > 1) {
690
     size_t n = end - ptr;
691
@@ -1141,7 +1141,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
692
     *nextTokPtr = ptr;
693
     return XML_TOK_INVALID;
694
   }
695
-  while (ptr != end) {
696
+  while (ptr < end) {
697
     switch (BYTE_TYPE(enc, ptr)) {
698
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
699
     case BT_GT: case BT_RPAR: case BT_COMMA:
700
@@ -1204,10 +1204,10 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
701
                           const char *end, const char **nextTokPtr)
702
 {
703
   const char *start;
704
-  if (ptr == end)
705
+  if (ptr >= end)
706
     return XML_TOK_NONE;
707
   start = ptr;
708
-  while (ptr != end) {
709
+  while (ptr < end) {
710
     switch (BYTE_TYPE(enc, ptr)) {
711
 #define LEAD_CASE(n) \
712
     case BT_LEAD ## n: ptr += n; break;
713
@@ -1262,10 +1262,10 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
714
                        const char *end, const char **nextTokPtr)
715
 {
716
   const char *start;
717
-  if (ptr == end)
718
+  if (ptr >= end)
719
     return XML_TOK_NONE;
720
   start = ptr;
721
-  while (ptr != end) {
722
+  while (ptr < end) {
723
     switch (BYTE_TYPE(enc, ptr)) {
724
 #define LEAD_CASE(n) \
725
     case BT_LEAD ## n: ptr += n; break;
726
@@ -1326,7 +1326,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
727
       end = ptr + n;
728
     }
729
   }
730
-  while (ptr != end) {
731
+  while (ptr < end) {
732
     switch (BYTE_TYPE(enc, ptr)) {
733
     INVALID_CASES(ptr, nextTokPtr)
734
     case BT_LT:
735
@@ -1373,7 +1373,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
736
 {
737
   ptr += MINBPC(enc);
738
   end -= MINBPC(enc);
739
-  for (; ptr != end; ptr += MINBPC(enc)) {
740
+  for (; ptr < end; ptr += MINBPC(enc)) {
741
     switch (BYTE_TYPE(enc, ptr)) {
742
     case BT_DIGIT:
743
     case BT_HEX:
744
@@ -1760,7 +1760,7 @@ PREFIX(updatePosition)(const ENCODING *enc,
745
     case BT_CR:
746
       pos->lineNumber++;
747
       ptr += MINBPC(enc);
748
-      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
749
+      if (ptr < end && BYTE_TYPE(enc, ptr) == BT_LF)
750
         ptr += MINBPC(enc);
751
       pos->columnNumber = (XML_Size)-1;
752
       break;
753
-- 
754
2.8.2
(-)textproc/expat2/files/patch-cve-2012-6702-plus-cve-2016-5300-v1 (-134 lines)
Lines 1-134 Link Here
1
From cb31522769d11a375078a073cba94e7176cb48a4 Mon Sep 17 00:00:00 2001
2
From: Sebastian Pipping <sebastian@pipping.org>
3
Date: Wed, 16 Mar 2016 15:30:12 +0100
4
Subject: [PATCH] Resolve call to srand, use more entropy (patch version 1.0)
5
6
Squashed backport against vanilla Expat 2.1.1, addressing:
7
* CVE-2012-6702 -- unanticipated internal calls to srand
8
* CVE-2016-5300 -- use of too little entropy
9
10
Since commit e3e81a6d9f0885ea02d3979151c358f314bf3d6d
11
(released with Expat 2.1.0) Expat called srand by itself
12
from inside generate_hash_secret_salt for an instance
13
of XML_Parser if XML_SetHashSalt was either (a) not called
14
for that instance or if (b) salt 0 was passed to XML_SetHashSalt
15
prior to parsing.  That call to srand passed (rather litle)
16
entropy extracted from the current time as a seed for srand.
17
18
That call to srand (1) broke repeatability for code calling
19
srand with a non-random seed prior to parsing with Expat,
20
and (2) resulted in a rather small set of hashing salts in
21
Expat in total.
22
23
For a short- to mid-term fix, the new approach avoids calling
24
srand altogether, extracts more entropy out of the clock and
25
other sources, too.
26
27
For a long term fix, we may want to read sizeof(long) bytes
28
from a source like getrandom(..) on Linux, and from similar
29
sources on other supported architectures.
30
31
https://bugzilla.redhat.com/show_bug.cgi?id=1197087
32
---
33
 expat/CMakeLists.txt |  3 +++
34
 expat/lib/xmlparse.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
35
 2 files changed, 44 insertions(+), 7 deletions(-)
36
37
diff --git a/expat/CMakeLists.txt b/expat/CMakeLists.txt
38
index 353627e..524d514 100755
39
--- CMakeLists.txt
40
+++ CMakeLists.txt
41
@@ -41,6 +41,9 @@ include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/lib)
42
 if(MSVC)
43
     add_definitions(-D_CRT_SECURE_NO_WARNINGS -wd4996)
44
 endif(MSVC)
45
+if(WIN32)
46
+    add_definitions(-DCOMPILED_FROM_DSP)
47
+endif(WIN32)
48
 
49
 set(expat_SRCS
50
     lib/xmlparse.c
51
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
52
index e308c79..c5f942f 100644
53
--- lib/xmlparse.c
54
+++ lib/xmlparse.c
55
@@ -6,7 +6,14 @@
56
 #include <string.h>                     /* memset(), memcpy() */
57
 #include <assert.h>
58
 #include <limits.h>                     /* UINT_MAX */
59
-#include <time.h>                       /* time() */
60
+
61
+#ifdef COMPILED_FROM_DSP
62
+#define getpid GetCurrentProcessId
63
+#else
64
+#include <sys/time.h>                   /* gettimeofday() */
65
+#include <sys/types.h>                  /* getpid() */
66
+#include <unistd.h>                     /* getpid() */
67
+#endif
68
 
69
 #define XML_BUILDING_EXPAT 1
70
 
71
@@ -432,7 +439,7 @@ static ELEMENT_TYPE *
72
 getElementType(XML_Parser parser, const ENCODING *enc,
73
                const char *ptr, const char *end);
74
 
75
-static unsigned long generate_hash_secret_salt(void);
76
+static unsigned long generate_hash_secret_salt(XML_Parser parser);
77
 static XML_Bool startParsing(XML_Parser parser);
78
 
79
 static XML_Parser
80
@@ -691,11 +698,38 @@ static const XML_Char implicitContext[] = {
81
 };
82
 
83
 static unsigned long
84
-generate_hash_secret_salt(void)
85
+gather_time_entropy(void)
86
 {
87
-  unsigned int seed = time(NULL) % UINT_MAX;
88
-  srand(seed);
89
-  return rand();
90
+#ifdef COMPILED_FROM_DSP
91
+  FILETIME ft;
92
+  GetSystemTimeAsFileTime(&ft); /* never fails */
93
+  return ft.dwHighDateTime ^ ft.dwLowDateTime;
94
+#else
95
+  struct timeval tv;
96
+  int gettimeofday_res;
97
+
98
+  gettimeofday_res = gettimeofday(&tv, NULL);
99
+  assert (gettimeofday_res == 0);
100
+
101
+  /* Microseconds time is <20 bits entropy */
102
+  return tv.tv_usec;
103
+#endif
104
+}
105
+
106
+static unsigned long
107
+generate_hash_secret_salt(XML_Parser parser)
108
+{
109
+  /* Process ID is 0 bits entropy if attacker has local access
110
+   * XML_Parser address is few bits of entropy if attacker has local access */
111
+  const unsigned long entropy =
112
+      gather_time_entropy() ^ getpid() ^ (unsigned long)parser;
113
+
114
+  /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
115
+  if (sizeof(unsigned long) == 4) {
116
+    return entropy * 2147483647;
117
+  } else {
118
+    return entropy * 2305843009213693951;
119
+  }
120
 }
121
 
122
 static XML_Bool  /* only valid for root parser */
123
@@ -703,7 +737,7 @@ startParsing(XML_Parser parser)
124
 {
125
     /* hash functions must be initialized before setContext() is called */
126
     if (hash_secret_salt == 0)
127
-      hash_secret_salt = generate_hash_secret_salt();
128
+      hash_secret_salt = generate_hash_secret_salt(parser);
129
     if (ns) {
130
       /* implicit context only set for root parser, since child
131
          parsers (i.e. external entity parsers) will inherit it
132
-- 
133
2.8.2
134
(-)textproc/expat2/pkg-plist (-1 / +1 lines)
Lines 5-11 include/expat_external.h Link Here
5
lib/libexpat.a
5
lib/libexpat.a
6
lib/libexpat.so
6
lib/libexpat.so
7
lib/libexpat.so.1
7
lib/libexpat.so.1
8
lib/libexpat.so.1.6.0
8
lib/libexpat.so.1.6.2
9
lib/libexpat.so.6
9
lib/libexpat.so.6
10
libdata/pkgconfig/expat.pc
10
libdata/pkgconfig/expat.pc
11
man/man1/xmlwf.1.gz
11
man/man1/xmlwf.1.gz

Return to bug 210531