Skip to content
This repository was archived by the owner on Dec 1, 2017. It is now read-only.

Commit 83a4b92

Browse files
author
erouault
committed
* tools/tiffcrop.c: fix various out-of-bounds write vulnerabilities
in heap or stack allocated buffers. Reported as MSVR 35093, MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * tools/tiff2pdf.c: fix out-of-bounds write vulnerabilities in heap allocate buffer in t2p_process_jpeg_strip(). Reported as MSVR 35098. Discovered by Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities in heap allocated buffers. Reported as MSVR 35094. Discovered by Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1() that didn't reset the tif_rawcc and tif_rawcp members. I'm not completely sure if that could happen in practice outside of the odd behaviour of t2p_seekproc() of tiff2pdf). The report points that a better fix could be to check the return value of TIFFFlushData1() in places where it isn't done currently, but it seems this patch is enough. Reported as MSVR 35095. Discovered by Axel Souchet & Vishal Chauhan & Suha Can from the MSRC Vulnerabilities & Mitigations team.
1 parent a402cdf commit 83a4b92

File tree

5 files changed

+92
-35
lines changed

5 files changed

+92
-35
lines changed

Diff for: ChangeLog

+23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
2016-09-23 Even Rouault <even.rouault at spatialys.com>
2+
3+
* tools/tiffcrop.c: fix various out-of-bounds write vulnerabilities
4+
in heap or stack allocated buffers. Reported as MSVR 35093,
5+
MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal
6+
Chauhan from the MSRC Vulnerabilities & Mitigations team.
7+
* tools/tiff2pdf.c: fix out-of-bounds write vulnerabilities in
8+
heap allocate buffer in t2p_process_jpeg_strip(). Reported as MSVR
9+
35098. Discovered by Axel Souchet and Vishal Chauhan from the MSRC
10+
Vulnerabilities & Mitigations team.
11+
* libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities
12+
in heap allocated buffers. Reported as MSVR 35094. Discovered by
13+
Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities &
14+
Mitigations team.
15+
* libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1()
16+
that didn't reset the tif_rawcc and tif_rawcp members. I'm not
17+
completely sure if that could happen in practice outside of the odd
18+
behaviour of t2p_seekproc() of tiff2pdf). The report points that a
19+
better fix could be to check the return value of TIFFFlushData1() in
20+
places where it isn't done currently, but it seems this patch is enough.
21+
Reported as MSVR 35095. Discovered by Axel Souchet & Vishal Chauhan &
22+
Suha Can from the MSRC Vulnerabilities & Mitigations team.
23+
124
2016-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
225

326
* html/man/index.html: Comment out links to documentation for

Diff for: libtiff/tif_pixarlog.c

+23-32
Original file line numberDiff line numberDiff line change
@@ -983,17 +983,14 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
983983
a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
984984
}
985985
} else {
986-
ip += n - 1; /* point to last one */
987-
wp += n - 1; /* point to last one */
988-
n -= stride;
989-
while (n > 0) {
990-
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
991-
wp[stride] -= wp[0];
992-
wp[stride] &= mask;
993-
wp--; ip--)
994-
n -= stride;
995-
}
996-
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
986+
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++)
987+
n -= stride;
988+
while (n > 0) {
989+
REPEAT(stride,
990+
wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask);
991+
wp++; ip++)
992+
n -= stride;
993+
}
997994
}
998995
}
999996
}
@@ -1036,17 +1033,14 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
10361033
a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
10371034
}
10381035
} else {
1039-
ip += n - 1; /* point to last one */
1040-
wp += n - 1; /* point to last one */
1036+
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
10411037
n -= stride;
10421038
while (n > 0) {
1043-
REPEAT(stride, wp[0] = CLAMP(ip[0]);
1044-
wp[stride] -= wp[0];
1045-
wp[stride] &= mask;
1046-
wp--; ip--)
1047-
n -= stride;
1048-
}
1049-
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
1039+
REPEAT(stride,
1040+
wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
1041+
wp++; ip++)
1042+
n -= stride;
1043+
}
10501044
}
10511045
}
10521046
}
@@ -1089,18 +1083,15 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
10891083
ip += 4;
10901084
}
10911085
} else {
1092-
wp += n + stride - 1; /* point to last one */
1093-
ip += n + stride - 1; /* point to last one */
1094-
n -= stride;
1095-
while (n > 0) {
1096-
REPEAT(stride, wp[0] = CLAMP(ip[0]);
1097-
wp[stride] -= wp[0];
1098-
wp[stride] &= mask;
1099-
wp--; ip--)
1100-
n -= stride;
1101-
}
1102-
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
1103-
}
1086+
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
1087+
n -= stride;
1088+
while (n > 0) {
1089+
REPEAT(stride,
1090+
wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
1091+
wp++; ip++)
1092+
n -= stride;
1093+
}
1094+
}
11041095
}
11051096
}
11061097

Diff for: libtiff/tif_write.c

+7
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,14 @@ TIFFFlushData1(TIFF* tif)
798798
if (!TIFFAppendToStrip(tif,
799799
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
800800
tif->tif_rawdata, tif->tif_rawcc))
801+
{
802+
/* We update those variables even in case of error since there's */
803+
/* code that doesn't really check the return code of this */
804+
/* function */
805+
tif->tif_rawcc = 0;
806+
tif->tif_rawcp = tif->tif_rawdata;
801807
return (0);
808+
}
802809
tif->tif_rawcc = 0;
803810
tif->tif_rawcp = tif->tif_rawdata;
804811
}

Diff for: tools/tiff2pdf.c

+20-2
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t);
286286
int t2p_process_ojpeg_tables(T2P*, TIFF*);
287287
#endif
288288
#ifdef JPEG_SUPPORT
289-
int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t*, tstrip_t, uint32);
289+
int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t, tsize_t*, tstrip_t, uint32);
290290
#endif
291291
void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32);
292292
void t2p_write_advance_directory(T2P*, TIFF*);
@@ -2408,7 +2408,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){
24082408
if(!t2p_process_jpeg_strip(
24092409
stripbuffer,
24102410
&striplength,
2411-
buffer,
2411+
buffer,
2412+
t2p->tiff_datasize,
24122413
&bufferoffset,
24132414
i,
24142415
t2p->tiff_length)){
@@ -3439,6 +3440,7 @@ int t2p_process_jpeg_strip(
34393440
unsigned char* strip,
34403441
tsize_t* striplength,
34413442
unsigned char* buffer,
3443+
tsize_t buffersize,
34423444
tsize_t* bufferoffset,
34433445
tstrip_t no,
34443446
uint32 height){
@@ -3473,6 +3475,8 @@ int t2p_process_jpeg_strip(
34733475
}
34743476
switch( strip[i] ){
34753477
case 0xd8: /* SOI - start of image */
3478+
if( *bufferoffset + 2 > buffersize )
3479+
return(0);
34763480
_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2);
34773481
*bufferoffset+=2;
34783482
break;
@@ -3482,12 +3486,18 @@ int t2p_process_jpeg_strip(
34823486
case 0xc9: /* SOF9 */
34833487
case 0xca: /* SOF10 */
34843488
if(no==0){
3489+
if( *bufferoffset + datalen + 2 + 6 > buffersize )
3490+
return(0);
34853491
_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
3492+
if( *bufferoffset + 9 >= buffersize )
3493+
return(0);
34863494
ncomp = buffer[*bufferoffset+9];
34873495
if (ncomp < 1 || ncomp > 4)
34883496
return(0);
34893497
v_samp=1;
34903498
h_samp=1;
3499+
if( *bufferoffset + 11 + 3*(ncomp-1) >= buffersize )
3500+
return(0);
34913501
for(j=0;j<ncomp;j++){
34923502
uint16 samp = buffer[*bufferoffset+11+(3*j)];
34933503
if( (samp>>4) > h_samp)
@@ -3519,20 +3529,28 @@ int t2p_process_jpeg_strip(
35193529
break;
35203530
case 0xc4: /* DHT */
35213531
case 0xdb: /* DQT */
3532+
if( *bufferoffset + datalen + 2 > buffersize )
3533+
return(0);
35223534
_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
35233535
*bufferoffset+=datalen+2;
35243536
break;
35253537
case 0xda: /* SOS */
35263538
if(no==0){
3539+
if( *bufferoffset + datalen + 2 > buffersize )
3540+
return(0);
35273541
_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
35283542
*bufferoffset+=datalen+2;
35293543
} else {
3544+
if( *bufferoffset + 2 > buffersize )
3545+
return(0);
35303546
buffer[(*bufferoffset)++]=0xff;
35313547
buffer[(*bufferoffset)++]=
35323548
(unsigned char)(0xd0 | ((no-1)%8));
35333549
}
35343550
i += datalen + 1;
35353551
/* copy remainder of strip */
3552+
if( *bufferoffset + *striplength - i > buffersize )
3553+
return(0);
35363554
_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i);
35373555
*bufferoffset+= *striplength - i;
35383556
return(1);

Diff for: tools/tiffcrop.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -5758,7 +5758,8 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
57585758
{
57595759
uint32 i;
57605760
float xres = 0.0, yres = 0.0;
5761-
uint16 nstrips = 0, ntiles = 0, planar = 0;
5761+
uint32 nstrips = 0, ntiles = 0;
5762+
uint16 planar = 0;
57625763
uint16 bps = 0, spp = 0, res_unit = 0;
57635764
uint16 orientation = 0;
57645765
uint16 input_compression = 0, input_photometric = 0;
@@ -6066,11 +6067,23 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
60666067
/* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */
60676068
/* outside buffer */
60686069
if (!read_buff)
6070+
{
6071+
if( buffsize > 0xFFFFFFFFU - 3 )
6072+
{
6073+
TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6074+
return (-1);
6075+
}
60696076
read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
6077+
}
60706078
else
60716079
{
60726080
if (prev_readsize < buffsize)
6081+
{
6082+
if( buffsize > 0xFFFFFFFFU - 3 )
60736083
{
6084+
TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6085+
return (-1);
6086+
}
60746087
new_buff = _TIFFrealloc(read_buff, buffsize+3);
60756088
if (!new_buff)
60766089
{
@@ -8912,6 +8925,11 @@ reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width,
89128925
}
89138926

89148927
bytes_per_pixel = ((bps * spp) + 7) / 8;
8928+
if( bytes_per_pixel > sizeof(swapbuff) )
8929+
{
8930+
TIFFError("reverseSamplesBytes","bytes_per_pixel too large");
8931+
return (1);
8932+
}
89158933
switch (bps / 8)
89168934
{
89178935
case 8: /* Use memcpy for multiple bytes per sample data */

0 commit comments

Comments
 (0)