Apply CVE patches 26/134326/2 accepted/tizen/4.0/unified/20170816.011716 accepted/tizen/4.0/unified/20170828.221613 accepted/tizen/unified/20170703.063912 submit/tizen/20170619.015819 submit/tizen/20170626.233913 submit/tizen_4.0/20170811.094300 submit/tizen_4.0/20170828.100007 tizen_4.0.IoT.p1_release tizen_4.0.IoT.p2_release tizen_4.0.m2_release
authorJiyong Min <jiyong.min@samsung.com>
Fri, 16 Jun 2017 04:16:40 +0000 (13:16 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Fri, 16 Jun 2017 04:24:18 +0000 (13:24 +0900)
CVE-2016-10092
Heap-based buffer overflow in the readContigStripsIntoBuffer function in tif_unix.c
in LibTIFF 4.0.7 allows remote attackers to have unspecified impact via a crafted image.

CVE-2016-10093
Integer overflow in tools/tiffcp.c in LibTIFF 4.0.7 allows remote attackers to have
unspecified impact via a crafted image, which triggers a heap-based buffer overflow.

CVE-2016-10266
LibTIFF 4.0.7 allows remote attackers to cause a denial of service (divide-by-zero
error and application crash) via a crafted TIFF image, related to libtiff/tif_read.c:351:22.

CVE-2016-10267
LibTIFF 4.0.7 allows remote attackers to cause a denial of service (divide-by-zero
error and application crash) via a crafted TIFF image, related to libtiff/tif_ojpeg.c:816:8.

CVE-2016-10268
tools/tiffcp.c in LibTIFF 4.0.7 allows remote attackers to cause a denial of service
(integer underflow and heap-based buffer under-read) or possibly have unspecified other
impact via a crafted TIFF image, related to "READ of size 78490" and libtiff/tif_unix.c:115:23.

CVE-2016-10269
LibTIFF 4.0.7 allows remote attackers to cause a denial of service (heap-based buffer
over-read) or possibly have unspecified other impact via a crafted TIFF image,
related to "READ of size 512" and libtiff/tif_unix.c:340:2.

CVE-2016-10270
LibTIFF 4.0.7 allows remote attackers to cause a denial of service (heap-based buffer
over-read) or possibly have unspecified other impact via a crafted TIFF image,
related to "READ of size 8" and libtiff/tif_read.c:523:22.

CVE-2016-10271
tools/tiffcrop.c in LibTIFF 4.0.7 allows remote attackers to cause a denial of service
(heap-based buffer over-read and buffer overflow) or possibly have unspecified other
impact via a crafted TIFF image, related to "READ of size 1" and libtiff/tif_fax3.c:413:13.

CVE-2016-10272
LibTIFF 4.0.7 allows remote attackers to cause a denial of service (heap-based buffer
overflow) or possibly have unspecified other impact via a crafted TIFF image,
related to "WRITE of size 2048" and libtiff/tif_next.c:64:9.

CVE-2017-5225
LibTIFF version 4.0.7 is vulnerable to a heap buffer overflow in the tools/tiffcp
resulting in DoS or code execution via a crafted BitsPerSample value.

Change-Id: I434b78119e17f22d6b2fd23cdeecfca5d8fce567
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
ChangeLog
libtiff/tif_dirread.c [changed mode: 0644->0755]
libtiff/tif_luv.c [changed mode: 0644->0755]
libtiff/tif_ojpeg.c [changed mode: 0644->0755]
libtiff/tif_pixarlog.c
libtiff/tif_read.c [changed mode: 0644->0755]
libtiff/tif_strip.c [changed mode: 0644->0755]
libtiff/tiffiop.h [changed mode: 0644->0755]
tools/tiffcp.c [changed mode: 0644->0755]
tools/tiffcrop.c [changed mode: 0644->0755]

index 9b9d397..893fa24 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+       * tools/tiffcp.c: error out cleanly in cpContig2SeparateByRow and
+       cpSeparate2ContigByRow if BitsPerSample != 8 to avoid heap based overflow.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2656 and
+       http://bugzilla.maptools.org/show_bug.cgi?id=2657
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+       * tools/tiffcp.c: fix uint32 underflow/overflow that can cause heap-based
+       buffer overflow.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2610
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+       * tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i (ignore) mode so
+       that the output buffer is correctly incremented to avoid write outside bounds.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2620
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+       * libtiff/tif_ojpeg.c: make OJPEGDecode() early exit in case of failure in
+       OJPEGPreDecode(). This will avoid a divide by zero, and potential other issues.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2611
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+       * libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to
+       instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip),
+       instead of a logic based on the total size of data. Which is faulty is
+       the total size of data is not sufficient to fill the whole image, and thus
+       results in reading outside of the StripByCounts/StripOffsets arrays when
+       using TIFFReadScanline().
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608.
+
+       * libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done
+       for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since
+       the above change is a better fix that makes it unnecessary.
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+       * libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based buffer
+       overflow on generation of PixarLog / LUV compressed files, with
+       ColorMap, TransferFunction attached and nasty plays with bitspersample.
+       The fix for LUV has not been tested, but suffers from the same kind
+       of issue of PixarLog.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2604
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+       * tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that
+       can cause various issues, such as buffer overflows in the library.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2598
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+       * libtiff/tif_read.c, libtiff/tiffiop.h: fix uint32 overflow in
+       TIFFReadEncodedStrip() that caused an integer division by zero.
+       Reported by Agostino Sarubbo.
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2596
+
 2016-11-19  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
        * libtiff 4.0.7 released.
        writeBufferToSeparateStrips(), writeBufferToContigTiles() and
        writeBufferToSeparateTiles() that could cause heap buffer overflows.
        Reported by Henri Salo from Nixu Corporation.
-       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592
+       Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592 (CVE-2016-9532)
 
 2016-11-10 Even Rouault <even.rouault at spatialys.com>
 
old mode 100644 (file)
new mode 100755 (executable)
index 01070f2..b984e0c
@@ -5502,8 +5502,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
        uint64 rowblockbytes;
        uint64 stripbytes;
        uint32 strip;
-       uint64 nstrips64;
-       uint32 nstrips32;
+       uint64 nstrips;
        uint32 rowsperstrip;
        uint64* newcounts;
        uint64* newoffsets;
@@ -5534,18 +5533,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
            return;
 
        /*
-        * never increase the number of strips in an image
+        * never increase the number of rows per strip
         */
        if (rowsperstrip >= td->td_rowsperstrip)
                return;
-       nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
-       if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
+       nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+       if ( nstrips==0 )
            return;
-       nstrips32 = (uint32)nstrips64;
 
-       newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+       newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
                                "for chopped \"StripByteCounts\" array");
-       newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+       newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
                                "for chopped \"StripOffsets\" array");
        if (newcounts == NULL || newoffsets == NULL) {
                /*
@@ -5562,18 +5560,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
         * Fill the strip information arrays with new bytecounts and offsets
         * that reflect the broken-up format.
         */
-       for (strip = 0; strip < nstrips32; strip++) {
+       for (strip = 0; strip < nstrips; strip++) {
                if (stripbytes > bytecount)
                        stripbytes = bytecount;
                newcounts[strip] = stripbytes;
-               newoffsets[strip] = offset;
+               newoffsets[strip] = stripbytes ? offset : 0;;
                offset += stripbytes;
                bytecount -= stripbytes;
        }
        /*
         * Replace old single strip info with multi-strip info.
         */
-       td->td_stripsperimage = td->td_nstrips = nstrips32;
+       td->td_stripsperimage = td->td_nstrips = nstrips;
        TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
        _TIFFfree(td->td_stripbytecount);
old mode 100644 (file)
new mode 100755 (executable)
index ca08f30..a3b73cc
 typedef struct logLuvState LogLuvState;
 
 struct logLuvState {
+       int                     encoder_state;   /* 1 if encoder correctly initialized */
        int                     user_datafmt;   /* user data format */
        int                     encode_meth;    /* encoding method */
        int                     pixel_size;     /* bytes per pixel */
@@ -1552,6 +1553,7 @@ LogLuvSetupEncode(TIFF* tif)
                    td->td_photometric, "must be either LogLUV or LogL");
                break;
        }
+       sp->encoder_state = 1;
        return (1);
 notsupported:
        TIFFErrorExt(tif->tif_clientdata, module,
@@ -1563,19 +1565,27 @@ notsupported:
 static void
 LogLuvClose(TIFF* tif)
 {
+       LogLuvState *sp = (LogLuvState*) tif->tif_data;
        TIFFDirectory *td = &tif->tif_dir;
 
+       assert(sp != 0);
        /*
         * For consistency, we always want to write out the same
         * bitspersample and sampleformat for our TIFF file,
         * regardless of the data format being used by the application.
         * Since this routine is called after tags have been set but
         * before they have been recorded in the file, we reset them here.
+        * Note: this is really a nasty approach. See PixarLogClose
         */
-       td->td_samplesperpixel =
-           (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-       td->td_bitspersample = 16;
-       td->td_sampleformat = SAMPLEFORMAT_INT;
+        if( sp->encoder_state )
+        {
+            /* See PixarLogClose. Might avoid issues with tags whose size depends
+             * on those below, but not completely sure this is enough. */
+            td->td_samplesperpixel =
+                (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+            td->td_bitspersample = 16;
+            td->td_sampleformat = SAMPLEFORMAT_INT;
+        }
 }
 
 static void
old mode 100644 (file)
new mode 100755 (executable)
index 30a1812..01b672a
@@ -244,6 +244,7 @@ typedef enum {
 
 typedef struct {
        TIFF* tif;
+       int decoder_ok;
        #ifndef LIBJPEG_ENCAP_EXTERNAL
        JMP_BUF exit_jmpbuf;
        #endif
@@ -722,6 +723,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
                }
                sp->write_curstrile++;
        }
+       sp->decoder_ok = 1;
        return(1);
 }
 
@@ -784,8 +786,14 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif)
 static int
 OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 {
+       static const char module[]="OJPEGDecode";
        OJPEGState* sp=(OJPEGState*)tif->tif_data;
        (void)s;
+       if ( !sp->decoder_ok )
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
+               return 0;
+       }
        if (sp->libjpeg_jpeg_query_style==0)
        {
                if (OJPEGDecodeRaw(tif,buf,cc)==0)
index f4af2ba..d3e1f61 100755 (executable)
@@ -1233,8 +1233,10 @@ PixarLogPostEncode(TIFF* tif)
 static void
 PixarLogClose(TIFF* tif)
 {
+       PixarLogState* sp = (PixarLogState*) tif->tif_data;
        TIFFDirectory *td = &tif->tif_dir;
 
+       assert(sp != 0);
        /* In a really sneaky (and really incorrect, and untruthful, and
         * troublesome, and error-prone) maneuver that completely goes against
         * the spirit of TIFF, and breaks TIFF, on close, we covertly
@@ -1243,8 +1245,18 @@ PixarLogClose(TIFF* tif)
         * readers that don't know about PixarLog, or how to set
         * the PIXARLOGDATFMT pseudo-tag.
         */
-       td->td_bitspersample = 8;
-       td->td_sampleformat = SAMPLEFORMAT_UINT;
+        if (sp->state&PLSTATE_INIT) {
+            /* We test the state to avoid an issue such as in
+             * http://bugzilla.maptools.org/show_bug.cgi?id=2604
+             * What appends in that case is that the bitspersample is 1 and
+             * a TransferFunction is set. The size of the TransferFunction
+             * depends on 1<<bitspersample. So if we increase it, an access
+             * out of the buffer will happen at directory flushing.
+             * Another option would be to clear those targs. 
+             */
+            td->td_bitspersample = 8;
+            td->td_sampleformat = SAMPLEFORMAT_UINT;
+        }
 }
 
 static void
old mode 100644 (file)
new mode 100755 (executable)
index 8003592..20def61
@@ -346,7 +346,7 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
        rowsperstrip=td->td_rowsperstrip;
        if (rowsperstrip>td->td_imagelength)
                rowsperstrip=td->td_imagelength;
-       stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
+       stripsperplane=TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
        stripinplane=(strip%stripsperplane);
        plane=(uint16)(strip/stripsperplane);
        rows=td->td_imagelength-stripinplane*rowsperstrip;
old mode 100644 (file)
new mode 100755 (executable)
index b6098dd..3b55285
@@ -63,15 +63,6 @@ TIFFNumberOfStrips(TIFF* tif)
        TIFFDirectory *td = &tif->tif_dir;
        uint32 nstrips;
 
-    /* If the value was already computed and store in td_nstrips, then return it,
-       since ChopUpSingleUncompressedStrip might have altered and resized the
-       since the td_stripbytecount and td_stripoffset arrays to the new value
-       after the initial affectation of td_nstrips = TIFFNumberOfStrips() in
-       tif_dirread.c ~line 3612.
-       See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */
-    if( td->td_nstrips )
-        return td->td_nstrips;
-
        nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
             TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
        if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
old mode 100644 (file)
new mode 100755 (executable)
index aacb14f..20e6449
@@ -250,6 +250,10 @@ struct tiff {
 #define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
                           ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
                           0U)
+/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
+/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
+#define TIFFhowmany_32_maxuint_compat(x, y) \
+                                  (((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0))
 #define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
 #define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
 #define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
old mode 100644 (file)
new mode 100755 (executable)
index 338a3d1..2fe68fc
@@ -592,7 +592,7 @@ static      copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
 static int
 tiffcp(TIFF* in, TIFF* out)
 {
-       uint16 bitspersample, samplesperpixel = 1;
+       uint16 bitspersample = 1, samplesperpixel = 1;
        uint16 input_compression, input_photometric = PHOTOMETRIC_MINISBLACK;
        copyFunc cf;
        uint32 width, length;
@@ -985,7 +985,7 @@ DECLAREcpFunc(cpDecodedStrips)
                tstrip_t s, ns = TIFFNumberOfStrips(in);
                uint32 row = 0;
                _TIFFmemset(buf, 0, stripsize);
-               for (s = 0; s < ns; s++) {
+               for (s = 0; s < ns && row < imagelength; s++) {
                        tsize_t cc = (row + rowsperstrip > imagelength) ?
                            TIFFVStripSize(in, imagelength - row) : stripsize;
                        if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
@@ -1068,6 +1068,16 @@ DECLAREcpFunc(cpContig2SeparateByRow)
        register uint32 n;
        uint32 row;
        tsample_t s;
+       uint16 bps = 0;
+       
+       (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
+       if( bps != 8 )
+       {
+               TIFFError(TIFFFileName(in),
+                                 "Error, can only handle BitsPerSample=8 in %s",
+                                 "cpContig2SeparateByRow");
+               return 0;
+       }
 
        inbuf = _TIFFmalloc(scanlinesizein);
        outbuf = _TIFFmalloc(scanlinesizeout);
@@ -1121,6 +1131,16 @@ DECLAREcpFunc(cpSeparate2ContigByRow)
        register uint32 n;
        uint32 row;
        tsample_t s;
+       uint16 bps = 0;
+       
+       (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
+       if( bps != 8 )
+       {
+               TIFFError(TIFFFileName(in),
+                                 "Error, can only handle BitsPerSample=8 in %s",
+                                 "cpSeparate2ContigByRow");
+               return 0;
+       }
 
        inbuf = _TIFFmalloc(scanlinesizein);
        outbuf = _TIFFmalloc(scanlinesizeout);
@@ -1163,7 +1183,7 @@ bad:
 
 static void
 cpStripToTile(uint8* out, uint8* in,
-    uint32 rows, uint32 cols, int outskew, int inskew)
+    uint32 rows, uint32 cols, int outskew, int64 inskew)
 {
        while (rows-- > 0) {
                uint32 j = cols;
@@ -1320,7 +1340,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer)
        tdata_t tilebuf;
        uint32 imagew = TIFFScanlineSize(in);
        uint32 tilew  = TIFFTileRowSize(in);
-       int iskew = imagew - tilew;
+       int64 iskew = (int64)imagew - (int64)tilew;
        uint8* bufp = (uint8*) buf;
        uint32 tw, tl;
        uint32 row;
@@ -1348,7 +1368,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer)
                                status = 0;
                                goto done;
                        }
-                       if (colb + tilew > imagew) {
+                       if (colb > iskew) {
                                uint32 width = imagew - colb;
                                uint32 oskew = tilew - width;
                                cpStripToTile(bufp + colb,
@@ -1763,7 +1783,7 @@ pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
        uint32 w, l, tw, tl;
        int bychunk;
 
-       (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
+       (void) TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &shortv);
        if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
                fprintf(stderr,
                    "%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
old mode 100644 (file)
new mode 100755 (executable)
index 722b132..ad2c00f
@@ -3698,7 +3698,7 @@ static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
                                   (unsigned long) strip, (unsigned long)rows);
                         return 0;
                 }
-                bufp += bytes_read;
+                bufp += stripsize;
         }
 
         return 1;