fix out of bounds exif read in heifload

We were subtracting 4 from the length of the exif data block without
checking that there were 4 or more bytes there.
This commit is contained in:
John Cupitt 2020-10-20 08:54:54 +01:00
parent 0131d4d3eb
commit ae82bcc3e8
3 changed files with 14 additions and 3 deletions

View File

@ -1,6 +1,7 @@
18/10/20 started 8.10.3
- relax heic is_a rules [hisham]
- fix vips7 webp load [barryspearce]
- fix out of bounds exif read in heifload
6/9/20 started 8.10.2
- update magicksave/load profile handling [kelilevi]

View File

@ -158,10 +158,18 @@ show_values( ExifData *data )
* their default value and we won't know about it.
*/
static ExifData *
vips_exif_load_data_without_fix( const void *data, int length )
vips_exif_load_data_without_fix( const void *data, size_t length )
{
ExifData *ed;
/* exif_data_load_data() only allows uint for length. Limit it to less
* than that: 2**20 should be enough for anyone.
*/
if( length > 1 << 20 ) {
vips_error( "exif", "%s", _( "exif too large" ) );
return( NULL );
}
if( !(ed = exif_data_new()) ) {
vips_error( "exif", "%s", _( "unable to init exif" ) );
return( NULL );

View File

@ -464,7 +464,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
char name[256];
#ifdef DEBUG
printf( "metadata type = %s, length = %zd\n", type, length );
printf( "metadata type = %s, length = %zu\n", type, length );
#endif /*DEBUG*/
if( !(data = VIPS_ARRAY( out, length, unsigned char )) )
@ -479,7 +479,8 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
/* We need to skip the first four bytes of EXIF, they just
* contain the offset.
*/
if( g_ascii_strcasecmp( type, "exif" ) == 0 ) {
if( length > 4 &&
g_ascii_strcasecmp( type, "exif" ) == 0 ) {
data += 4;
length -= 4;
}
@ -492,6 +493,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
if( g_ascii_strcasecmp( type, "exif" ) == 0 )
vips_snprintf( name, 256, VIPS_META_EXIF_NAME );
else if( g_ascii_strcasecmp( type, "mime" ) == 0 &&
length > 10 &&
vips_isprefix( "<x:xmpmeta", (const char *) data ) )
vips_snprintf( name, 256, VIPS_META_XMP_NAME );
else