Home | History | Annotate | Download | only in libtiff
      1 From aaab5c3c9d2a2c6984f23ccbc79702610439bc65 Mon Sep 17 00:00:00 2001
      2 From: erouault <erouault>
      3 Date: Sun, 27 Dec 2015 16:25:11 +0000
      4 Subject: [PATCH] * libtiff/tif_luv.c: fix potential out-of-bound writes in
      5  decode functions in non debug builds by replacing assert()s by regular if
      6  checks (bugzilla #2522). Fix potential out-of-bound reads in case of short
      7  input data.
      8 
      9 ---
     10  ChangeLog         |  7 +++++++
     11  libtiff/tif_luv.c | 55 ++++++++++++++++++++++++++++++++++++++++++++-----------
     12  2 files changed, 51 insertions(+), 11 deletions(-)
     13 
     14 Index: tiff-4.0.3/libtiff/tif_luv.c
     15 ===================================================================
     16 --- tiff-4.0.3.orig/libtiff/tif_luv.c	2016-03-23 10:13:56.868540963 -0400
     17 +++ tiff-4.0.3/libtiff/tif_luv.c	2016-03-23 10:13:56.864540914 -0400
     18 @@ -202,7 +202,11 @@
     19  	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
     20  		tp = (int16*) op;
     21  	else {
     22 -		assert(sp->tbuflen >= npixels);
     23 +		if(sp->tbuflen < npixels) {
     24 +			TIFFErrorExt(tif->tif_clientdata, module,
     25 +						 "Translation buffer too short");
     26 +			return (0);
     27 +		}
     28  		tp = (int16*) sp->tbuf;
     29  	}
     30  	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
     31 @@ -211,9 +215,11 @@
     32  	cc = tif->tif_rawcc;
     33  	/* get each byte string */
     34  	for (shft = 2*8; (shft -= 8) >= 0; ) {
     35 -		for (i = 0; i < npixels && cc > 0; )
     36 +		for (i = 0; i < npixels && cc > 0; ) {
     37  			if (*bp >= 128) {		/* run */
     38 -				rc = *bp++ + (2-128);   /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
     39 +				if( cc < 2 )
     40 +					break;
     41 +				rc = *bp++ + (2-128);
     42  				b = (int16)(*bp++ << shft);
     43  				cc -= 2;
     44  				while (rc-- && i < npixels)
     45 @@ -223,6 +229,7 @@
     46  				while (--cc && rc-- && i < npixels)
     47  					tp[i++] |= (int16)*bp++ << shft;
     48  			}
     49 +		}
     50  		if (i != npixels) {
     51  #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
     52  			TIFFErrorExt(tif->tif_clientdata, module,
     53 @@ -268,13 +275,17 @@
     54  	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
     55  		tp = (uint32 *)op;
     56  	else {
     57 -		assert(sp->tbuflen >= npixels);
     58 +		if(sp->tbuflen < npixels) {
     59 +			TIFFErrorExt(tif->tif_clientdata, module,
     60 +						 "Translation buffer too short");
     61 +			return (0);
     62 +		}
     63  		tp = (uint32 *) sp->tbuf;
     64  	}
     65  	/* copy to array of uint32 */
     66  	bp = (unsigned char*) tif->tif_rawcp;
     67  	cc = tif->tif_rawcc;
     68 -	for (i = 0; i < npixels && cc > 0; i++) {
     69 +	for (i = 0; i < npixels && cc >= 3; i++) {
     70  		tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
     71  		bp += 3;
     72  		cc -= 3;
     73 @@ -325,7 +336,11 @@
     74  	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
     75  		tp = (uint32*) op;
     76  	else {
     77 -		assert(sp->tbuflen >= npixels);
     78 +		if(sp->tbuflen < npixels) {
     79 +			TIFFErrorExt(tif->tif_clientdata, module,
     80 +						 "Translation buffer too short");
     81 +			return (0);
     82 +		}
     83  		tp = (uint32*) sp->tbuf;
     84  	}
     85  	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
     86 @@ -334,11 +349,13 @@
     87  	cc = tif->tif_rawcc;
     88  	/* get each byte string */
     89  	for (shft = 4*8; (shft -= 8) >= 0; ) {
     90 -		for (i = 0; i < npixels && cc > 0; )
     91 +		for (i = 0; i < npixels && cc > 0; ) {
     92  			if (*bp >= 128) {		/* run */
     93 +				if( cc < 2 )
     94 +					break;
     95  				rc = *bp++ + (2-128);
     96  				b = (uint32)*bp++ << shft;
     97 -				cc -= 2;                /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
     98 +				cc -= 2;
     99  				while (rc-- && i < npixels)
    100  					tp[i++] |= b;
    101  			} else {			/* non-run */
    102 @@ -346,6 +363,7 @@
    103  				while (--cc && rc-- && i < npixels)
    104  					tp[i++] |= (uint32)*bp++ << shft;
    105  			}
    106 +		}
    107  		if (i != npixels) {
    108  #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    109  			TIFFErrorExt(tif->tif_clientdata, module,
    110 @@ -407,6 +425,7 @@
    111  static int
    112  LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
    113  {
    114 +	static const char module[] = "LogL16Encode";
    115  	LogLuvState* sp = EncoderState(tif);
    116  	int shft;
    117  	tmsize_t i;
    118 @@ -427,7 +446,11 @@
    119  		tp = (int16*) bp;
    120  	else {
    121  		tp = (int16*) sp->tbuf;
    122 -		assert(sp->tbuflen >= npixels);
    123 +		if(sp->tbuflen < npixels) {
    124 +			TIFFErrorExt(tif->tif_clientdata, module,
    125 +						 "Translation buffer too short");
    126 +			return (0);
    127 +		}
    128  		(*sp->tfunc)(sp, bp, npixels);
    129  	}
    130  	/* compress each byte string */
    131 @@ -500,6 +523,7 @@
    132  static int
    133  LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
    134  {
    135 +	static const char module[] = "LogLuvEncode24";
    136  	LogLuvState* sp = EncoderState(tif);
    137  	tmsize_t i;
    138  	tmsize_t npixels;
    139 @@ -515,7 +539,11 @@
    140  		tp = (uint32*) bp;
    141  	else {
    142  		tp = (uint32*) sp->tbuf;
    143 -		assert(sp->tbuflen >= npixels);
    144 +		if(sp->tbuflen < npixels) {
    145 +			TIFFErrorExt(tif->tif_clientdata, module,
    146 +						 "Translation buffer too short");
    147 +			return (0);
    148 +		}
    149  		(*sp->tfunc)(sp, bp, npixels);
    150  	}
    151  	/* write out encoded pixels */
    152 @@ -547,6 +575,7 @@
    153  static int
    154  LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
    155  {
    156 +	static const char module[] = "LogLuvEncode32";
    157  	LogLuvState* sp = EncoderState(tif);
    158  	int shft;
    159  	tmsize_t i;
    160 @@ -568,7 +597,11 @@
    161  		tp = (uint32*) bp;
    162  	else {
    163  		tp = (uint32*) sp->tbuf;
    164 -		assert(sp->tbuflen >= npixels);
    165 +		if(sp->tbuflen < npixels) {
    166 +			TIFFErrorExt(tif->tif_clientdata, module,
    167 +						 "Translation buffer too short");
    168 +			return (0);
    169 +		}
    170  		(*sp->tfunc)(sp, bp, npixels);
    171  	}
    172  	/* compress each byte string */
    173