* tools/tiffdither.c: check memory allocations to avoid writing to

NULL pointer. Also check multiplication overflow. Fixes #2501,
CVE-2014-8128. Derived from patch by Petr Gajdos.
This commit is contained in:
Even Rouault 2015-03-02 16:16:38 +00:00
parent cb66df4e65
commit 7bed6738f2
2 changed files with 23 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2015-03-02 Even Rouault <even.rouault@spatialys.com>
* tools/tiffdither.c: check memory allocations to avoid writing to
NULL pointer. Also check multiplication overflow. Fixes #2501,
CVE-2014-8128. Derived from patch by Petr Gajdos.
2015-01-26 Even Rouault <even.rouault@spatialys.com> 2015-01-26 Even Rouault <even.rouault@spatialys.com>
* add html/v4.0.4beta.html under version control * add html/v4.0.4beta.html under version control

View File

@ -1,4 +1,4 @@
/* $Id: tiffdither.c,v 1.14 2013-05-02 14:44:29 tgl Exp $ */ /* $Id: tiffdither.c,v 1.15 2015-03-02 16:16:38 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -39,6 +39,7 @@
#endif #endif
#include "tiffio.h" #include "tiffio.h"
#include "tiffiop.h"
#define streq(a,b) (strcmp(a,b) == 0) #define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0) #define strneq(a,b,n) (strncmp(a,b,n) == 0)
@ -56,7 +57,7 @@ static void usage(void);
* Floyd-Steinberg error propragation with threshold. * Floyd-Steinberg error propragation with threshold.
* This code is stolen from tiffmedian. * This code is stolen from tiffmedian.
*/ */
static void static int
fsdither(TIFF* in, TIFF* out) fsdither(TIFF* in, TIFF* out)
{ {
unsigned char *outline, *inputline, *inptr; unsigned char *outline, *inputline, *inptr;
@ -68,14 +69,19 @@ fsdither(TIFF* in, TIFF* out)
int lastline, lastpixel; int lastline, lastpixel;
int bit; int bit;
tsize_t outlinesize; tsize_t outlinesize;
int errcode = 0;
imax = imagelength - 1; imax = imagelength - 1;
jmax = imagewidth - 1; jmax = imagewidth - 1;
inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
thisline = (short *)_TIFFmalloc(imagewidth * sizeof (short)); thisline = (short *)_TIFFmalloc(TIFFSafeMultiply(tmsize_t, imagewidth, sizeof (short)));
nextline = (short *)_TIFFmalloc(imagewidth * sizeof (short)); nextline = (short *)_TIFFmalloc(TIFFSafeMultiply(tmsize_t, imagewidth, sizeof (short)));
outlinesize = TIFFScanlineSize(out); outlinesize = TIFFScanlineSize(out);
outline = (unsigned char *) _TIFFmalloc(outlinesize); outline = (unsigned char *) _TIFFmalloc(outlinesize);
if (! (inputline && thisline && nextline && outline)) {
fprintf(stderr, "Out of memory.\n");
goto skip_on_error;
}
/* /*
* Get first line * Get first line
@ -93,7 +99,7 @@ fsdither(TIFF* in, TIFF* out)
nextline = tmpptr; nextline = tmpptr;
lastline = (i == imax); lastline = (i == imax);
if (TIFFReadScanline(in, inputline, i, 0) <= 0) if (TIFFReadScanline(in, inputline, i, 0) <= 0)
break; goto skip_on_error;
inptr = inputline; inptr = inputline;
nextptr = nextline; nextptr = nextline;
for (j = 0; j < imagewidth; ++j) for (j = 0; j < imagewidth; ++j)
@ -131,13 +137,18 @@ fsdither(TIFF* in, TIFF* out)
} }
} }
if (TIFFWriteScanline(out, outline, i-1, 0) < 0) if (TIFFWriteScanline(out, outline, i-1, 0) < 0)
break; goto skip_on_error;
} }
goto exit_label;
skip_on_error: skip_on_error:
errcode = 1;
exit_label:
_TIFFfree(inputline); _TIFFfree(inputline);
_TIFFfree(thisline); _TIFFfree(thisline);
_TIFFfree(nextline); _TIFFfree(nextline);
_TIFFfree(outline); _TIFFfree(outline);
return errcode;
} }
static uint16 compression = COMPRESSION_PACKBITS; static uint16 compression = COMPRESSION_PACKBITS;