bpo-39017: Avoid infinite loop in the tarfile module (GH-21454)

Avoid infinite loop when reading specially crafted TAR files using the tarfile module
(CVE-2019-20907).
This commit is contained in:
Rishi 2020-07-15 13:51:00 +02:00 committed by GitHub
parent bbceef6851
commit 5a8d121a1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 10 additions and 0 deletions

View File

@ -1249,6 +1249,8 @@ class TarInfo(object):
length, keyword = match.groups() length, keyword = match.groups()
length = int(length) length = int(length)
if length == 0:
raise InvalidHeaderError("invalid header")
value = buf[match.end(2) + 1:match.start(1) + length - 1] value = buf[match.end(2) + 1:match.start(1) + length - 1]
# Normally, we could just use "utf-8" as the encoding and "strict" # Normally, we could just use "utf-8" as the encoding and "strict"

BIN
Lib/test/recursion.tar Normal file

Binary file not shown.

View File

@ -429,6 +429,13 @@ class CommonReadTest(ReadTest):
with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"): with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"):
tar.extractfile(t).read() tar.extractfile(t).read()
def test_length_zero_header(self):
# bpo-39017 (CVE-2019-20907): reading a zero-length header should fail
# with an exception
with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"):
with tarfile.open(support.findfile('recursion.tar')) as tar:
pass
class MiscReadTestBase(CommonReadTest): class MiscReadTestBase(CommonReadTest):
def requires_name_attribute(self): def requires_name_attribute(self):
pass pass

View File

@ -0,0 +1 @@
Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907).