Skip to content

Commit 8ad5f45

Browse files
committed
- Issue python#1179: Fix CVE-2007-4965 and CVE-2008-1679, multiple integer
overflows in the imageop and rgbimgmodule modules.
1 parent 1596ed9 commit 8ad5f45

File tree

3 files changed

+76
-12
lines changed

3 files changed

+76
-12
lines changed

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Core and builtins
2121
would previously leak memory on the error path when such an allocation
2222
failed have been fixed.
2323

24+
- Issue #1179: Fix CVE-2007-4965 and CVE-2008-1679, multiple integer
25+
overflows in the imageop and rgbimgmodule modules.
26+
2427
Extension Modules
2528
-----------------
2629

Modules/imageop.c

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ imageop_crop(PyObject *self, PyObject *args)
7878
char *cp, *ncp;
7979
short *nsp;
8080
Py_Int32 *nlp;
81-
int len, size, x, y, newx1, newx2, newy1, newy2;
81+
int len, size, x, y, newx1, newx2, newy1, newy2, nlen;
8282
int ix, iy, xstep, ystep;
8383
PyObject *rv;
8484

@@ -90,13 +90,19 @@ imageop_crop(PyObject *self, PyObject *args)
9090
PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
9191
return 0;
9292
}
93-
if ( len != size*x*y ) {
93+
if (( len != size*x*y ) ||
94+
( size != ((len / x) / y) )) {
9495
PyErr_SetString(ImageopError, "String has incorrect length");
9596
return 0;
9697
}
9798
xstep = (newx1 < newx2)? 1 : -1;
9899
ystep = (newy1 < newy2)? 1 : -1;
99100

101+
nlen = (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size;
102+
if ( size != ((nlen / (abs(newx2-newx1)+1)) / (abs(newy2-newy1)+1)) ) {
103+
PyErr_SetString(ImageopError, "String has incorrect length");
104+
return 0;
105+
}
100106
rv = PyString_FromStringAndSize(NULL,
101107
(abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
102108
if ( rv == 0 )
@@ -132,7 +138,7 @@ imageop_scale(PyObject *self, PyObject *args)
132138
char *cp, *ncp;
133139
short *nsp;
134140
Py_Int32 *nlp;
135-
int len, size, x, y, newx, newy;
141+
int len, size, x, y, newx, newy, nlen;
136142
int ix, iy;
137143
int oix, oiy;
138144
PyObject *rv;
@@ -145,12 +151,18 @@ imageop_scale(PyObject *self, PyObject *args)
145151
PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
146152
return 0;
147153
}
148-
if ( len != size*x*y ) {
154+
if ( ( len != size*x*y ) ||
155+
( size != ((len / x) / y) ) ) {
156+
PyErr_SetString(ImageopError, "String has incorrect length");
157+
return 0;
158+
}
159+
nlen = newx*newy*size;
160+
if ( size != ((nlen / newx) / newy) ) {
149161
PyErr_SetString(ImageopError, "String has incorrect length");
150162
return 0;
151163
}
152164

153-
rv = PyString_FromStringAndSize(NULL, newx*newy*size);
165+
rv = PyString_FromStringAndSize(NULL, nlen);
154166
if ( rv == 0 )
155167
return 0;
156168
ncp = (char *)PyString_AsString(rv);
@@ -190,7 +202,8 @@ imageop_tovideo(PyObject *self, PyObject *args)
190202
PyErr_SetString(ImageopError, "Size should be 1 or 4");
191203
return 0;
192204
}
193-
if ( maxx*maxy*width != len ) {
205+
if ( ( maxx*maxy*width != len ) ||
206+
( maxx != ((len / maxy) / width) ) ) {
194207
PyErr_SetString(ImageopError, "String has incorrect length");
195208
return 0;
196209
}
@@ -240,7 +253,8 @@ imageop_grey2mono(PyObject *self, PyObject *args)
240253
if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) )
241254
return 0;
242255

243-
if ( x*y != len ) {
256+
if ( ( x*y != len ) ||
257+
( x != len / y ) ) {
244258
PyErr_SetString(ImageopError, "String has incorrect length");
245259
return 0;
246260
}
@@ -281,7 +295,8 @@ imageop_grey2grey4(PyObject *self, PyObject *args)
281295
if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
282296
return 0;
283297

284-
if ( x*y != len ) {
298+
if ( ( x*y != len ) ||
299+
( x != len / y ) ) {
285300
PyErr_SetString(ImageopError, "String has incorrect length");
286301
return 0;
287302
}
@@ -320,7 +335,8 @@ imageop_grey2grey2(PyObject *self, PyObject *args)
320335
if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
321336
return 0;
322337

323-
if ( x*y != len ) {
338+
if ( ( x*y != len ) ||
339+
( x != len / y ) ) {
324340
PyErr_SetString(ImageopError, "String has incorrect length");
325341
return 0;
326342
}
@@ -358,7 +374,8 @@ imageop_dither2mono(PyObject *self, PyObject *args)
358374
if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
359375
return 0;
360376

361-
if ( x*y != len ) {
377+
if ( ( x*y != len ) ||
378+
( x != len / y ) ) {
362379
PyErr_SetString(ImageopError, "String has incorrect length");
363380
return 0;
364381
}
@@ -404,7 +421,8 @@ imageop_dither2grey2(PyObject *self, PyObject *args)
404421
if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
405422
return 0;
406423

407-
if ( x*y != len ) {
424+
if ( ( x*y != len ) ||
425+
( x != len / y ) ) {
408426
PyErr_SetString(ImageopError, "String has incorrect length");
409427
return 0;
410428
}
@@ -443,7 +461,11 @@ imageop_mono2grey(PyObject *self, PyObject *args)
443461
if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) )
444462
return 0;
445463

446-
nlen = x*y;
464+
nlen = x*y;
465+
if ( x != (nlen / y) ) {
466+
PyErr_SetString(ImageopError, "String has incorrect length");
467+
return 0;
468+
}
447469
if ( (nlen+7)/8 != len ) {
448470
PyErr_SetString(ImageopError, "String has incorrect length");
449471
return 0;
@@ -481,6 +503,10 @@ imageop_grey22grey(PyObject *self, PyObject *args)
481503
return 0;
482504

483505
nlen = x*y;
506+
if ( x != (nlen / y) ) {
507+
PyErr_SetString(ImageopError, "String has incorrect length");
508+
return 0;
509+
}
484510
if ( (nlen+3)/4 != len ) {
485511
PyErr_SetString(ImageopError, "String has incorrect length");
486512
return 0;
@@ -517,6 +543,10 @@ imageop_grey42grey(PyObject *self, PyObject *args)
517543
return 0;
518544

519545
nlen = x*y;
546+
if ( x != (nlen / y) ) {
547+
PyErr_SetString(ImageopError, "String has incorrect length");
548+
return 0;
549+
}
520550
if ( (nlen+1)/2 != len ) {
521551
PyErr_SetString(ImageopError, "String has incorrect length");
522552
return 0;
@@ -554,6 +584,10 @@ imageop_rgb2rgb8(PyObject *self, PyObject *args)
554584
return 0;
555585

556586
nlen = x*y;
587+
if ( x != (nlen / y) ) {
588+
PyErr_SetString(ImageopError, "String has incorrect length");
589+
return 0;
590+
}
557591
if ( nlen*4 != len ) {
558592
PyErr_SetString(ImageopError, "String has incorrect length");
559593
return 0;
@@ -598,10 +632,19 @@ imageop_rgb82rgb(PyObject *self, PyObject *args)
598632
return 0;
599633

600634
nlen = x*y;
635+
if ( x != (nlen / y) ) {
636+
PyErr_SetString(ImageopError, "String has incorrect length");
637+
return 0;
638+
}
601639
if ( nlen != len ) {
602640
PyErr_SetString(ImageopError, "String has incorrect length");
603641
return 0;
604642
}
643+
644+
if ( nlen / x != y || nlen > INT_MAX / 4) {
645+
PyErr_SetString(ImageopError, "Image is too large");
646+
return 0;
647+
}
605648

606649
rv = PyString_FromStringAndSize(NULL, nlen*4);
607650
if ( rv == 0 )
@@ -648,6 +691,10 @@ imageop_rgb2grey(PyObject *self, PyObject *args)
648691
return 0;
649692

650693
nlen = x*y;
694+
if ( x != (nlen / y) ) {
695+
PyErr_SetString(ImageopError, "String has incorrect length");
696+
return 0;
697+
}
651698
if ( nlen*4 != len ) {
652699
PyErr_SetString(ImageopError, "String has incorrect length");
653700
return 0;
@@ -693,10 +740,19 @@ imageop_grey2rgb(PyObject *self, PyObject *args)
693740
return 0;
694741

695742
nlen = x*y;
743+
if ( x != (nlen / y) ) {
744+
PyErr_SetString(ImageopError, "String has incorrect length");
745+
return 0;
746+
}
696747
if ( nlen != len ) {
697748
PyErr_SetString(ImageopError, "String has incorrect length");
698749
return 0;
699750
}
751+
752+
if ( nlen / x != y || nlen > INT_MAX / 4) {
753+
PyErr_SetString(ImageopError, "Image is too large");
754+
return 0;
755+
}
700756

701757
rv = PyString_FromStringAndSize(NULL, nlen*4);
702758
if ( rv == 0 )

Modules/rgbimgmodule.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ longimagedata(PyObject *self, PyObject *args)
299299
xsize = image.xsize;
300300
ysize = image.ysize;
301301
zsize = image.zsize;
302+
tablen = xsize * ysize * zsize * sizeof(Py_Int32);
303+
if (xsize != (((tablen / ysize) / zsize) / sizeof(Py_Int32))) {
304+
PyErr_NoMemory();
305+
goto finally;
306+
}
302307
if (rle) {
303308
tablen = ysize * zsize * sizeof(Py_Int32);
304309
rlebuflen = (int) (1.05 * xsize +10);

0 commit comments

Comments
 (0)