From ea606f2f2e7b2aef2ca65b5aa1f06ec468d359dd Mon Sep 17 00:00:00 2001 From: dmalcolm Date: Jun 04 2010 18:12:44 +0000 Subject: - ensure that the compiler is invoked with "-fwrapv" (rhbz#594819) - CVE-2010-1634: fix various integer overflow checks in the audioop module (patch 113) - CVE-2010-2089: further checks within the audioop module (patch 114) - CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 115) --- diff --git a/python-2.6.2-CVE-2008-5983.patch b/python-2.6.2-CVE-2008-5983.patch new file mode 100644 index 0000000..de640cb --- /dev/null +++ b/python-2.6.2-CVE-2008-5983.patch @@ -0,0 +1,137 @@ +diff -up Python-2.6.2/Doc/c-api/init.rst.CVE-2008-5983 Python-2.6.2/Doc/c-api/init.rst +--- Python-2.6.2/Doc/c-api/init.rst.CVE-2008-5983 2009-04-05 17:26:31.000000000 -0400 ++++ Python-2.6.2/Doc/c-api/init.rst 2010-06-04 11:19:30.750199971 -0400 +@@ -22,6 +22,7 @@ Initialization, Finalization, and Thread + module: sys + triple: module; search; path + single: PySys_SetArgv() ++ single: PySys_SetArgvEx() + single: Py_Finalize() + + Initialize the Python interpreter. In an application embedding Python, this +@@ -31,7 +32,7 @@ Initialization, Finalization, and Thread + the table of loaded modules (``sys.modules``), and creates the fundamental + modules :mod:`__builtin__`, :mod:`__main__` and :mod:`sys`. It also initializes + the module search path (``sys.path``). It does not set ``sys.argv``; use +- :cfunc:`PySys_SetArgv` for that. This is a no-op when called for a second time ++ :cfunc:`PySys_SetArgvEx` for that. This is a no-op when called for a second time + (without calling :cfunc:`Py_Finalize` first). There is no return value; it is a + fatal error if the initialization fails. + +@@ -346,7 +347,7 @@ Initialization, Finalization, and Thread + ``sys.version``. + + +-.. cfunction:: void PySys_SetArgv(int argc, char **argv) ++.. cfunction:: void PySys_SetArgvEx(int argc, char **argv, int updatepath) + + .. index:: + single: main() +@@ -361,14 +362,41 @@ Initialization, Finalization, and Thread + string. If this function fails to initialize :data:`sys.argv`, a fatal + condition is signalled using :cfunc:`Py_FatalError`. + +- This function also prepends the executed script's path to :data:`sys.path`. +- If no script is executed (in the case of calling ``python -c`` or just the +- interactive interpreter), the empty string is used instead. ++ If *updatepath* is zero, this is all the function does. If *updatepath* ++ is non-zero, the function also modifies :data:`sys.path` according to the ++ following algorithm: ++ ++ - If the name of an existing script is passed in ``argv[0]``, the absolute ++ path of the directory where the script is located is prepended to ++ :data:`sys.path`. ++ - Otherwise (that is, if *argc* is 0 or ``argv[0]`` doesn't point ++ to an existing file name), an empty string is prepended to ++ :data:`sys.path`, which is the same as prepending the current working ++ directory (``"."``). ++ ++ .. note:: ++ It is recommended that applications embedding the Python interpreter ++ for purposes other than executing a single script pass 0 as *updatepath*, ++ and update :data:`sys.path` themselves if desired. ++ See `CVE-2008-5983 `_. ++ ++ On versions before 2.6.6, you can achieve the same effect by manually ++ popping the first :data:`sys.path` element after having called ++ :cfunc:`PySys_SetArgv`, for example using:: ++ ++ PyRun_SimpleString("import sys; sys.path.pop(0)\n"); ++ ++ .. versionadded:: 2.6.6 + + .. XXX impl. doesn't seem consistent in allowing 0/NULL for the params; + check w/ Guido. + + ++.. cfunction:: void PySys_SetArgv(int argc, char **argv) ++ ++ This function works like :cfunc:`PySys_SetArgv` with *updatepath* set to 1. ++ ++ + .. cfunction:: void Py_SetPythonHome(char *home) + + Set the default "home" directory, that is, the location of the standard +diff -up Python-2.6.2/Include/sysmodule.h.CVE-2008-5983 Python-2.6.2/Include/sysmodule.h +--- Python-2.6.2/Include/sysmodule.h.CVE-2008-5983 2008-04-12 19:44:07.000000000 -0400 ++++ Python-2.6.2/Include/sysmodule.h 2010-06-04 11:19:30.747199764 -0400 +@@ -11,6 +11,7 @@ PyAPI_FUNC(PyObject *) PySys_GetObject(c + PyAPI_FUNC(int) PySys_SetObject(char *, PyObject *); + PyAPI_FUNC(FILE *) PySys_GetFile(char *, FILE *); + PyAPI_FUNC(void) PySys_SetArgv(int, char **); ++PyAPI_FUNC(void) PySys_SetArgvEx(int, char **, int); + PyAPI_FUNC(void) PySys_SetPath(char *); + + PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) +diff -up Python-2.6.2/Misc/NEWS.CVE-2008-5983 Python-2.6.2/Misc/NEWS +--- Python-2.6.2/Misc/NEWS.CVE-2008-5983 2010-06-04 11:19:30.730199353 -0400 ++++ Python-2.6.2/Misc/NEWS 2010-06-04 11:19:30.749199965 -0400 +@@ -111,6 +111,14 @@ Core and Builtins + Valgrind. This gives improved memory leak detection when running + under Valgrind, while taking advantage of pymalloc at other times. + ++C-API ++----- ++ ++- Issue #5753: A new C API function, :cfunc:`PySys_SetArgvEx`, allows ++ embedders of the interpreter to set sys.argv without also modifying ++ sys.path. This helps fix `CVE-2008-5983 ++ `_. ++ + Library + ------- + +diff -up Python-2.6.2/Python/sysmodule.c.CVE-2008-5983 Python-2.6.2/Python/sysmodule.c +--- Python-2.6.2/Python/sysmodule.c.CVE-2008-5983 2009-01-13 19:08:09.000000000 -0500 ++++ Python-2.6.2/Python/sysmodule.c 2010-06-04 11:20:18.931825713 -0400 +@@ -1528,7 +1528,7 @@ makeargvobject(int argc, char **argv) + } + + void +-PySys_SetArgv(int argc, char **argv) ++PySys_SetArgvEx(int argc, char **argv, int updatepath) + { + #if defined(HAVE_REALPATH) + char fullpath[MAXPATHLEN]; +@@ -1541,7 +1541,7 @@ PySys_SetArgv(int argc, char **argv) + Py_FatalError("no mem for sys.argv"); + if (PySys_SetObject("argv", av) != 0) + Py_FatalError("can't assign sys.argv"); +- if (path != NULL) { ++ if (updatepath && path != NULL) { + char *argv0 = argv[0]; + char *p = NULL; + Py_ssize_t n = 0; +@@ -1631,6 +1631,12 @@ PySys_SetArgv(int argc, char **argv) + Py_DECREF(av); + } + ++void ++PySys_SetArgv(int argc, char **argv) ++{ ++ PySys_SetArgvEx(argc, argv, 1); ++} ++ + + /* APIs to write to sys.stdout or sys.stderr using a printf-like interface. + Adapted from code submitted by Just van Rossum. diff --git a/python-2.6.2-CVE-2010-1634.patch b/python-2.6.2-CVE-2010-1634.patch new file mode 100644 index 0000000..a4144eb --- /dev/null +++ b/python-2.6.2-CVE-2010-1634.patch @@ -0,0 +1,210 @@ +diff -up Python-2.6.2/Modules/audioop.c.CVE-2010-1634 Python-2.6.2/Modules/audioop.c +--- Python-2.6.2/Modules/audioop.c.CVE-2010-1634 2008-07-07 13:02:59.000000000 -0400 ++++ Python-2.6.2/Modules/audioop.c 2010-06-04 11:02:45.743200233 -0400 +@@ -829,7 +829,7 @@ static PyObject * + audioop_tostereo(PyObject *self, PyObject *args) + { + signed char *cp, *ncp; +- int len, new_len, size, val1, val2, val = 0; ++ int len, size, val1, val2, val = 0; + double fac1, fac2, fval, maxval; + PyObject *rv; + int i; +@@ -846,14 +846,13 @@ audioop_tostereo(PyObject *self, PyObjec + return 0; + } + +- new_len = len*2; +- if (new_len < 0) { ++ if (len > INT_MAX/2) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + +- rv = PyString_FromStringAndSize(NULL, new_len); ++ rv = PyString_FromStringAndSize(NULL, len*2); + if ( rv == 0 ) + return 0; + ncp = (signed char *)PyString_AsString(rv); +@@ -1016,7 +1015,7 @@ audioop_lin2lin(PyObject *self, PyObject + { + signed char *cp; + unsigned char *ncp; +- int len, new_len, size, size2, val = 0; ++ int len, size, size2, val = 0; + PyObject *rv; + int i, j; + +@@ -1030,13 +1029,12 @@ audioop_lin2lin(PyObject *self, PyObject + return 0; + } + +- new_len = (len/size)*size2; +- if (new_len < 0) { ++ if (len/size > INT_MAX/size2) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } +- rv = PyString_FromStringAndSize(NULL, new_len); ++ rv = PyString_FromStringAndSize(NULL, (len/size)*size2); + if ( rv == 0 ) + return 0; + ncp = (unsigned char *)PyString_AsString(rv); +@@ -1072,7 +1070,6 @@ audioop_ratecv(PyObject *self, PyObject + int chan, d, *prev_i, *cur_i, cur_o; + PyObject *state, *samps, *str, *rv = NULL; + int bytes_per_frame; +- size_t alloc_size; + + weightA = 1; + weightB = 0; +@@ -1115,14 +1112,13 @@ audioop_ratecv(PyObject *self, PyObject + inrate /= d; + outrate /= d; + +- alloc_size = sizeof(int) * (unsigned)nchannels; +- if (alloc_size < nchannels) { ++ if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } +- prev_i = (int *) malloc(alloc_size); +- cur_i = (int *) malloc(alloc_size); ++ prev_i = (int *) malloc(nchannels * sizeof(int)); ++ cur_i = (int *) malloc(nchannels * sizeof(int)); + if (prev_i == NULL || cur_i == NULL) { + (void) PyErr_NoMemory(); + goto exit; +@@ -1159,25 +1155,16 @@ audioop_ratecv(PyObject *self, PyObject + ceiling(len*outrate/inrate) output frames, and each frame + requires bytes_per_frame bytes. Computing this + without spurious overflow is the challenge; we can +- settle for a reasonable upper bound, though. */ +- int ceiling; /* the number of output frames */ +- int nbytes; /* the number of output bytes needed */ +- int q = len / inrate; +- /* Now len = q * inrate + r exactly (with r = len % inrate), +- and this is less than q * inrate + inrate = (q+1)*inrate. +- So a reasonable upper bound on len*outrate/inrate is +- ((q+1)*inrate)*outrate/inrate = +- (q+1)*outrate. +- */ +- ceiling = (q+1) * outrate; +- nbytes = ceiling * bytes_per_frame; +- /* See whether anything overflowed; if not, get the space. */ +- if (q+1 < 0 || +- ceiling / outrate != q+1 || +- nbytes / bytes_per_frame != ceiling) ++ settle for a reasonable upper bound, though, in this ++ case ceiling(len/inrate) * outrate. */ ++ ++ /* compute ceiling(len/inrate) without overflow */ ++ int q = len > 0 ? 1 + (len - 1) / inrate : 0; ++ if (outrate > INT_MAX / q / bytes_per_frame) + str = NULL; + else +- str = PyString_FromStringAndSize(NULL, nbytes); ++ str = PyString_FromStringAndSize(NULL, ++ q * outrate * bytes_per_frame); + + if (str == NULL) { + PyErr_SetString(PyExc_MemoryError, +@@ -1296,7 +1283,7 @@ audioop_ulaw2lin(PyObject *self, PyObjec + unsigned char *cp; + unsigned char cval; + signed char *ncp; +- int len, new_len, size, val; ++ int len, size, val; + PyObject *rv; + int i; + +@@ -1309,18 +1296,17 @@ audioop_ulaw2lin(PyObject *self, PyObjec + return 0; + } + +- new_len = len*size; +- if (new_len < 0) { ++ if (len > INT_MAX/size) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } +- rv = PyString_FromStringAndSize(NULL, new_len); ++ rv = PyString_FromStringAndSize(NULL, len*size); + if ( rv == 0 ) + return 0; + ncp = (signed char *)PyString_AsString(rv); + +- for ( i=0; i < new_len; i += size ) { ++ for ( i=0; i < len*size; i += size ) { + cval = *cp++; + val = st_ulaw2linear16(cval); + +@@ -1370,7 +1356,7 @@ audioop_alaw2lin(PyObject *self, PyObjec + unsigned char *cp; + unsigned char cval; + signed char *ncp; +- int len, new_len, size, val; ++ int len, size, val; + PyObject *rv; + int i; + +@@ -1383,18 +1369,17 @@ audioop_alaw2lin(PyObject *self, PyObjec + return 0; + } + +- new_len = len*size; +- if (new_len < 0) { ++ if (len > INT_MAX/size) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } +- rv = PyString_FromStringAndSize(NULL, new_len); ++ rv = PyString_FromStringAndSize(NULL, len*size); + if ( rv == 0 ) + return 0; + ncp = (signed char *)PyString_AsString(rv); + +- for ( i=0; i < new_len; i += size ) { ++ for ( i=0; i < len*size; i += size ) { + cval = *cp++; + val = st_alaw2linear16(cval); + +@@ -1519,7 +1504,7 @@ audioop_adpcm2lin(PyObject *self, PyObje + { + signed char *cp; + signed char *ncp; +- int len, new_len, size, valpred, step, delta, index, sign, vpdiff; ++ int len, size, valpred, step, delta, index, sign, vpdiff; + PyObject *rv, *str, *state; + int i, inputbuffer = 0, bufferstep; + +@@ -1541,13 +1526,12 @@ audioop_adpcm2lin(PyObject *self, PyObje + } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) + return 0; + +- new_len = len*size*2; +- if (new_len < 0) { ++ if (len > (INT_MAX/2)/size) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } +- str = PyString_FromStringAndSize(NULL, new_len); ++ str = PyString_FromStringAndSize(NULL, len*size*2); + if ( str == 0 ) + return 0; + ncp = (signed char *)PyString_AsString(str); +@@ -1555,7 +1539,7 @@ audioop_adpcm2lin(PyObject *self, PyObje + step = stepsizeTable[index]; + bufferstep = 0; + +- for ( i=0; i < new_len; i += size ) { ++ for ( i=0; i < len*size*2; i += size ) { + /* Step 1 - get the delta value and compute next index */ + if ( bufferstep ) { + delta = inputbuffer & 0xf; diff --git a/python-2.6.2-CVE-2010-2089.patch b/python-2.6.2-CVE-2010-2089.patch new file mode 100644 index 0000000..92efafd --- /dev/null +++ b/python-2.6.2-CVE-2010-2089.patch @@ -0,0 +1,349 @@ +From ddc63ebe9b52c0ab4ba033301e70fac89f610704 Mon Sep 17 00:00:00 2001 +From: Victor Stinner +Date: Sun, 10 Jan 2010 21:10:01 +0100 +Subject: [PATCH] audioop: check that length is a multiple the size + +Most functions of audioop takes as input a byte string (audio data) and a size +argument (number of bytes of a sample). Functions don't check that the byte +string length is a multiple of the size. It leads to read and write from/to +uninitialised memory and might crash. + +Example on writing into uninitilized memory: + + $ python -c "import audioop; audioop.reverse('X', 2)" + Fatal Python error: Inconsistent interned string state. + Abandon + +It allocates a string of 1 byte and write 2 bytes into this string => memory +corruption. + +Attached patch creates audioop_check_size() and audioop_check_parameters() +functions. +--- + Modules/audioop.c | 153 ++++++++++++++++++++++++---------------------------- + 1 files changed, 71 insertions(+), 82 deletions(-) + +diff --git a/Modules/audioop.c b/Modules/audioop.c +index 42daf9b..ebb992a 100644 +--- a/Modules/audioop.c ++++ b/Modules/audioop.c +@@ -295,6 +295,29 @@ static int stepsizeTable[89] = { + + static PyObject *AudioopError; + ++static int ++audioop_check_size(int size) ++{ ++ if ( size != 1 && size != 2 && size != 4 ) { ++ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++static int ++audioop_check_parameters(int len, int size) ++{ ++ if (!audioop_check_size(size)) ++ return 0; ++ if ( len % size != 0 ) { ++ PyErr_SetString(AudioopError, "not a whole number of frames"); ++ return 0; ++ } ++ return 1; ++} ++ + static PyObject * + audioop_getsample(PyObject *self, PyObject *args) + { +@@ -304,10 +327,8 @@ audioop_getsample(PyObject *self, PyObject *args) + + if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) ) + return 0; +- if ( size != 1 && size != 2 && size != 4 ) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_parameters(len, size)) ++ return NULL; + if ( i < 0 || i >= len/size ) { + PyErr_SetString(AudioopError, "Index out of range"); + return 0; +@@ -328,10 +349,8 @@ audioop_max(PyObject *self, PyObject *args) + + if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) ) + return 0; +- if ( size != 1 && size != 2 && size != 4 ) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_parameters(len, size)) ++ return NULL; + for ( i=0; i 0,1 */ + for ( i=0; i= 1"); + return NULL; +@@ -1269,11 +1277,8 @@ audioop_lin2ulaw(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw", + &cp, &len, &size) ) + return 0 ; +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_parameters(len, size)) ++ return NULL; + + rv = PyString_FromStringAndSize(NULL, len/size); + if ( rv == 0 ) +@@ -1303,11 +1308,8 @@ audioop_ulaw2lin(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin", + &cp, &len, &size) ) + return 0; +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_size(size)) ++ return NULL; + + new_len = len*size; + if (new_len < 0) { +@@ -1343,11 +1345,8 @@ audioop_lin2alaw(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#i:lin2alaw", + &cp, &len, &size) ) + return 0; +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_parameters(len, size)) ++ return NULL; + + rv = PyString_FromStringAndSize(NULL, len/size); + if ( rv == 0 ) +@@ -1377,11 +1376,8 @@ audioop_alaw2lin(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#i:alaw2lin", + &cp, &len, &size) ) + return 0; +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_size(size)) ++ return NULL; + + new_len = len*size; + if (new_len < 0) { +@@ -1418,12 +1414,8 @@ audioop_lin2adpcm(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm", + &cp, &len, &size, &state) ) + return 0; +- +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_parameters(len, size)) ++ return NULL; + + str = PyString_FromStringAndSize(NULL, len/(size*2)); + if ( str == 0 ) +@@ -1526,11 +1518,8 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) + if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin", + &cp, &len, &size, &state) ) + return 0; +- +- if ( size != 1 && size != 2 && size != 4) { +- PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); +- return 0; +- } ++ if (!audioop_check_size(size)) ++ return NULL; + + /* Decode state, should have (value, step) */ + if ( state == Py_None ) { +-- +1.6.0.4 + diff --git a/python.spec b/python.spec index b1c1068..2e86495 100644 --- a/python.spec +++ b/python.spec @@ -59,7 +59,7 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{python} Version: 2.6.4 -Release: 26%{?dist} +Release: 27%{?dist} License: Python Group: Development/Languages Provides: python-abi = %{pybasever} @@ -299,6 +299,18 @@ Patch110: python-2.6-ctypes-noexecmem.patch # a libpythonMAJOR.MINOR.a (bug 550692): Patch111: python-2.6.4-no-static-lib.patch +# CVE-2010-1634: fix various integer overflow checks in the audioop module +# This is the difference from r81031 to r81080 (i.e r81046 and r81080), but +# backported to the old layout before the whitespeace cleanup to +# release26-maint (in r81031): +Patch116: python-2.6.2-CVE-2010-1634.patch + +# CVE-2010-2089: verify sizes/lengths within audioop module: +Patch117: python-2.6.2-CVE-2010-2089.patch + +# CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (backported to +# the old layout before the whitespeace cleanup of release26-maint in r81031): +Patch118: python-2.6.2-CVE-2008-5983.patch %if %{main_python} Obsoletes: Distutils @@ -499,15 +511,19 @@ rm -r Modules/zlib || exit 1 %patch111 -p1 -b .no-static-lib +%patch116 -p1 -b .CVE-2010-1634 +%patch117 -p1 -b .CVE-2010-2089 +%patch118 -p1 -b .CVE-2008-5983 + # This shouldn't be necesarry, but is right now (2.2a3) find -name "*~" |xargs rm -f %build topdir=$(pwd) -export CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC" -export CXXFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC" +export CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export CXXFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" export CPPFLAGS="$(pkg-config --cflags-only-I libffi)" -export OPT="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC" +export OPT="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" export LINKCC="gcc" if pkg-config openssl ; then export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)" @@ -964,6 +980,13 @@ rm -fr %{buildroot} # payload file would be unpackaged) %changelog +* Fri Jun 4 2010 David Malcolm - 2.6.4-27 +- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819) +- CVE-2010-1634: fix various integer overflow checks in the audioop +module (patch 113) +- CVE-2010-2089: further checks within the audioop module (patch 114) +- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 115) + * Mon Apr 26 2010 Dennis Gilmore - 2.6.4-26 - disable --with-valgrind on sparc arches