* include/freetype/internal/ftmemory.h, src/base/ftbitmap.c,

src/base/ftmac.c, src/base/ftrfork.c, src/lzw/ftzopen.c,
    src/raster/ftrend1.c, src/sfnt/ttpost.c, src/truetype/ttgxvar.c,
    src/type42/t42parse.c, src/winfonts/winfnt.c: hardening the code
    against out-of-bounds conditions when allocating arrays. This is
    for the cases where FT_NEW_ARRAY and FT_RENEW_ARRAY are not used
    already. Introducing the new FT_ALLOC_MULT and FT_REALLOC_MULT
    macros.
This commit is contained in:
David Turner 2006-05-02 09:00:29 +00:00
parent 264f307e66
commit 9ca782569c
11 changed files with 76 additions and 20 deletions

View File

@ -1,5 +1,15 @@
2006-05-02 David Turner <david@freetype.org>
* include/freetype/internal/ftmemory.h, src/base/ftbitmap.c,
src/base/ftmac.c, src/base/ftrfork.c, src/lzw/ftzopen.c,
src/raster/ftrend1.c, src/sfnt/ttpost.c, src/truetype/ttgxvar.c,
src/type42/t42parse.c, src/winfonts/winfnt.c: hardening the code
against out-of-bounds conditions when allocating arrays. This is
for the cases where FT_NEW_ARRAY and FT_RENEW_ARRAY are not used
already. Introducing the new FT_ALLOC_MULT and FT_REALLOC_MULT
macros.
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
@ -25,6 +35,7 @@
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-04-30 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
Fix bug in Mac_Read_POST_Resource() to parse PFB font with MacOS

View File

@ -134,6 +134,19 @@ FT_BASE( long ) _ft_debug_lineno;
#define FT_MEM_QRENEW_ARRAY(ptr,cur,new) \
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, sizeof(*(ptr)), (cur), (new), (ptr), &error ) )
#define FT_MEM_ALLOC_MULT(ptr,count,item_size) \
FT_DEBUG_INNER( (ptr) = ft_mem_realloc( memory, (item_size), 0, (count), NULL, &error ) )
#define FT_MEM_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
FT_DEBUG_INNER( (ptr) = ft_mem_realloc( memory, (itmsz), (oldcnt), (newcnt), (ptr), &error ) )
#define FT_MEM_QALLOC_MULT(ptr,count,item_size) \
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, (item_size), 0, (count), NULL, &error ) )
#define FT_MEM_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, (itmsz), (oldcnt), (newcnt), (ptr), &error ) )
#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 )
@ -198,12 +211,24 @@ FT_BASE( long ) _ft_debug_lineno;
#define FT_REALLOC(ptr,cursz,newsz) \
FT_MEM_SET_ERROR( FT_MEM_REALLOC(ptr,cursz,newsz) )
#define FT_ALLOC_MULT(ptr,count,item_size) \
FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT(ptr,count,item_size) )
#define FT_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) )
#define FT_QALLOC(ptr,size) \
FT_MEM_SET_ERROR( FT_MEM_QALLOC(ptr,size) )
#define FT_QREALLOC(ptr,cursz,newsz) \
FT_MEM_SET_ERROR( FT_MEM_QREALLOC(ptr,cursz,newsz) )
#define FT_QALLOC_MULT(ptr,count,item_size) \
FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT(ptr,count,item_size) )
#define FT_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) )
#define FT_FREE(ptr) FT_MEM_FREE( ptr )
#define FT_NEW(ptr) \

View File

@ -165,7 +165,7 @@
new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
if ( FT_ALLOC( buffer, new_pitch * ( bitmap->rows + ypixels ) ) )
if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
return error;
if ( bitmap->pitch > 0 )

View File

@ -808,6 +808,7 @@
short res_id;
unsigned char *buffer, *p, *size_p = NULL;
FT_ULong total_size = 0;
FT_ULong old_total_size = 0;
FT_ULong post_size, pfb_chunk_size;
Handle post_data;
char code, last_code;
@ -838,6 +839,15 @@
total_size += GetHandleSize( post_data ) - 2;
last_code = code;
/* detect integer overflows */
if ( total_size < old_total_size )
{
error = FT_Err_Array_Too_Large;
goto Error;
}
old_total_size = total_size;
}
if ( FT_ALLOC( buffer, (FT_Long)total_size ) )

View File

@ -179,7 +179,7 @@
if ( error )
return error;
if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) )
if ( FT_NEW_ARRAY( offsets_internal, *count ) )
return error;
for ( j = 0; j < *count; ++j )
@ -426,20 +426,25 @@
FT_Error error;
char* newpath;
FT_Memory memory;
FT_Long base_file_len = ft_strlen( base_file_name );
FT_UNUSED( stream );
memory = library->memory;
if ( FT_ALLOC( newpath,
ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) )
if ( base_file_len > FT_INT_MAX )
return FT_Err_Array_Too_Large;
if ( FT_ALLOC( newpath, base_file_len + 6 ) )
return error;
ft_strcpy( newpath, base_file_name );
ft_strcat( newpath, "/rsrc" );
FT_MEM_COPY( newpath, base_file_name, base_file_len );
FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
*result_file_name = newpath;
*result_offset = 0;
*result_offset = 0;
return FT_Err_Ok;
}

View File

@ -127,10 +127,8 @@
* to write it literally.
*
*/
if ( FT_REALLOC(
state->prefix,
old_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ),
new_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) ) )
if ( FT_REALLOC_MULT( state->prefix, old_size, new_size,
sizeof(FT_UShort)+sizeof(FT_Byte) ) )
return -1;
/* now adjust `suffix' and move the data accordingly */

View File

@ -161,13 +161,13 @@
if ( !( mode & FT_RENDER_MODE_MONO ) )
{
/* we pad to 32 bits, only for backwards compatibility with FT 1.x */
pitch = FT_PAD_CEIL( width, 4 );
pitch = FT_PAD_CEIL( width, 4 );
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
bitmap->num_grays = 256;
}
else
{
pitch = ( ( width + 15 ) >> 4 ) << 1;
pitch = ( ( width + 15 ) >> 4 ) << 1;
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
}
@ -175,7 +175,7 @@
bitmap->rows = height;
bitmap->pitch = pitch;
if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) )
goto Exit;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;

View File

@ -292,7 +292,7 @@
goto Exit;
}
if ( FT_ALLOC( offset_table, num_glyphs ) ||
if ( FT_NEW_ARRAY( offset_table, num_glyphs ) ||
FT_STREAM_READ( offset_table, num_glyphs ) )
goto Fail;

View File

@ -684,15 +684,17 @@
goto Exit;
}
if ( FT_ALLOC( face->blend, sizeof ( GX_BlendRec ) ) )
if ( FT_NEW( face->blend ) )
goto Exit;
/* XXX: TODO - check for overflows */
face->blend->mmvar_len =
sizeof ( FT_MM_Var ) +
fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) +
fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) +
5 * fvar_head.axisCount;
if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
goto Exit;
face->blend->mmvar = mmvar;
@ -1253,7 +1255,7 @@
for ( j = 0; j < point_count; ++j )
{
int pindex = localpoints[j];
face->cvt[pindex] = (FT_Short)( face->cvt[pindex] +
FT_MulFix( deltas[j], apply ) );
}

View File

@ -623,6 +623,7 @@
status = OTHER_TABLES;
face->ttf_size = ttf_size;
/* there are no more than 256 tables, so no size check here */
if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
ttf_size + 1 ) )
goto Fail;
@ -1071,7 +1072,7 @@
if ( !name )
continue;
if ( cur[0] == name[0] &&
if ( cur[0] == name[0] &&
len == (FT_PtrDist)ft_strlen( (const char *)name ) &&
ft_memcmp( cur, name, len ) == 0 )
{

View File

@ -531,7 +531,7 @@
/* reserve one slot for the .notdef glyph at index 0 */
root->num_glyphs = font->header.last_char -
font->header.first_char + 1 + 1;
font->header.first_char + 1 + 1;
/* Some broken fonts don't delimit the face name with a final */
/* NULL byte -- the frame is erroneously one byte too small. */
@ -540,14 +540,18 @@
family_size = font->header.file_size - font->header.face_name_offset;
if ( FT_ALLOC( font->family_name, family_size + 1 ) )
goto Fail;
FT_MEM_COPY( font->family_name,
font->fnt_frame + font->header.face_name_offset,
family_size );
font->family_name[family_size] = '\0';
if ( FT_REALLOC( font->family_name,
family_size,
ft_strlen( font->family_name ) + 1 ) )
goto Fail;
root->family_name = font->family_name;
root->style_name = (char *)"Regular";
@ -693,7 +697,7 @@
/* note: since glyphs are stored in columns and not in rows we */
/* can't use ft_glyphslot_set_bitmap */
if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) )
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )
goto Exit;
column = (FT_Byte*)bitmap->buffer;