diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2020-01-23 13:26:17 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2020-01-23 13:31:44 +0100 |
commit | 8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9 (patch) | |
tree | e33583bad84d423079bbe5abbfc9583314bc1c9b | |
parent | da0d4ca4ffc94a69525da49718036faadde1d973 (diff) | |
download | alpine_aports-8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9.tar.bz2 alpine_aports-8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9.tar.xz alpine_aports-8c593acdd5ae3aa50db4851fe92f8b3eea5fd0e9.zip |
main/libjpeg-turbo: backport fix for CVE-2019-2201
fixes #10948
-rw-r--r-- | main/libjpeg-turbo/APKBUILD | 8 | ||||
-rw-r--r-- | main/libjpeg-turbo/CVE-2019-2201.patch | 466 |
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 @@ | |||
2 | # Maintainer: Natanael Copa <ncopa@alpinelinux.org> | 2 | # Maintainer: Natanael Copa <ncopa@alpinelinux.org> |
3 | pkgname=libjpeg-turbo | 3 | pkgname=libjpeg-turbo |
4 | pkgver=1.5.3 | 4 | pkgver=1.5.3 |
5 | pkgrel=5 | 5 | pkgrel=6 |
6 | pkgdesc="accelerated baseline JPEG compression and decompression library" | 6 | pkgdesc="accelerated baseline JPEG compression and decompression library" |
7 | url="https://libjpeg-turbo.org/" | 7 | url="https://libjpeg-turbo.org/" |
8 | arch="all" | 8 | arch="all" |
@@ -15,9 +15,12 @@ source="https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-$pkgver.ta | |||
15 | 0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch | 15 | 0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch |
16 | CVE-2018-11813.patch | 16 | CVE-2018-11813.patch |
17 | CVE-2018-14498.patch | 17 | CVE-2018-14498.patch |
18 | CVE-2019-2201.patch | ||
18 | " | 19 | " |
19 | 20 | ||
20 | # secfixes: | 21 | # secfixes: |
22 | # 1.5.3-r6: | ||
23 | # - CVE-2019-2201 | ||
21 | # 1.5.3-r5: | 24 | # 1.5.3-r5: |
22 | # - CVE-2018-14498 | 25 | # - CVE-2018-14498 |
23 | # 1.5.3-r3: | 26 | # 1.5.3-r3: |
@@ -74,4 +77,5 @@ dev() { | |||
74 | sha512sums="b611b1cc3d1ddedddad871854b42449d053a5f910ed1bdfa45c98e0270f4ecc110fde3a10111d2b876d847a826fa634f09c0bb8c357056c9c3a91c9065eb5202 libjpeg-turbo-1.5.3.tar.gz | 77 | sha512sums="b611b1cc3d1ddedddad871854b42449d053a5f910ed1bdfa45c98e0270f4ecc110fde3a10111d2b876d847a826fa634f09c0bb8c357056c9c3a91c9065eb5202 libjpeg-turbo-1.5.3.tar.gz |
75 | d6465d96427289d90c342e94316018565eb1711ea0028121ea0a962900b7c7599a7457e42201bcfd288da30019ae3b841ce319cfbe02705d49749d660ef04b74 0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch | 78 | d6465d96427289d90c342e94316018565eb1711ea0028121ea0a962900b7c7599a7457e42201bcfd288da30019ae3b841ce319cfbe02705d49749d660ef04b74 0001-tjLoadImage-Fix-FPE-triggered-by-malformed-BMP.patch |
76 | d32234df784ebe1cad6af114f74d14995637e494a502c171e154e1abc5aa335930d3a256fda234a85842d5c1658d2fac6474e0bc959fdf04413f69a35e3bf39a CVE-2018-11813.patch | 79 | d32234df784ebe1cad6af114f74d14995637e494a502c171e154e1abc5aa335930d3a256fda234a85842d5c1658d2fac6474e0bc959fdf04413f69a35e3bf39a CVE-2018-11813.patch |
77 | 315aba552a2d66cdc8d83c5602a7e47c995f6709509afd07daf3ffacaf650404dc9f7a4beeb1373cabb5afc915a3d4c704b71dfdfcad3bc25ae5361ed16980d5 CVE-2018-14498.patch" | 80 | 315aba552a2d66cdc8d83c5602a7e47c995f6709509afd07daf3ffacaf650404dc9f7a4beeb1373cabb5afc915a3d4c704b71dfdfcad3bc25ae5361ed16980d5 CVE-2018-14498.patch |
81 | 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 @@ | |||
1 | From b5eb30229e9b9c4a09917e7f563317c380031a22 Mon Sep 17 00:00:00 2001 | ||
2 | From: DRC <information@libjpeg-turbo.org> | ||
3 | Date: Thu, 11 Jul 2019 15:30:04 -0500 | ||
4 | Subject: [PATCH 1/2] TurboJPEG: Properly handle gigapixel images | ||
5 | |||
6 | Prevent several integer overflow issues and subsequent segfaults that | ||
7 | occurred when attempting to compress or decompress gigapixel images with | ||
8 | the TurboJPEG API: | ||
9 | |||
10 | - Modify tjBufSize(), tjBufSizeYUV2(), and tjPlaneSizeYUV() to avoid | ||
11 | integer overflow when computing the return values and to return an | ||
12 | error if such an overflow is unavoidable. | ||
13 | - Modify tjunittest to validate the above. | ||
14 | - Modify tjCompress2(), tjEncodeYUVPlanes(), tjDecompress2(), and | ||
15 | tjDecodeYUVPlanes() to avoid integer overflow when computing the row | ||
16 | pointers in the 64-bit TurboJPEG C API. | ||
17 | - Modify TJBench (both C and Java versions) to avoid overflowing the | ||
18 | size argument to malloc()/new and to fail gracefully if such an | ||
19 | overflow is unavoidable. | ||
20 | |||
21 | In general, this allows gigapixel images to be accommodated by the | ||
22 | 64-bit TurboJPEG C API when using automatic JPEG buffer (re)allocation. | ||
23 | Such images cannot currently be accommodated without automatic JPEG | ||
24 | buffer (re)allocation, due to the fact that tjAlloc() accepts a 32-bit | ||
25 | integer argument (oops.) Such images cannot be accommodated in the | ||
26 | TurboJPEG Java API due to the fact that Java always uses a signed 32-bit | ||
27 | integer as an array index. | ||
28 | |||
29 | Fixes #361 | ||
30 | |||
31 | (cherry picked from commit 2a9e3bd7430cfda1bc812d139e0609c6aca0b884) | ||
32 | --- | ||
33 | java/TJBench.java | 11 ++++++++++- | ||
34 | tjbench.c | 44 +++++++++++++++++++++++++++++------------ | ||
35 | tjunittest.c | 38 +++++++++++++++++++++++++++++++++++ | ||
36 | turbojpeg.c | 50 ++++++++++++++++++++++++++++------------------- | ||
37 | 4 files changed, 109 insertions(+), 34 deletions(-) | ||
38 | |||
39 | diff --git a/java/TJBench.java b/java/TJBench.java | ||
40 | index ddc414c..9b1ff81 100644 | ||
41 | --- a/java/TJBench.java | ||
42 | +++ b/java/TJBench.java | ||
43 | @@ -96,6 +96,8 @@ class TJBench { | ||
44 | int rindex = TJ.getRedOffset(pixelFormat); | ||
45 | int gindex = TJ.getGreenOffset(pixelFormat); | ||
46 | int bindex = TJ.getBlueOffset(pixelFormat); | ||
47 | + if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE) | ||
48 | + throw new Exception("Image is too large"); | ||
49 | byte[] dstBuf = new byte[w[0] * h[0] * ps]; | ||
50 | int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0; | ||
51 | while (pixels-- > 0) { | ||
52 | @@ -147,8 +149,11 @@ class TJBench { | ||
53 | |||
54 | tjd = new TJDecompressor(); | ||
55 | |||
56 | - if (dstBuf == null) | ||
57 | + if (dstBuf == null) { | ||
58 | + if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE) | ||
59 | + throw new Exception("Image is too large"); | ||
60 | dstBuf = new byte[pitch * scaledh]; | ||
61 | + } | ||
62 | |||
63 | /* Set the destination buffer to gray so we know whether the decompressor | ||
64 | attempted to write to it */ | ||
65 | @@ -287,6 +292,8 @@ class TJBench { | ||
66 | String pfStr = pixFormatStr[pf]; | ||
67 | YUVImage yuvImage = null; | ||
68 | |||
69 | + if ((long)pitch * (long)h > (long)Integer.MAX_VALUE) | ||
70 | + throw new Exception("Image is too large"); | ||
71 | tmpBuf = new byte[pitch * h]; | ||
72 | |||
73 | if (quiet == 0) | ||
74 | @@ -435,6 +442,8 @@ class TJBench { | ||
75 | int ps = TJ.getPixelSize(pf), tile; | ||
76 | |||
77 | FileInputStream fis = new FileInputStream(fileName); | ||
78 | + if (fis.getChannel().size() > (long)Integer.MAX_VALUE) | ||
79 | + throw new Exception("Image is too large"); | ||
80 | int srcSize = (int)fis.getChannel().size(); | ||
81 | srcBuf = new byte[srcSize]; | ||
82 | fis.read(srcBuf, 0, srcSize); | ||
83 | diff --git a/tjbench.c b/tjbench.c | ||
84 | index 0187b75..e90ba3d 100644 | ||
85 | --- a/tjbench.c | ||
86 | +++ b/tjbench.c | ||
87 | @@ -32,6 +32,7 @@ | ||
88 | #include <ctype.h> | ||
89 | #include <math.h> | ||
90 | #include <errno.h> | ||
91 | +#include <limits.h> | ||
92 | #include <cdjpeg.h> | ||
93 | #include "./bmp.h" | ||
94 | #include "./tjutil.h" | ||
95 | @@ -127,7 +128,10 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf, | ||
96 | |||
97 | if(dstbuf==NULL) | ||
98 | { | ||
99 | - if((dstbuf=(unsigned char *)malloc(pitch*scaledh))==NULL) | ||
100 | + if ((unsigned long long)pitch * (unsigned long long)scaledh > | ||
101 | + (unsigned long long)((size_t)-1)) | ||
102 | + _throw("allocating destination buffer", "Image is too large"); | ||
103 | + if ((dstbuf = (unsigned char *)malloc((size_t)pitch * scaledh)) == NULL) | ||
104 | _throwunix("allocating destination buffer"); | ||
105 | dstbufalloc=1; | ||
106 | } | ||
107 | @@ -139,7 +143,10 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf, | ||
108 | { | ||
109 | int width=dotile? tilew:scaledw; | ||
110 | int height=dotile? tileh:scaledh; | ||
111 | - int yuvsize=tjBufSizeYUV2(width, yuvpad, height, subsamp); | ||
112 | + unsigned long yuvsize=tjBufSizeYUV2(width, yuvpad, height, subsamp); | ||
113 | + | ||
114 | + if (yuvsize == (unsigned long)-1) | ||
115 | + _throwtj("allocating YUV buffer"); | ||
116 | if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) | ||
117 | _throwunix("allocating YUV buffer"); | ||
118 | memset(yuvbuf, 127, yuvsize); | ||
119 | @@ -242,14 +249,14 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf, | ||
120 | if(!quiet) printf("Compression error written to %s.\n", tempstr); | ||
121 | if(subsamp==TJ_GRAYSCALE) | ||
122 | { | ||
123 | - int index, index2; | ||
124 | + unsigned long index, index2; | ||
125 | for(row=0, index=0; row<h; row++, index+=pitch) | ||
126 | { | ||
127 | for(col=0, index2=index; col<w; col++, index2+=ps) | ||
128 | { | ||
129 | - int rindex=index2+tjRedOffset[pf]; | ||
130 | - int gindex=index2+tjGreenOffset[pf]; | ||
131 | - int bindex=index2+tjBlueOffset[pf]; | ||
132 | + unsigned long rindex=index2+tjRedOffset[pf]; | ||
133 | + unsigned long gindex=index2+tjGreenOffset[pf]; | ||
134 | + unsigned long bindex=index2+tjBlueOffset[pf]; | ||
135 | int y=(int)((double)srcbuf[rindex]*0.299 | ||
136 | + (double)srcbuf[gindex]*0.587 | ||
137 | + (double)srcbuf[bindex]*0.114 + 0.5); | ||
138 | @@ -290,13 +297,16 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual, | ||
139 | unsigned char **jpegbuf=NULL, *yuvbuf=NULL, *tmpbuf=NULL, *srcptr, *srcptr2; | ||
140 | double start, elapsed, elapsedEncode; | ||
141 | int totaljpegsize=0, row, col, i, tilew=w, tileh=h, retval=0; | ||
142 | - int iter, yuvsize=0; | ||
143 | - unsigned long *jpegsize=NULL; | ||
144 | + int iter; | ||
145 | + unsigned long *jpegsize=NULL, yuvsize=0; | ||
146 | int ps=tjPixelSize[pf]; | ||
147 | int ntilesw=1, ntilesh=1, pitch=w*ps; | ||
148 | const char *pfStr=pixFormatStr[pf]; | ||
149 | |||
150 | - if((tmpbuf=(unsigned char *)malloc(pitch*h)) == NULL) | ||
151 | + if((unsigned long long)pitch * (unsigned long long)h > | ||
152 | + (unsigned long long)((size_t)-1)) | ||
153 | + _throw("allocating temporary image buffer", "Image is too large"); | ||
154 | + if((tmpbuf = (unsigned char *)malloc((size_t)pitch * h)) == NULL) | ||
155 | _throwunix("allocating temporary image buffer"); | ||
156 | |||
157 | if(!quiet) | ||
158 | @@ -322,6 +332,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual, | ||
159 | if((flags&TJFLAG_NOREALLOC)!=0) | ||
160 | for(i=0; i<ntilesw*ntilesh; i++) | ||
161 | { | ||
162 | + if(tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) | ||
163 | + _throw("getting buffer size", "Image is too large"); | ||
164 | if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, | ||
165 | subsamp)))==NULL) | ||
166 | _throwunix("allocating JPEG tiles"); | ||
167 | @@ -339,6 +351,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual, | ||
168 | if(doyuv) | ||
169 | { | ||
170 | yuvsize=tjBufSizeYUV2(tilew, yuvpad, tileh, subsamp); | ||
171 | + if(yuvsize == (unsigned long)-1) | ||
172 | + _throwtj("allocating YUV buffer"); | ||
173 | if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) | ||
174 | _throwunix("allocating YUV buffer"); | ||
175 | memset(yuvbuf, 127, yuvsize); | ||
176 | @@ -418,7 +432,7 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual, | ||
177 | { | ||
178 | printf("Encode YUV --> Frame rate: %f fps\n", | ||
179 | (double)iter/elapsedEncode); | ||
180 | - printf(" Output image size: %d bytes\n", yuvsize); | ||
181 | + printf(" Output image size: %lu bytes\n", yuvsize); | ||
182 | printf(" Compression ratio: %f:1\n", | ||
183 | (double)(w*h*ps)/(double)yuvsize); | ||
184 | printf(" Throughput: %f Megapixels/sec\n", | ||
185 | @@ -561,9 +575,12 @@ int decompTest(char *filename) | ||
186 | _throwunix("allocating JPEG size array"); | ||
187 | memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); | ||
188 | |||
189 | - if((flags&TJFLAG_NOREALLOC)!=0 || !dotile) | ||
190 | + if ((flags & TJFLAG_NOREALLOC) != 0 && | ||
191 | + (dotile || xformop != TJXOP_NONE || xformopt != 0 || customFilter)) | ||
192 | for(i=0; i<ntilesw*ntilesh; i++) | ||
193 | { | ||
194 | + if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) | ||
195 | + _throw("getting buffer size", "Image is too large"); | ||
196 | if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, | ||
197 | subsamp)))==NULL) | ||
198 | _throwunix("allocating JPEG tiles"); | ||
199 | @@ -684,7 +701,7 @@ int decompTest(char *filename) | ||
200 | else | ||
201 | { | ||
202 | if(quiet==1) printf("N/A N/A "); | ||
203 | - tjFree(jpegbuf[0]); | ||
204 | + if(jpegbuf[0]) tjFree(jpegbuf[0]); | ||
205 | jpegbuf[0]=NULL; | ||
206 | decompsrc=1; | ||
207 | } | ||
208 | @@ -701,7 +718,8 @@ int decompTest(char *filename) | ||
209 | |||
210 | for(i=0; i<ntilesw*ntilesh; i++) | ||
211 | { | ||
212 | - tjFree(jpegbuf[i]); jpegbuf[i]=NULL; | ||
213 | + if(jpegbuf[i]) tjFree(jpegbuf[i]); | ||
214 | + jpegbuf[i] = NULL; | ||
215 | } | ||
216 | free(jpegbuf); jpegbuf=NULL; | ||
217 | if(jpegsize) {free(jpegsize); jpegsize=NULL;} | ||
218 | diff --git a/tjunittest.c b/tjunittest.c | ||
219 | index f793796..a96440b 100644 | ||
220 | --- a/tjunittest.c | ||
221 | +++ b/tjunittest.c | ||
222 | @@ -40,6 +40,7 @@ | ||
223 | #include <time.h> | ||
224 | #define random() rand() | ||
225 | #endif | ||
226 | +#include "config.h" /* for SIZEOF_SIZE_T */ | ||
227 | |||
228 | |||
229 | void usage(char *progName) | ||
230 | @@ -593,6 +594,42 @@ void doTest(int w, int h, const int *formats, int nformats, int subsamp, | ||
231 | } | ||
232 | |||
233 | |||
234 | +#if SIZEOF_SIZE_T == 8 | ||
235 | +#define CHECKSIZE(function) { \ | ||
236 | + if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \ | ||
237 | + _throw(#function " overflow"); \ | ||
238 | +} | ||
239 | +#else | ||
240 | +#define CHECKSIZE(function) { \ | ||
241 | + if (size != (unsigned long)(-1) || \ | ||
242 | + !strcmp(tjGetErrorStr(), "No error")) \ | ||
243 | + _throw(#function " overflow"); \ | ||
244 | +} | ||
245 | +#endif | ||
246 | + | ||
247 | +static void overflowTest(void) | ||
248 | +{ | ||
249 | + /* Ensure that the various buffer size functions don't overflow */ | ||
250 | + unsigned long size; | ||
251 | + | ||
252 | + size = tjBufSize(26755, 26755, TJSAMP_444); | ||
253 | + CHECKSIZE(tjBufSize()); | ||
254 | + size = TJBUFSIZE(26755, 26755); | ||
255 | + CHECKSIZE(TJBUFSIZE()); | ||
256 | + size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444); | ||
257 | + CHECKSIZE(tjBufSizeYUV2()); | ||
258 | + size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444); | ||
259 | + CHECKSIZE(TJBUFSIZEYUV()); | ||
260 | + size = tjBufSizeYUV(37838, 37838, TJSAMP_444); | ||
261 | + CHECKSIZE(tjBufSizeYUV()); | ||
262 | + size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444); | ||
263 | + CHECKSIZE(tjPlaneSizeYUV()); | ||
264 | + | ||
265 | +bailout: | ||
266 | + return; | ||
267 | +} | ||
268 | + | ||
269 | + | ||
270 | void bufSizeTest(void) | ||
271 | { | ||
272 | int w, h, i, subsamp; | ||
273 | @@ -704,6 +741,7 @@ int main(int argc, char *argv[]) | ||
274 | } | ||
275 | if(alloc) printf("Testing automatic buffer allocation\n"); | ||
276 | if(doyuv) num4bf=4; | ||
277 | + overflowTest(); | ||
278 | doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test"); | ||
279 | doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test"); | ||
280 | doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test"); | ||
281 | diff --git a/turbojpeg.c b/turbojpeg.c | ||
282 | index 330a004..be03482 100644 | ||
283 | --- a/turbojpeg.c | ||
284 | +++ b/turbojpeg.c | ||
285 | @@ -644,7 +644,8 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void) | ||
286 | DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, | ||
287 | int jpegSubsamp) | ||
288 | { | ||
289 | - unsigned long retval=0; int mcuw, mcuh, chromasf; | ||
290 | + unsigned long long retval=0; | ||
291 | + int mcuw, mcuh, chromasf; | ||
292 | if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) | ||
293 | _throw("tjBufSize(): Invalid argument"); | ||
294 | |||
295 | @@ -654,32 +655,37 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, | ||
296 | mcuw=tjMCUWidth[jpegSubsamp]; | ||
297 | mcuh=tjMCUHeight[jpegSubsamp]; | ||
298 | chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); | ||
299 | - retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; | ||
300 | + retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL; | ||
301 | + if (retval > (unsigned long long)((unsigned long)-1)) | ||
302 | + _throw("tjBufSize(): Image is too large"); | ||
303 | |||
304 | bailout: | ||
305 | - return retval; | ||
306 | + return (unsigned long)retval; | ||
307 | } | ||
308 | |||
309 | DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) | ||
310 | { | ||
311 | - unsigned long retval=0; | ||
312 | + unsigned long long retval = 0; | ||
313 | if(width<1 || height<1) | ||
314 | _throw("TJBUFSIZE(): Invalid argument"); | ||
315 | |||
316 | /* This allows for rare corner cases in which a JPEG image can actually be | ||
317 | larger than the uncompressed input (we wouldn't mention it if it hadn't | ||
318 | happened before.) */ | ||
319 | - retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; | ||
320 | + retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL; | ||
321 | + if (retval > (unsigned long long)((unsigned long)-1)) | ||
322 | + _throw("TJBUFSIZE(): Image is too large"); | ||
323 | |||
324 | bailout: | ||
325 | - return retval; | ||
326 | + return (unsigned long)retval; | ||
327 | } | ||
328 | |||
329 | |||
330 | DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, | ||
331 | int subsamp) | ||
332 | { | ||
333 | - int retval=0, nc, i; | ||
334 | + unsigned long long retval=0; | ||
335 | + int nc, i; | ||
336 | |||
337 | if(subsamp<0 || subsamp>=NUMSUBOPT) | ||
338 | _throw("tjBufSizeYUV2(): Invalid argument"); | ||
339 | @@ -691,11 +697,13 @@ DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, | ||
340 | int stride=PAD(pw, pad); | ||
341 | int ph=tjPlaneHeight(i, height, subsamp); | ||
342 | if(pw<0 || ph<0) return -1; | ||
343 | - else retval+=stride*ph; | ||
344 | + else retval+=(unsigned long long)stride*ph; | ||
345 | } | ||
346 | + if (retval > (unsigned long long)((unsigned long)-1)) | ||
347 | + _throw("tjBufSizeYUV2(): Image is too large"); | ||
348 | |||
349 | bailout: | ||
350 | - return retval; | ||
351 | + return (unsigned long) retval; | ||
352 | } | ||
353 | |||
354 | DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, | ||
355 | @@ -756,7 +764,7 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) | ||
356 | DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, | ||
357 | int stride, int height, int subsamp) | ||
358 | { | ||
359 | - unsigned long retval=0; | ||
360 | + unsigned long long retval=0; | ||
361 | int pw, ph; | ||
362 | |||
363 | if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) | ||
364 | @@ -769,10 +777,12 @@ DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, | ||
365 | if(stride==0) stride=pw; | ||
366 | else stride=abs(stride); | ||
367 | |||
368 | - retval=stride*(ph-1)+pw; | ||
369 | + retval=(unsigned long long)stride*(ph-1)+pw; | ||
370 | + if (retval > (unsigned long long)((unsigned long)-1)) | ||
371 | + _throw("tjPlaneSizeYUV(): Image is too large"); | ||
372 | |||
373 | bailout: | ||
374 | - return retval; | ||
375 | + return (unsigned long)retval; | ||
376 | } | ||
377 | |||
378 | |||
379 | @@ -836,8 +846,8 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, | ||
380 | for(i=0; i<height; i++) | ||
381 | { | ||
382 | if(flags&TJFLAG_BOTTOMUP) | ||
383 | - row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; | ||
384 | - else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; | ||
385 | + row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*(size_t)pitch]; | ||
386 | + else row_pointer[i]=(JSAMPROW)&srcBuf[i*(size_t)pitch]; | ||
387 | } | ||
388 | while(cinfo->next_scanline<cinfo->image_height) | ||
389 | { | ||
390 | @@ -964,8 +974,8 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, | ||
391 | for(i=0; i<height; i++) | ||
392 | { | ||
393 | if(flags&TJFLAG_BOTTOMUP) | ||
394 | - row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; | ||
395 | - else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; | ||
396 | + row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*(size_t)pitch]; | ||
397 | + else row_pointer[i]=(JSAMPROW)&srcBuf[i*(size_t)pitch]; | ||
398 | } | ||
399 | if(height<ph0) | ||
400 | for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; | ||
401 | @@ -1485,8 +1495,8 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, | ||
402 | for(i=0; i<(int)dinfo->output_height; i++) | ||
403 | { | ||
404 | if(flags&TJFLAG_BOTTOMUP) | ||
405 | - row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; | ||
406 | - else row_pointer[i]=&dstBuf[i*pitch]; | ||
407 | + row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*(size_t)pitch]; | ||
408 | + else row_pointer[i]=&dstBuf[i*(size_t)pitch]; | ||
409 | } | ||
410 | while(dinfo->output_scanline<dinfo->output_height) | ||
411 | { | ||
412 | @@ -1672,8 +1682,8 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, | ||
413 | _throw("tjDecodeYUVPlanes(): Memory allocation failure"); | ||
414 | for(i=0; i<height; i++) | ||
415 | { | ||
416 | - if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*pitch]; | ||
417 | - else row_pointer[i]=&dstBuf[i*pitch]; | ||
418 | + if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*(size_t)pitch]; | ||
419 | + else row_pointer[i]=&dstBuf[i*(size_t)pitch]; | ||
420 | } | ||
421 | if(height<ph0) | ||
422 | for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; | ||
423 | -- | ||
424 | 2.25.0 | ||
425 | |||
426 | |||
427 | From c511336e5ead5f125647cc92174295d5d5c7d4bf Mon Sep 17 00:00:00 2001 | ||
428 | From: DRC <information@libjpeg-turbo.org> | ||
429 | Date: Tue, 12 Nov 2019 12:27:22 -0600 | ||
430 | Subject: [PATCH 2/2] 64-bit tjbench: Fix signed int overflow/segfault | ||
431 | |||
432 | ... that occurred when attempting to decompress images with more than | ||
433 | 715827882 (2048*1024*1024 / 3) pixels. | ||
434 | |||
435 | Fixes #388 | ||
436 | |||
437 | (cherry picked from commit c30b1e72dac76343ef9029833d1561de07d29bad) | ||
438 | --- | ||
439 | tjbench.c | 4 ++-- | ||
440 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
441 | |||
442 | diff --git a/tjbench.c b/tjbench.c | ||
443 | index e90ba3d..858471c 100644 | ||
444 | --- a/tjbench.c | ||
445 | +++ b/tjbench.c | ||
446 | @@ -137,7 +137,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf, | ||
447 | } | ||
448 | /* Set the destination buffer to gray so we know whether the decompressor | ||
449 | attempted to write to it */ | ||
450 | - memset(dstbuf, 127, pitch*scaledh); | ||
451 | + memset(dstbuf, 127, (size_t)pitch * scaledh); | ||
452 | |||
453 | if(doyuv) | ||
454 | { | ||
455 | @@ -159,7 +159,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf, | ||
456 | { | ||
457 | int tile=0; | ||
458 | double start=gettime(); | ||
459 | - for(row=0, dstptr=dstbuf; row<ntilesh; row++, dstptr+=pitch*tileh) | ||
460 | + for(row=0, dstptr=dstbuf; row<ntilesh; row++, dstptr+=(size_t)pitch*tileh) | ||
461 | { | ||
462 | for(col=0, dstptr2=dstptr; col<ntilesw; col++, tile++, dstptr2+=ps*tilew) | ||
463 | { | ||
464 | -- | ||
465 | 2.25.0 | ||
466 | |||