Improve previous patch for CVE-2012-4564.

This commit is contained in:
Tom Lane 2012-12-10 18:19:11 +00:00
parent bff7f45716
commit 800527edd2
2 changed files with 42 additions and 15 deletions

View File

@ -1,3 +1,10 @@
2012-12-10 Tom Lane <tgl@sss.pgh.pa.us>
* tools/ppm2tiff.c: Improve previous patch for CVE-2012-4564:
check the linebytes calculation too, get the max() calculation
straight, avoid redundant error messages, check for malloc
failure.
2012-12-10 Tom Lane <tgl@sss.pgh.pa.us> 2012-12-10 Tom Lane <tgl@sss.pgh.pa.us>
* libtiff/tif_pixarlog.c: Improve previous patch for CVE-2012-4447 * libtiff/tif_pixarlog.c: Improve previous patch for CVE-2012-4447

View File

@ -1,4 +1,4 @@
/* $Id: ppm2tiff.c,v 1.17 2012-11-02 05:13:24 fwarmerdam Exp $ */ /* $Id: ppm2tiff.c,v 1.18 2012-12-10 18:19:11 tgl Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -72,6 +72,17 @@ BadPPM(char* file)
exit(-2); exit(-2);
} }
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
tmsize_t bytes = m1 * m2;
if (m1 && bytes / m1 != m2)
bytes = 0;
return bytes;
}
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
@ -79,7 +90,7 @@ main(int argc, char* argv[])
uint32 rowsperstrip = (uint32) -1; uint32 rowsperstrip = (uint32) -1;
double resolution = -1; double resolution = -1;
unsigned char *buf = NULL; unsigned char *buf = NULL;
tsize_t linebytes = 0; tmsize_t linebytes = 0;
uint16 spp = 1; uint16 spp = 1;
uint16 bpp = 8; uint16 bpp = 8;
TIFF *out; TIFF *out;
@ -222,7 +233,8 @@ main(int argc, char* argv[])
} }
switch (bpp) { switch (bpp) {
case 1: case 1:
linebytes = (spp * w + (8 - 1)) / 8; /* if round-up overflows, result will be zero, OK */
linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8;
if (rowsperstrip == (uint32) -1) { if (rowsperstrip == (uint32) -1) {
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h);
} else { } else {
@ -231,22 +243,30 @@ main(int argc, char* argv[])
} }
break; break;
case 8: case 8:
linebytes = spp * w; linebytes = multiply_ms(spp, w);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip)); TIFFDefaultStripSize(out, rowsperstrip));
break; break;
} }
if (TIFFScanlineSize(out) > linebytes) if (linebytes == 0) {
buf = (unsigned char *)_TIFFmalloc(linebytes);
else {
scanline_size = TIFFScanlineSize(out);
if (scanline_size != 0)
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
else {
fprintf(stderr, "%s: scanline size overflow\n", infile); fprintf(stderr, "%s: scanline size overflow\n", infile);
(void) TIFFClose(out); (void) TIFFClose(out);
exit(-2); exit(-2);
} }
scanline_size = TIFFScanlineSize(out);
if (scanline_size == 0) {
/* overflow - TIFFScanlineSize already printed a message */
(void) TIFFClose(out);
exit(-2);
}
if (scanline_size < linebytes)
buf = (unsigned char *)_TIFFmalloc(linebytes);
else
buf = (unsigned char *)_TIFFmalloc(scanline_size);
if (buf == NULL) {
fprintf(stderr, "%s: Not enough memory\n", infile);
(void) TIFFClose(out);
exit(-2);
} }
if (resolution > 0) { if (resolution > 0) {
TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution);