Blame SOURCES/libtiff-CVE-2012-2088.patch

8ca2e9
Do strip and tile size calculations in unsigned arithmetic, and then
8ca2e9
complain if the result overflows signed int32, because callers of these
8ca2e9
functions expect signed results (tsize_t is signed).  CVE-2012-2088
8ca2e9
8ca2e9
NB: must be applied after libtiff-subsampling.patch to avoid fuzz issues.
8ca2e9
8ca2e9
8ca2e9
diff -Naur tiff-3.9.4.orig/libtiff/tif_strip.c tiff-3.9.4/libtiff/tif_strip.c
8ca2e9
--- tiff-3.9.4.orig/libtiff/tif_strip.c	2010-06-08 14:50:43.000000000 -0400
8ca2e9
+++ tiff-3.9.4/libtiff/tif_strip.c	2012-06-27 12:37:55.054788399 -0400
8ca2e9
@@ -107,6 +107,7 @@
8ca2e9
 TIFFVStripSize(TIFF* tif, uint32 nrows)
8ca2e9
 {
8ca2e9
 	TIFFDirectory *td = &tif->tif_dir;
8ca2e9
+	uint32 stripsize;
8ca2e9
 
8ca2e9
 	if (nrows == (uint32) -1)
8ca2e9
 		nrows = td->td_imagelength;
8ca2e9
@@ -122,7 +123,7 @@
8ca2e9
 		 * YCbCr data for the extended image.
8ca2e9
 		 */
8ca2e9
 		uint16 ycbcrsubsampling[2];
8ca2e9
-		tsize_t w, scanline, samplingarea;
8ca2e9
+		uint32 w, scanline, samplingarea;
8ca2e9
 
8ca2e9
 		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
8ca2e9
 				      ycbcrsubsampling + 0,
8ca2e9
@@ -141,13 +142,27 @@
8ca2e9
 		nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
8ca2e9
 		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
8ca2e9
 		scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
8ca2e9
-		return ((tsize_t)
8ca2e9
-		    summarize(tif, scanline,
8ca2e9
-			      multiply(tif, 2, scanline / samplingarea,
8ca2e9
-				       "TIFFVStripSize"), "TIFFVStripSize"));
8ca2e9
+		/* a zero anywhere in here means overflow, must return zero */
8ca2e9
+		if (scanline > 0) {
8ca2e9
+			uint32 extra =
8ca2e9
+			    multiply(tif, 2, scanline / samplingarea,
8ca2e9
+				     "TIFFVStripSize");
8ca2e9
+			if (extra > 0)
8ca2e9
+				stripsize = summarize(tif, scanline, extra,
8ca2e9
+						      "TIFFVStripSize");
8ca2e9
+			else
8ca2e9
+				stripsize = 0;
8ca2e9
+		} else
8ca2e9
+			stripsize = 0;
8ca2e9
 	} else
8ca2e9
-		return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
8ca2e9
-					   "TIFFVStripSize"));
8ca2e9
+		stripsize = multiply(tif, nrows, TIFFScanlineSize(tif),
8ca2e9
+				     "TIFFVStripSize");
8ca2e9
+	/* Because tsize_t is signed, we might have conversion overflow */
8ca2e9
+	if (((tsize_t) stripsize) < 0) {
8ca2e9
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", "TIFFVStripSize");
8ca2e9
+		stripsize = 0;
8ca2e9
+	}
8ca2e9
+	return (tsize_t) stripsize;
8ca2e9
 }
8ca2e9
 
8ca2e9
 
8ca2e9
diff -Naur tiff-3.9.4.orig/libtiff/tif_tile.c tiff-3.9.4/libtiff/tif_tile.c
8ca2e9
--- tiff-3.9.4.orig/libtiff/tif_tile.c	2010-06-08 14:50:43.000000000 -0400
8ca2e9
+++ tiff-3.9.4/libtiff/tif_tile.c	2012-06-27 12:37:55.055788446 -0400
8ca2e9
@@ -174,7 +174,7 @@
8ca2e9
 TIFFTileRowSize(TIFF* tif)
8ca2e9
 {
8ca2e9
 	TIFFDirectory *td = &tif->tif_dir;
8ca2e9
-	tsize_t rowsize;
8ca2e9
+	uint32 rowsize;
8ca2e9
 	
8ca2e9
 	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
8ca2e9
 		return ((tsize_t) 0);
8ca2e9
@@ -193,7 +193,7 @@
8ca2e9
 TIFFVTileSize(TIFF* tif, uint32 nrows)
8ca2e9
 {
8ca2e9
 	TIFFDirectory *td = &tif->tif_dir;
8ca2e9
-	tsize_t tilesize;
8ca2e9
+	uint32 tilesize;
8ca2e9
 
8ca2e9
 	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
8ca2e9
 	    td->td_tiledepth == 0)
8ca2e9
@@ -209,12 +209,12 @@
8ca2e9
 		 * horizontal/vertical subsampling area include
8ca2e9
 		 * YCbCr data for the extended image.
8ca2e9
 		 */
8ca2e9
-		tsize_t w =
8ca2e9
+		uint32 w =
8ca2e9
 		    TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]);
8ca2e9
-		tsize_t rowsize =
8ca2e9
+		uint32 rowsize =
8ca2e9
 		    TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
8ca2e9
 					  "TIFFVTileSize"));
8ca2e9
-		tsize_t samplingarea =
8ca2e9
+		uint32 samplingarea =
8ca2e9
 		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
8ca2e9
 		if (samplingarea == 0) {
8ca2e9
 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling");
8ca2e9
@@ -223,15 +223,27 @@
8ca2e9
 		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
8ca2e9
 		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
8ca2e9
 		tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize");
8ca2e9
-		tilesize = summarize(tif, tilesize,
8ca2e9
-				     multiply(tif, 2, tilesize / samplingarea,
8ca2e9
-					      "TIFFVTileSize"),
8ca2e9
+		/* a zero anywhere in here means overflow, must return zero */
8ca2e9
+		if (tilesize > 0) {
8ca2e9
+			uint32 extra =
8ca2e9
+			    multiply(tif, 2, tilesize / samplingarea,
8ca2e9
 				     "TIFFVTileSize");
8ca2e9
+			if (extra > 0)
8ca2e9
+				tilesize = summarize(tif, tilesize, extra,
8ca2e9
+						     "TIFFVTileSize");
8ca2e9
+			else
8ca2e9
+				tilesize = 0;
8ca2e9
+		}
8ca2e9
 	} else
8ca2e9
 		tilesize = multiply(tif, nrows, TIFFTileRowSize(tif),
8ca2e9
 				    "TIFFVTileSize");
8ca2e9
-	return ((tsize_t)
8ca2e9
-	    multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize"));
8ca2e9
+	tilesize = multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize");
8ca2e9
+	/* Because tsize_t is signed, we might have conversion overflow */
8ca2e9
+	if (((tsize_t) tilesize) < 0) {
8ca2e9
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", "TIFFVTileSize");
8ca2e9
+		tilesize = 0;
8ca2e9
+	}
8ca2e9
+	return (tsize_t) tilesize;
8ca2e9
 }
8ca2e9
 
8ca2e9
 /*