CVE-2016-10269: Out-of-bounds Read (CWE-125)
value: LibTIFF 4.0.0alpha4, 4.0.0alpha5, 4.0.0alpha6, 4.0.0beta7, 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.4beta, 4.0.5, 4.0.6 and 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.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2017-03-24T19:59Z
Repository: https://github.com/vadz/libtiff
Language: C
Files changed: ChangeLog, libtiff/tif_luv.c, libtiff/tif_pixarlog.c
Commit date: 2016-12-02 23:05:51 +0000
Commit message: * 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

Diff: diff --git a/ChangeLog b/ChangeLog
index 0f154d662..93c01f80e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
+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.
diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c
index f68a9b13b..e6783db56 100644
--- a/libtiff/tif_luv.c
+++ b/libtiff/tif_luv.c
@@ -156,10 +156,11 @@
  * file using LogLuv compression/decompression.
  */
 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 */
 
 	uint8*                  tbuf;           /* translation buffer */
@@ -1550,10 +1551,11 @@ LogLuvSetupEncode(TIFF* tif)
 		TIFFErrorExt(tif->tif_clientdata, module,
 		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
 		    td->td_photometric, "must be either LogLUV or LogL");
 		break;
 	}
+	sp->encoder_state = 1;
 	return (1);
 notsupported:
 	TIFFErrorExt(tif->tif_clientdata, module,
 	    "SGILog compression supported only for %s, or raw data",
 	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
@@ -1561,23 +1563,31 @@ 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
 LogLuvCleanup(TIFF* tif)
 {
diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
index d1246c3df..aa99bc920 100644
--- a/libtiff/tif_pixarlog.c
+++ b/libtiff/tif_pixarlog.c
@@ -1231,22 +1231,35 @@ 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
 	 * modify both bitspersample and sampleformat in the directory to
 	 * indicate 8-bit linear.  This way, the decode "just works" even for
 	 * 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
 PixarLogCleanup(TIFF* tif)
 {

Vulnerable code: 	td->td_samplesperpixel =
	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
	td->td_bitspersample = 16;
	td->td_sampleformat = SAMPLEFORMAT_INT;
	td->td_bitspersample = 8;
	td->td_sampleformat = SAMPLEFORMAT_UINT;
Fixed code: 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

        int                     encoder_state;  /* 1 if encoder correctly initialized */
	sp->encoder_state = 1;
        LogLuvState* sp = (LogLuvState*) tif->tif_data;
	assert(sp != 0);
         * Note: this is really a nasty approach. See PixarLogClose
        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;
        }
        PixarLogState* sp = (PixarLogState*) tif->tif_data;
	assert(sp != 0);

        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;
        }