Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.2:Test
tiff
tiff-3.8.2-CVE-2012-2113.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File tiff-3.8.2-CVE-2012-2113.patch of Package tiff
Description: fix possible arbitrary code execution via integer overflows in tiff2pdf Origin: thanks to Red Hat Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/tiff/+bug/1016324 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=678140 Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=810551 diff -Naurp tiff-3.8.2.ori/tools/tiff2pdf.c tiff-3.8.2/tools/tiff2pdf.c --- tiff-3.8.2.ori/tools/tiff2pdf.c 2012-07-04 11:08:21.743665954 -0400 +++ tiff-3.8.2/tools/tiff2pdf.c 2012-07-04 11:14:58.847676122 -0400 @@ -28,6 +28,7 @@ #include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include <string.h> #include <ctype.h> #include <time.h> @@ -42,6 +43,8 @@ #define NULL ((void*)0) #endif +typedef uint64_t uint64; + #if defined(VMS) #define unlink remove #endif @@ -313,6 +316,34 @@ tsize_t t2p_write_pdf_xobject_stream_fil tsize_t t2p_write_pdf_xreftable(T2P*, TIFF*); tsize_t t2p_write_pdf_trailer(T2P*, TIFF*); +static uint64 +checkAdd64(uint64 summand1, uint64 summand2, T2P* t2p) +{ + uint64 bytes = summand1 + summand2; + + if (bytes - summand1 != summand2) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; + bytes = 0; + } + + return bytes; +} + +static uint64 +checkMultiply64(uint64 first, uint64 second, T2P* t2p) +{ + uint64 bytes = first * second; + + if (second && bytes / second != first) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; + bytes = 0; + } + + return bytes; +} + /* This is the main function. @@ -1754,9 +1785,7 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* tstrip_t i=0; tstrip_t stripcount=0; #endif -#ifdef OJPEG_SUPPORT - tsize_t k = 0; -#endif + uint64 k = 0; if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){ #ifdef CCITT_SUPPORT @@ -1784,19 +1813,25 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* } stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ - k += sbc[i]; + k = checkAdd64(k, sbc[i], t2p); } if(TIFFGetField(input, TIFFTAG_JPEGIFOFFSET, &(t2p->tiff_dataoffset))){ if(t2p->tiff_dataoffset != 0){ if(TIFFGetField(input, TIFFTAG_JPEGIFBYTECOUNT, &(t2p->tiff_datasize))!=0){ if(t2p->tiff_datasize < k) { - t2p->pdf_ojpegiflength=t2p->tiff_datasize; - t2p->tiff_datasize+=k; - t2p->tiff_datasize+=6; - t2p->tiff_datasize+=2*stripcount; TIFFWarning(TIFF2PDF_MODULE, "Input file %s has short JPEG interchange file byte count", TIFFFileName(input)); + t2p->pdf_ojpegiflength=t2p->tiff_datasize; + k = checkAdd64(k, t2p->tiff_datasize, t2p); + k = checkAdd64(k, 6, t2p); + k = checkAdd64(k, stripcount, t2p); + k = checkAdd64(k, stripcount, t2p); + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; + } return; } return; @@ -1809,9 +1844,14 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* } } } - t2p->tiff_datasize+=k; - t2p->tiff_datasize+=2*stripcount; - t2p->tiff_datasize+=2048; + k = checkAdd64(k, stripcount, t2p); + k = checkAdd64(k, stripcount, t2p); + k = checkAdd64(k, 2048, t2p); + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; + } return; } #endif @@ -1819,11 +1859,11 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* if(t2p->tiff_compression == COMPRESSION_JPEG){ if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &xuint16, &jpt) != 0 ){ if(xuint16>4){ - t2p->tiff_datasize+= xuint16; - t2p->tiff_datasize -=2; /* don't use EOI of header */ + k += xuint16; + k -= 2; /* don't use EOI of header */ } } else { - t2p->tiff_datasize=2; /* SOI for first strip */ + k = 2; /* SOI for first strip */ } stripcount=TIFFNumberOfStrips(input); if(!TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc)){ @@ -1834,17 +1874,32 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* return; } for(i=0;i<stripcount;i++){ - t2p->tiff_datasize += sbc[i]; - t2p->tiff_datasize -=4; /* don't use SOI or EOI of strip */ + k = checkAdd64(k, sbc[i], t2p); + k -=4; /* don't use SOI or EOI of strip */ + } + k = checkAdd64(k, 2, t2p); /* use EOI of last strip */ + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; } - t2p->tiff_datasize +=2; /* use EOI of last strip */ } #endif (void) 0; } - t2p->tiff_datasize=TIFFScanlineSize(input) * t2p->tiff_length; + k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ - t2p->tiff_datasize*= t2p->tiff_samplesperpixel; + k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); + } + if (k == 0) { + /* Assume we had overflow inside TIFFScanlineSize */ + t2p->t2p_error = T2P_ERR_ERROR; + } + + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; } return; @@ -1863,6 +1918,7 @@ void t2p_read_tiff_size_tile(T2P* t2p, T uint16 xuint16=0; unsigned char* jpt; #endif + uint64 k; edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile); edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile); @@ -1874,32 +1930,50 @@ void t2p_read_tiff_size_tile(T2P* t2p, T #endif ){ t2p->tiff_datasize=TIFFTileSize(input); + if (t2p->tiff_datasize == 0) { + /* Assume we had overflow inside TIFFTileSize */ + t2p->t2p_error = T2P_ERR_ERROR; + } return; } else { TIFFGetField(input, TIFFTAG_TILEBYTECOUNTS, &tbc); - t2p->tiff_datasize=tbc[tile]; + k=tbc[tile]; #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ - t2p->tiff_datasize+=2048; - return; + k = checkAdd64(k, 2048, t2p); } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_JPEG){ if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &xuint16, &jpt)!=0){ if(xuint16>4){ - t2p->tiff_datasize+=xuint16; - t2p->tiff_datasize-=4; /* don't use EOI of header or SOI of tile */ + k = checkAdd64(k, xuint16, t2p); + k -= 4; /* don't use EOI of header or SOI of tile */ } } } #endif + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; + } return; } } - t2p->tiff_datasize=TIFFTileSize(input); + k = TIFFTileSize(input); if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ - t2p->tiff_datasize*= t2p->tiff_samplesperpixel; + k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); + } + if (k == 0) { + /* Assume we had overflow inside TIFFTileSize */ + t2p->t2p_error = T2P_ERR_ERROR; + } + + t2p->tiff_datasize = (tsize_t) k; + if ((uint64) t2p->tiff_datasize != k) { + TIFFError(TIFF2PDF_MODULE, "Integer overflow"); + t2p->t2p_error = T2P_ERR_ERROR; } return; @@ -2045,6 +2119,10 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p uint32 max_striplength=0; #endif + /* Fail if prior error (in particular, can't trust tiff_datasize) */ + if (t2p->t2p_error != T2P_ERR_OK) + return(0); + if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){ #ifdef CCITT_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_G4){ @@ -2582,6 +2660,10 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P uint32 xuint32=0; #endif + /* Fail if prior error (in particular, can't trust tiff_datasize) */ + if (t2p->t2p_error != T2P_ERR_OK) + return(0); + edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile); edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor