fix out of bounds read in tiffload

libtiff can change the value of some fields while scanning a corrupt
TIFF file and this could trigger an out of bounds read.

This patch makes tiffload more cautious about rescanning a TIFF
directory before reading out header fields.
This commit is contained in:
John Cupitt 2020-11-03 11:48:21 +00:00
parent ae82bcc3e8
commit 91d9610a55
2 changed files with 16 additions and 6 deletions

View File

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

View File

@ -2680,18 +2680,23 @@ rtiff_header_read_all( Rtiff *rtiff )
"reading header for page %d ...\n", rtiff->page ); "reading header for page %d ...\n", rtiff->page );
#endif /*DEBUG*/ #endif /*DEBUG*/
/* -1 means "to the end".
*
* We must count pages before selecting and reading the header of the
* first page, since scanning a TIFF can change the value of libtiff's
* internal header fields in strange ways, especially if the TIFF is
* corrupt.
*/
rtiff->n_pages = rtiff_n_pages( rtiff );
if( rtiff_set_page( rtiff, rtiff->page ) || if( rtiff_set_page( rtiff, rtiff->page ) ||
rtiff_header_read( rtiff, &rtiff->header ) ) rtiff_header_read( rtiff, &rtiff->header ) )
return( -1 ); return( -1 );
/* -1 means "to the end".
*/
rtiff->n_pages = rtiff_n_pages( rtiff );
if( rtiff->n == -1 )
rtiff->n = rtiff->n_pages - rtiff->page;
/* If we're to read many pages, verify that they are all identical. /* If we're to read many pages, verify that they are all identical.
*/ */
if( rtiff->n == -1 )
rtiff->n = rtiff->n_pages - rtiff->page;
if( rtiff->n > 1 ) { if( rtiff->n > 1 ) {
int i; int i;
@ -2715,6 +2720,10 @@ rtiff_header_read_all( Rtiff *rtiff )
return( -1 ); return( -1 );
} }
} }
/* Make sure the next set_page() will reread the directory.
*/
rtiff->current_page = -1;
} }
return( 0 ); return( 0 );