pkgsrc-Changes-HG archive

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

[pkgsrc/pkgsrc-2017Q1]: pkgsrc/textproc/icu Pullup ticket #5357 - requested b...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/843fcc7be470
branches:  pkgsrc-2017Q1
changeset: 360294:843fcc7be470
user:      bsiegert <bsiegert%pkgsrc.org@localhost>
date:      Tue Apr 25 17:54:53 2017 +0000

description:
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.

diffstat:

 textproc/icu/Makefile                          |    3 +-
 textproc/icu/distinfo                          |    5 +-
 textproc/icu/patches/patch-common_rbbiscan.cpp |   24 +++
 textproc/icu/patches/patch-common_utext.cpp    |   71 ++++++++++
 textproc/icu/patches/patch-i18n_regexcmp.cpp   |  173 +++++++++++++++++++++++++
 5 files changed, 274 insertions(+), 2 deletions(-)

diffs (truncated from 322 to 300 lines):

diff -r 1c42b228ee61 -r 843fcc7be470 textproc/icu/Makefile
--- a/textproc/icu/Makefile     Tue Apr 25 17:39:11 2017 +0000
+++ b/textproc/icu/Makefile     Tue Apr 25 17:54:53 2017 +0000
@@ -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
diff -r 1c42b228ee61 -r 843fcc7be470 textproc/icu/distinfo
--- a/textproc/icu/distinfo     Tue Apr 25 17:39:11 2017 +0000
+++ b/textproc/icu/distinfo     Tue Apr 25 17:54:53 2017 +0000
@@ -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-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
diff -r 1c42b228ee61 -r 843fcc7be470 textproc/icu/patches/patch-common_rbbiscan.cpp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/textproc/icu/patches/patch-common_rbbiscan.cpp    Tue Apr 25 17:54:53 2017 +0000
@@ -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;
diff -r 1c42b228ee61 -r 843fcc7be470 textproc/icu/patches/patch-common_utext.cpp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/textproc/icu/patches/patch-common_utext.cpp       Tue Apr 25 17:54:53 2017 +0000
@@ -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;
diff -r 1c42b228ee61 -r 843fcc7be470 textproc/icu/patches/patch-i18n_regexcmp.cpp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/textproc/icu/patches/patch-i18n_regexcmp.cpp      Tue Apr 25 17:54:53 2017 +0000
@@ -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);



Home | Main Index | Thread Index | Old Index