libtiff: fix CVE-2013-1960
authorMing Liu <ming.liu@windriver.com>
Thu, 5 Dec 2013 23:52:14 +0000 (17:52 -0600)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Tue, 10 Dec 2013 17:42:44 +0000 (17:42 +0000)
Heap-based buffer overflow in the tp_process_jpeg_strip function in tiff2pdf
in libtiff 4.0.3 and earlier allows remote attackers to cause a denial of
service (crash) and possibly execute arbitrary code via a crafted TIFF image
file.

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-1960

(From OE-Core rev: 9db7a897d216a8293152c1a3b96c72b699d469c7)

Signed-off-by: Ming Liu <ming.liu@windriver.com>
Signed-off-by: Jeff Polk <jeff.polk@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
meta/recipes-multimedia/libtiff/files/libtiff-CVE-2013-1960.patch [new file with mode: 0644]
meta/recipes-multimedia/libtiff/tiff_4.0.3.bb

diff --git a/meta/recipes-multimedia/libtiff/files/libtiff-CVE-2013-1960.patch b/meta/recipes-multimedia/libtiff/files/libtiff-CVE-2013-1960.patch
new file mode 100644 (file)
index 0000000..e4348f1
--- /dev/null
@@ -0,0 +1,151 @@
+This patch comes from: http://pkgs.fedoraproject.org/cgit/libtiff.git/plain/libtiff-CVE-2013-1960.patch
+
+Upstream-Status: Pending
+
+Signed-off-by: Ming Liu <ming.liu@windriver.com>
+
+diff -Naur a/tools/tiff2pdf.c b/tools/tiff2pdf.c
+--- a/tools/tiff2pdf.c 2012-07-25 22:56:43.000000000 -0400
++++ b/tools/tiff2pdf.c 2013-05-02 12:04:49.057090227 -0400
+@@ -3341,33 +3341,56 @@
+       uint32 height){
+       tsize_t i=0;
+-      uint16 ri =0;
+-      uint16 v_samp=1;
+-      uint16 h_samp=1;
+-      int j=0;
+-      
+-      i++;
+-      
+-      while(i<(*striplength)){
++
++      while (i < *striplength) {
++              tsize_t datalen;
++              uint16 ri;
++              uint16 v_samp;
++              uint16 h_samp;
++              int j;
++              int ncomp;
++
++              /* marker header: one or more FFs */
++              if (strip[i] != 0xff)
++                      return(0);
++              i++;
++              while (i < *striplength && strip[i] == 0xff)
++                      i++;
++              if (i >= *striplength)
++                      return(0);
++              /* SOI is the only pre-SOS marker without a length word */
++              if (strip[i] == 0xd8)
++                      datalen = 0;
++              else {
++                      if ((*striplength - i) <= 2)
++                              return(0);
++                      datalen = (strip[i+1] << 8) | strip[i+2];
++                      if (datalen < 2 || datalen >= (*striplength - i))
++                              return(0);
++              }
+               switch( strip[i] ){
+-                      case 0xd8:
+-                              /* SOI - start of image */
++                      case 0xd8:      /* SOI - start of image */
+                               _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2);
+                               *bufferoffset+=2;
+-                              i+=2;
+                               break;
+-                      case 0xc0:
+-                      case 0xc1:
+-                      case 0xc3:
+-                      case 0xc9:
+-                      case 0xca:
++                      case 0xc0:      /* SOF0 */
++                      case 0xc1:      /* SOF1 */
++                      case 0xc3:      /* SOF3 */
++                      case 0xc9:      /* SOF9 */
++                      case 0xca:      /* SOF10 */
+                               if(no==0){
+-                                      _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
+-                                      for(j=0;j<buffer[*bufferoffset+9];j++){
+-                                              if( (buffer[*bufferoffset+11+(2*j)]>>4) > h_samp) 
+-                                                      h_samp = (buffer[*bufferoffset+11+(2*j)]>>4);
+-                                              if( (buffer[*bufferoffset+11+(2*j)] & 0x0f) > v_samp) 
+-                                                      v_samp = (buffer[*bufferoffset+11+(2*j)] & 0x0f);
++                                      _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
++                                      ncomp = buffer[*bufferoffset+9];
++                                      if (ncomp < 1 || ncomp > 4)
++                                              return(0);
++                                      v_samp=1;
++                                      h_samp=1;
++                                      for(j=0;j<ncomp;j++){
++                                              uint16 samp = buffer[*bufferoffset+11+(3*j)];
++                                              if( (samp>>4) > h_samp) 
++                                                      h_samp = (samp>>4);
++                                              if( (samp & 0x0f) > v_samp) 
++                                                      v_samp = (samp & 0x0f);
+                                       }
+                                       v_samp*=8;
+                                       h_samp*=8;
+@@ -3381,45 +3404,43 @@
+                                           (unsigned char) ((height>>8) & 0xff);
+                                       buffer[*bufferoffset+6]=
+                                             (unsigned char) (height & 0xff);
+-                                      *bufferoffset+=strip[i+2]+2;
+-                                      i+=strip[i+2]+2;
+-
++                                      *bufferoffset+=datalen+2;
++                                      /* insert a DRI marker */
+                                       buffer[(*bufferoffset)++]=0xff;
+                                       buffer[(*bufferoffset)++]=0xdd;
+                                       buffer[(*bufferoffset)++]=0x00;
+                                       buffer[(*bufferoffset)++]=0x04;
+                                       buffer[(*bufferoffset)++]=(ri >> 8) & 0xff;
+                                       buffer[(*bufferoffset)++]= ri & 0xff;
+-                              } else {
+-                                      i+=strip[i+2]+2;
+                               }
+                               break;
+-                      case 0xc4:
+-                      case 0xdb:
+-                              _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
+-                              *bufferoffset+=strip[i+2]+2;
+-                              i+=strip[i+2]+2;
++                      case 0xc4: /* DHT */
++                      case 0xdb: /* DQT */
++                              _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
++                              *bufferoffset+=datalen+2;
+                               break;
+-                      case 0xda:
++                      case 0xda: /* SOS */
+                               if(no==0){
+-                                      _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
+-                                      *bufferoffset+=strip[i+2]+2;
+-                                      i+=strip[i+2]+2;
++                                      _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
++                                      *bufferoffset+=datalen+2;
+                               } else {
+                                       buffer[(*bufferoffset)++]=0xff;
+                                       buffer[(*bufferoffset)++]=
+                                             (unsigned char)(0xd0 | ((no-1)%8));
+-                                      i+=strip[i+2]+2;
+                               }
+-                              _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), (*striplength)-i-1);
+-                              *bufferoffset+=(*striplength)-i-1;
++                              i += datalen + 1;
++                              /* copy remainder of strip */
++                              _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i);
++                              *bufferoffset+= *striplength - i;
+                               return(1);
+                       default:
+-                              i+=strip[i+2]+2;
++                              /* ignore any other marker */
++                              break;
+               }
++              i += datalen + 1;
+       }
+-      
++      /* failed to find SOS marker */
+       return(0);
+ }
+ #endif
index c90b4b2..def408e 100644 (file)
@@ -5,7 +5,8 @@ HOMEPAGE = "http://www.remotesensing.org/libtiff/"
 DEPENDS = "zlib jpeg xz"
 
 SRC_URI = "ftp://ftp.remotesensing.org/pub/libtiff/tiff-${PV}.tar.gz \
-           file://libtool2.patch"
+           file://libtool2.patch \
+           file://libtiff-CVE-2013-1960.patch"
 
 SRC_URI[md5sum] = "051c1068e6a0627f461948c365290410"
 SRC_URI[sha256sum] = "ea1aebe282319537fb2d4d7805f478dd4e0e05c33d0928baba76a7c963684872"