diff --git a/python-2.7-CVE-2011-1521-fileurl.patch b/python-2.7-CVE-2011-1521-fileurl.patch new file mode 100644 index 0000000..2feae1a --- /dev/null +++ b/python-2.7-CVE-2011-1521-fileurl.patch @@ -0,0 +1,106 @@ + +# HG changeset patch +# User Guido van Rossum +# Date 1301428435 25200 +# Node ID b2934d98dac1f7b13cc6cc280f06d1aec3f6e80d +# Parent 1a5aab273332a7a379e35ed6f88400a110b5de0c# Parent 9eeda8e3a13f107a698f10b0a45ffc2c6bd710fb +Merge issue 11662 from 2.6. + +diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py +--- a/Lib/test/test_urllib.py ++++ b/Lib/test/test_urllib.py +@@ -161,6 +161,20 @@ Content-Type: text/html; charset=iso-885 + finally: + self.unfakehttp() + ++ def test_invalid_redirect(self): ++ # urlopen() should raise IOError for many error codes. ++ self.fakehttp("""HTTP/1.1 302 Found ++Date: Wed, 02 Jan 2008 03:03:54 GMT ++Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e ++Location: file:README ++Connection: close ++Content-Type: text/html; charset=iso-8859-1 ++""") ++ try: ++ self.assertRaises(IOError, urllib.urlopen, "http://python.org/") ++ finally: ++ self.unfakehttp() ++ + def test_empty_socket(self): + # urlopen() raises IOError if the underlying socket does not send any + # data. (#1680230) +diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py +--- a/Lib/test/test_urllib2.py ++++ b/Lib/test/test_urllib2.py +@@ -969,6 +969,27 @@ class HandlerTests(unittest.TestCase): + self.assertEqual(count, + urllib2.HTTPRedirectHandler.max_redirections) + ++ def test_invalid_redirect(self): ++ from_url = "http://example.com/a.html" ++ valid_schemes = ['http', 'https', 'ftp'] ++ invalid_schemes = ['file', 'imap', 'ldap'] ++ schemeless_url = "example.com/b.html" ++ h = urllib2.HTTPRedirectHandler() ++ o = h.parent = MockOpener() ++ req = Request(from_url) ++ ++ for scheme in invalid_schemes: ++ invalid_url = scheme + '://' + schemeless_url ++ self.assertRaises(urllib2.HTTPError, h.http_error_302, ++ req, MockFile(), 302, "Security Loophole", ++ MockHeaders({"location": invalid_url})) ++ ++ for scheme in valid_schemes: ++ valid_url = scheme + '://' + schemeless_url ++ h.http_error_302(req, MockFile(), 302, "That's fine", ++ MockHeaders({"location": valid_url})) ++ self.assertEqual(o.req.get_full_url(), valid_url) ++ + def test_cookie_redirect(self): + # cookies shouldn't leak into redirected requests + from cookielib import CookieJar +diff --git a/Lib/urllib.py b/Lib/urllib.py +--- a/Lib/urllib.py ++++ b/Lib/urllib.py +@@ -644,6 +644,18 @@ class FancyURLopener(URLopener): + 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://')): ++ raise IOError('redirect error', errcode, ++ errmsg + " - Redirection to url '%s' is not allowed" % ++ newurl, ++ headers) ++ + return self.open(newurl) + + def http_error_301(self, url, fp, errcode, errmsg, headers, data=None): +diff --git a/Lib/urllib2.py b/Lib/urllib2.py +--- a/Lib/urllib2.py ++++ b/Lib/urllib2.py +@@ -578,6 +578,17 @@ class HTTPRedirectHandler(BaseHandler): + + 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://')): ++ raise HTTPError(newurl, code, ++ msg + " - Redirection to url '%s' is not allowed" % ++ newurl, ++ headers, fp) ++ + # 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/python-2.7-fix-parallel-make.patch b/python-2.7-fix-parallel-make.patch new file mode 100644 index 0000000..d0f485b --- /dev/null +++ b/python-2.7-fix-parallel-make.patch @@ -0,0 +1,37 @@ +diff -up Python-2.7/Makefile.pre.in.fix-parallel-make Python-2.7/Makefile.pre.in +--- Python-2.7/Makefile.pre.in.fix-parallel-make 2010-07-22 15:01:39.567996932 -0400 ++++ Python-2.7/Makefile.pre.in 2010-07-22 15:47:02.437998509 -0400 +@@ -207,6 +207,7 @@ SIGNAL_OBJS= @SIGNAL_OBJS@ + + ########################################################################## + # Grammar ++GRAMMAR_STAMP= $(srcdir)/grammar-stamp + GRAMMAR_H= $(srcdir)/Include/graminit.h + GRAMMAR_C= $(srcdir)/Python/graminit.c + GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar +@@ -530,10 +531,24 @@ Modules/getpath.o: $(srcdir)/Modules/get + Modules/python.o: $(srcdir)/Modules/python.c + $(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c + ++# GNU "make" interprets rules with two dependents as two copies of the rule. ++# ++# In a parallel build this can lead to pgen being run twice, once for each of ++# GRAMMAR_H and GRAMMAR_C, leading to race conditions in which the compiler ++# reads a partially-overwritten copy of one of these files, leading to syntax ++# errors (or linker errors if the fragment happens to be syntactically valid C) ++# ++# See http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html ++# for more information ++# ++# Introduce ".grammar-stamp" as a contrived single output from PGEN to avoid ++# this: ++$(GRAMMAR_H) $(GRAMMAR_C): $(GRAMMAR_STAMP) + +-$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) ++$(GRAMMAR_STAMP): $(PGEN) $(GRAMMAR_INPUT) + -@$(INSTALL) -d Include + -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) ++ touch $(GRAMMAR_STAMP) + + $(PGEN): $(PGENOBJS) + $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN) diff --git a/python-base.changes b/python-base.changes index c3d4803..fa6b90e 100644 --- a/python-base.changes +++ b/python-base.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Mon May 2 16:04:49 UTC 2011 - jmatejek@novell.com + +- fixed a security flaw where malicious sites could redirect + Python application from http to a local file + (CVE-2011-1521, bnc#682554) +- fixed race condition in Makefile which randomly failed + parallel builds ( http://bugs.python.org/issue10013 ) + ------------------------------------------------------------------- Thu Feb 17 17:37:09 CET 2011 - pth@suse.de diff --git a/python-base.spec b/python-base.spec index 356107f..676ff68 100644 --- a/python-base.spec +++ b/python-base.spec @@ -53,6 +53,8 @@ Patch10: urllib2-AbstractBasicAuthHandler_reset_attr.diff Patch11: smtpd-dos.patch Patch12: http://psf.upfronthosting.co.za/roundup/tracker/file19029/python-test_structmembers.patch Patch13: python-fix_date_time_compiler.patch +Patch14: python-2.7-CVE-2011-1521-fileurl.patch +Patch15: python-2.7-fix-parallel-make.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define python_version %(echo %{version} | head -c 3) Provides: %{name} = %{python_version} @@ -145,8 +147,10 @@ Authors: %patch9 -p1 %patch10 %patch11 -%patch12 -p0 +%patch12 %patch13 +%patch14 -p1 +%patch15 -p1 # some cleanup find . -name .cvsignore -type f -print0 | xargs -0 rm -f