aboutsummaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/packages/icu4c.scm3
-rw-r--r--gnu/packages/patches/icu4c-CVE-2015-4760.patch189
2 files changed, 191 insertions, 1 deletions
diff --git a/gnu/packages/icu4c.scm b/gnu/packages/icu4c.scm
index a753a22b20..46e5d12049 100644
--- a/gnu/packages/icu4c.scm
+++ b/gnu/packages/icu4c.scm
@@ -37,7 +37,8 @@
(string-map (lambda (x) (if (char=? x #\.) #\_ x)) version)
"-src.tgz"))
(sha256
- (base32 "0ys5f5spizg45qlaa31j2lhgry0jka2gfha527n4ndfxxz5j4sz1"))))
+ (base32 "0ys5f5spizg45qlaa31j2lhgry0jka2gfha527n4ndfxxz5j4sz1"))
+ (patches (list (search-patch "icu4c-CVE-2015-4760.patch")))))
(build-system gnu-build-system)
(inputs
`(("perl" ,perl)))
diff --git a/gnu/packages/patches/icu4c-CVE-2015-4760.patch b/gnu/packages/patches/icu4c-CVE-2015-4760.patch
new file mode 100644
index 0000000000..77da283b7b
--- /dev/null
+++ b/gnu/packages/patches/icu4c-CVE-2015-4760.patch
@@ -0,0 +1,189 @@
+Copied from Debian.
+
+Description: missing boundary checks in layout engine
+ It was discovered that ICU Layout Engine was missing multiple boundary checks.
+ These could lead to buffer overflows and memory corruption. A specially
+ crafted file could cause an application using ICU to parse untrusted font
+ files to crash and, possibly, execute arbitrary code.
+Author: Laszlo Boszormenyi (GCS) <gcs@debian.org>
+Origin: upstream, http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/3f9845510b47
+Reviewed-By: srl, bae, mschoene
+Forwarded: not-needed
+Last-Update: 2015-07-30
+
+---
+
+--- icu-52.1.orig/source/layout/ContextualGlyphInsertionProc2.cpp
++++ icu-52.1/source/layout/ContextualGlyphInsertionProc2.cpp
+@@ -82,6 +82,10 @@ le_uint16 ContextualGlyphInsertionProces
+
+ le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
+ if (markIndex > 0) {
++ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
+ le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
+ le_bool isBefore = (flags & cgiMarkInsertBefore);
+@@ -90,6 +94,10 @@ le_uint16 ContextualGlyphInsertionProces
+
+ le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
+ if (currIndex > 0) {
++ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ le_int16 count = flags & cgiCurrentInsertCountMask;
+ le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
+ le_bool isBefore = (flags & cgiCurrentInsertBefore);
+--- icu-52.1.orig/source/layout/ContextualGlyphSubstProc.cpp
++++ icu-52.1/source/layout/ContextualGlyphSubstProc.cpp
+@@ -51,6 +51,10 @@ ByteOffset ContextualGlyphSubstitutionPr
+ WordOffset currOffset = SWAPW(entry->currOffset);
+
+ if (markOffset != 0 && LE_SUCCESS(success)) {
++ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ LEGlyphID mGlyph = glyphStorage[markGlyph];
+ TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
+
+@@ -58,6 +62,10 @@ ByteOffset ContextualGlyphSubstitutionPr
+ }
+
+ if (currOffset != 0) {
++ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ LEGlyphID thisGlyph = glyphStorage[currGlyph];
+ TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
+
+--- icu-52.1.orig/source/layout/ContextualGlyphSubstProc2.cpp
++++ icu-52.1/source/layout/ContextualGlyphSubstProc2.cpp
+@@ -45,17 +45,25 @@ le_uint16 ContextualGlyphSubstitutionPro
+ if(LE_FAILURE(success)) return 0;
+ le_uint16 newState = SWAPW(entry->newStateIndex);
+ le_uint16 flags = SWAPW(entry->flags);
+- le_int16 markIndex = SWAPW(entry->markIndex);
+- le_int16 currIndex = SWAPW(entry->currIndex);
++ le_uint16 markIndex = SWAPW(entry->markIndex);
++ le_uint16 currIndex = SWAPW(entry->currIndex);
+
+- if (markIndex != -1) {
++ if (markIndex != 0x0FFFF) {
++ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
+ LEGlyphID mGlyph = glyphStorage[markGlyph];
+ TTGlyphID newGlyph = lookup(offset, mGlyph, success);
+ glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
+ }
+
+- if (currIndex != -1) {
++ if (currIndex != 0x0FFFF) {
++ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
+ le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
+ LEGlyphID thisGlyph = glyphStorage[currGlyph];
+ TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
+--- icu-52.1.orig/source/layout/IndicRearrangementProcessor.cpp
++++ icu-52.1/source/layout/IndicRearrangementProcessor.cpp
+@@ -45,6 +45,11 @@ ByteOffset IndicRearrangementProcessor::
+ ByteOffset newState = SWAPW(entry->newStateOffset);
+ IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
+
++ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
++
+ if (flags & irfMarkFirst) {
+ firstGlyph = currGlyph;
+ }
+--- icu-52.1.orig/source/layout/IndicRearrangementProcessor2.cpp
++++ icu-52.1/source/layout/IndicRearrangementProcessor2.cpp
+@@ -43,6 +43,11 @@ le_uint16 IndicRearrangementProcessor2::
+ le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
+ IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
+
++ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
++ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
++ return 0;
++ }
++
+ if (flags & irfMarkFirst) {
+ firstGlyph = currGlyph;
+ }
+--- icu-52.1.orig/source/layout/LigatureSubstProc.cpp
++++ icu-52.1/source/layout/LigatureSubstProc.cpp
+@@ -48,7 +48,7 @@ ByteOffset LigatureSubstitutionProcessor
+ const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+
+ ByteOffset newState = SWAPW(entry->newStateOffset);
+- le_int16 flags = SWAPW(entry->flags);
++ le_uint16 flags = SWAPW(entry->flags);
+
+ if (flags & lsfSetComponent) {
+ if (++m >= nComponents) {
+--- icu-52.1.orig/source/layout/StateTableProcessor.cpp
++++ icu-52.1/source/layout/StateTableProcessor.cpp
+@@ -60,6 +60,7 @@ void StateTableProcessor::process(LEGlyp
+ if (currGlyph == glyphCount) {
+ // XXX: How do we handle EOT vs. EOL?
+ classCode = classCodeEOT;
++ break;
+ } else {
+ TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
+
+--- icu-52.1.orig/source/layout/StateTableProcessor2.cpp
++++ icu-52.1/source/layout/StateTableProcessor2.cpp
+@@ -78,6 +78,7 @@ void StateTableProcessor2::process(LEGly
+ if (currGlyph == glyphCount || currGlyph == -1) {
+ // XXX: How do we handle EOT vs. EOL?
+ classCode = classCodeEOT;
++ break;
+ } else {
+ LEGlyphID gid = glyphStorage[currGlyph];
+ TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+@@ -109,6 +110,7 @@ void StateTableProcessor2::process(LEGly
+ if (currGlyph == glyphCount || currGlyph == -1) {
+ // XXX: How do we handle EOT vs. EOL?
+ classCode = classCodeEOT;
++ break;
+ } else {
+ LEGlyphID gid = glyphStorage[currGlyph];
+ TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+@@ -146,6 +148,7 @@ void StateTableProcessor2::process(LEGly
+ if (currGlyph == glyphCount || currGlyph == -1) {
+ // XXX: How do we handle EOT vs. EOL?
+ classCode = classCodeEOT;
++ break;
+ } else if(currGlyph > glyphCount) {
+ // note if > glyphCount, we've run off the end (bad font)
+ currGlyph = glyphCount;
+@@ -186,6 +189,7 @@ void StateTableProcessor2::process(LEGly
+ if (currGlyph == glyphCount || currGlyph == -1) {
+ // XXX: How do we handle EOT vs. EOL?
+ classCode = classCodeEOT;
++ break;
+ } else {
+ TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
+ if (glyphCode == 0xFFFF) {
+--- icu-52.1.orig/source/layout/StateTables.h
++++ icu-52.1/source/layout/StateTables.h
+@@ -101,7 +101,7 @@ typedef le_uint8 EntryTableIndex;
+ struct StateEntry
+ {
+ ByteOffset newStateOffset;
+- le_int16 flags;
++ le_uint16 flags;
+ };
+
+ typedef le_uint16 EntryTableIndex2;