From 3b6fb6241d9a2efe81bdb60aeabcbf8a422a4aa7a8961beee27b1c1c9766f41b Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Sat, 18 May 2024 16:51:08 +0000 Subject: [PATCH] - bsc#1221854 (CVE-2024-0450) Add CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch detecting the vulnerability of the "quoted-overlap" zipbomb (from gh#python/cpython!110016). OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=416 --- ...zipfile-avoid-quoted-overlap-zipbomb.patch | 144 ++++++++++++++++++ python-base.changes | 8 + python-base.spec | 4 + python-doc.changes | 8 + python-doc.spec | 4 + python.changes | 8 + python.spec | 4 + 7 files changed, 180 insertions(+) create mode 100644 CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch diff --git a/CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch b/CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch new file mode 100644 index 0000000..5eb04c7 --- /dev/null +++ b/CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch @@ -0,0 +1,144 @@ +From d8877aaabe9aa5d9b9904c222c552f3c6a85017c Mon Sep 17 00:00:00 2001 +From: Serhiy Storchaka +Date: Wed, 17 Jan 2024 15:41:50 +0200 +Subject: [PATCH] [CVE-2024-0450] Protect zipfile from "quoted-overlap" zipbomb + +Raise BadZipFile when try to read an entry that overlaps with +other entry or central directory. +(cherry picked from commit 66363b9a7b9fe7c99eba3a185b74c5fdbf842eba) + +From-PR: gh#python/cpython!110016 +Fixes: gh#python/cpython#109858 +Patch: CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch +--- + Lib/test/test_zipfile.py | 61 ++++++++++ + Lib/zipfile.py | 12 + + Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst | 3 + 3 files changed, 76 insertions(+) + create mode 100644 Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst + +--- a/Lib/test/test_zipfile.py ++++ b/Lib/test/test_zipfile.py +@@ -11,6 +11,7 @@ import unittest + + from tempfile import TemporaryFile + from random import randint, random, getrandbits ++from unittest import mock + + from test.support import (TESTFN, findfile, unlink, rmtree, + requires_zlib, requires_bz2, requires_lzma, +@@ -1556,6 +1557,66 @@ class AbstractTestsWithRandomBinaryFiles + with open(TESTFN, "wb") as fp: + fp.write(self.data) + ++ @requires_zlib ++ def test_full_overlap(self): ++ data = ( ++ b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e' ++ b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00a\xed' ++ b'\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\d\x0b`P' ++ b'K\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2' ++ b'\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00' ++ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aPK' ++ b'\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e' ++ b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00\x00' ++ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bPK\x05' ++ b'\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00\x00/\x00\x00' ++ b'\x00\x00\x00' ++ ) ++ with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf: ++ self.assertEqual(zipf.namelist(), ['a', 'b']) ++ zi = zipf.getinfo('a') ++ self.assertEqual(zi.header_offset, 0) ++ self.assertEqual(zi.compress_size, 16) ++ self.assertEqual(zi.file_size, 1033) ++ zi = zipf.getinfo('b') ++ self.assertEqual(zi.header_offset, 0) ++ self.assertEqual(zi.compress_size, 16) ++ self.assertEqual(zi.file_size, 1033) ++ self.assertEqual(len(zipf.read('a')), 1033) ++ with self.assertRaisesRegex(zipfile.BadZipFile, 'File name.*differ'): ++ zipf.read('b') ++ ++ @requires_zlib ++ def test_quoted_overlap(self): ++ data = ( ++ b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05Y\xfc' ++ b'8\x044\x00\x00\x00(\x04\x00\x00\x01\x00\x00\x00a\x00' ++ b'\x1f\x00\xe0\xffPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0l' ++ b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00' ++ b'\x00\x00b\xed\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\' ++ b'd\x0b`PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0' ++ b'lH\x05Y\xfc8\x044\x00\x00\x00(\x04\x00\x00\x01' ++ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ++ b'\x00aPK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0l' ++ b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00' ++ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00' ++ b'bPK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00' ++ b'\x00S\x00\x00\x00\x00\x00' ++ ) ++ with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf: ++ self.assertEqual(zipf.namelist(), ['a', 'b']) ++ zi = zipf.getinfo('a') ++ self.assertEqual(zi.header_offset, 0) ++ self.assertEqual(zi.compress_size, 52) ++ self.assertEqual(zi.file_size, 1064) ++ zi = zipf.getinfo('b') ++ self.assertEqual(zi.header_offset, 36) ++ self.assertEqual(zi.compress_size, 16) ++ self.assertEqual(zi.file_size, 1033) ++ with self.assertRaisesRegex(zipfile.BadZipFile, 'Overlapped entries'): ++ zipf.read('a') ++ self.assertEqual(len(zipf.read('b')), 1033) ++ + def tearDown(self): + unlink(TESTFN) + unlink(TESTFN2) +--- a/Lib/zipfile.py ++++ b/Lib/zipfile.py +@@ -311,6 +311,7 @@ class ZipInfo (object): + 'compress_size', + 'file_size', + '_raw_time', ++ '_end_offset', + ) + + def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): +@@ -349,6 +350,7 @@ class ZipInfo (object): + self.volume = 0 # Volume number of file header + self.internal_attr = 0 # Internal attributes + self.external_attr = 0 # External file attributes ++ self._end_offset = None # Start of the next local header or central directory + # Other attributes are set by class ZipFile: + # header_offset Byte offset to the file header + # CRC CRC-32 of the uncompressed file +@@ -1044,6 +1046,12 @@ class ZipFile: + if self.debug > 2: + print("total", total) + ++ end_offset = self.start_dir ++ for zinfo in sorted(self.filelist, ++ key=lambda zinfo: zinfo.header_offset, ++ reverse=True): ++ zinfo._end_offset = end_offset ++ end_offset = zinfo.header_offset + + def namelist(self): + """Return a list of file names in the archive.""" +@@ -1179,6 +1187,10 @@ class ZipFile: + 'File name in directory %r and header %r differ.' + % (zinfo.orig_filename, fname)) + ++ if (zinfo._end_offset is not None and ++ zef_file.tell() + zinfo.compress_size > zinfo._end_offset): ++ raise BadZipFile("Overlapped entries: {!r} (possible zip bomb)".format(zinfo.orig_filename)) ++ + # check for encrypted flag & handle password + is_encrypted = zinfo.flag_bits & 0x1 + zd = None +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst +@@ -0,0 +1,3 @@ ++Protect :mod:`zipfile` from "quoted-overlap" zipbomb. It now raises ++BadZipFile when try to read an entry that overlaps with other entry or ++central directory. diff --git a/python-base.changes b/python-base.changes index d465808..fc49fab 100644 --- a/python-base.changes +++ b/python-base.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat May 18 15:49:07 UTC 2024 - Matej Cepl + +- bsc#1221854 (CVE-2024-0450) Add + CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch + detecting the vulnerability of the "quoted-overlap" zipbomb + (from gh#python/cpython!110016). + ------------------------------------------------------------------- Sat May 11 05:46:55 UTC 2024 - Matej Cepl diff --git a/python-base.spec b/python-base.spec index e5affbe..450e77d 100644 --- a/python-base.spec +++ b/python-base.spec @@ -165,6 +165,9 @@ Patch79: CVE-2023-40217-avoid-ssl-pre-close.patch # PATCH-FIX-UPSTREAM CVE-2022-48566-compare_digest-more-constant.patch bsc#1214691 mcepl@suse.com # Make compare_digest more constant-time Patch80: CVE-2022-48566-compare_digest-more-constant.patch +# PATCH-FIX-UPSTREAM CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch bsc#1221854 mcepl@suse.com +# detecting the vulnerability of the "quoted-overlap" zipbomb (from gh#python/cpython!110016). +Patch81: CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) BuildRequires: automake @@ -322,6 +325,7 @@ other applications. %patch -P 78 -p1 %patch -P 79 -p1 %patch -P 80 -p1 +%patch -P 81 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python-doc.changes b/python-doc.changes index d465808..fc49fab 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat May 18 15:49:07 UTC 2024 - Matej Cepl + +- bsc#1221854 (CVE-2024-0450) Add + CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch + detecting the vulnerability of the "quoted-overlap" zipbomb + (from gh#python/cpython!110016). + ------------------------------------------------------------------- Sat May 11 05:46:55 UTC 2024 - Matej Cepl diff --git a/python-doc.spec b/python-doc.spec index cce64ff..d6e9011 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -161,6 +161,9 @@ Patch79: CVE-2023-40217-avoid-ssl-pre-close.patch # PATCH-FIX-UPSTREAM CVE-2022-48566-compare_digest-more-constant.patch bsc#1214691 mcepl@suse.com # Make compare_digest more constant-time Patch80: CVE-2022-48566-compare_digest-more-constant.patch +# PATCH-FIX-UPSTREAM CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch bsc#1221854 mcepl@suse.com +# detecting the vulnerability of the "quoted-overlap" zipbomb (from gh#python/cpython!110016). +Patch81: CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch # COMMON-PATCH-END Provides: pyth_doc = %{version} Provides: pyth_ps = %{version} @@ -252,6 +255,7 @@ Python, and Macintosh Module Reference in PDF format. %patch -P 78 -p1 %patch -P 79 -p1 %patch -P 80 -p1 +%patch -P 81 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python.changes b/python.changes index d465808..fc49fab 100644 --- a/python.changes +++ b/python.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat May 18 15:49:07 UTC 2024 - Matej Cepl + +- bsc#1221854 (CVE-2024-0450) Add + CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch + detecting the vulnerability of the "quoted-overlap" zipbomb + (from gh#python/cpython!110016). + ------------------------------------------------------------------- Sat May 11 05:46:55 UTC 2024 - Matej Cepl diff --git a/python.spec b/python.spec index bd33603..1f681f9 100644 --- a/python.spec +++ b/python.spec @@ -161,6 +161,9 @@ Patch79: CVE-2023-40217-avoid-ssl-pre-close.patch # PATCH-FIX-UPSTREAM CVE-2022-48566-compare_digest-more-constant.patch bsc#1214691 mcepl@suse.com # Make compare_digest more constant-time Patch80: CVE-2022-48566-compare_digest-more-constant.patch +# PATCH-FIX-UPSTREAM CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch bsc#1221854 mcepl@suse.com +# detecting the vulnerability of the "quoted-overlap" zipbomb (from gh#python/cpython!110016). +Patch81: CVE-2024-0450-zipfile-avoid-quoted-overlap-zipbomb.patch # COMMON-PATCH-END BuildRequires: automake BuildRequires: db-devel @@ -372,6 +375,7 @@ that rely on earlier non-verification behavior. %patch -P 78 -p1 %patch -P 79 -p1 %patch -P 80 -p1 +%patch -P 81 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar