Blob Blame History Raw
From c188f95bd865b1428f88c193b895fe9b3f6767e9 Mon Sep 17 00:00:00 2001
From: Even Rouault <even.rouault@spatialys.com>
Date: Tue, 30 Oct 2018 18:50:27 +0100
Subject: [PATCH] tiff2bw: avoid null pointer dereference in case of out of
 memory situation. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2819 /
 CVE-2018-18661

---
 libtiff/tiffiop.h |  1 +
 tools/tiff2bw.c   | 63 +++++++++++++++++++++++++++++++++++++++--------
 tools/tiffcrop.c  |  5 ----
 3 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
index 53357d8..8d1357b 100644
--- a/libtiff/tiffiop.h
+++ b/libtiff/tiffiop.h
@@ -66,6 +66,7 @@ extern void *lfind(const void *, const void *, size_t *, size_t,
 #endif
 
 #define    streq(a,b)      (strcmp(a,b) == 0)
+#define    strneq(a,b,n)   (strncmp(a,b,n) == 0)
 
 #ifndef TRUE
 #define	TRUE	1
diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c
index 53067e7..ad797b2 100644
--- a/tools/tiff2bw.c
+++ b/tools/tiff2bw.c
@@ -40,9 +40,7 @@
 #endif
 
 #include "tiffio.h"
-
-#define	streq(a,b)	(strcmp((a),(b)) == 0)
-#define	strneq(a,b,n)	(strncmp(a,b,n) == 0)
+#include "tiffiop.h"
 
 /* x% weighting -> fraction of full color */
 #define	PCT(x)	(((x)*255+127)/100)
@@ -130,6 +128,11 @@ main(int argc, char* argv[])
 	extern int optind;
 	extern char *optarg;
 
+	in = (TIFF *) NULL;
+	out = (TIFF *) NULL;
+	inbuf = (unsigned char *) NULL;
+	outbuf = (unsigned char *) NULL;
+        
 	while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1)
 		switch (c) {
 		case 'c':		/* compression scheme */
@@ -163,24 +166,24 @@ main(int argc, char* argv[])
 		fprintf(stderr,
 	    "%s: Bad photometric; can only handle RGB and Palette images.\n",
 		    argv[optind]);
-		return (-1);
+		goto tiff2bw_error;
 	}
 	TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
 	if (samplesperpixel != 1 && samplesperpixel != 3) {
 		fprintf(stderr, "%s: Bad samples/pixel %u.\n",
 		    argv[optind], samplesperpixel);
-		return (-1);
+		goto tiff2bw_error;
 	}
 	if( photometric == PHOTOMETRIC_RGB && samplesperpixel != 3) {
 		fprintf(stderr, "%s: Bad samples/pixel %u for PHOTOMETRIC_RGB.\n",
 		    argv[optind], samplesperpixel);
-		return (-1);
+		goto tiff2bw_error;
 	}
 	TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
 	if (bitspersample != 8) {
 		fprintf(stderr,
 		    " %s: Sorry, only handle 8-bit samples.\n", argv[optind]);
-		return (-1);
+		goto tiff2bw_error;
 	}
 	TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
 	TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h);
@@ -188,7 +191,7 @@ main(int argc, char* argv[])
 
 	out = TIFFOpen(argv[optind+1], "w");
 	if (out == NULL)
-		return (-1);
+		goto tiff2bw_error;
 	TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w);
 	TIFFSetField(out, TIFFTAG_IMAGELENGTH, h);
 	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
@@ -214,6 +217,11 @@ main(int argc, char* argv[])
 	TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
 	TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
 	outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
+        if( !outbuf )
+        {
+            fprintf(stderr, "Out of memory\n");
+            goto tiff2bw_error;
+        }
 	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
 	    TIFFDefaultStripSize(out, rowsperstrip));
 
@@ -237,6 +245,11 @@ main(int argc, char* argv[])
 #undef CVT
 		}
 		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
+                if( !inbuf )
+                {
+                    fprintf(stderr, "Out of memory\n");
+                    goto tiff2bw_error;
+                }
 		for (row = 0; row < h; row++) {
 			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
 				break;
@@ -247,6 +260,11 @@ main(int argc, char* argv[])
 		break;
 	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
 		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
+                if( !inbuf )
+                {
+                    fprintf(stderr, "Out of memory\n");
+                    goto tiff2bw_error;
+                }
 		for (row = 0; row < h; row++) {
 			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
 				break;
@@ -256,23 +274,48 @@ main(int argc, char* argv[])
 		}
 		break;
 	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
+        {
+                tmsize_t inbufsize;
 		rowsize = TIFFScanlineSize(in);
-		inbuf = (unsigned char *)_TIFFmalloc(3*rowsize);
+                inbufsize = TIFFSafeMultiply(tmsize_t, 3, rowsize);
+		inbuf = (unsigned char *)_TIFFmalloc(inbufsize);
+                if( !inbuf )
+                {
+                    fprintf(stderr, "Out of memory\n");
+                    goto tiff2bw_error;
+                }
 		for (row = 0; row < h; row++) {
 			for (s = 0; s < 3; s++)
 				if (TIFFReadScanline(in,
 				    inbuf+s*rowsize, row, s) < 0)
-					 return (-1);
+                                        goto tiff2bw_error;
 			compresssep(outbuf,
 			    inbuf, inbuf+rowsize, inbuf+2*rowsize, w);
 			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
 				break;
 		}
 		break;
+        }
 	}
 #undef pack
+        if (inbuf)
+                _TIFFfree(inbuf);
+        if (outbuf)
+                _TIFFfree(outbuf);
+        TIFFClose(in);
 	TIFFClose(out);
 	return (0);
+
+ tiff2bw_error:
+        if (inbuf)
+                _TIFFfree(inbuf);
+        if (outbuf)
+                _TIFFfree(outbuf);
+        if (out)
+                TIFFClose(out);
+        if (in)
+                TIFFClose(in);
+        return (-1);
 }
 
 static int
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index 02c53cd..0192f3f 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -148,11 +148,6 @@ extern int getopt(int, char**, char*);
 #define PATH_MAX 1024
 #endif
 
-#ifndef streq
-#define	streq(a,b)	(strcmp((a),(b)) == 0)
-#endif
-#define	strneq(a,b,n)	(strncmp((a),(b),(n)) == 0)
-
 #define	TRUE	1
 #define	FALSE	0
 
-- 
2.17.2