180 lines
5.4 KiB

# --- SDE-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
#
# Filename: package/.../libtiff/libtiff-4.0.3-0103-CVE-2013-1960.patch
# Copyright (C) 2013 The OpenSDE Project
#
# More information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- SDE-COPYRIGHT-NOTE-END ---
From 249e097cacd9d25d9579d7e1b46a82fd0032585d Mon Sep 17 00:00:00 2001
From: tgl <tgl>
Date: Thu, 2 May 2013 14:54:08 +0000
Subject: [PATCH] Rewrite t2p_process_jpeg_strip(), to fix CVE-2013-1960.
----------------------------------------------------------------------------
2013-05-02 Tom Lane <tgl@sss.pgh.pa.us>
* tools/tiff2pdf.c: Rewrite JPEG marker parsing in
t2p_process_jpeg_strip to be at least marginally competent. The
approach is still fundamentally flawed, but at least now it won't
stomp all over memory when given bogus input. Fixes CVE-2013-1960.
----------------------------------------------------------------------------
diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
index b9a6075..5c424b4 100644
--- a/tools/tiff2pdf.c
+++ b/tools/tiff2pdf.c
@@ -3341,33 +3341,56 @@ int t2p_process_jpeg_strip(
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 @@ int t2p_process_jpeg_strip(
(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
--
1.7.10.2