rkuska pushed to python (f21). "CVE-2013-1752 multiple unbound readline() DoS flaws in python stdlib (..more)"

notifications at fedoraproject.org notifications at fedoraproject.org
Fri Apr 10 08:47:41 UTC 2015


>From c319a065ae2b5c7aabb4fc8896b06ed63b079c0d Mon Sep 17 00:00:00 2001
From: Robert Kuska <rkuska at redhat.com>
Date: Fri, 10 Apr 2015 09:54:27 +0200
Subject: CVE-2013-1752 multiple unbound readline() DoS flaws in python stdlib
 Resolves: rhbz#1159200


diff --git a/00196-fix-CVE-2013-1752.patch b/00196-fix-CVE-2013-1752.patch
new file mode 100644
index 0000000..06d57d1
--- /dev/null
+++ b/00196-fix-CVE-2013-1752.patch
@@ -0,0 +1,159 @@
+# HG changeset patch
+# User Benjamin Peterson <benjamin at python.org>
+# Date 1417827758 18000
+# Node ID 339f877cca115c1901f5dd93d7bc066031d2a669
+# Parent  54af094087953f4997a4ead63e949d845c4b4412
+in poplib, limit maximum line length that we read from the network (closes #16041)
+
+Patch from Berker Peksag.
+
+diff --git a/Lib/poplib.py b/Lib/poplib.py
+--- a/Lib/poplib.py
++++ b/Lib/poplib.py
+@@ -32,6 +32,12 @@ CR = '\r'
+ LF = '\n'
+ CRLF = CR+LF
+ 
++# maximal line length when calling readline(). This is to prevent
++# reading arbitrary length lines. RFC 1939 limits POP3 line length to
++# 512 characters, including CRLF. We have selected 2048 just to be on
++# the safe side.
++_MAXLINE = 2048
++
+ 
+ class POP3:
+ 
+@@ -103,7 +109,9 @@ class POP3:
+     # Raise error_proto('-ERR EOF') if the connection is closed.
+ 
+     def _getline(self):
+-        line = self.file.readline()
++        line = self.file.readline(_MAXLINE + 1)
++        if len(line) > _MAXLINE:
++            raise error_proto('line too long')
+         if self._debugging > 1: print '*get*', repr(line)
+         if not line: raise error_proto('-ERR EOF')
+         octets = len(line)
+@@ -365,6 +373,8 @@ else:
+             match = renewline.match(self.buffer)
+             while not match:
+                 self._fillBuffer()
++                if len(self.buffer) > _MAXLINE:
++                    raise error_proto('line too long')
+                 match = renewline.match(self.buffer)
+             line = match.group(0)
+             self.buffer = renewline.sub('' ,self.buffer, 1)
+diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
+--- a/Lib/test/test_poplib.py
++++ b/Lib/test/test_poplib.py
+@@ -198,6 +198,10 @@ class TestPOP3Class(TestCase):
+                     113)
+         self.assertEqual(self.client.retr('foo'), expected)
+ 
++    def test_too_long_lines(self):
++        self.assertRaises(poplib.error_proto, self.client._shortcmd,
++                          'echo +%s' % ((poplib._MAXLINE + 10) * 'a'))
++
+     def test_dele(self):
+         self.assertOK(self.client.dele('foo'))
+ 
+
+# HG changeset patch
+# User Benjamin Peterson <benjamin at python.org>
+# Date 1417827918 18000
+# Node ID 923aac88a3cc76a95d5a04d9d3ece245147a8064
+# Parent  339f877cca115c1901f5dd93d7bc066031d2a669
+smtplib: limit amount read from the network (closes #16042)
+
+diff --git a/Lib/smtplib.py b/Lib/smtplib.py
+--- a/Lib/smtplib.py
++++ b/Lib/smtplib.py
+@@ -57,6 +57,7 @@ from sys import stderr
+ SMTP_PORT = 25
+ SMTP_SSL_PORT = 465
+ CRLF = "\r\n"
++_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3
+ 
+ OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
+ 
+@@ -179,10 +180,14 @@ else:
+         def __init__(self, sslobj):
+             self.sslobj = sslobj
+ 
+-        def readline(self):
++        def readline(self, size=-1):
++            if size < 0:
++                size = None
+             str = ""
+             chr = None
+             while chr != "\n":
++                if size is not None and len(str) >= size:
++                    break
+                 chr = self.sslobj.read(1)
+                 if not chr:
+                     break
+@@ -353,7 +358,7 @@ class SMTP:
+             self.file = self.sock.makefile('rb')
+         while 1:
+             try:
+-                line = self.file.readline()
++                line = self.file.readline(_MAXLINE + 1)
+             except socket.error as e:
+                 self.close()
+                 raise SMTPServerDisconnected("Connection unexpectedly closed: "
+@@ -363,6 +368,8 @@ class SMTP:
+                 raise SMTPServerDisconnected("Connection unexpectedly closed")
+             if self.debuglevel > 0:
+                 print>>stderr, 'reply:', repr(line)
++            if len(line) > _MAXLINE:
++                raise SMTPResponseException(500, "Line too long.")
+             resp.append(line[4:].strip())
+             code = line[:3]
+             # Check that the error code is syntactically correct.
+diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
+--- a/Lib/test/test_smtplib.py
++++ b/Lib/test/test_smtplib.py
+@@ -292,6 +292,33 @@ class BadHELOServerTests(unittest.TestCa
+                             HOST, self.port, 'localhost', 3)
+ 
+ 
++ at unittest.skipUnless(threading, 'Threading required for this test.')
++class TooLongLineTests(unittest.TestCase):
++    respdata = '250 OK' + ('.' * smtplib._MAXLINE * 2) + '\n'
++
++    def setUp(self):
++        self.old_stdout = sys.stdout
++        self.output = StringIO.StringIO()
++        sys.stdout = self.output
++
++        self.evt = threading.Event()
++        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++        self.sock.settimeout(15)
++        self.port = test_support.bind_port(self.sock)
++        servargs = (self.evt, self.respdata, self.sock)
++        threading.Thread(target=server, args=servargs).start()
++        self.evt.wait()
++        self.evt.clear()
++
++    def tearDown(self):
++        self.evt.wait()
++        sys.stdout = self.old_stdout
++
++    def testLineTooLong(self):
++        self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP,
++                          HOST, self.port, 'localhost', 3)
++
++
+ sim_users = {'Mr.A at somewhere.com':'John A',
+              'Ms.B at somewhere.com':'Sally B',
+              'Mrs.C at somewhereesle.com':'Ruth C',
+@@ -526,7 +553,8 @@ class SMTPSimTests(unittest.TestCase):
+ def test_main(verbose=None):
+     test_support.run_unittest(GeneralTests, DebuggingServerTests,
+                               NonConnectingTests,
+-                              BadHELOServerTests, SMTPSimTests)
++                              BadHELOServerTests, SMTPSimTests,
++                              TooLongLineTests)
+ 
+ if __name__ == '__main__':
+     test_main()
diff --git a/python.spec b/python.spec
index b019a26..45b17b7 100644
--- a/python.spec
+++ b/python.spec
@@ -106,7 +106,7 @@ Summary: An interpreted, interactive, object-oriented programming language
 Name: %{python}
 # Remember to also rebase python-docs when changing this:
 Version: 2.7.8
-Release: 7%{?dist}
+Release: 8%{?dist}
 License: Python
 Group: Development/Languages
 Requires: %{python}-libs%{?_isa} = %{version}-%{release}
@@ -886,6 +886,14 @@ Patch193: 00193-enable-loading-sqlite-extensions.patch
 #         check if (self->ctx == NULL) is needed
 #Patch195: 00195-enable-sslv23-in-ssl.patch
 
+
+# multiple unbound readline() DoS flaws in python stdlib
+# CVE-2013-1752
+# following fixes (which all relates to this CVE) are in this patch:
+# * poplib: limit maximum line length that we read from the network #16041
+# * smtplib: limit amount read from the network #16042
+Patch196: 00196-fix-CVE-2013-1752.patch
+
 # (New patches go here ^^^)
 #
 # When adding new patches to "python" and "python3" in Fedora 17 onwards,
@@ -1243,6 +1251,7 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c
 %patch193 -p1
 # 00194: upstream as of Python 2.7.7
 #%patch195 -p1
+%patch196 -p1
 
 
 # This shouldn't be necesarry, but is right now (2.2a3)
@@ -2086,6 +2095,10 @@ rm -fr %{buildroot}
 # ======================================================
 
 %changelog
+* Fri Apr 10 2015 Robert Kuska <rkuska at redhat.com> - 2.7.8-8
+- Fix CVE-2013-1752 multiple unbound readline() DoS flaws in python stdlib
+Resolves: rhbz#1159200
+
 * Mon Nov 10 2014 Slavek Kabrda <bkabrda at redhat.com> - 2.7.8-7
 - Revert previous change, see rhbz#1161166#c6.
 
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/python.git/commit/?h=f21&id=c319a065ae2b5c7aabb4fc8896b06ed63b079c0d


More information about the scm-commits mailing list