[Python-checkins] cpython (2.6): - Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to

barry.warsaw python-checkins at python.org
Tue Oct 1 01:10:14 CEST 2013


http://hg.python.org/cpython/rev/731abf7834c4
changeset:   85897:731abf7834c4
branch:      2.6
parent:      85895:3f09756916ce
user:        Barry Warsaw <barry at python.org>
date:        Mon Sep 30 18:35:15 2013 -0400
summary:
  - Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to
  prevent readline() calls from consuming too much memory.  Patch by Jyrki
  Pulliainen.

files:
  Lib/nntplib.py           |  11 ++++-
  Lib/test/test_nntplib.py |  65 ++++++++++++++++++++++++++++
  Misc/NEWS                |   4 +
  3 files changed, 79 insertions(+), 1 deletions(-)


diff --git a/Lib/nntplib.py b/Lib/nntplib.py
--- a/Lib/nntplib.py
+++ b/Lib/nntplib.py
@@ -37,6 +37,13 @@
            "error_reply","error_temp","error_perm","error_proto",
            "error_data",]
 
+# maximal line length when calling readline(). This is to prevent
+# reading arbitrary lenght lines. RFC 3977 limits NNTP line length to
+# 512 characters, including CRLF. We have selected 2048 just to be on
+# the safe side.
+_MAXLINE = 2048
+
+
 # Exceptions raised when an error or invalid response is received
 class NNTPError(Exception):
     """Base class for all nntplib exceptions"""
@@ -200,7 +207,9 @@
     def getline(self):
         """Internal: return one line from the server, stripping CRLF.
         Raise EOFError if the connection is closed."""
-        line = self.file.readline()
+        line = self.file.readline(_MAXLINE + 1)
+        if len(line) > _MAXLINE:
+            raise NNTPDataError('line too long')
         if self.debugging > 1:
             print '*get*', repr(line)
         if not line: raise EOFError
diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_nntplib.py
@@ -0,0 +1,65 @@
+import socket
+import threading
+import nntplib
+import time
+
+from unittest import TestCase
+from test import test_support
+
+HOST = test_support.HOST
+
+
+def server(evt, serv, evil=False):
+    serv.listen(5)
+    try:
+        conn, addr = serv.accept()
+    except socket.timeout:
+        pass
+    else:
+        if evil:
+            conn.send("1 I'm too long response" * 3000 + "\n")
+        else:
+            conn.send("1 I'm OK response\n")
+        conn.close()
+    finally:
+        serv.close()
+        evt.set()
+
+
+class BaseServerTest(TestCase):
+    def setUp(self):
+        self.evt = threading.Event()
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.sock.settimeout(3)
+        self.port = test_support.bind_port(self.sock)
+        threading.Thread(
+            target=server,
+            args=(self.evt, self.sock, self.evil)).start()
+        time.sleep(.1)
+
+    def tearDown(self):
+        self.evt.wait()
+
+
+class ServerTests(BaseServerTest):
+    evil = False
+
+    def test_basic_connect(self):
+        nntp = nntplib.NNTP('localhost', self.port)
+        nntp.sock.close()
+
+
+class EvilServerTests(BaseServerTest):
+    evil = True
+
+    def test_too_long_line(self):
+        self.assertRaises(nntplib.NNTPDataError,
+                          nntplib.NNTP, 'localhost', self.port)
+
+
+def test_main(verbose=None):
+    test_support.run_unittest(EvilServerTests)
+    test_support.run_unittest(ServerTests)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -20,6 +20,10 @@
   prevent readline() calls from consuming too much memory.  Patch by Jyrki
   Pulliainen.
 
+- Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to
+  prevent readline() calls from consuming too much memory.  Patch by Jyrki
+  Pulliainen.
+
 - Issue #16039: CVE-2013-1752: Change use of readline in imaplib module to
   limit line length.  Patch by Emil Lind.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list