From 15f68138d4d0ff56704217369facc8baf03783a5 Mon Sep 17 00:00:00 2001 From: Tudor Florea Date: Tue, 22 Sep 2015 01:38:33 +0200 Subject: python: Backport CVE-2013-1752 fix from upstream Signed-off-by: Tudor Florea --- .../python-2.7.3-CVE-2013-1752-ftplib-fix.patch | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 meta/recipes-devtools/python/python/python-2.7.3-CVE-2013-1752-ftplib-fix.patch (limited to 'meta/recipes-devtools/python/python/python-2.7.3-CVE-2013-1752-ftplib-fix.patch') diff --git a/meta/recipes-devtools/python/python/python-2.7.3-CVE-2013-1752-ftplib-fix.patch b/meta/recipes-devtools/python/python/python-2.7.3-CVE-2013-1752-ftplib-fix.patch new file mode 100644 index 0000000000..97c890e777 --- /dev/null +++ b/meta/recipes-devtools/python/python/python-2.7.3-CVE-2013-1752-ftplib-fix.patch @@ -0,0 +1,149 @@ + +# HG changeset patch +# User Serhiy Storchaka +# Date 1382277427 -10800 +# Node ID 44ac81e6d584758ee56a865a7c18d82505be0643 +# Parent 625ece68d79a27d376889579c414ed4b2d8a2649 +Issue #16038: CVE-2013-1752: ftplib: Limit amount of data read by +limiting the call to readline(). Original patch by Michał +Jastrzębski and Giampaolo Rodola. + +diff --git a/Lib/ftplib.py b/Lib/ftplib.py +--- a/Lib/ftplib.py ++++ b/Lib/ftplib.py +@@ -55,6 +55,8 @@ MSG_OOB = 0x1 + + # The standard FTP server control port + FTP_PORT = 21 ++# The sizehint parameter passed to readline() calls ++MAXLINE = 8192 + + + # Exception raised when an error or invalid response is received +@@ -101,6 +103,7 @@ class FTP: + debugging = 0 + host = '' + port = FTP_PORT ++ maxline = MAXLINE + sock = None + file = None + welcome = None +@@ -180,7 +183,9 @@ class FTP: + # Internal: return one line from the server, stripping CRLF. + # Raise EOFError if the connection is closed + def getline(self): +- line = self.file.readline() ++ line = self.file.readline(self.maxline + 1) ++ if len(line) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if self.debugging > 1: + print '*get*', self.sanitize(line) + if not line: raise EOFError +@@ -432,7 +437,9 @@ class FTP: + conn = self.transfercmd(cmd) + fp = conn.makefile('rb') + while 1: +- line = fp.readline() ++ line = fp.readline(self.maxline + 1) ++ if len(line) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if self.debugging > 2: print '*retr*', repr(line) + if not line: + break +@@ -485,7 +492,9 @@ class FTP: + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + while 1: +- buf = fp.readline() ++ buf = fp.readline(self.maxline + 1) ++ if len(buf) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if not buf: break + if buf[-2:] != CRLF: + if buf[-1] in CRLF: buf = buf[:-1] +@@ -710,7 +719,9 @@ else: + fp = conn.makefile('rb') + try: + while 1: +- line = fp.readline() ++ line = fp.readline(self.maxline + 1) ++ if len(line) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if self.debugging > 2: print '*retr*', repr(line) + if not line: + break +@@ -748,7 +759,9 @@ else: + conn = self.transfercmd(cmd) + try: + while 1: +- buf = fp.readline() ++ buf = fp.readline(self.maxline + 1) ++ if len(buf) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if not buf: break + if buf[-2:] != CRLF: + if buf[-1] in CRLF: buf = buf[:-1] +@@ -905,7 +918,9 @@ class Netrc: + fp = open(filename, "r") + in_macro = 0 + while 1: +- line = fp.readline() ++ line = fp.readline(self.maxline + 1) ++ if len(line) > self.maxline: ++ raise Error("got more than %d bytes" % self.maxline) + if not line: break + if in_macro and line.strip(): + macro_lines.append(line) +diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py +--- a/Lib/test/test_ftplib.py ++++ b/Lib/test/test_ftplib.py +@@ -65,6 +65,7 @@ class DummyFTPHandler(asynchat.async_cha + self.last_received_data = '' + self.next_response = '' + self.rest = None ++ self.next_retr_data = RETR_DATA + self.push('220 welcome') + + def collect_incoming_data(self, data): +@@ -189,7 +190,7 @@ class DummyFTPHandler(asynchat.async_cha + offset = int(self.rest) + else: + offset = 0 +- self.dtp.push(RETR_DATA[offset:]) ++ self.dtp.push(self.next_retr_data[offset:]) + self.dtp.close_when_done() + self.rest = None + +@@ -203,6 +204,11 @@ class DummyFTPHandler(asynchat.async_cha + self.dtp.push(NLST_DATA) + self.dtp.close_when_done() + ++ def cmd_setlongretr(self, arg): ++ # For testing. Next RETR will return long line. ++ self.next_retr_data = 'x' * int(arg) ++ self.push('125 setlongretr ok') ++ + + class DummyFTPServer(asyncore.dispatcher, threading.Thread): + +@@ -558,6 +564,20 @@ class TestFTPClass(TestCase): + # IPv4 is in use, just make sure send_epsv has not been used + self.assertEqual(self.server.handler.last_received_cmd, 'pasv') + ++ def test_line_too_long(self): ++ self.assertRaises(ftplib.Error, self.client.sendcmd, ++ 'x' * self.client.maxline * 2) ++ ++ def test_retrlines_too_long(self): ++ self.client.sendcmd('SETLONGRETR %d' % (self.client.maxline * 2)) ++ received = [] ++ self.assertRaises(ftplib.Error, ++ self.client.retrlines, 'retr', received.append) ++ ++ def test_storlines_too_long(self): ++ f = StringIO.StringIO('x' * self.client.maxline * 2) ++ self.assertRaises(ftplib.Error, self.client.storlines, 'stor', f) ++ + + class TestIPv6Environment(TestCase): + -- cgit v1.2.3-54-g00ecf