summaryrefslogtreecommitdiff
path: root/lang/python25
diff options
context:
space:
mode:
authordrochner <drochner@pkgsrc.org>2011-03-28 15:58:15 +0000
committerdrochner <drochner@pkgsrc.org>2011-03-28 15:58:15 +0000
commit0f2ea06e1a2092cf4453b384c7a75cfa967eb9eb (patch)
tree4ad97e0a8c855822288b548b390ee6dc86dfefa5 /lang/python25
parentb63c7917f6eceec40f47bc7e31f59a2a6512fee0 (diff)
downloadpkgsrc-0f2ea06e1a2092cf4453b384c7a75cfa967eb9eb.tar.gz
fix two security issues, using patches from upstream:
-stricter redirect handling in urllib, to prevent redirects to eg "file://" URLs (CVE-2011-1521) -stricter argument checks in the audioop module (CVE-2010-2089)
Diffstat (limited to 'lang/python25')
-rw-r--r--lang/python25/Makefile4
-rw-r--r--lang/python25/distinfo5
-rw-r--r--lang/python25/patches/patch-ba29
-rw-r--r--lang/python25/patches/patch-bb21
-rw-r--r--lang/python25/patches/patch-bc348
5 files changed, 404 insertions, 3 deletions
diff --git a/lang/python25/Makefile b/lang/python25/Makefile
index 3180cd52704..2dbad064020 100644
--- a/lang/python25/Makefile
+++ b/lang/python25/Makefile
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.30 2011/03/06 03:24:11 dholland Exp $
+# $NetBSD: Makefile,v 1.31 2011/03/28 15:58:15 drochner Exp $
.include "dist.mk"
PKGNAME= python25-${PY_DISTVERSION}
-PKGREVISION= 2
+PKGREVISION= 3
CATEGORIES= lang python
MAINTAINER= pkgsrc-users@NetBSD.org
diff --git a/lang/python25/distinfo b/lang/python25/distinfo
index 301c75648b1..4b767e50469 100644
--- a/lang/python25/distinfo
+++ b/lang/python25/distinfo
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.14 2011/03/06 03:24:11 dholland Exp $
+$NetBSD: distinfo,v 1.15 2011/03/28 15:58:15 drochner Exp $
SHA1 (Python-2.5.5.tar.bz2) = dcf1abd94a1ab4155dcd3668cca42c5bfc81159f
RMD160 (Python-2.5.5.tar.bz2) = 4754238d415142466778560d989582464385654c
@@ -23,3 +23,6 @@ SHA1 (patch-ar) = 2a0c3f9a798afdfda7af4823e67579b2e000c072
SHA1 (patch-at) = 6fdd64ce70eb8c2de5336f3415f45bc467e46373
SHA1 (patch-au) = c1a759765095d246151ba027ed06f423e05c9218
SHA1 (patch-av) = a1d41cb3a93879d54f0964ff84a63a297c333156
+SHA1 (patch-ba) = aa0ad5a9dff1cd7c1c456aa6371733727ac1425b
+SHA1 (patch-bb) = 56beb934d46edd77b42bc89766a9ab921a42f8f9
+SHA1 (patch-bc) = 7d73c761c581b55d2810719ddd606d1a2c874714
diff --git a/lang/python25/patches/patch-ba b/lang/python25/patches/patch-ba
new file mode 100644
index 00000000000..018ac9983c1
--- /dev/null
+++ b/lang/python25/patches/patch-ba
@@ -0,0 +1,29 @@
+$NetBSD: patch-ba,v 1.3 2011/03/28 15:58:15 drochner Exp $
+
+Issue #11662 (CVE-2011-1521)
+
+--- Lib/urllib.py.orig 2007-03-14 08:27:57.000000000 +0000
++++ Lib/urllib.py
+@@ -638,10 +638,20 @@ class FancyURLopener(URLopener):
+ newurl = headers['uri']
+ else:
+ return
+- void = fp.read()
+- fp.close()
++
+ # In case the server sent a relative URL, join with original:
+ newurl = basejoin(self.type + ":" + url, newurl)
++
++ # For security reasons we do not allow redirects to protocols
++ # other than HTTP, HTTPS or FTP.
++ newurl_lower = newurl.lower()
++ if not (newurl_lower.startswith('http://') or
++ newurl_lower.startswith('https://') or
++ newurl_lower.startswith('ftp://')):
++ return
++
++ void = fp.read()
++ fp.close()
+ return self.open(newurl)
+
+ def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
diff --git a/lang/python25/patches/patch-bb b/lang/python25/patches/patch-bb
new file mode 100644
index 00000000000..061659d0a5e
--- /dev/null
+++ b/lang/python25/patches/patch-bb
@@ -0,0 +1,21 @@
+$NetBSD: patch-bb,v 1.3 2011/03/28 15:58:15 drochner Exp $
+
+Issue #11662 (CVE-2011-1521)
+
+--- Lib/urllib2.py.orig 2008-04-22 21:17:18.000000000 +0000
++++ Lib/urllib2.py
+@@ -555,6 +555,14 @@ class HTTPRedirectHandler(BaseHandler):
+ return
+ newurl = urlparse.urljoin(req.get_full_url(), newurl)
+
++ # For security reasons we do not allow redirects to protocols
++ # other than HTTP, HTTPS or FTP.
++ newurl_lower = newurl.lower()
++ if not (newurl_lower.startswith('http://') or
++ newurl_lower.startswith('https://') or
++ newurl_lower.startswith('ftp://')):
++ return
++
+ # XXX Probably want to forget about the state of the current
+ # request, although that might interact poorly with other
+ # handlers that also use handler-specific request attributes
diff --git a/lang/python25/patches/patch-bc b/lang/python25/patches/patch-bc
new file mode 100644
index 00000000000..5eb5e15d3b3
--- /dev/null
+++ b/lang/python25/patches/patch-bc
@@ -0,0 +1,348 @@
+$NetBSD: patch-bc,v 1.3 2011/03/28 15:58:15 drochner Exp $
+
+Issue #8674/#7673
+
+--- Modules/audioop.c.orig 2008-02-14 11:26:18.000000000 +0000
++++ 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, PyObje
+
+ 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 *ar
+
+ 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
+
+ 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 *ar
+
+ 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 *ar
+
+ 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);
+@@ -609,10 +622,8 @@ audioop_avgpp(PyObject *self, PyObject *
+
+ 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
+ */
+@@ -666,10 +677,8 @@ audioop_maxpp(PyObject *self, PyObject *
+
+ 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
+ */
+@@ -717,10 +726,8 @@ audioop_cross(PyObject *self, PyObject *
+
+ 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) {
+@@ -745,6 +752,8 @@ audioop_mul(PyObject *self, PyObject *ar
+
+ 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;
+@@ -787,6 +796,12 @@ audioop_tomono(PyObject *self, PyObject
+ 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;
+@@ -832,6 +847,8 @@ audioop_tostereo(PyObject *self, PyObjec
+ 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;
+@@ -891,7 +908,8 @@ audioop_add(PyObject *self, PyObject *ar
+ 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;
+@@ -946,10 +964,8 @@ audioop_bias(PyObject *self, PyObject *a
+ &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 )
+@@ -982,10 +998,8 @@ audioop_reverse(PyObject *self, PyObject
+ &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);
+ if ( rv == 0 )
+@@ -1019,11 +1033,10 @@ audioop_lin2lin(PyObject *self, PyObject
+ &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) {
+@@ -1075,10 +1088,8 @@ audioop_ratecv(PyObject *self, PyObject
+ &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;
+@@ -1154,25 +1165,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,
+@@ -1265,10 +1267,8 @@ audioop_lin2ulaw(PyObject *self, PyObjec
+ &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 )
+@@ -1299,10 +1299,8 @@ audioop_ulaw2lin(PyObject *self, PyObjec
+ &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;
+
+ new_len = len*size;
+ if (new_len < 0) {
+@@ -1339,10 +1337,8 @@ audioop_lin2alaw(PyObject *self, PyObjec
+ &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 )
+@@ -1373,10 +1369,8 @@ audioop_alaw2lin(PyObject *self, PyObjec
+ &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;
+
+ new_len = len*size;
+ if (new_len < 0) {
+@@ -1414,12 +1408,9 @@ audioop_lin2adpcm(PyObject *self, PyObje
+ &cp, &len, &size, &state) )
+ 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;
+- }
+-
+ str = PyString_FromStringAndSize(NULL, len/(size*2));
+ if ( str == 0 )
+ return 0;
+@@ -1522,10 +1513,8 @@ audioop_adpcm2lin(PyObject *self, PyObje
+ &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;
+
+ /* Decode state, should have (value, step) */
+ if ( state == Py_None ) {