AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
December 2014

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2014.12.21 15:35 "For review", by Even Rouault
2014.12.21 18:49 "Re: For review", by Kai-uwe Behrmann
2014.12.21 19:05 "Re: For review", by Even Rouault
2014.12.22 02:58 "Re: For review", by Bob Friesenhahn

2014.12.21 15:35 "For review", by Even Rouault

Hi,

In case someone wants to double-check, after painful investigations, I've 
committed the following changes to avoid crashes/Valgrind errors on a set of 
fuzzed images that Bob provided to me. I'm not too sure about the stuff related 
to LOGLUV/CIELAB/ITULAB (changes in libtiff/tif_getimage.c and  
tools/tiff2pdf.c), so review would be appreciated.

My feeling is that TIFFReadDirectory() is much too tolerant. It can return OK 
for really corrupted images, and this opens the door to a lot of potential 
errors in user code/utilities/other parts of the lib that must do later sanity 
checks, and hardly anybody is good at that. For example, my fix related to 
ColorMap is really due to accepting images with not increasingly sorted tags. 
If we had error out before, that issue would have never happened.

Idem for LOGLUV/CIELAB/ITULAB, if those colorspaces have indeed the 
restrictions I guessed on BitsPerSample/SamplesPerPixel, I feel we should 
reject them at TIFFReadDirectory() stage, rather than trying to process them 
in tiff2pdf or TIFFRGBAImageOK().

Even

2014-12-21  Even Rouault  <even.rouault@spatialys.com>

	Fix various crasher bugs on fuzzed images.
	* libtiff/tif_dir.c: TIFFSetField(): refuse to set negative values for
	TIFFTAG_XRESOLUTION and TIFFTAG_YRESOLUTION that cause asserts when 
writing
	the directory
	* libtiff/tif_dirread.c: TIFFReadDirectory(): refuse to read ColorMap or
	TransferFunction if BitsPerSample has not yet been read, otherwise 
reading
	it later will cause user code to crash if BitsPerSample > 1
	* libtiff/tif_getimage.c: TIFFRGBAImageOK(): return FALSE if LOGLUV with
	SamplesPerPixel != 3, or if CIELAB with SamplesPerPixel != 3 or 
BitsPerSample != 8
	* libtiff/tif_next.c: in the "run mode", use tilewidth for tiled images
	instead of imagewidth to avoid crash
	* tools/bmp2tiff.c: fix crash due to int overflow related to input BMP 
dimensions
	* tools/tiff2pdf.c: fix crash due to invalid tile count (should likely be 
checked by
	libtiff too). Detect invalid settings of BitsPerSample/SamplesPerPixel for 
CIELAB / ITULAB
	* tools/tiffcrop.c: fix crash due to invalid TileWidth/TileHeight
	* tools/tiffdump.c: fix crash due to overflow of entry count.


Index: libtiff/tif_dir.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dir.c,v
retrieving revision 1.117
diff -r1.117 tif_dir.c
162a163
>     double dblval;
287c288,291
< 		td->td_xresolution = (float) va_arg(ap, double);
---
>         dblval = va_arg(ap, double);
>         if( dblval < 0 )
>             goto badvaluedouble;
> 		td->td_xresolution = (float) dblval;
290c294,297
< 		td->td_yresolution = (float) va_arg(ap, double);
---
>         dblval = va_arg(ap, double);
>         if( dblval < 0 )
>             goto badvaluedouble;
> 		td->td_yresolution = (float) dblval;
696a704,713
> badvaluedouble:
>         {
>         const TIFFField* fip=TIFFFieldWithTag(tif,tag);
>         TIFFErrorExt(tif->tif_clientdata, module,
>              "%s: Bad value %f for \"%s\" tag",
>              tif->tif_name, dblval,
>              fip ? fip->field_name : "Unknown");
>         va_end(ap);
>         }
>     return (0);
Index: libtiff/tif_dirread.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dirread.c,v
retrieving revision 1.180
diff -r1.180 tif_dirread.c
3432a3433,3434
>     int bitspersample_read = FALSE;
> 
3708a3711,3712
>                     if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
>                         bitspersample_read = TRUE;
3765a3770,3782
>                     /* It would be dangerous to instanciate those tag values 
*/
>                     /* since if td_bitspersample has not yet been read (due 
to */
>                     /* unordered tags), it could be read afterwards with a 
*/
>                     /* values greater than the default one (1), which may 
cause */
>                     /* crashes in user code */
>                     if( !bitspersample_read )
>                     {
>                         fip = TIFFFieldWithTag(tif,dp->tdir_tag);
>                         TIFFWarningExt(tif->tif_clientdata,module,
>                                        "Ignoring %s since BitsPerSample tag 
not found",
>                                        fip ? fip->field_name : "unknown 
tagname");
>                         continue;
>                     }
Index: libtiff/tif_getimage.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v
retrieving revision 1.82
diff -r1.82 tif_getimage.c
184a185,191
> 			if( td->td_samplesperpixel != 3 )
>             {
>                 sprintf(emsg,
>                         "Sorry, can not handle image with %s=%d",
>                         "Samples/pixel", td->td_samplesperpixel);
>                 return 0;
>             }
186a194,201
>             if( td->td_samplesperpixel != 3 || td->td_bitspersample != 8 )
>             {
>                 sprintf(emsg,
>                         "Sorry, can not handle image with %s=%d and %s=%d",
>                         "Samples/pixel", td->td_samplesperpixel,
>                         "Bits/sample", td->td_bitspersample);
>                 return 0;
>             }
Index: libtiff/tif_next.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_next.c,v
retrieving revision 1.13
diff -r1.13 tif_next.c
104a105,106
>             if( isTiled(tif) )
>                 imagewidth = tif->tif_dir.td_tilewidth;
Index: tools/bmp2tiff.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/bmp2tiff.c,v
retrieving revision 1.23
diff -r1.23 bmp2tiff.c
405a406,412
>         if( width <= 0 || length <= 0 )
>         {
>             TIFFError(infilename,
>                   "Invalid dimensions of BMP file" );
>             close(fd);
>             return -1;
>         }
595a603,610
>             /* Detect int overflow */
>             if( uncompr_size / width != length )
>             {
>                 TIFFError(infilename,
>                     "Invalid dimensions of BMP file" );
>                 close(fd);
>                 return -1;
>             }
Index: tools/tiff2pdf.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiff2pdf.c,v
retrieving revision 1.77
diff -r1.77 tiff2pdf.c
1169a1170,1178
>                 if( (t2p->tiff_tiles[i].tiles_tilecount % xuint16) != 0 )
>                 {
>                     TIFFError(
>                         TIFF2PDF_MODULE, 
>                         "Invalid tile count, %s", 
>                         TIFFFileName(input));
>                     t2p->t2p_error = T2P_ERR_ERROR;
>                     return;
>                 }
1554a1564,1579
>             if( t2p->tiff_samplesperpixel != 3){
>                 TIFFError(
>                     TIFF2PDF_MODULE, 
>                     "Unsupported samplesperpixel = %d for CIELAB", 
>                     t2p->tiff_samplesperpixel);
>                 t2p->t2p_error = T2P_ERR_ERROR;
>                 return;
>             }
>             if( t2p->tiff_bitspersample != 8){
>                 TIFFError(
>                     TIFF2PDF_MODULE, 
>                     "Invalid bitspersample = %d for CIELAB", 
>                     t2p->tiff_bitspersample);
>                 t2p->t2p_error = T2P_ERR_ERROR;
>                 return;
>             }
1569a1595,1610
>             if( t2p->tiff_samplesperpixel != 3){
>                 TIFFError(
>                     TIFF2PDF_MODULE, 
>                     "Unsupported samplesperpixel = %d for ITULAB", 
>                     t2p->tiff_samplesperpixel);
>                 t2p->t2p_error = T2P_ERR_ERROR;
>                 return;
>             }
>             if( t2p->tiff_bitspersample != 8){
>                 TIFFError(
>                     TIFF2PDF_MODULE, 
>                     "Invalid bitspersample = %d for ITULAB", 
>                     t2p->tiff_bitspersample);
>                 t2p->t2p_error = T2P_ERR_ERROR;
>                 return;
>             }
Index: tools/tiffcrop.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
retrieving revision 1.23
diff -r1.23 tiffcrop.c
1208,1210c1208,1211
<   TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
<   TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
<   TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
---
>   if( !TIFFGetField(out, TIFFTAG_TILELENGTH, &tl) ||
>       !TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw) ||
>       !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) )
>       return 1;
Index: tools/tiffdump.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffdump.c,v
retrieving revision 1.28
diff -r1.28 tiffdump.c
376a377,378
>         int datasizeoverflow;
> 
414a417
>         datasizeoverflow = (typewidth > 0 && datasize / typewidth != count);
421c424
< 			if (datasize>4)
---
> 			if (datasizeoverflow || datasize>4)
435c438
< 			if (datasize>8)
---
> 			if (datasizeoverflow || datasize>8)
445c448
< 		if (datasize>0x10000)
---
> 		if (datasizeoverflow || datasize>0x10000)


-- 
Spatialys - Geospatial professional services
http://www.spatialys.com