rpms/python26/EL-5 python-2.6.2-CVE-2008-5983.patch, NONE, 1.1 python-2.6.2-CVE-2010-1634.patch, NONE, 1.1 python-2.6.2-CVE-2010-2089.patch, NONE, 1.1 python26.spec, 1.2, 1.3

dmalcolm dmalcolm at fedoraproject.org
Fri Jun 4 21:36:20 UTC 2010


Author: dmalcolm

Update of /cvs/pkgs/rpms/python26/EL-5
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv1972

Modified Files:
	python26.spec 
Added Files:
	python-2.6.2-CVE-2008-5983.patch 
	python-2.6.2-CVE-2010-1634.patch 
	python-2.6.2-CVE-2010-2089.patch 
Log Message:
* Fri Jun  4 2010 David Malcolm <dmalcolm at redhat.com> - 2.6.5-5
- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819)
- CVE-2010-1634: fix various integer overflow checks in the audioop
module (patch 116)
- CVE-2010-2089: further checks within the audioop module (patch 117)
- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 118)


python-2.6.2-CVE-2008-5983.patch:
 Doc/c-api/init.rst  |   38 +++++++++++++++++++++++++++++++++-----
 Include/sysmodule.h |    1 +
 Misc/NEWS           |    8 ++++++++
 Python/sysmodule.c  |   10 ++++++++--
 4 files changed, 50 insertions(+), 7 deletions(-)

--- NEW FILE python-2.6.2-CVE-2008-5983.patch ---
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 <http://cve.mitre.org/cgi-bin/cvename.cgi?name=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
+  <http://cve.mitre.org/cgi-bin/cvename.cgi?name=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.

python-2.6.2-CVE-2010-1634.patch:
 audioop.c |   74 ++++++++++++++++++++++++--------------------------------------
 1 file changed, 29 insertions(+), 45 deletions(-)

--- NEW FILE python-2.6.2-CVE-2010-1634.patch ---
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;

python-2.6.2-CVE-2010-2089.patch:
 audioop.c |  154 ++++++++++++++++++++++++++++----------------------------------
 1 file changed, 71 insertions(+), 83 deletions(-)

--- NEW FILE python-2.6.2-CVE-2010-2089.patch ---
>From ddc63ebe9b52c0ab4ba033301e70fac89f610704 Mon Sep 17 00:00:00 2001
From: Victor Stinner <victor.stinner at haypocalc.com>
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<len; i+= size) {
                 if ( size == 1 )      val = (int)*CHARP(cp, i);
                 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
@@ -352,10 +371,8 @@ audioop_minmax(PyObject *self, PyObject *args)
 
         if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
                 return NULL;
-        if (size != 1 && size != 2 && size != 4) {
-                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+        if (!audioop_check_parameters(len, size))
                 return NULL;
-        }
         for (i = 0; i < len; i += size) {
                 if (size == 1) val = (int) *CHARP(cp, i);
                 else if (size == 2) val = (int) *SHORTP(cp, i);
@@ -376,10 +393,8 @@ audioop_avg(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#i:avg", &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<len; i+= size) {
                 if ( size == 1 )      val = (int)*CHARP(cp, i);
                 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
@@ -403,10 +418,8 @@ audioop_rms(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#i:rms", &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<len; i+= size) {
                 if ( size == 1 )      val = (int)*CHARP(cp, i);
                 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
@@ -614,10 +627,8 @@ audioop_avgpp(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#i:avgpp", &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;
         /* Compute first delta value ahead. Also automatically makes us
         ** skip the first extreme value
         */
@@ -671,10 +682,8 @@ audioop_maxpp(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#i:maxpp", &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;
         /* Compute first delta value ahead. Also automatically makes us
         ** skip the first extreme value
         */
@@ -722,10 +731,8 @@ audioop_cross(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#i:cross", &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;
         ncross = -1;
         prevval = 17; /* Anything <> 0,1 */
         for ( i=0; i<len; i+= size) {
@@ -750,6 +757,8 @@ audioop_mul(PyObject *self, PyObject *args)
 
         if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
                 return 0;
+        if (!audioop_check_parameters(len, size))
+                return NULL;
     
         if ( size == 1 ) maxval = (double) 0x7f;
         else if ( size == 2 ) maxval = (double) 0x7fff;
@@ -792,6 +801,12 @@ audioop_tomono(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#idd:tomono",
 	                       &cp, &len, &size, &fac1, &fac2 ) )
                 return 0;
+        if (!audioop_check_parameters(len, size))
+                return NULL;
+        if ( ((len / size) & 1) != 0 ) {
+                PyErr_SetString(AudioopError, "not a whole number of frames");
+                return NULL;
+        }
     
         if ( size == 1 ) maxval = (double) 0x7f;
         else if ( size == 2 ) maxval = (double) 0x7fff;
@@ -837,6 +852,8 @@ audioop_tostereo(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
 	                       &cp, &len, &size, &fac1, &fac2 ) )
                 return 0;
+        if (!audioop_check_parameters(len, size))
+                return NULL;
     
         if ( size == 1 ) maxval = (double) 0x7f;
         else if ( size == 2 ) maxval = (double) 0x7fff;
@@ -896,7 +913,8 @@ audioop_add(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#s#i:add",
                           &cp1, &len1, &cp2, &len2, &size ) )
                 return 0;
-
+        if (!audioop_check_parameters(len1, size))
+                return NULL;
         if ( len1 != len2 ) {
                 PyErr_SetString(AudioopError, "Lengths should be the same");
                 return 0;
@@ -950,11 +968,8 @@ audioop_bias(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#ii:bias",
                           &cp, &len, &size , &bias) )
                 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);
         if ( rv == 0 )
@@ -986,12 +1001,9 @@ audioop_reverse(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#i:reverse",
                           &cp, &len, &size) )
                 return 0;
+        if (!audioop_check_parameters(len, size))
+                return NULL;
 
-        if ( size != 1 && size != 2 && size != 4 ) {
-                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-                return 0;
-        }
-    
         rv = PyString_FromStringAndSize(NULL, len);
         if ( rv == 0 )
                 return 0;
@@ -1023,12 +1035,10 @@ audioop_lin2lin(PyObject *self, PyObject *args)
         if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
                           &cp, &len, &size, &size2) )
                 return 0;
-
-        if ( (size != 1 && size != 2 && size != 4) ||
-             (size2 != 1 && size2 != 2 && size2 != 4)) {
-                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-                return 0;
-        }
+        if (!audioop_check_parameters(len, size))
+                return NULL;
+        if (!audioop_check_size(size2))
+                return NULL;
     
         new_len = (len/size)*size2;
         if (new_len < 0) {
@@ -1080,10 +1090,8 @@ audioop_ratecv(PyObject *self, PyObject *args)
 	                      &nchannels, &inrate, &outrate, &state,
 			      &weightA, &weightB))
                 return NULL;
-        if (size != 1 && size != 2 && size != 4) {
-                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+        if (!audioop_check_size(size))
                 return NULL;
-        }
         if (nchannels < 1) {
                 PyErr_SetString(AudioopError, "# of channels should be >= 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



Index: python26.spec
===================================================================
RCS file: /cvs/pkgs/rpms/python26/EL-5/python26.spec,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -p -r1.2 -r1.3
--- python26.spec	4 May 2010 19:47:46 -0000	1.2
+++ python26.spec	4 Jun 2010 21:36:20 -0000	1.3
@@ -99,7 +99,7 @@
 Summary: An interpreted, interactive, object-oriented programming language
 Name: %{python}
 Version: 2.6.5
-Release: 4%{?dist}
+Release: 5%{?dist}
 License: Python
 Group: Development/Languages
 Provides: python-abi = %{pybasever}
@@ -344,6 +344,19 @@ Patch110: python-2.6-ctypes-noexecmem.pa
 # 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
+
 # Patch up pyexpat.h so it will build against RHEL-5's pyexpat-devel:
 Patch200: python-2.6.4-expat-version.patch
 
@@ -560,6 +573,10 @@ 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
+
 %if 0%{?with_system_expat}
 %patch200 -p1 -b .expat-version
 %endif
@@ -575,10 +592,10 @@ 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)"
@@ -1175,6 +1192,13 @@ rm -fr %{buildroot}
 # payload file would be unpackaged)
 
 %changelog
+* Fri Jun  4 2010 David Malcolm <dmalcolm at redhat.com> - 2.6.5-5
+- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819)
+- CVE-2010-1634: fix various integer overflow checks in the audioop
+module (patch 116)
+- CVE-2010-2089: further checks within the audioop module (patch 117)
+- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 118)
+
 * Tue May  4 2010 David Malcolm <dmalcolm at redhat.com> - 2.6.5-4
 - don't delete wsgiref.egg-info (rhbz:588426)
 



More information about the scm-commits mailing list