mirror of
https://git.FreeBSD.org/ports.git
synced 2025-01-06 06:30:19 +00:00
Add patches to correct the security issues described in CVE-2006-3467.
Reported by: remko Obtained from: Freetype CVS via NetBSD Security: Fixes CVE-2006-3467
This commit is contained in:
parent
304b9350e6
commit
9c44000d22
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=171220
@ -7,7 +7,7 @@
|
||||
|
||||
PORTNAME= freetype2
|
||||
PORTVERSION= 2.1.10
|
||||
PORTREVISION= 3
|
||||
PORTREVISION= 4
|
||||
CATEGORIES= print
|
||||
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:S,%SUBDIR%,freetype,} \
|
||||
http://sunsite.cnlab-switch.ch/ftp/mirror/freetype/%SUBDIR%/ \
|
||||
|
50
print/freetype2/files/patch-src_pcf_pcfdriver.c
Normal file
50
print/freetype2/files/patch-src_pcf_pcfdriver.c
Normal file
@ -0,0 +1,50 @@
|
||||
--- src/pcf/pcfdrivr.c.orig 2006-02-17 07:40:36.000000000 +0100
|
||||
+++ src/pcf/pcfdrivr.c
|
||||
@@ -203,19 +203,23 @@ THE SOFTWARE.
|
||||
|
||||
/* free properties */
|
||||
{
|
||||
- PCF_Property prop = face->properties;
|
||||
+ PCF_Property prop;
|
||||
FT_Int i;
|
||||
|
||||
|
||||
- for ( i = 0; i < face->nprops; i++ )
|
||||
+ if ( face->properties )
|
||||
{
|
||||
- prop = &face->properties[i];
|
||||
+ for ( i = 0; i < face->nprops; i++ )
|
||||
+ {
|
||||
+ prop = &face->properties[i];
|
||||
|
||||
- FT_FREE( prop->name );
|
||||
- if ( prop->isString )
|
||||
- FT_FREE( prop->value.atom );
|
||||
+ if ( prop ) {
|
||||
+ FT_FREE( prop->name );
|
||||
+ if ( prop->isString )
|
||||
+ FT_FREE( prop->value.atom );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
-
|
||||
FT_FREE( face->properties );
|
||||
}
|
||||
|
||||
@@ -258,6 +262,8 @@ THE SOFTWARE.
|
||||
FT_Error error2;
|
||||
|
||||
|
||||
+ PCF_Face_Done( pcfface );
|
||||
+
|
||||
/* this didn't work, try gzip support! */
|
||||
error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
|
||||
if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
|
||||
@@ -357,6 +363,7 @@ THE SOFTWARE.
|
||||
|
||||
Fail:
|
||||
FT_TRACE2(( "[not a valid PCF file]\n" ));
|
||||
+ PCF_Face_Done( pcfface );
|
||||
error = PCF_Err_Unknown_File_Format; /* error */
|
||||
goto Exit;
|
||||
}
|
455
print/freetype2/files/patch-src_pcf_pcfread.c
Normal file
455
print/freetype2/files/patch-src_pcf_pcfread.c
Normal file
@ -0,0 +1,455 @@
|
||||
--- src/pcf/pcfread.c.orig 2006-01-23 17:35:18.000000000 +0100
|
||||
+++ src/pcf/pcfread.c
|
||||
@@ -102,7 +102,8 @@ THE SOFTWARE.
|
||||
return PCF_Err_Cannot_Open_Resource;
|
||||
|
||||
if ( toc->version != PCF_FILE_VERSION ||
|
||||
- toc->count > FT_ARRAY_MAX( face->toc.tables ) )
|
||||
+ toc->count > FT_ARRAY_MAX( face->toc.tables ) ||
|
||||
+ toc->count == 0 )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
|
||||
@@ -116,6 +117,41 @@ THE SOFTWARE.
|
||||
tables++;
|
||||
}
|
||||
|
||||
+ /* Sort tables and check for overlaps. Because they are almost */
|
||||
+ /* always ordered already, an in-place bubble sort with simultaneous */
|
||||
+ /* boundary checking seems appropriate. */
|
||||
+ tables = face->toc.tables;
|
||||
+
|
||||
+ for ( n = 0; n < toc->count - 1; n++ )
|
||||
+ {
|
||||
+ FT_UInt i, have_change;
|
||||
+
|
||||
+
|
||||
+ have_change = 0;
|
||||
+
|
||||
+ for ( i = 0; i < toc->count - 1 - n; i++ )
|
||||
+ {
|
||||
+ PCF_TableRec tmp;
|
||||
+
|
||||
+
|
||||
+ if ( tables[i].offset > tables[i + 1].offset )
|
||||
+ {
|
||||
+ tmp = tables[i];
|
||||
+ tables[i] = tables[i + 1];
|
||||
+ tables[i + 1] = tmp;
|
||||
+
|
||||
+ have_change = 1;
|
||||
+ }
|
||||
+
|
||||
+ if ( ( tables[i].size > tables[i + 1].offset ) ||
|
||||
+ ( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
|
||||
+ return PCF_Err_Invalid_Offset;
|
||||
+ }
|
||||
+
|
||||
+ if ( !have_change )
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
#if defined( FT_DEBUG_LEVEL_TRACE )
|
||||
|
||||
{
|
||||
@@ -130,7 +166,8 @@ THE SOFTWARE.
|
||||
tables = face->toc.tables;
|
||||
for ( i = 0; i < toc->count; i++ )
|
||||
{
|
||||
- for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
|
||||
+ for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
|
||||
+ j++ )
|
||||
if ( tables[i].type == (FT_UInt)( 1 << j ) )
|
||||
name = tableNames[j];
|
||||
|
||||
@@ -153,13 +190,15 @@ THE SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
+#define PCF_METRIC_SIZE 12
|
||||
+
|
||||
static
|
||||
const FT_Frame_Field pcf_metric_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_MetricRec
|
||||
|
||||
- FT_FRAME_START( 12 ),
|
||||
+ FT_FRAME_START( PCF_METRIC_SIZE ),
|
||||
FT_FRAME_SHORT_LE( leftSideBearing ),
|
||||
FT_FRAME_SHORT_LE( rightSideBearing ),
|
||||
FT_FRAME_SHORT_LE( characterWidth ),
|
||||
@@ -176,7 +215,7 @@ THE SOFTWARE.
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_MetricRec
|
||||
|
||||
- FT_FRAME_START( 12 ),
|
||||
+ FT_FRAME_START( PCF_METRIC_SIZE ),
|
||||
FT_FRAME_SHORT( leftSideBearing ),
|
||||
FT_FRAME_SHORT( rightSideBearing ),
|
||||
FT_FRAME_SHORT( characterWidth ),
|
||||
@@ -187,13 +226,15 @@ THE SOFTWARE.
|
||||
};
|
||||
|
||||
|
||||
+#define PCF_COMPRESSED_METRIC_SIZE 5
|
||||
+
|
||||
static
|
||||
const FT_Frame_Field pcf_compressed_metric_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_Compressed_MetricRec
|
||||
|
||||
- FT_FRAME_START( 5 ),
|
||||
+ FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ),
|
||||
FT_FRAME_BYTE( leftSideBearing ),
|
||||
FT_FRAME_BYTE( rightSideBearing ),
|
||||
FT_FRAME_BYTE( characterWidth ),
|
||||
@@ -221,7 +262,7 @@ THE SOFTWARE.
|
||||
? pcf_metric_msb_header
|
||||
: pcf_metric_header;
|
||||
|
||||
- /* the following sets 'error' but doesn't return in case of failure */
|
||||
+ /* the following sets `error' but doesn't return in case of failure */
|
||||
(void)FT_STREAM_READ_FIELDS( fields, metric );
|
||||
}
|
||||
else
|
||||
@@ -261,17 +302,19 @@ THE SOFTWARE.
|
||||
for ( i = 0; i < ntables; i++ )
|
||||
if ( tables[i].type == type )
|
||||
{
|
||||
- if ( stream->pos > tables[i].offset ) {
|
||||
+ if ( stream->pos > tables[i].offset )
|
||||
+ {
|
||||
error = PCF_Err_Invalid_Stream_Skip;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
- if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) {
|
||||
+ if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
|
||||
+ {
|
||||
error = PCF_Err_Invalid_Stream_Skip;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
- *asize = tables[i].size; /* unused - to be removed */
|
||||
+ *asize = tables[i].size;
|
||||
*aformat = tables[i].format;
|
||||
|
||||
return PCF_Err_Ok;
|
||||
@@ -298,13 +341,15 @@ THE SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
+#define PCF_PROPERTY_SIZE 9
|
||||
+
|
||||
static
|
||||
const FT_Frame_Field pcf_property_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_ParsePropertyRec
|
||||
|
||||
- FT_FRAME_START( 9 ),
|
||||
+ FT_FRAME_START( PCF_PROPERTY_SIZE ),
|
||||
FT_FRAME_LONG_LE( name ),
|
||||
FT_FRAME_BYTE ( isString ),
|
||||
FT_FRAME_LONG_LE( value ),
|
||||
@@ -318,7 +363,7 @@ THE SOFTWARE.
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_ParsePropertyRec
|
||||
|
||||
- FT_FRAME_START( 9 ),
|
||||
+ FT_FRAME_START( PCF_PROPERTY_SIZE ),
|
||||
FT_FRAME_LONG( name ),
|
||||
FT_FRAME_BYTE( isString ),
|
||||
FT_FRAME_LONG( value ),
|
||||
@@ -353,8 +398,8 @@ THE SOFTWARE.
|
||||
PCF_Face face )
|
||||
{
|
||||
PCF_ParseProperty props = 0;
|
||||
- PCF_Property properties = 0;
|
||||
- FT_Int nprops, i;
|
||||
+ PCF_Property properties;
|
||||
+ FT_UInt nprops, i;
|
||||
FT_ULong format, size;
|
||||
FT_Error error;
|
||||
FT_Memory memory = FT_FACE(face)->memory;
|
||||
@@ -390,6 +435,15 @@ THE SOFTWARE.
|
||||
|
||||
FT_TRACE4(( " nprop = %d\n", nprops ));
|
||||
|
||||
+ /* rough estimate */
|
||||
+ if ( nprops > size / PCF_PROPERTY_SIZE )
|
||||
+ {
|
||||
+ error = PCF_Err_Invalid_Table;
|
||||
+ goto Bail;
|
||||
+ }
|
||||
+
|
||||
+ face->nprops = nprops;
|
||||
+
|
||||
if ( FT_NEW_ARRAY( props, nprops ) )
|
||||
goto Bail;
|
||||
|
||||
@@ -427,6 +481,13 @@ THE SOFTWARE.
|
||||
|
||||
FT_TRACE4(( " string_size = %ld\n", string_size ));
|
||||
|
||||
+ /* rough estimate */
|
||||
+ if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
|
||||
+ {
|
||||
+ error = PCF_Err_Invalid_Table;
|
||||
+ goto Bail;
|
||||
+ }
|
||||
+
|
||||
if ( FT_NEW_ARRAY( strings, string_size ) )
|
||||
goto Bail;
|
||||
|
||||
@@ -437,13 +498,24 @@ THE SOFTWARE.
|
||||
if ( FT_NEW_ARRAY( properties, nprops ) )
|
||||
goto Bail;
|
||||
|
||||
+ face->properties = properties;
|
||||
+
|
||||
for ( i = 0; i < nprops; i++ )
|
||||
{
|
||||
- /* XXX: make atom */
|
||||
+ FT_Long name_offset = props[i].name;
|
||||
+
|
||||
+
|
||||
+ if ( ( name_offset < 0 ) ||
|
||||
+ ( (FT_ULong)name_offset > string_size ) )
|
||||
+ {
|
||||
+ error = PCF_Err_Invalid_Offset;
|
||||
+ goto Bail;
|
||||
+ }
|
||||
+
|
||||
if ( FT_NEW_ARRAY( properties[i].name,
|
||||
- ft_strlen( strings + props[i].name ) + 1 ) )
|
||||
+ ft_strlen( strings + name_offset ) + 1 ) )
|
||||
goto Bail;
|
||||
- ft_strcpy( properties[i].name, strings + props[i].name );
|
||||
+ ft_strcpy( properties[i].name, strings + name_offset );
|
||||
|
||||
FT_TRACE4(( " %s:", properties[i].name ));
|
||||
|
||||
@@ -451,8 +523,18 @@ THE SOFTWARE.
|
||||
|
||||
if ( props[i].isString )
|
||||
{
|
||||
+ FT_Long value_offset = props[i].value;
|
||||
+
|
||||
+
|
||||
+ if ( ( value_offset < 0 ) ||
|
||||
+ ( (FT_ULong)value_offset > string_size ) )
|
||||
+ {
|
||||
+ error = PCF_Err_Invalid_Offset;
|
||||
+ goto Bail;
|
||||
+ }
|
||||
+
|
||||
if ( FT_NEW_ARRAY( properties[i].value.atom,
|
||||
- ft_strlen( strings + props[i].value ) + 1 ) )
|
||||
+ ft_strlen( strings + value_offset ) + 1 ) )
|
||||
goto Bail;
|
||||
ft_strcpy( properties[i].value.atom, strings + props[i].value );
|
||||
|
||||
@@ -466,14 +548,8 @@ THE SOFTWARE.
|
||||
}
|
||||
}
|
||||
|
||||
- face->properties = properties;
|
||||
- face->nprops = nprops;
|
||||
-
|
||||
- FT_FREE( props );
|
||||
- FT_FREE( strings );
|
||||
-
|
||||
- return PCF_Err_Ok;
|
||||
-
|
||||
+ error = PCF_Err_Ok;
|
||||
+
|
||||
Bail:
|
||||
FT_FREE( props );
|
||||
FT_FREE( strings );
|
||||
@@ -488,11 +564,9 @@ THE SOFTWARE.
|
||||
{
|
||||
FT_Error error = PCF_Err_Ok;
|
||||
FT_Memory memory = FT_FACE(face)->memory;
|
||||
- FT_ULong format = 0;
|
||||
- FT_ULong size = 0;
|
||||
+ FT_ULong format, size;
|
||||
PCF_Metric metrics = 0;
|
||||
- int i;
|
||||
- int nmetrics = -1;
|
||||
+ FT_ULong nmetrics, i;
|
||||
|
||||
|
||||
error = pcf_seek_to_table_type( stream,
|
||||
@@ -504,7 +578,8 @@ THE SOFTWARE.
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
- error = FT_READ_ULONG_LE( format );
|
||||
+ if ( FT_READ_ULONG_LE( format ) )
|
||||
+ goto Bail;
|
||||
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
|
||||
!PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
|
||||
@@ -524,16 +599,30 @@ THE SOFTWARE.
|
||||
else
|
||||
(void)FT_READ_USHORT_LE( nmetrics );
|
||||
}
|
||||
- if ( error || nmetrics == -1 )
|
||||
+ if ( error )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
face->nmetrics = nmetrics;
|
||||
|
||||
+ FT_TRACE4(( "pcf_get_metrics:\n" ));
|
||||
+
|
||||
+ FT_TRACE4(( " number of metrics: %d\n", nmetrics ));
|
||||
+
|
||||
+ /* rough estimate */
|
||||
+ if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
|
||||
+ {
|
||||
+ if ( nmetrics > size / PCF_METRIC_SIZE )
|
||||
+ return PCF_Err_Invalid_Table;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
|
||||
+ return PCF_Err_Invalid_Table;
|
||||
+ }
|
||||
+
|
||||
if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
|
||||
return PCF_Err_Out_Of_Memory;
|
||||
|
||||
- FT_TRACE4(( "pcf_get_metrics:\n" ));
|
||||
-
|
||||
metrics = face->metrics;
|
||||
for ( i = 0; i < nmetrics; i++ )
|
||||
{
|
||||
@@ -541,7 +630,7 @@ THE SOFTWARE.
|
||||
|
||||
metrics[i].bits = 0;
|
||||
|
||||
- FT_TRACE4(( " idx %d: width=%d, "
|
||||
+ FT_TRACE5(( " idx %d: width=%d, "
|
||||
"lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
|
||||
i,
|
||||
( metrics + i )->characterWidth,
|
||||
@@ -557,6 +646,8 @@ THE SOFTWARE.
|
||||
|
||||
if ( error )
|
||||
FT_FREE( face->metrics );
|
||||
+
|
||||
+ Bail:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -597,14 +688,16 @@ THE SOFTWARE.
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
+ FT_TRACE4(( "pcf_get_bitmaps:\n" ));
|
||||
+
|
||||
+ FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps ));
|
||||
+
|
||||
if ( nbitmaps != face->nmetrics )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
|
||||
return error;
|
||||
|
||||
- FT_TRACE4(( "pcf_get_bitmaps:\n" ));
|
||||
-
|
||||
for ( i = 0; i < nbitmaps; i++ )
|
||||
{
|
||||
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
|
||||
@@ -612,7 +705,7 @@ THE SOFTWARE.
|
||||
else
|
||||
(void)FT_READ_LONG_LE( offsets[i] );
|
||||
|
||||
- FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n",
|
||||
+ FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n",
|
||||
i, offsets[i], offsets[i] ));
|
||||
}
|
||||
if ( error )
|
||||
@@ -640,15 +733,22 @@ THE SOFTWARE.
|
||||
FT_UNUSED( sizebitmaps ); /* only used for debugging */
|
||||
|
||||
for ( i = 0; i < nbitmaps; i++ )
|
||||
- face->metrics[i].bits = stream->pos + offsets[i];
|
||||
+ {
|
||||
+ /* rough estimate */
|
||||
+ if ( ( offsets[i] < 0 ) ||
|
||||
+ ( (FT_ULong)offsets[i] > size ) )
|
||||
+ {
|
||||
+ FT_ERROR(( "pcf_get_bitmaps:"));
|
||||
+ FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i ));
|
||||
+ }
|
||||
+ else
|
||||
+ face->metrics[i].bits = stream->pos + offsets[i];
|
||||
+ }
|
||||
|
||||
face->bitmapsFormat = format;
|
||||
|
||||
- FT_FREE ( offsets );
|
||||
- return error;
|
||||
-
|
||||
Bail:
|
||||
- FT_FREE ( offsets );
|
||||
+ FT_FREE( offsets );
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -734,7 +834,7 @@ THE SOFTWARE.
|
||||
|
||||
tmpEncoding[j].glyph = (FT_Short)encodingOffset;
|
||||
|
||||
- FT_TRACE4(( " code %d (0x%04X): idx %d\n",
|
||||
+ FT_TRACE5(( " code %d (0x%04X): idx %d\n",
|
||||
tmpEncoding[j].enc, tmpEncoding[j].enc,
|
||||
tmpEncoding[j].glyph ));
|
||||
|
||||
@@ -828,7 +928,8 @@ THE SOFTWARE.
|
||||
if ( error )
|
||||
goto Bail;
|
||||
|
||||
- error = FT_READ_ULONG_LE( format );
|
||||
+ if ( FT_READ_ULONG_LE( format ) )
|
||||
+ goto Bail;
|
||||
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
|
||||
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
|
||||
@@ -876,7 +977,6 @@ THE SOFTWARE.
|
||||
accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
|
||||
accel->ink_maxbounds = accel->maxbounds;
|
||||
}
|
||||
- return error;
|
||||
|
||||
Bail:
|
||||
return error;
|
||||
@@ -1082,11 +1182,12 @@ THE SOFTWARE.
|
||||
else
|
||||
root->family_name = NULL;
|
||||
|
||||
- /* Note: We shift all glyph indices by +1 since we must
|
||||
+ /*
|
||||
+ * Note: We shift all glyph indices by +1 since we must
|
||||
* respect the convention that glyph 0 always corresponds
|
||||
- * to the "missing glyph".
|
||||
+ * to the `missing glyph'.
|
||||
*
|
||||
- * This implies bumping the number of "available" glyphs by 1.
|
||||
+ * This implies bumping the number of `available' glyphs by 1.
|
||||
*/
|
||||
root->num_glyphs = face->nmetrics + 1;
|
||||
|
||||
@@ -1171,7 +1272,7 @@ THE SOFTWARE.
|
||||
Exit:
|
||||
if ( error )
|
||||
{
|
||||
- /* this is done to respect the behaviour of the original */
|
||||
+ /* This is done to respect the behaviour of the original */
|
||||
/* PCF font driver. */
|
||||
error = PCF_Err_Invalid_File_Format;
|
||||
}
|
Loading…
Reference in New Issue
Block a user