Skip to content

Commit 192b714

Browse files
committed
Merged revisions 81046 from the python2.6 branch:
Issue python#8674: Fix incorrect and UB-inducing overflow checks in audioop module. Thanks Tomas Hoger for the patch.
1 parent b3b56fc commit 192b714

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ Joerg-Cyril Hoehle
288288
Gregor Hoffleit
289289
Chris Hoffman
290290
Albert Hofkamp
291+
Tomas Hoger
291292
Jonathan Hogg
292293
Gerrit Holl
293294
Rune Holm

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ What's New in Python 2.5.6c1?
99

1010
*Release date: XX-XXX-2010*
1111

12+
Library
13+
-------
14+
15+
- Issue #8674: Fixed a number of incorrect or undefined-behaviour-inducing
16+
overflow checks in the audioop module (CVE-2010-1634).
17+
1218

1319
What's New in Python 2.5.5?
1420
===========================

Modules/audioop.c

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ static PyObject *
824824
audioop_tostereo(PyObject *self, PyObject *args)
825825
{
826826
signed char *cp, *ncp;
827-
int len, new_len, size, val1, val2, val = 0;
827+
int len, size, val1, val2, val = 0;
828828
double fac1, fac2, fval, maxval;
829829
PyObject *rv;
830830
int i;
@@ -841,14 +841,13 @@ audioop_tostereo(PyObject *self, PyObject *args)
841841
return 0;
842842
}
843843

844-
new_len = len*2;
845-
if (new_len < 0) {
844+
if (len > INT_MAX/2) {
846845
PyErr_SetString(PyExc_MemoryError,
847846
"not enough memory for output buffer");
848847
return 0;
849848
}
850849

851-
rv = PyString_FromStringAndSize(NULL, new_len);
850+
rv = PyString_FromStringAndSize(NULL, len*2);
852851
if ( rv == 0 )
853852
return 0;
854853
ncp = (signed char *)PyString_AsString(rv);
@@ -1011,7 +1010,7 @@ audioop_lin2lin(PyObject *self, PyObject *args)
10111010
{
10121011
signed char *cp;
10131012
unsigned char *ncp;
1014-
int len, new_len, size, size2, val = 0;
1013+
int len, size, size2, val = 0;
10151014
PyObject *rv;
10161015
int i, j;
10171016

@@ -1025,13 +1024,12 @@ audioop_lin2lin(PyObject *self, PyObject *args)
10251024
return 0;
10261025
}
10271026

1028-
new_len = (len/size)*size2;
1029-
if (new_len < 0) {
1027+
if (len/size > INT_MAX/size2) {
10301028
PyErr_SetString(PyExc_MemoryError,
10311029
"not enough memory for output buffer");
10321030
return 0;
10331031
}
1034-
rv = PyString_FromStringAndSize(NULL, new_len);
1032+
rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
10351033
if ( rv == 0 )
10361034
return 0;
10371035
ncp = (unsigned char *)PyString_AsString(rv);
@@ -1067,7 +1065,6 @@ audioop_ratecv(PyObject *self, PyObject *args)
10671065
int chan, d, *prev_i, *cur_i, cur_o;
10681066
PyObject *state, *samps, *str, *rv = NULL;
10691067
int bytes_per_frame;
1070-
size_t alloc_size;
10711068

10721069
weightA = 1;
10731070
weightB = 0;
@@ -1110,14 +1107,13 @@ audioop_ratecv(PyObject *self, PyObject *args)
11101107
inrate /= d;
11111108
outrate /= d;
11121109

1113-
alloc_size = sizeof(int) * (unsigned)nchannels;
1114-
if (alloc_size < nchannels) {
1110+
if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
11151111
PyErr_SetString(PyExc_MemoryError,
11161112
"not enough memory for output buffer");
11171113
return 0;
11181114
}
1119-
prev_i = (int *) malloc(alloc_size);
1120-
cur_i = (int *) malloc(alloc_size);
1115+
prev_i = (int *) malloc(nchannels * sizeof(int));
1116+
cur_i = (int *) malloc(nchannels * sizeof(int));
11211117
if (prev_i == NULL || cur_i == NULL) {
11221118
(void) PyErr_NoMemory();
11231119
goto exit;
@@ -1291,7 +1287,7 @@ audioop_ulaw2lin(PyObject *self, PyObject *args)
12911287
unsigned char *cp;
12921288
unsigned char cval;
12931289
signed char *ncp;
1294-
int len, new_len, size, val;
1290+
int len, size, val;
12951291
PyObject *rv;
12961292
int i;
12971293

@@ -1304,18 +1300,17 @@ audioop_ulaw2lin(PyObject *self, PyObject *args)
13041300
return 0;
13051301
}
13061302

1307-
new_len = len*size;
1308-
if (new_len < 0) {
1303+
if (len > INT_MAX/size) {
13091304
PyErr_SetString(PyExc_MemoryError,
13101305
"not enough memory for output buffer");
13111306
return 0;
13121307
}
1313-
rv = PyString_FromStringAndSize(NULL, new_len);
1308+
rv = PyString_FromStringAndSize(NULL, len*size);
13141309
if ( rv == 0 )
13151310
return 0;
13161311
ncp = (signed char *)PyString_AsString(rv);
13171312

1318-
for ( i=0; i < new_len; i += size ) {
1313+
for ( i=0; i < len*size; i += size ) {
13191314
cval = *cp++;
13201315
val = st_ulaw2linear16(cval);
13211316

@@ -1365,7 +1360,7 @@ audioop_alaw2lin(PyObject *self, PyObject *args)
13651360
unsigned char *cp;
13661361
unsigned char cval;
13671362
signed char *ncp;
1368-
int len, new_len, size, val;
1363+
int len, size, val;
13691364
PyObject *rv;
13701365
int i;
13711366

@@ -1378,18 +1373,17 @@ audioop_alaw2lin(PyObject *self, PyObject *args)
13781373
return 0;
13791374
}
13801375

1381-
new_len = len*size;
1382-
if (new_len < 0) {
1376+
if (len > INT_MAX/size) {
13831377
PyErr_SetString(PyExc_MemoryError,
13841378
"not enough memory for output buffer");
13851379
return 0;
13861380
}
1387-
rv = PyString_FromStringAndSize(NULL, new_len);
1381+
rv = PyString_FromStringAndSize(NULL, len*size);
13881382
if ( rv == 0 )
13891383
return 0;
13901384
ncp = (signed char *)PyString_AsString(rv);
13911385

1392-
for ( i=0; i < new_len; i += size ) {
1386+
for ( i=0; i < len*size; i += size ) {
13931387
cval = *cp++;
13941388
val = st_alaw2linear16(cval);
13951389

@@ -1514,7 +1508,7 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
15141508
{
15151509
signed char *cp;
15161510
signed char *ncp;
1517-
int len, new_len, size, valpred, step, delta, index, sign, vpdiff;
1511+
int len, size, valpred, step, delta, index, sign, vpdiff;
15181512
PyObject *rv, *str, *state;
15191513
int i, inputbuffer = 0, bufferstep;
15201514

@@ -1536,21 +1530,20 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
15361530
} else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
15371531
return 0;
15381532

1539-
new_len = len*size*2;
1540-
if (new_len < 0) {
1533+
if (len > (INT_MAX/2)/size) {
15411534
PyErr_SetString(PyExc_MemoryError,
15421535
"not enough memory for output buffer");
15431536
return 0;
15441537
}
1545-
str = PyString_FromStringAndSize(NULL, new_len);
1538+
str = PyString_FromStringAndSize(NULL, len*size*2);
15461539
if ( str == 0 )
15471540
return 0;
15481541
ncp = (signed char *)PyString_AsString(str);
15491542

15501543
step = stepsizeTable[index];
15511544
bufferstep = 0;
15521545

1553-
for ( i=0; i < new_len; i += size ) {
1546+
for ( i=0; i < len*size*2; i += size ) {
15541547
/* Step 1 - get the delta value and compute next index */
15551548
if ( bufferstep ) {
15561549
delta = inputbuffer & 0xf;

0 commit comments

Comments
 (0)