Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2acc456

Browse files
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.
2 parents 6de9200 + c30b178 commit 2acc456

3 files changed

Lines changed: 37 additions & 4 deletions

File tree

Lib/ftplib.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050

5151
# The standard FTP server control port
5252
FTP_PORT = 21
53+
# The sizehint parameter passed to readline() calls
54+
MAXLINE = 8192
5355

5456

5557
# Exception raised when an error or invalid response is received
@@ -97,6 +99,7 @@ class FTP:
9799
debugging = 0
98100
host = ''
99101
port = FTP_PORT
102+
maxline = MAXLINE
100103
sock = None
101104
file = None
102105
welcome = None
@@ -197,7 +200,9 @@ def putcmd(self, line):
197200
# Internal: return one line from the server, stripping CRLF.
198201
# Raise EOFError if the connection is closed
199202
def getline(self):
200-
line = self.file.readline()
203+
line = self.file.readline(self.maxline + 1)
204+
if len(line) > self.maxline:
205+
raise Error("got more than %d bytes" % self.maxline)
201206
if self.debugging > 1:
202207
print('*get*', self.sanitize(line))
203208
if not line:
@@ -463,7 +468,9 @@ def retrlines(self, cmd, callback = None):
463468
with self.transfercmd(cmd) as conn, \
464469
conn.makefile('r', encoding=self.encoding) as fp:
465470
while 1:
466-
line = fp.readline()
471+
line = fp.readline(self.maxline + 1)
472+
if len(line) > self.maxline:
473+
raise Error("got more than %d bytes" % self.maxline)
467474
if self.debugging > 2:
468475
print('*retr*', repr(line))
469476
if not line:
@@ -522,7 +529,9 @@ def storlines(self, cmd, fp, callback=None):
522529
self.voidcmd('TYPE A')
523530
with self.transfercmd(cmd) as conn:
524531
while 1:
525-
buf = fp.readline()
532+
buf = fp.readline(self.maxline + 1)
533+
if len(buf) > self.maxline:
534+
raise Error("got more than %d bytes" % self.maxline)
526535
if not buf:
527536
break
528537
if buf[-2:] != B_CRLF:

Lib/test/test_ftplib.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def __init__(self, conn):
9292
self.next_response = ''
9393
self.next_data = None
9494
self.rest = None
95+
self.next_retr_data = RETR_DATA
9596
self.push('220 welcome')
9697

9798
def collect_incoming_data(self, data):
@@ -221,7 +222,7 @@ def cmd_retr(self, arg):
221222
offset = int(self.rest)
222223
else:
223224
offset = 0
224-
self.dtp.push(RETR_DATA[offset:])
225+
self.dtp.push(self.next_retr_data[offset:])
225226
self.dtp.close_when_done()
226227
self.rest = None
227228

@@ -243,6 +244,11 @@ def cmd_mlsd(self, arg):
243244
self.dtp.push(MLSD_DATA)
244245
self.dtp.close_when_done()
245246

247+
def cmd_setlongretr(self, arg):
248+
# For testing. Next RETR will return long line.
249+
self.next_retr_data = 'x' * int(arg)
250+
self.push('125 setlongretr ok')
251+
246252

247253
class DummyFTPServer(asyncore.dispatcher, threading.Thread):
248254

@@ -759,6 +765,20 @@ def test_parse257(self):
759765
self.assertEqual(ftplib.parse257('257 "/foo/b""ar"'), '/foo/b"ar')
760766
self.assertEqual(ftplib.parse257('257 "/foo/b""ar" created'), '/foo/b"ar')
761767

768+
def test_line_too_long(self):
769+
self.assertRaises(ftplib.Error, self.client.sendcmd,
770+
'x' * self.client.maxline * 2)
771+
772+
def test_retrlines_too_long(self):
773+
self.client.sendcmd('SETLONGRETR %d' % (self.client.maxline * 2))
774+
received = []
775+
self.assertRaises(ftplib.Error,
776+
self.client.retrlines, 'retr', received.append)
777+
778+
def test_storlines_too_long(self):
779+
f = io.BytesIO(b'x' * self.client.maxline * 2)
780+
self.assertRaises(ftplib.Error, self.client.storlines, 'stor', f)
781+
762782

763783
class TestIPv6Environment(TestCase):
764784

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ Core and Builtins
6262
Library
6363
-------
6464

65+
- Issue #16038: CVE-2013-1752: ftplib: Limit amount of data read by
66+
limiting the call to readline(). Original patch by Michał
67+
Jastrzębski and Giampaolo Rodola.
68+
6569
- Issue #17087: Improved the repr for regular expression match objects.
6670

6771
- Issue #18235: Fix the sysconfig variables LDSHARED and BLDSHARED under AIX.

0 commit comments

Comments
 (0)