From c188f95bd865b1428f88c193b895fe9b3f6767e9 Mon Sep 17 00:00:00 2001 From: Even Rouault 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