Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.2:Rings:1-MinimalX
libjpeg-turbo
libjpeg-turbo-CVE-2019-2201.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libjpeg-turbo-CVE-2019-2201.patch of Package libjpeg-turbo
Index: libjpeg-turbo-1.5.3/tjbench.c =================================================================== --- libjpeg-turbo-1.5.3.orig/tjbench.c 2017-12-14 05:39:01.000000000 +0100 +++ libjpeg-turbo-1.5.3/tjbench.c 2019-11-13 08:48:18.339233270 +0100 @@ -32,6 +32,7 @@ #include <ctype.h> #include <math.h> #include <errno.h> +#include <limits.h> #include <cdjpeg.h> #include "./bmp.h" #include "./tjutil.h" @@ -125,21 +126,25 @@ int decomp(unsigned char *srcbuf, unsign if((handle=tjInitDecompress())==NULL) _throwtj("executing tjInitDecompress()"); - if(dstbuf==NULL) - { - if((dstbuf=(unsigned char *)malloc(pitch*scaledh))==NULL) + if (dstbuf == NULL) { + if ((unsigned long long)pitch * (unsigned long long)scaledh > + (unsigned long long)((size_t)-1)) + _throw("allocating destination buffer", "Image is too large"); + if((dstbuf=(unsigned char *)malloc((size_t)pitch*scaledh))==NULL) _throwunix("allocating destination buffer"); dstbufalloc=1; } /* Set the destination buffer to gray so we know whether the decompressor attempted to write to it */ - memset(dstbuf, 127, pitch*scaledh); + memset(dstbuf, 127, (size_t)pitch*scaledh); if(doyuv) { int width=dotile? tilew:scaledw; int height=dotile? tileh:scaledh; - int yuvsize=tjBufSizeYUV2(width, yuvpad, height, subsamp); + unsigned long yuvsize=tjBufSizeYUV2(width, yuvpad, height, subsamp); + if (yuvsize == (unsigned long)-1) + _throwtj("allocating YUV buffer"); if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) _throwunix("allocating YUV buffer"); memset(yuvbuf, 127, yuvsize); @@ -152,7 +157,7 @@ int decomp(unsigned char *srcbuf, unsign { int tile=0; double start=gettime(); - for(row=0, dstptr=dstbuf; row<ntilesh; row++, dstptr+=pitch*tileh) + for(row=0, dstptr=dstbuf; row<ntilesh; row++, dstptr+=(size_t)pitch*tileh) { for(col=0, dstptr2=dstptr; col<ntilesw; col++, tile++, dstptr2+=ps*tilew) { @@ -242,14 +247,14 @@ int decomp(unsigned char *srcbuf, unsign if(!quiet) printf("Compression error written to %s.\n", tempstr); if(subsamp==TJ_GRAYSCALE) { - int index, index2; + unsigned long index, index2; for(row=0, index=0; row<h; row++, index+=pitch) { for(col=0, index2=index; col<w; col++, index2+=ps) { - int rindex=index2+tjRedOffset[pf]; - int gindex=index2+tjGreenOffset[pf]; - int bindex=index2+tjBlueOffset[pf]; + unsigned long rindex=index2+tjRedOffset[pf]; + unsigned long gindex=index2+tjGreenOffset[pf]; + unsigned long bindex=index2+tjBlueOffset[pf]; int y=(int)((double)srcbuf[rindex]*0.299 + (double)srcbuf[gindex]*0.587 + (double)srcbuf[bindex]*0.114 + 0.5); @@ -290,13 +295,17 @@ int fullTest(unsigned char *srcbuf, int unsigned char **jpegbuf=NULL, *yuvbuf=NULL, *tmpbuf=NULL, *srcptr, *srcptr2; double start, elapsed, elapsedEncode; int totaljpegsize=0, row, col, i, tilew=w, tileh=h, retval=0; - int iter, yuvsize=0; + int iter; + unsigned long yuvsize=0; unsigned long *jpegsize=NULL; int ps=tjPixelSize[pf]; int ntilesw=1, ntilesh=1, pitch=w*ps; const char *pfStr=pixFormatStr[pf]; - if((tmpbuf=(unsigned char *)malloc(pitch*h)) == NULL) + if ((unsigned long long)pitch * (unsigned long long)h > + (unsigned long long)((size_t)-1)) + _throw("allocating temporary image buffer", "Image is too large"); + if((tmpbuf=(unsigned char *)malloc((size_t)pitch*h)) == NULL) _throwunix("allocating temporary image buffer"); if(!quiet) @@ -322,6 +331,8 @@ int fullTest(unsigned char *srcbuf, int if((flags&TJFLAG_NOREALLOC)!=0) for(i=0; i<ntilesw*ntilesh; i++) { + if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) + _throw("getting buffer size", "Image is too large"); if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, subsamp)))==NULL) _throwunix("allocating JPEG tiles"); @@ -339,6 +350,8 @@ int fullTest(unsigned char *srcbuf, int if(doyuv) { yuvsize=tjBufSizeYUV2(tilew, yuvpad, tileh, subsamp); + if (yuvsize == (unsigned long)-1) + _throwtj("allocating YUV buffer"); if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) _throwunix("allocating YUV buffer"); memset(yuvbuf, 127, yuvsize); @@ -418,7 +431,7 @@ int fullTest(unsigned char *srcbuf, int { printf("Encode YUV --> Frame rate: %f fps\n", (double)iter/elapsedEncode); - printf(" Output image size: %d bytes\n", yuvsize); + printf(" Output image size: %lu bytes\n", yuvsize); printf(" Compression ratio: %f:1\n", (double)(w*h*ps)/(double)yuvsize); printf(" Throughput: %f Megapixels/sec\n", @@ -559,9 +572,12 @@ int decompTest(char *filename) _throwunix("allocating JPEG size array"); memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); - if((flags&TJFLAG_NOREALLOC)!=0 || !dotile) + if((flags&TJFLAG_NOREALLOC)!=0 && + (dotile || xformop != TJXOP_NONE || xformopt != 0 || customFilter)) for(i=0; i<ntilesw*ntilesh; i++) { + if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) + _throw("getting buffer size", "Image is too large"); if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, subsamp)))==NULL) _throwunix("allocating JPEG tiles"); @@ -682,7 +698,7 @@ int decompTest(char *filename) else { if(quiet==1) printf("N/A N/A "); - tjFree(jpegbuf[0]); + if(jpegbuf[0]) tjFree(jpegbuf[0]); jpegbuf[0]=NULL; decompsrc=1; } @@ -699,7 +715,7 @@ int decompTest(char *filename) for(i=0; i<ntilesw*ntilesh; i++) { - tjFree(jpegbuf[i]); jpegbuf[i]=NULL; + if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; } free(jpegbuf); jpegbuf=NULL; if(jpegsize) {free(jpegsize); jpegsize=NULL;} Index: libjpeg-turbo-1.5.3/tjunittest.c =================================================================== --- libjpeg-turbo-1.5.3.orig/tjunittest.c 2017-12-14 05:39:01.000000000 +0100 +++ libjpeg-turbo-1.5.3/tjunittest.c 2019-11-12 14:01:00.301625434 +0100 @@ -36,6 +36,7 @@ #include <errno.h> #include "./tjutil.h" #include "./turbojpeg.h" +#include "./jconfigint.h" #ifdef _WIN32 #include <time.h> #define random() rand() @@ -592,6 +593,43 @@ void doTest(int w, int h, const int *for if(dstBuf) tjFree(dstBuf); } +#if SIZEOF_SIZE_T == 8 +#define CHECKSIZE(function) { \ + if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) { \ + printf(#function " Overflow\n"); \ + exit(1); \ + } \ +} +#else +#define CHECKSIZE(function) { \ + if (size != (unsigned long)(-1) || \ + !strcmp(tjGetErrorStr(), "No error")) { \ + printf(#function " Overflow\n"); \ + exit(1); \ + } \ +} +#endif + +static void overflowTest(void) +{ + /* Ensure that the various buffer size functions don't overflow */ + unsigned long size; + + printf("Overflow test ..\n"); + + size = tjBufSize(26755, 26755, TJSAMP_444); + CHECKSIZE(tjBufSize()); + size = TJBUFSIZE(26755, 26755); + CHECKSIZE(TJBUFSIZE()); + size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444); + CHECKSIZE(tjBufSizeYUV2()); + size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444); + CHECKSIZE(TJBUFSIZEYUV()); + size = tjBufSizeYUV(37838, 37838, TJSAMP_444); + CHECKSIZE(tjBufSizeYUV()); + size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444); + CHECKSIZE(tjPlaneSizeYUV()); +} void bufSizeTest(void) { @@ -704,6 +742,7 @@ int main(int argc, char *argv[]) } if(alloc) printf("Testing automatic buffer allocation\n"); if(doyuv) num4bf=4; + overflowTest(); doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test"); doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test"); doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test"); Index: libjpeg-turbo-1.5.3/turbojpeg.c =================================================================== --- libjpeg-turbo-1.5.3.orig/turbojpeg.c 2017-12-14 05:39:01.000000000 +0100 +++ libjpeg-turbo-1.5.3/turbojpeg.c 2019-11-12 14:01:00.301625434 +0100 @@ -622,7 +622,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompres DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, int jpegSubsamp) { - unsigned long retval=0; int mcuw, mcuh, chromasf; + unsigned long long retval=0; int mcuw, mcuh, chromasf; if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) _throw("tjBufSize(): Invalid argument"); @@ -632,32 +632,37 @@ DLLEXPORT unsigned long DLLCALL tjBufSiz mcuw=tjMCUWidth[jpegSubsamp]; mcuh=tjMCUHeight[jpegSubsamp]; chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); - retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; + retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL; + if (retval > (unsigned long long)((unsigned long)-1)) + _throw("tjBufSize(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) { - unsigned long retval=0; + unsigned long long retval=0; if(width<1 || height<1) _throw("TJBUFSIZE(): Invalid argument"); /* This allows for rare corner cases in which a JPEG image can actually be larger than the uncompressed input (we wouldn't mention it if it hadn't happened before.) */ - retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; + retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL; + if (retval > (unsigned long long)((unsigned long)-1)) + _throw("TJBUFSIZE(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, int subsamp) { - int retval=0, nc, i; + unsigned long long retval=0; + int nc, i; if(subsamp<0 || subsamp>=NUMSUBOPT) _throw("tjBufSizeYUV2(): Invalid argument"); @@ -669,11 +674,13 @@ DLLEXPORT unsigned long DLLCALL tjBufSiz int stride=PAD(pw, pad); int ph=tjPlaneHeight(i, height, subsamp); if(pw<0 || ph<0) return -1; - else retval+=stride*ph; + else retval+=(unsigned long long)stride*ph; } + if (retval > (unsigned long long)((unsigned long)-1)) + _throw("tjBufSizeYUV2(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, @@ -734,7 +741,7 @@ DLLEXPORT int tjPlaneHeight(int componen DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, int stride, int height, int subsamp) { - unsigned long retval=0; + unsigned long long retval=0; int pw, ph; if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) @@ -747,10 +754,12 @@ DLLEXPORT unsigned long DLLCALL tjPlaneS if(stride==0) stride=pw; else stride=abs(stride); - retval=stride*(ph-1)+pw; + retval=(unsigned long long)stride*(ph-1)+pw; + if (retval > (unsigned long long)((unsigned long)-1)) + _throw("tjPlaneSizeYUV(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } @@ -812,8 +821,8 @@ DLLEXPORT int DLLCALL tjCompress2(tjhand for(i=0; i<height; i++) { if(flags&TJFLAG_BOTTOMUP) - row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; - else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; + row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*(size_t)pitch]; + else row_pointer[i]=(JSAMPROW)&srcBuf[i*(size_t)pitch]; } while(cinfo->next_scanline<cinfo->image_height) { @@ -938,8 +947,8 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes( for(i=0; i<height; i++) { if(flags&TJFLAG_BOTTOMUP) - row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; - else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; + row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*(size_t)pitch]; + else row_pointer[i]=(JSAMPROW)&srcBuf[i*(size_t)pitch]; } if(height<ph0) for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; @@ -1455,8 +1464,8 @@ DLLEXPORT int DLLCALL tjDecompress2(tjha for(i=0; i<(int)dinfo->output_height; i++) { if(flags&TJFLAG_BOTTOMUP) - row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; - else row_pointer[i]=&dstBuf[i*pitch]; + row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*(size_t)pitch]; + else row_pointer[i]=&dstBuf[i*(size_t)pitch]; } while(dinfo->output_scanline<dinfo->output_height) { @@ -1640,8 +1649,8 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes( _throw("tjDecodeYUVPlanes(): Memory allocation failure"); for(i=0; i<height; i++) { - if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*pitch]; - else row_pointer[i]=&dstBuf[i*pitch]; + if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*(size_t)pitch]; + else row_pointer[i]=&dstBuf[i*(size_t)pitch]; } if(height<ph0) for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1];
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