diff options
author | drochner <drochner> | 2011-03-28 15:58:15 +0000 |
---|---|---|
committer | drochner <drochner> | 2011-03-28 15:58:15 +0000 |
commit | 444dab98c1ff51e18ca5197d62e526227dc80dca (patch) | |
tree | 4ad97e0a8c855822288b548b390ee6dc86dfefa5 /lang/python25/patches | |
parent | 2a5979075c7ded9657b0f18d20328ba55dc526c7 (diff) | |
download | pkgsrc-444dab98c1ff51e18ca5197d62e526227dc80dca.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/patches')
-rw-r--r-- | lang/python25/patches/patch-ba | 29 | ||||
-rw-r--r-- | lang/python25/patches/patch-bb | 21 | ||||
-rw-r--r-- | lang/python25/patches/patch-bc | 348 |
3 files changed, 398 insertions, 0 deletions
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 ) { |