From 7c39352ccd9060d311d3dc9a1f1bc00133a160e6 Mon Sep 17 00:00:00 2001 From: erouault Date: Mon, 15 Aug 2016 20:06:40 +0000 Subject: [PATCH] * tools/tiff2rgba.c: Fix integer overflow in size of allocated buffer, when -b mode is enabled, that could result in out-of-bounds write. Based initially on patch tiff-CVE-2016-3945.patch from libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro, with correction for invalid tests that rejected valid files. CVE: CVE-2016-3945 Upstream-Status: Backport https://github.com/vadz/libtiff/commit/7c39352ccd9060d311d3dc9a1f1bc00133a160e6 Signed-off-by: Yi Zhao --- ChangeLog | 8 ++++++++ tools/tiff2rgba.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62dc1b5..9c0ab29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-08-15 Even Rouault + + * tools/tiff2rgba.c: Fix integer overflow in size of allocated + buffer, when -b mode is enabled, that could result in out-of-bounds + write. Based initially on patch tiff-CVE-2016-3945.patch from + libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro, with correction for + invalid tests that rejected valid files. + 2016-07-11 Even Rouault * tools/tiffcrop.c: Avoid access outside of stack allocated array diff --git a/tools/tiff2rgba.c b/tools/tiff2rgba.c index b7a81eb..16e3dc4 100644 --- a/tools/tiff2rgba.c +++ b/tools/tiff2rgba.c @@ -147,6 +147,7 @@ cvt_by_tile( TIFF *in, TIFF *out ) uint32 row, col; uint32 *wrk_line; int ok = 1; + uint32 rastersize, wrk_linesize; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); @@ -163,7 +164,13 @@ cvt_by_tile( TIFF *in, TIFF *out ) /* * Allocate tile buffer */ - raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32)); + rastersize = tile_width * tile_height * sizeof (uint32); + if (tile_width != (rastersize / tile_height) / sizeof( uint32)) + { + TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); + exit(-1); + } + raster = (uint32*)_TIFFmalloc(rastersize); if (raster == 0) { TIFFError(TIFFFileName(in), "No space for raster buffer"); return (0); @@ -173,7 +180,13 @@ cvt_by_tile( TIFF *in, TIFF *out ) * Allocate a scanline buffer for swapping during the vertical * mirroring pass. */ - wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32)); + wrk_linesize = tile_width * sizeof (uint32); + if (tile_width != wrk_linesize / sizeof (uint32)) + { + TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); + exit(-1); + } + wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); if (!wrk_line) { TIFFError(TIFFFileName(in), "No space for raster scanline buffer"); ok = 0; @@ -249,6 +262,7 @@ cvt_by_strip( TIFF *in, TIFF *out ) uint32 row; uint32 *wrk_line; int ok = 1; + uint32 rastersize, wrk_linesize; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); @@ -263,7 +277,13 @@ cvt_by_strip( TIFF *in, TIFF *out ) /* * Allocate strip buffer */ - raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32)); + rastersize = width * rowsperstrip * sizeof (uint32); + if (width != (rastersize / rowsperstrip) / sizeof( uint32)) + { + TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); + exit(-1); + } + raster = (uint32*)_TIFFmalloc(rastersize); if (raster == 0) { TIFFError(TIFFFileName(in), "No space for raster buffer"); return (0); @@ -273,7 +293,13 @@ cvt_by_strip( TIFF *in, TIFF *out ) * Allocate a scanline buffer for swapping during the vertical * mirroring pass. */ - wrk_line = (uint32*)_TIFFmalloc(width * sizeof (uint32)); + wrk_linesize = width * sizeof (uint32); + if (width != wrk_linesize / sizeof (uint32)) + { + TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); + exit(-1); + } + wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); if (!wrk_line) { TIFFError(TIFFFileName(in), "No space for raster scanline buffer"); ok = 0; -- 2.7.4