Gentoo Archives: gentoo-commits

From: "Christian Hoffmann (hoffie)" <hoffie@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-libs/icu/files: icu-3.6-regexp-CVE-2007-4770+4771.diff
Date: Sat, 02 Feb 2008 22:22:42
Message-Id: E1JLQky-0002lb-3S@stork.gentoo.org
1 hoffie 08/02/02 22:22:40
2
3 Added: icu-3.6-regexp-CVE-2007-4770+4771.diff
4 Log:
5 adding patch (by redhat) for CVE-2007-{4770,4771} per bug #208001 for 3.6 series as well
6 (Portage version: 2.1.4.1)
7
8 Revision Changes Path
9 1.1 dev-libs/icu/files/icu-3.6-regexp-CVE-2007-4770+4771.diff
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-libs/icu/files/icu-3.6-regexp-CVE-2007-4770+4771.diff?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-libs/icu/files/icu-3.6-regexp-CVE-2007-4770+4771.diff?rev=1.1&content-type=text/plain
13
14 Index: icu-3.6-regexp-CVE-2007-4770+4771.diff
15 ===================================================================
16 # borrowed from redhat -- https://bugzilla.redhat.com/show_bug.cgi?id=429023
17
18 diff -ru icu.orig/source/common/uvectr32.cpp icu/source/common/uvectr32.cpp
19 --- icu.orig/source/common/uvectr32.cpp 2003-08-27 02:01:30.000000000 +0100
20 +++ icu/source/common/uvectr32.cpp 2008-01-22 08:37:06.000000000 +0000
21 @@ -1,6 +1,6 @@
22 /*
23 ******************************************************************************
24 -* Copyright (C) 1999-2003, International Business Machines Corporation and *
25 +* Copyright (C) 1999-2008, International Business Machines Corporation and *
26 * others. All Rights Reserved. *
27 ******************************************************************************
28 * Date Name Description
29 @@ -26,6 +26,7 @@
30 UVector32::UVector32(UErrorCode &status) :
31 count(0),
32 capacity(0),
33 + maxCapacity(0),
34 elements(NULL)
35 {
36 _init(DEFUALT_CAPACITY, status);
37 @@ -34,6 +35,7 @@
38 UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
39 count(0),
40 capacity(0),
41 + maxCapacity(0),
42 elements(0)
43 {
44 _init(initialCapacity, status);
45 @@ -46,6 +48,9 @@
46 if (initialCapacity < 1) {
47 initialCapacity = DEFUALT_CAPACITY;
48 }
49 + if (maxCapacity>0 && maxCapacity<initialCapacity) {
50 + initialCapacity = maxCapacity;
51 + }
52 elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity);
53 if (elements == 0) {
54 status = U_MEMORY_ALLOCATION_ERROR;
55 @@ -189,21 +194,35 @@
56 UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
57 if (capacity >= minimumCapacity) {
58 return TRUE;
59 - } else {
60 - int32_t newCap = capacity * 2;
61 - if (newCap < minimumCapacity) {
62 - newCap = minimumCapacity;
63 - }
64 - int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap);
65 - if (newElems == 0) {
66 - status = U_MEMORY_ALLOCATION_ERROR;
67 - return FALSE;
68 - }
69 - uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
70 - uprv_free(elements);
71 - elements = newElems;
72 - capacity = newCap;
73 - return TRUE;
74 + }
75 + if (maxCapacity>0 && minimumCapacity>maxCapacity) {
76 + status = U_BUFFER_OVERFLOW_ERROR;
77 + return FALSE;
78 + }
79 + int32_t newCap = capacity * 2;
80 + if (newCap < minimumCapacity) {
81 + newCap = minimumCapacity;
82 + }
83 + if (maxCapacity > 0 && newCap > maxCapacity) {
84 + newCap = maxCapacity;
85 + }
86 + int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap);
87 + if (newElems == 0) {
88 + status = U_MEMORY_ALLOCATION_ERROR;
89 + return FALSE;
90 + }
91 + uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
92 + uprv_free(elements);
93 + elements = newElems;
94 + capacity = newCap;
95 + return TRUE;
96 +}
97 +
98 +void UVector32::setMaxCapacity(int32_t limit) {
99 + U_ASSERT(limit >= 0);
100 + maxCapacity = limit;
101 + if (maxCapacity < 0) {
102 + maxCapacity = 0;
103 }
104 }
105
106 diff -ru icu.orig/source/common/uvectr32.h icu/source/common/uvectr32.h
107 --- icu.orig/source/common/uvectr32.h 2006-01-18 03:52:04.000000000 +0000
108 +++ icu/source/common/uvectr32.h 2008-01-22 08:37:07.000000000 +0000
109 @@ -1,6 +1,6 @@
110 /*
111 **********************************************************************
112 -* Copyright (C) 1999-2006, International Business Machines
113 +* Copyright (C) 1999-2008, International Business Machines
114 * Corporation and others. All Rights Reserved.
115 **********************************************************************
116 */
117 @@ -61,6 +61,8 @@
118 int32_t count;
119
120 int32_t capacity;
121 +
122 + int32_t maxCapacity; // Limit beyond which capacity is not permitted to grow.
123
124 int32_t* elements;
125
126 @@ -162,6 +164,14 @@
127 int32_t *getBuffer() const;
128
129 /**
130 + * Set the maximum allowed buffer capacity for this vector/stack.
131 + * Default with no limit set is unlimited, go until malloc() fails.
132 + * A Limit of zero means unlimited capacity.
133 + * Units are vector elements (32 bits each), not bytes.
134 + */
135 + void setMaxCapacity(int32_t limit);
136 +
137 + /**
138 * ICU "poor man's RTTI", returns a UClassID for this class.
139 */
140 static UClassID U_EXPORT2 getStaticClassID();
141 @@ -221,7 +231,9 @@
142 }
143
144 inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) {
145 - ensureCapacity(count+size, status);
146 + if (ensureCapacity(count+size, status) == FALSE) {
147 + return NULL;
148 + }
149 int32_t *rp = elements+count;
150 count += size;
151 return rp;
152 diff -ru icu.orig/source/i18n/regexcmp.cpp icu/source/i18n/regexcmp.cpp
153 --- icu.orig/source/i18n/regexcmp.cpp 2006-02-02 04:37:14.000000000 +0000
154 +++ icu/source/i18n/regexcmp.cpp 2008-01-22 08:37:06.000000000 +0000
155 @@ -1187,14 +1187,17 @@
156 // Because capture groups can be forward-referenced by back-references,
157 // we fill the operand with the capture group number. At the end
158 // of compilation, it will be changed to the variable's location.
159 - U_ASSERT(groupNum > 0);
160 - int32_t op;
161 - if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
162 - op = URX_BUILD(URX_BACKREF_I, groupNum);
163 + if (groupNum < 1) {
164 + error(U_REGEX_INVALID_BACK_REF);
165 } else {
166 - op = URX_BUILD(URX_BACKREF, groupNum);
167 + int32_t op;
168 + if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
169 + op = URX_BUILD(URX_BACKREF_I, groupNum);
170 + } else {
171 + op = URX_BUILD(URX_BACKREF, groupNum);
172 + }
173 + fRXPat->fCompiledPat->addElement(op, *fStatus);
174 }
175 - fRXPat->fCompiledPat->addElement(op, *fStatus);
176 }
177 break;
178
179 diff -ru icu.orig/source/i18n/rematch.cpp icu/source/i18n/rematch.cpp
180 --- icu.orig/source/i18n/rematch.cpp 2005-08-25 19:02:20.000000000 +0100
181 +++ icu/source/i18n/rematch.cpp 2008-01-22 08:37:44.000000000 +0000
182 @@ -30,6 +30,15 @@
183
184 U_NAMESPACE_BEGIN
185
186 +// Limit the size of the back track stack, to avoid system failures caused
187 +// by heap exhaustion. Units are in 32 bit words, not bytes.
188 +// This value puts ICU's limits higher than most other regexp implementations,
189 +// which use recursion rather than the heap, and take more storage per
190 +// backtrack point.
191 +// This constant is _temporary_. Proper API to control the value will added.
192 +//
193 +static const int32_t BACKTRACK_STACK_CAPACITY = 8000000;
194 +
195 //-----------------------------------------------------------------------------
196 //
197 // Constructor and Destructor
198 @@ -53,6 +62,8 @@
199 }
200 if (fStack == NULL || fData == NULL) {
201 fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
202 + } else {
203 + fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
204 }
205
206 reset(*RegexStaticSets::gStaticSets->fEmptyString);
207 @@ -78,6 +89,8 @@
208 }
209 if (fStack == NULL || fData == NULL) {
210 status = U_MEMORY_ALLOCATION_ERROR;
211 + } else {
212 + fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
213 }
214 reset(input);
215 }
216 @@ -102,6 +115,8 @@
217 }
218 if (fStack == NULL || fData == NULL) {
219 status = U_MEMORY_ALLOCATION_ERROR;
220 + } else {
221 + fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
222 }
223 reset(*RegexStaticSets::gStaticSets->fEmptyString);
224 }
225 @@ -1015,6 +1030,14 @@
226 inline REStackFrame *RegexMatcher::StateSave(REStackFrame *fp, int32_t savePatIdx, int32_t frameSize, UErrorCode &status) {
227 // push storage for a new frame.
228 int32_t *newFP = fStack->reserveBlock(frameSize, status);
229 + if (newFP == NULL) {
230 + // Heap allocation error on attempted stack expansion.
231 + // We need to return a writable stack frame, so just return the
232 + // previous frame. The match operation will stop quickly
233 + // becuase of the error status, after which the frame will never
234 + // be looked at again.
235 + return fp;
236 + }
237 fp = (REStackFrame *)(newFP - frameSize); // in case of realloc of stack.
238
239 // New stack frame = copy of old top frame.
240 @@ -1030,8 +1053,8 @@
241 fp->fPatIdx = savePatIdx;
242 return (REStackFrame *)newFP;
243 }
244 -
245 -
246 +
247 +
248 //--------------------------------------------------------------------------------
249 //
250 // MatchAt This is the actual matching engine.
251 @@ -2262,6 +2285,7 @@
252 }
253
254 if (U_FAILURE(status)) {
255 + isMatch = FALSE;
256 break;
257 }
258 }
259 diff -ru icu.orig/source/test/intltest/regextst.cpp icu/source/test/intltest/regextst.cpp
260 --- icu.orig/source/test/intltest/regextst.cpp 2005-07-05 19:39:00.000000000 +0100
261 +++ icu/source/test/intltest/regextst.cpp 2008-01-22 08:38:21.000000000 +0000
262 @@ -66,6 +66,10 @@
263 case 6: name = "PerlTests";
264 if (exec) PerlTests();
265 break;
266 + case 7: name = "Bug 6149";
267 + if (exec) Bug6149();
268 + break;
269 +
270
271
272 default: name = "";
273 @@ -1637,6 +1641,13 @@
274 // UnicodeSet containing a string
275 REGEX_ERR("abc[{def}]xyz", 1, 10, U_REGEX_SET_CONTAINS_STRING);
276
277 +
278 + // Invalid Back Reference \0
279 + // For ICU 3.8 and earlier
280 + // For ICU versions newer than 3.8, \0 introduces an octal escape.
281 + //
282 + REGEX_ERR("(ab)\\0", 1, 6, U_REGEX_INVALID_BACK_REF);
283 +
284 }
285
286
287 @@ -2119,6 +2130,26 @@
288 }
289
290
291 +//--------------------------------------------------------------
292 +//
293 +// Bug6149 Verify limits to heap expansion for backtrack stack.
294 +// Use this pattern,
295 +// "(a?){1,}"
296 +// The zero-length match will repeat forever.
297 +// (That this goes into a loop is another bug)
298 +//
299 +//---------------------------------------------------------------
300 +void RegexTest::Bug6149() {
301 + UnicodeString pattern("(a?){1,}");
302 + UnicodeString s("xyz");
303 + uint32_t flags = 0;
304 + UErrorCode status = U_ZERO_ERROR;
305 +
306 + RegexMatcher matcher(pattern, s, flags, status);
307 + UBool result = false;
308 + REGEX_ASSERT_FAIL(result=matcher.matches(status), U_BUFFER_OVERFLOW_ERROR);
309 + REGEX_ASSERT(result == FALSE);
310 + }
311
312 #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
313
314 diff -ru icu.orig/source/test/intltest/regextst.h icu/source/test/intltest/regextst.h
315 --- icu.orig/source/test/intltest/regextst.h 2003-12-03 06:58:28.000000000 +0000
316 +++ icu/source/test/intltest/regextst.h 2008-01-22 08:37:06.000000000 +0000
317 @@ -30,6 +30,7 @@
318 virtual void Extended();
319 virtual void Errors();
320 virtual void PerlTests();
321 + virtual void Bug6149();
322
323 // The following functions are internal to the regexp tests.
324 virtual UBool doRegexLMTest(const char *pat, const char *text, UBool looking, UBool match, int line);
325
326
327
328 --
329 gentoo-commits@l.g.o mailing list