aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2020-01-23 13:26:17 +0100
committerNatanael Copa <ncopa@alpinelinux.org>2020-01-23 13:31:44 +0100
commit8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9 (patch)
treee33583bad84d423079bbe5abbfc9583314bc1c9b
parentda0d4ca4ffc94a69525da49718036faadde1d973 (diff)
downloadaports-8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9.tar.bz2
aports-8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9.tar.xz
main/libjpeg-turbo: backport fix for CVE-2019-2201
fixes #10948
-rw-r--r--main/libjpeg-turbo/APKBUILD8
-rw-r--r--main/libjpeg-turbo/CVE-2019-2201.patch466
2 files changed, 472 insertions, 2 deletions
diff --git a/main/libjpeg-turbo/APKBUILD b/main/libjpeg-turbo/APKBUILD
index b14a205b13..a996682d70 100644
--- a/main/libjpeg-turbo/APKBUILD
+++ b/main/libjpeg-turbo/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=libjpeg-turbo
pkgver=1.5.3
-pkgrel=5
+pkgrel=6
pkgdesc="accelerated baseline JPEG compression and decompression library"
url="https://libjpeg-turbo.org/"
arch="all"
@@ -15,9 +15,12 @@ source="https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-$pkgver.ta
0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch
CVE-2018-11813.patch
CVE-2018-14498.patch
+ CVE-2019-2201.patch
"
# secfixes:
+# 1.5.3-r6:
+# - CVE-2019-2201
# 1.5.3-r5:
# - CVE-2018-14498
# 1.5.3-r3:
@@ -74,4 +77,5 @@ dev() {
sha512sums="b611b1cc3d1ddedddad871854b42449d053a5f910ed1bdfa45c98e0270f4ecc110fde3a10111d2b876d847a826fa634f09c0bb8c357056c9c3a91c9065eb5202 libjpeg-turbo-1.5.3.tar.gz
d6465d96427289d90c342e94316018565eb1711ea0028121ea0a962900b7c7599a7457e42201bcfd288da30019ae3b841ce319cfbe02705d49749d660ef04b74 0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch
d32234df784ebe1cad6af114f74d14995637e494a502c171e154e1abc5aa335930d3a256fda234a85842d5c1658d2fac6474e0bc959fdf04413f69a35e3bf39a CVE-2018-11813.patch
-315aba552a2d66cdc8d83c5602a7e47c995f6709509afd07daf3ffacaf650404dc9f7a4beeb1373cabb5afc915a3d4c704b71dfdfcad3bc25ae5361ed16980d5 CVE-2018-14498.patch"
+315aba552a2d66cdc8d83c5602a7e47c995f6709509afd07daf3ffacaf650404dc9f7a4beeb1373cabb5afc915a3d4c704b71dfdfcad3bc25ae5361ed16980d5 CVE-2018-14498.patch
+28e0efd9227c3f6fe3d328f8ad6ae3f52875cdbb91934a93b516a0005bf4d22ac9e589e27472a17da8d8641cad10561cbd2de46e41d2b83378d6df969eed8848 CVE-2019-2201.patch"
diff --git a/main/libjpeg-turbo/CVE-2019-2201.patch b/main/libjpeg-turbo/CVE-2019-2201.patch
new file mode 100644
index 0000000000..31f1d92bba
--- /dev/null
+++ b/main/libjpeg-turbo/CVE-2019-2201.patch
@@ -0,0 +1,466 @@
+From b5eb30229e9b9c4a09917e7f563317c380031a22 Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Thu, 11 Jul 2019 15:30:04 -0500
+Subject: [PATCH 1/2] TurboJPEG: Properly handle gigapixel images
+
+Prevent several integer overflow issues and subsequent segfaults that
+occurred when attempting to compress or decompress gigapixel images with
+the TurboJPEG API:
+
+- Modify tjBufSize(), tjBufSizeYUV2(), and tjPlaneSizeYUV() to avoid
+ integer overflow when computing the return values and to return an
+ error if such an overflow is unavoidable.
+- Modify tjunittest to validate the above.
+- Modify tjCompress2(), tjEncodeYUVPlanes(), tjDecompress2(), and
+ tjDecodeYUVPlanes() to avoid integer overflow when computing the row
+ pointers in the 64-bit TurboJPEG C API.
+- Modify TJBench (both C and Java versions) to avoid overflowing the
+ size argument to malloc()/new and to fail gracefully if such an
+ overflow is unavoidable.
+
+In general, this allows gigapixel images to be accommodated by the
+64-bit TurboJPEG C API when using automatic JPEG buffer (re)allocation.
+Such images cannot currently be accommodated without automatic JPEG
+buffer (re)allocation, due to the fact that tjAlloc() accepts a 32-bit
+integer argument (oops.) Such images cannot be accommodated in the
+TurboJPEG Java API due to the fact that Java always uses a signed 32-bit
+integer as an array index.
+
+Fixes #361
+
+(cherry picked from commit 2a9e3bd7430cfda1bc812d139e0609c6aca0b884)
+---
+ java/TJBench.java | 11 ++++++++++-
+ tjbench.c | 44 +++++++++++++++++++++++++++++------------
+ tjunittest.c | 38 +++++++++++++++++++++++++++++++++++
+ turbojpeg.c | 50 ++++++++++++++++++++++++++++-------------------
+ 4 files changed, 109 insertions(+), 34 deletions(-)
+
+diff --git a/java/TJBench.java b/java/TJBench.java
+index ddc414c..9b1ff81 100644
+--- a/java/TJBench.java
++++ b/java/TJBench.java
+@@ -96,6 +96,8 @@ class TJBench {
+ int rindex = TJ.getRedOffset(pixelFormat);
+ int gindex = TJ.getGreenOffset(pixelFormat);
+ int bindex = TJ.getBlueOffset(pixelFormat);
++ if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE)
++ throw new Exception("Image is too large");
+ byte[] dstBuf = new byte[w[0] * h[0] * ps];
+ int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
+ while (pixels-- > 0) {
+@@ -147,8 +149,11 @@ class TJBench {
+
+ tjd = new TJDecompressor();
+
+- if (dstBuf == null)
++ if (dstBuf == null) {
++ if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE)
++ throw new Exception("Image is too large");
+ dstBuf = new byte[pitch * scaledh];
++ }
+
+ /* Set the destination buffer to gray so we know whether the decompressor
+ attempted to write to it */
+@@ -287,6 +292,8 @@ class TJBench {
+ String pfStr = pixFormatStr[pf];
+ YUVImage yuvImage = null;
+
++ if ((long)pitch * (long)h > (long)Integer.MAX_VALUE)
++ throw new Exception("Image is too large");
+ tmpBuf = new byte[pitch * h];
+
+ if (quiet == 0)
+@@ -435,6 +442,8 @@ class TJBench {
+ int ps = TJ.getPixelSize(pf), tile;
+
+ FileInputStream fis = new FileInputStream(fileName);
++ if (fis.getChannel().size() > (long)Integer.MAX_VALUE)
++ throw new Exception("Image is too large");
+ int srcSize = (int)fis.getChannel().size();
+ srcBuf = new byte[srcSize];
+ fis.read(srcBuf, 0, srcSize);
+diff --git a/tjbench.c b/tjbench.c
+index 0187b75..e90ba3d 100644
+--- a/tjbench.c
++++ b/tjbench.c
+@@ -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"
+@@ -127,7 +128,10 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
+
+ if(dstbuf==NULL)
+ {
+- if((dstbuf=(unsigned char *)malloc(pitch*scaledh))==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;
+ }
+@@ -139,7 +143,10 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
+ {
+ 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);
+@@ -242,14 +249,14 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
+ 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 +297,16 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
+ 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;
+- unsigned long *jpegsize=NULL;
++ int iter;
++ unsigned long *jpegsize=NULL, yuvsize=0;
+ 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 +332,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
+ 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 +351,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
+ 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 +432,7 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
+ {
+ 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",
+@@ -561,9 +575,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");
+@@ -684,7 +701,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;
+ }
+@@ -701,7 +718,8 @@ 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;}
+diff --git a/tjunittest.c b/tjunittest.c
+index f793796..a96440b 100644
+--- a/tjunittest.c
++++ b/tjunittest.c
+@@ -40,6 +40,7 @@
+ #include <time.h>
+ #define random() rand()
+ #endif
++#include "config.h" /* for SIZEOF_SIZE_T */
+
+
+ void usage(char *progName)
+@@ -593,6 +594,42 @@ void doTest(int w, int h, const int *formats, int nformats, int subsamp,
+ }
+
+
++#if SIZEOF_SIZE_T == 8
++#define CHECKSIZE(function) { \
++ if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \
++ _throw(#function " overflow"); \
++}
++#else
++#define CHECKSIZE(function) { \
++ if (size != (unsigned long)(-1) || \
++ !strcmp(tjGetErrorStr(), "No error")) \
++ _throw(#function " overflow"); \
++}
++#endif
++
++static void overflowTest(void)
++{
++ /* Ensure that the various buffer size functions don't overflow */
++ unsigned long size;
++
++ 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());
++
++bailout:
++ return;
++}
++
++
+ void bufSizeTest(void)
+ {
+ int w, h, i, subsamp;
+@@ -704,6 +741,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");
+diff --git a/turbojpeg.c b/turbojpeg.c
+index 330a004..be03482 100644
+--- a/turbojpeg.c
++++ b/turbojpeg.c
+@@ -644,7 +644,8 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void)
+ 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");
+
+@@ -654,32 +655,37 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
+ 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");
+@@ -691,11 +697,13 @@ DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height,
+ 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,
+@@ -756,7 +764,7 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp)
+ 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)
+@@ -769,10 +777,12 @@ DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width,
+ 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;
+ }
+
+
+@@ -836,8 +846,8 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
+ 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)
+ {
+@@ -964,8 +974,8 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle,
+ 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];
+@@ -1485,8 +1495,8 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle,
+ 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)
+ {
+@@ -1672,8 +1682,8 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle,
+ _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];
+--
+2.25.0
+
+
+From c511336e5ead5f125647cc92174295d5d5c7d4bf Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Tue, 12 Nov 2019 12:27:22 -0600
+Subject: [PATCH 2/2] 64-bit tjbench: Fix signed int overflow/segfault
+
+... that occurred when attempting to decompress images with more than
+715827882 (2048*1024*1024 / 3) pixels.
+
+Fixes #388
+
+(cherry picked from commit c30b1e72dac76343ef9029833d1561de07d29bad)
+---
+ tjbench.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tjbench.c b/tjbench.c
+index e90ba3d..858471c 100644
+--- a/tjbench.c
++++ b/tjbench.c
+@@ -137,7 +137,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
+ }
+ /* 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)
+ {
+@@ -159,7 +159,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
+ {
+ 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)
+ {
+--
+2.25.0
+