OLD | NEW |
(Empty) | |
| 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 */ |
OLD | NEW |