pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: [pkgsrc-2017Q1] pkgsrc/textproc/icu



Module Name:    pkgsrc
Committed By:   bsiegert
Date:           Tue Apr 25 17:54:53 UTC 2017

Modified Files:
        pkgsrc/textproc/icu [pkgsrc-2017Q1]: Makefile distinfo
Added Files:
        pkgsrc/textproc/icu/patches [pkgsrc-2017Q1]: patch-common_rbbiscan.cpp
            patch-common_utext.cpp patch-i18n_regexcmp.cpp

Log Message:
Pullup ticket #5357 - requested by maya
textproc/icu: security fix (backported)

ICU had a vulnerability (CVE-2017-786[78])
Unfortunately they fixed it by doing a major release and have previously
broken other packages at runtime with such updates.

I've made backports of all the changesets that were mentioned in any of
the links, specifically the oss-fuzz report was somewhat broad and
mentioned 39673 which backported several 'crash' changesets:
http://bugs.icu-project.org/trac/changeset/39663
http://bugs.icu-project.org/trac/changeset/39669
http://bugs.icu-project.org/trac/changeset/39671

The advisory only references code changes relevant to 39671, we could
limit the backport to that.
https://www.debian.org/security/2017/dsa-3830

I've run make replace and smoke-tested with midori
they have a rather extensive testsuite. I've run it with 'make test' and
it didn't show any issues.

These are manual backports by myself as the patches did not apply
cleanly.


To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.107.4.1 pkgsrc/textproc/icu/Makefile
cvs rdiff -u -r1.63 -r1.63.4.1 pkgsrc/textproc/icu/distinfo
cvs rdiff -u -r0 -r1.1.2.1 \
    pkgsrc/textproc/icu/patches/patch-common_rbbiscan.cpp \
    pkgsrc/textproc/icu/patches/patch-common_utext.cpp \
    pkgsrc/textproc/icu/patches/patch-i18n_regexcmp.cpp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/textproc/icu/Makefile
diff -u pkgsrc/textproc/icu/Makefile:1.107 pkgsrc/textproc/icu/Makefile:1.107.4.1
--- pkgsrc/textproc/icu/Makefile:1.107  Mon Dec 12 17:46:39 2016
+++ pkgsrc/textproc/icu/Makefile        Tue Apr 25 17:54:53 2017
@@ -1,7 +1,8 @@
-# $NetBSD: Makefile,v 1.107 2016/12/12 17:46:39 adam Exp $
+# $NetBSD: Makefile,v 1.107.4.1 2017/04/25 17:54:53 bsiegert Exp $
 
 DISTNAME=      icu4c-58_2-src
 PKGNAME=       ${DISTNAME:S/4c//:S/-src//:S/_/./g}
+PKGREVISION=   1
 CATEGORIES=    textproc
 MASTER_SITES=  ${MASTER_SITE_SOURCEFORGE:=icu/}
 EXTRACT_SUFX=  .tgz

Index: pkgsrc/textproc/icu/distinfo
diff -u pkgsrc/textproc/icu/distinfo:1.63 pkgsrc/textproc/icu/distinfo:1.63.4.1
--- pkgsrc/textproc/icu/distinfo:1.63   Mon Dec 12 17:46:39 2016
+++ pkgsrc/textproc/icu/distinfo        Tue Apr 25 17:54:53 2017
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.63 2016/12/12 17:46:39 adam Exp $
+$NetBSD: distinfo,v 1.63.4.1 2017/04/25 17:54:53 bsiegert Exp $
 
 SHA1 (icu4c-58_2-src.tgz) = b67913c90a484c59fda011797c6f3959d84bdc7c
 RMD160 (icu4c-58_2-src.tgz) = df06e7b18a87e383d3762564f2e9a59fd75865f9
@@ -12,16 +12,19 @@ SHA1 (patch-ad) = c2a9469bf896b5f0702d57
 SHA1 (patch-af) = 07421b669780e5eea5dc455cc39ca9737c0f728a
 SHA1 (patch-common_putil.cpp) = 3058a542bcb2fdfa34b36acf389570990acd0da5
 SHA1 (patch-common_putilimp.h) = a68faa97c2bffeecaca1586e26f5bbe48e71b262
+SHA1 (patch-common_rbbiscan.cpp) = 99436a1b5ee00d0eb9450c80ab8dadf9e5a8c227
 SHA1 (patch-common_ulist.c) = 8dd2c8152f99d762aab7e9d48293de3ccfb711cf
 SHA1 (patch-common_umutex.h) = 096d3e15ef7b84533456af4570ed70747a4ef70c
 SHA1 (patch-common_unicode_platform.h) = 8b7b8bcf6f5185225a1ca516ac212a495f7b47e8
 SHA1 (patch-common_uposixdefs.h) = 02dedd10282961dec66673069796122b447dac33
+SHA1 (patch-common_utext.cpp) = b4a721ba9d6d8ce05785afa3a3c6e2cdfe74f102
 SHA1 (patch-config_icu-config-bottom) = 168b89ee9180d4ae545125866ee91eb004010501
 SHA1 (patch-config_mh-scoosr5) = 47703dcc184f58c0382da3225f849424ab74d472
 SHA1 (patch-config_mh-solaris-gcc) = 19f76c27bef22cc3b572e4b67a526d5f1aa077bc
 SHA1 (patch-configure) = 429c0b3eb3f7d0a8cf3d01a9bc359132eebe8cf4
 SHA1 (patch-configure.ac) = b0291cf02351cbad9b0c7340baea9eb81cabb158
 SHA1 (patch-i18n_digitlst.cpp) = 2db1a8e28e353ecf201f965d9719d451534865ad
+SHA1 (patch-i18n_regexcmp.cpp) = 24d935ca2cfadd9d4ce0854309897fe4342d34b3
 SHA1 (patch-i18n_ucol__res.cpp) = 5e13b689941cf07bee997544aca19a6d6ce64511
 SHA1 (patch-test_intltest_apicoll.cpp) = e55d7cd13d2bb9f6b08f2c9c59ae475b875f110f
 SHA1 (patch-test_intltest_apicoll.h) = e2a93be1da65e08abe3e6b28bd8aee33307a7c3e

Added files:

Index: pkgsrc/textproc/icu/patches/patch-common_rbbiscan.cpp
diff -u /dev/null pkgsrc/textproc/icu/patches/patch-common_rbbiscan.cpp:1.1.2.1
--- /dev/null   Tue Apr 25 17:54:53 2017
+++ pkgsrc/textproc/icu/patches/patch-common_rbbiscan.cpp       Tue Apr 25 17:54:53 2017
@@ -0,0 +1,24 @@
+$NetBSD: patch-common_rbbiscan.cpp,v 1.1.2.1 2017/04/25 17:54:53 bsiegert Exp $
+
+Backport upstream changeset 39669
+ticket:12932 RBBI rule parsing, fix incorrect handling of node stack overflow.
+
+--- common/rbbiscan.cpp.orig   2016-07-22 21:50:34.000000000 +0000
++++ common/rbbiscan.cpp
+@@ -1179,13 +1179,12 @@ RBBINode  *RBBIRuleScanner::pushNewNode(
+     if (U_FAILURE(*fRB->fStatus)) {
+         return NULL;
+     }
+-    fNodeStackPtr++;
+-    if (fNodeStackPtr >= kStackSize) {
+-        error(U_BRK_INTERNAL_ERROR);
++    if (fNodeStackPtr >= kStackSize - 1) {
++        error(U_BRK_RULE_SYNTAX);
+         RBBIDebugPuts("RBBIRuleScanner::pushNewNode - stack overflow.");
+-        *fRB->fStatus = U_BRK_INTERNAL_ERROR;
+         return NULL;
+     }
++    fNodeStackPtr++;
+     fNodeStack[fNodeStackPtr] = new RBBINode(t);
+     if (fNodeStack[fNodeStackPtr] == NULL) {
+         *fRB->fStatus = U_MEMORY_ALLOCATION_ERROR;
Index: pkgsrc/textproc/icu/patches/patch-common_utext.cpp
diff -u /dev/null pkgsrc/textproc/icu/patches/patch-common_utext.cpp:1.1.2.1
--- /dev/null   Tue Apr 25 17:54:53 2017
+++ pkgsrc/textproc/icu/patches/patch-common_utext.cpp  Tue Apr 25 17:54:53 2017
@@ -0,0 +1,71 @@
+$NetBSD: patch-common_utext.cpp,v 1.1.2.1 2017/04/25 17:54:53 bsiegert Exp $
+
+Apply upstream changeset 39671
+ticket:12888 UText, problems with handling of bad UTF-8.
+
+--- common/utext.cpp.orig      2016-06-15 18:58:17.000000000 +0000
++++ common/utext.cpp
+@@ -889,7 +889,7 @@ struct UTF8Buf {
+                                                      //  Requires two extra slots,
+                                                      //    one for a supplementary starting in the last normal position,
+                                                      //    and one for an entry for the buffer limit position.
+-    uint8_t   mapToUChars[UTF8_TEXT_CHUNK_SIZE*3+6]; // Map native offset from bufNativeStart to
++    uint8_t   mapToUChars[UTF8_TEXT_CHUNK_SIZE*6+6]; // Map native offset from bufNativeStart to
+                                                      //   correspoding offset in filled part of buf.
+     int32_t   align;
+ };
+@@ -1032,6 +1032,7 @@ utf8TextAccess(UText *ut, int64_t index,
+             // Requested index is in this buffer.
+             u8b = (UTF8Buf *)ut->p;   // the current buffer
+             mapIndex = ix - u8b->toUCharsMapStart;
++            U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+             ut->chunkOffset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+             return TRUE;
+ 
+@@ -1298,6 +1299,10 @@ fillReverse:
+         // Can only do this if the incoming index is somewhere in the interior of the string.
+         //   If index is at the end, there is no character there to look at.
+         if (ix != ut->b) {
++            // Note: this function will only move the index back if it is on a trail byte
++            //       and there is a preceding lead byte and the sequence from the lead 
++            //       through this trail could be part of a valid UTF-8 sequence
++            //       Otherwise the index remains unchanged.
+             U8_SET_CP_START(s8, 0, ix);
+         }
+ 
+@@ -1311,7 +1316,10 @@ fillReverse:
+         UChar   *buf = u8b->buf;
+         uint8_t *mapToNative = u8b->mapToNative;
+         uint8_t *mapToUChars = u8b->mapToUChars;
+-        int32_t  toUCharsMapStart = ix - (UTF8_TEXT_CHUNK_SIZE*3 + 1);
++        int32_t  toUCharsMapStart = ix - sizeof(UTF8Buf::mapToUChars) + 1;
++        // Note that toUCharsMapStart can be negative. Happens when the remaining
++        // text from current position to the beginning is less than the buffer size.
++        // + 1 because mapToUChars must have a slot at the end for the bufNativeLimit entry
+         int32_t  destIx = UTF8_TEXT_CHUNK_SIZE+2;   // Start in the overflow region
+                                                     //   at end of buffer to leave room
+                                                     //   for a surrogate pair at the
+@@ -1338,6 +1346,7 @@ fillReverse:
+             if (c<0x80) {
+                 // Special case ASCII range for speed.
+                 buf[destIx] = (UChar)c;
++                U_ASSERT(toUCharsMapStart <= srcIx);
+                 mapToUChars[srcIx - toUCharsMapStart] = (uint8_t)destIx;
+                 mapToNative[destIx] = (uint8_t)(srcIx - toUCharsMapStart);
+             } else {
+@@ -1367,6 +1376,7 @@ fillReverse:
+                 do {
+                     mapToUChars[sIx-- - toUCharsMapStart] = (uint8_t)destIx;
+                 } while (sIx >= srcIx);
++                U_ASSERT(toUCharsMapStart <= (srcIx+1));
+ 
+                 // Set native indexing limit to be the current position.
+                 //   We are processing a non-ascii, non-native-indexing char now;
+@@ -1541,6 +1551,7 @@ utf8TextMapIndexToUTF16(const UText *ut,
+     U_ASSERT(index>=ut->chunkNativeStart+ut->nativeIndexingLimit);
+     U_ASSERT(index<=ut->chunkNativeLimit);
+     int32_t mapIndex = index - u8b->toUCharsMapStart;
++    U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+     int32_t offset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+     U_ASSERT(offset>=0 && offset<=ut->chunkLength);
+     return offset;
Index: pkgsrc/textproc/icu/patches/patch-i18n_regexcmp.cpp
diff -u /dev/null pkgsrc/textproc/icu/patches/patch-i18n_regexcmp.cpp:1.1.2.1
--- /dev/null   Tue Apr 25 17:54:53 2017
+++ pkgsrc/textproc/icu/patches/patch-i18n_regexcmp.cpp Tue Apr 25 17:54:53 2017
@@ -0,0 +1,173 @@
+$NetBSD: patch-i18n_regexcmp.cpp,v 1.1.2.1 2017/04/25 17:54:53 bsiegert Exp $
+
+Backport upstream changeset 39663
+ticket:12930 Fix assertion failure in regex compile.
+
+Use safeIncrement for progressing currentLen in matchStartType
+
+--- i18n/regexcmp.cpp.orig     2016-06-15 18:58:17.000000000 +0000
++++ i18n/regexcmp.cpp
+@@ -2637,6 +2637,18 @@ void  RegexCompile::findCaseInsensitiveS
+ }
+ 
+ 
++// Increment with overflow check.
++// val and delta will both be positive.
++
++static int32_t safeIncrement(int32_t val, int32_t delta) {
++    if (INT32_MAX - val > delta) {
++        return val + delta;
++    } else {
++        return INT32_MAX;
++    }
++}
++
++
+ 
+ 
+ //------------------------------------------------------------------------------
+@@ -2737,7 +2749,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->add(URX_VAL(op));
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2750,7 +2762,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->addAll(*s);
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2787,7 +2799,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->addAll(*s);
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2802,7 +2814,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->addAll(sc);
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2819,7 +2831,7 @@ void   RegexCompile::matchStartType() {
+                  fRXPat->fInitialChars->addAll(s);
+                  numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2836,7 +2848,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->addAll(s);
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2855,7 +2867,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->addAll(s);
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2879,7 +2891,7 @@ void   RegexCompile::matchStartType() {
+                 }
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2895,7 +2907,7 @@ void   RegexCompile::matchStartType() {
+                 fRXPat->fInitialChars->complement();
+                 numInitialStrings += 2;
+             }
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             atStart = FALSE;
+             break;
+ 
+@@ -2975,7 +2987,7 @@ void   RegexCompile::matchStartType() {
+                     fRXPat->fInitialStringLen = stringLen;
+                 }
+ 
+-                currentLen += stringLen;
++                currentLen = safeIncrement(currentLen, stringLen);
+                 atStart = FALSE;
+             }
+             break;
+@@ -3000,7 +3012,7 @@ void   RegexCompile::matchStartType() {
+                     fRXPat->fInitialChars->addAll(s);
+                     numInitialStrings += 2;  // Matching on an initial string not possible.
+                 }
+-                currentLen += stringLen;
++                currentLen = safeIncrement(currentLen, stringLen);
+                 atStart = FALSE;
+             }
+             break;
+@@ -3258,7 +3270,7 @@ int32_t   RegexCompile::minMatchLength(i
+         case URX_DOTANY_ALL:    // . matches one or two.
+         case URX_DOTANY:
+         case URX_DOTANY_UNIX:
+-            currentLen++;
++            currentLen = safeIncrement(currentLen, 1);
+             break;
+ 
+ 
+@@ -3310,7 +3322,7 @@ int32_t   RegexCompile::minMatchLength(i
+             {
+                 loc++;
+                 int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
+-                currentLen += URX_VAL(stringLenOp);
++                currentLen = safeIncrement(currentLen, URX_VAL(stringLenOp));
+             }
+             break;
+ 
+@@ -3323,7 +3335,7 @@ int32_t   RegexCompile::minMatchLength(i
+                 //       Assume a min length of one for now.  A min length of zero causes
+                 //        optimization failures for a pattern like "string"+
+                 // currentLen += URX_VAL(stringLenOp);
+-                currentLen += 1;
++                currentLen = safeIncrement(currentLen, 1);
+             }
+             break;
+ 
+@@ -3433,18 +3445,6 @@ int32_t   RegexCompile::minMatchLength(i
+     return currentLen;
+ }
+ 
+-// Increment with overflow check.
+-// val and delta will both be positive.
+-
+-static int32_t safeIncrement(int32_t val, int32_t delta) {
+-    if (INT32_MAX - val > delta) {
+-        return val + delta;
+-    } else {
+-        return INT32_MAX;
+-    }
+-}
+-
+-
+ //------------------------------------------------------------------------------
+ //
+ //   maxMatchLength    Calculate the length of the longest string that could



Home | Main Index | Thread Index | Old Index