gnu: icu4c: Add fix for CVE-2015-4760.
* gnu/packages/patches/icu4c-CVE-2015-4760.patch: New file. * gnu-system.am (dist_patch_DATA): Add it. * gnu/packages/icu4c.scm (icu4c)[source]: Add patch.
This commit is contained in:
		
							parent
							
								
									4988dd4008
								
							
						
					
					
						commit
						d2892f3a2d
					
				
					 3 changed files with 192 additions and 1 deletions
				
			
		|  | @ -486,6 +486,7 @@ dist_patch_DATA =						\ | |||
|   gnu/packages/patches/icecat-enable-acceleration-and-webgl.patch \ | ||||
|   gnu/packages/patches/icecat-freetype-2.6.patch		\ | ||||
|   gnu/packages/patches/icecat-libvpx-1.4.patch			\ | ||||
|   gnu/packages/patches/icu4c-CVE-2015-4760.patch		\ | ||||
|   gnu/packages/patches/irrlicht-mesa-10.patch			\ | ||||
|   gnu/packages/patches/jbig2dec-ignore-testtest.patch		\ | ||||
|   gnu/packages/patches/julia-0.3.10-fix-empty-array.patch	\ | ||||
|  |  | |||
|  | @ -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))) | ||||
|  |  | |||
							
								
								
									
										189
									
								
								gnu/packages/patches/icu4c-CVE-2015-4760.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								gnu/packages/patches/icu4c-CVE-2015-4760.patch
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||
		Reference in a new issue