SECURITY fixes for:

CVE-2014-6585
CVE-2014-6591
CVE-2014-7923
CVE-2014-7926
CVE-2014-9654
This commit is contained in:
ajacoutot 2015-04-19 09:02:06 +00:00
parent 5e6b60975a
commit 3a88f03f32
15 changed files with 1507 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.44 2015/01/03 07:53:00 ajacoutot Exp $
# $OpenBSD: Makefile,v 1.45 2015/04/19 09:02:06 ajacoutot Exp $
# XXX re-rolled tarball: drop at next release
DIST_SUBDIR= icu4c
@ -10,7 +10,7 @@ COMMENT= International Components for Unicode
VERSION= 54.1
DISTNAME= icu4c-${VERSION:S/./_/g}-src
PKGNAME= icu4c-${VERSION}
REVISION= 3
REVISION= 4
MAJ_V= ${VERSION:R}
SO_VERSION= 8.0

View File

@ -0,0 +1,15 @@
$OpenBSD: patch-source_common_unicode_utypes_h,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36801
--- source/common/unicode/utypes.h.orig Fri Oct 3 18:11:02 2014
+++ source/common/unicode/utypes.h Sun Apr 19 10:23:07 2015
@@ -647,6 +647,7 @@ typedef enum UErrorCode {
U_REGEX_STACK_OVERFLOW, /**< Regular expression backtrack stack overflow. */
U_REGEX_TIME_OUT, /**< Maximum allowed match time exceeded */
U_REGEX_STOPPED_BY_CALLER, /**< Matching operation aborted by user callback fn. */
+ U_REGEX_PATTERN_TOO_BIG, /**< Pattern exceeds limits on size or complexity. @draft ICU 55 */
U_REGEX_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for regexp errors */
/*

View File

@ -0,0 +1,26 @@
$OpenBSD: patch-source_common_utypes_c,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36801
--- source/common/utypes.c.orig Fri Oct 3 18:11:14 2014
+++ source/common/utypes.c Sun Apr 19 10:23:07 2015
@@ -1,7 +1,7 @@
/*
******************************************************************************
*
-* Copyright (C) 1997-2011, International Business Machines
+* Copyright (C) 1997-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@@ -165,7 +165,8 @@ _uRegexErrorName[U_REGEX_ERROR_LIMIT - U_REGEX_ERROR_S
"U_REGEX_INVALID_RANGE",
"U_REGEX_STACK_OVERFLOW",
"U_REGEX_TIME_OUT",
- "U_REGEX_STOPPED_BY_CALLER"
+ "U_REGEX_STOPPED_BY_CALLER",
+ "U_REGEX_PATTERN_TOO_BIG"
};
static const char * const

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
$OpenBSD: patch-source_i18n_regexcmp_h,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36727
https://ssl.icu-project.org/trac/changeset/36801
--- source/i18n/regexcmp.h.orig Sun Apr 19 10:23:01 2015
+++ source/i18n/regexcmp.h Sun Apr 19 10:23:07 2015
@@ -104,6 +104,13 @@ class U_I18N_API RegexCompile : public UMemory { (priv
void fixLiterals(UBool split=FALSE); // Generate code for pending literal characters.
void insertOp(int32_t where); // Open up a slot for a new op in the
// generated code at the specified location.
+ void appendOp(int32_t op); // Append a new op to the compiled pattern.
+ void appendOp(int32_t type, int32_t val); // Build & append a new op to the compiled pattern.
+ int32_t buildOp(int32_t type, int32_t val); // Construct a new pcode instruction.
+ int32_t allocateData(int32_t size); // Allocate space in the matcher data area.
+ // Return index of the newly allocated data.
+ int32_t allocateStackData(int32_t size); // Allocate space in the match back-track stack frame.
+ // Return offset index in the frame.
int32_t minMatchLength(int32_t start,
int32_t end);
int32_t maxMatchLength(int32_t start,
@@ -187,7 +194,9 @@ class U_I18N_API RegexCompile : public UMemory { (priv
int32_t fMatchOpenParen; // The position in the compiled pattern
// of the slot reserved for a state save
// at the start of the most recently processed
- // parenthesized block.
+ // parenthesized block. Updated when processing
+ // a close to the location for the corresponding open.
+
int32_t fMatchCloseParen; // The position in the pattern of the first
// location after the most recently processed
// parenthesized block.

View File

@ -0,0 +1,22 @@
$OpenBSD: patch-source_i18n_regeximp_h,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36801
--- source/i18n/regeximp.h.orig Fri Oct 3 18:10:44 2014
+++ source/i18n/regeximp.h Sun Apr 19 10:23:07 2015
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2002-2013 International Business Machines Corporation
+// Copyright (C) 2002-2014 International Business Machines Corporation
// and others. All rights reserved.
//
// file: regeximp.h
@@ -241,7 +241,6 @@ enum {
//
// Convenience macros for assembling and disassembling a compiled operation.
//
-#define URX_BUILD(type, val) (int32_t)((type << 24) | (val))
#define URX_TYPE(x) ((uint32_t)(x) >> 24)
#define URX_VAL(x) ((x) & 0xffffff)

View File

@ -0,0 +1,27 @@
$OpenBSD: patch-source_layout_ContextualSubstSubtables_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/ContextualSubstSubtables.cpp.orig Fri Oct 3 18:18:30 2014
+++ source/layout/ContextualSubstSubtables.cpp Sun Apr 19 10:25:11 2015
@@ -1,5 +1,5 @@
/*
- * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
*
*/
@@ -466,6 +466,12 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtabl
const ChainSubClassRuleTable *chainSubClassRuleTable =
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset);
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
+
+ // TODO: Ticket #11557 - enable this check, originally from ticket #11525.
+ // Depends on other, more extensive, changes.
+ // LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
+ if( LE_FAILURE(success) ) { return 0; }
+
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1];
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]);

View File

@ -0,0 +1,26 @@
$OpenBSD: patch-source_layout_CursiveAttachmentSubtables_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/CursiveAttachmentSubtables.cpp.orig Fri Oct 3 18:18:36 2014
+++ source/layout/CursiveAttachmentSubtables.cpp Sun Apr 19 10:25:11 2015
@@ -1,5 +1,5 @@
/*
- * (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998 - 2015 - All Rights Reserved
*
*/
@@ -20,7 +20,10 @@ le_uint32 CursiveAttachmentSubtable::process(const LER
le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success);
le_uint16 eeCount = SWAPW(entryExitCount);
- if (coverageIndex < 0 || coverageIndex >= eeCount) {
+ LEReferenceToArrayOf<EntryExitRecord>
+ entryExitRecordsArrayRef(base, success, entryExitRecords, coverageIndex);
+
+ if (coverageIndex < 0 || coverageIndex >= eeCount || LE_FAILURE(success)) {
glyphIterator->setCursiveGlyph();
return 0;
}

View File

@ -0,0 +1,26 @@
$OpenBSD: patch-source_layout_Features_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/Features.cpp.orig Fri Oct 3 18:18:34 2014
+++ source/layout/Features.cpp Sun Apr 19 10:25:11 2015
@@ -1,7 +1,7 @@
/*
* @(#)Features.cpp 1.4 00/03/15
*
- * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
*
*/
@@ -15,6 +15,9 @@ U_NAMESPACE_BEGIN
LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
{
+ LEReferenceToArrayOf<FeatureRecord>
+ featureRecordArrayRef(base, success, featureRecordArray, featureIndex);
+
if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
return LEReferenceTo<FeatureTable>();
}

View File

@ -0,0 +1,30 @@
$OpenBSD: patch-source_layout_LETableReference_h,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/LETableReference.h.orig Fri Oct 3 18:18:34 2014
+++ source/layout/LETableReference.h Sun Apr 19 10:25:11 2015
@@ -1,7 +1,7 @@
/*
* -*- c++ -*-
*
- * (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. and others 2015 - All Rights Reserved
*
* Range checking
*
@@ -313,7 +313,12 @@ LE_TRACE_TR("INFO: new RTAO")
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
const T& getObject(le_uint32 i, LEErrorCode &success) const {
- return *getAlias(i,success);
+ const T *ret = getAlias(i, success);
+ if (LE_FAILURE(success) || ret==NULL) {
+ return *(new T(0));
+ } else {
+ return *ret;
+ }
}
const T& operator()(le_uint32 i, LEErrorCode &success) const {

View File

@ -0,0 +1,24 @@
$OpenBSD: patch-source_layout_LigatureSubstSubtables_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/LigatureSubstSubtables.cpp.orig Fri Oct 3 18:18:32 2014
+++ source/layout/LigatureSubstSubtables.cpp Sun Apr 19 10:25:11 2015
@@ -1,5 +1,5 @@
/*
- * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
*
*/
@@ -27,6 +27,9 @@ le_uint32 LigatureSubstitutionSubtable::process(const
Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]);
const LigatureTable *ligTable = (const LigatureTable *) ((char *)ligSetTable + ligTableOffset);
le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
+ LEReferenceToArrayOf<TTGlyphID>
+ componentArrayRef(base, success, ligTable->componentArray, compCount);
+ if (LE_FAILURE(success)) { return 0; }
le_int32 startPosition = glyphIterator->getCurrStreamPosition();
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
le_uint16 comp;

View File

@ -0,0 +1,28 @@
$OpenBSD: patch-source_layout_MultipleSubstSubtables_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/37086
--- source/layout/MultipleSubstSubtables.cpp.orig Fri Oct 3 18:18:32 2014
+++ source/layout/MultipleSubstSubtables.cpp Sun Apr 19 10:25:11 2015
@@ -1,6 +1,6 @@
/*
*
- * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
*
*/
@@ -35,7 +35,12 @@ le_uint32 MultipleSubstitutionSubtable::process(const
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount);
+ LEReferenceToArrayOf<Offset>
+ sequenceTableOffsetArrayRef(base, success, sequenceTableOffsetArray, seqCount);
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
if (coverageIndex >= 0 && coverageIndex < seqCount) {
Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);

View File

@ -0,0 +1,67 @@
$OpenBSD: patch-source_test_intltest_regextst_cpp,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36801
--- source/test/intltest/regextst.cpp.orig Fri Oct 3 18:09:44 2014
+++ source/test/intltest/regextst.cpp Sun Apr 19 10:23:07 2015
@@ -144,6 +144,9 @@ void RegexTest::runIndexedTest( int32_t index, UBool e
case 24: name = "TestBug11049";
if (exec) TestBug11049();
break;
+ case 25: name = "TestBug11371";
+ if (exec) TestBug11371();
+ break;
default: name = "";
break; //needed to end loop
}
@@ -5367,6 +5370,49 @@ void RegexTest::TestCase11049(const char *pattern, con
}
+void RegexTest::TestBug11371() {
+ if (quick) {
+ logln("Skipping test. Runs in exhuastive mode only.");
+ return;
+ }
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString patternString;
+
+ for (int i=0; i<8000000; i++) {
+ patternString.append(UnicodeString("()"));
+ }
+ LocalPointer<RegexPattern> compiledPat(RegexPattern::compile(patternString, 0, status));
+ if (status != U_REGEX_PATTERN_TOO_BIG) {
+ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
+ __FILE__, __LINE__, u_errorName(status));
+ }
+
+ status = U_ZERO_ERROR;
+ patternString = "(";
+ for (int i=0; i<20000000; i++) {
+ patternString.append(UnicodeString("A++"));
+ }
+ patternString.append(UnicodeString("){0}B++"));
+ LocalPointer<RegexPattern> compiledPat2(RegexPattern::compile(patternString, 0, status));
+ if (status != U_REGEX_PATTERN_TOO_BIG) {
+ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
+ __FILE__, __LINE__, u_errorName(status));
+ }
+
+ // Pattern with too much string data, such that string indexes overflow operand data field size
+ // in compiled instruction.
+ status = U_ZERO_ERROR;
+ patternString = "";
+ while (patternString.length() < 0x00ffffff) {
+ patternString.append(UnicodeString("stuff and things dont you know, these are a few of my favorite strings\n"));
+ }
+ patternString.append(UnicodeString("X? trailing string"));
+ LocalPointer<RegexPattern> compiledPat3(RegexPattern::compile(patternString, 0, status));
+ if (status != U_REGEX_PATTERN_TOO_BIG) {
+ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
+ __FILE__, __LINE__, u_errorName(status));
+ }
+}
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */

View File

@ -0,0 +1,15 @@
$OpenBSD: patch-source_test_intltest_regextst_h,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36801
--- source/test/intltest/regextst.h.orig Fri Oct 3 18:09:40 2014
+++ source/test/intltest/regextst.h Sun Apr 19 10:23:07 2015
@@ -50,6 +50,7 @@ class RegexTest: public IntlTest { (public)
virtual void Bug10459();
virtual void TestCaseInsensitiveStarters();
virtual void TestBug11049();
+ virtual void TestBug11371();
// The following functions are internal to the regexp tests.
virtual void assertUText(const char *expected, UText *actual, const char *file, int line);

View File

@ -0,0 +1,35 @@
$OpenBSD: patch-source_test_testdata_regextst_txt,v 1.2 2015/04/19 09:02:06 ajacoutot Exp $
CVE-2014-6585, CVE-2014-6591:
https://ssl.icu-project.org/trac/changeset/36724
CVE-2014-7923 CVE-2014-7926 CVE-2014-9654
https://ssl.icu-project.org/trac/changeset/36727
--- source/test/testdata/regextst.txt.orig Sun Apr 19 10:13:58 2015
+++ source/test/testdata/regextst.txt Sun Apr 19 10:15:25 2015
@@ -1201,6 +1201,24 @@
"A|B|\U00012345" "hello <0>\U00012345</0>"
"A|B|\U00010000" "hello \ud800"
+# Bug 11369
+# Incorrect optimization of patterns with a zero length quantifier {0}
+
+"(.|b)(|b){0}\$(?#xxx){3}(?>\D*)" "AAAAABBBBBCCCCCDDDDEEEEE"
+"(|b)ab(c)" "<0><1></1>ab<2>c</2></0>"
+"(|b){0}a{3}(D*)" "<0>aaa<2></2></0>"
+"(|b){0,1}a{3}(D*)" "<0><1></1>aaa<2></2></0>"
+"((|b){0})a{3}(D*)" "<0><1></1>aaa<3></3></0>"
+
+# Bug 11370
+# Max match length computation of look-behind expression gives result that is too big to fit in the
+# in the 24 bit operand portion of the compiled code. Expressions should fail to compile
+# (Look-behind match length must be bounded. This case is treated as unbounded, an error.)
+
+"(?<!(0123456789a){10000000})x" E "no match"
+"(?<!\\ubeaf(\\ubeaf{11000}){11000})" E "no match"
+
+
# Random debugging, Temporary
#