From d4b42b6c1869681b56f653a60b1b72c1846e23f332a04488f19e948750efbdc0 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Mon, 15 Apr 2024 19:07:31 +0000 Subject: [PATCH 01/10] WIP OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=402 --- bsc1222537-py2-email-addr-parse.patch | 20 ++++++++++++++++++++ python-base.spec | 4 ++++ python-doc.spec | 4 ++++ python.spec | 4 ++++ 4 files changed, 32 insertions(+) create mode 100644 bsc1222537-py2-email-addr-parse.patch diff --git a/bsc1222537-py2-email-addr-parse.patch b/bsc1222537-py2-email-addr-parse.patch new file mode 100644 index 0000000..91ffe78 --- /dev/null +++ b/bsc1222537-py2-email-addr-parse.patch @@ -0,0 +1,20 @@ +--- + Lib/email/test/test_email.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/Lib/email/test/test_email.py ++++ b/Lib/email/test/test_email.py +@@ -2502,6 +2502,13 @@ Foo + # Test Utils.supports_strict_parsing attribute + self.assertEqual(Utils.supports_strict_parsing, True) + ++ def test_parsing_unicode_str(self): ++ email_in = "Honza Novák " ++ self.assertEqual(Utils.parseaddr(email_in), ++ ('Honza Nov\xc3\xa1k', 'honza@example.com')) ++ self.assertEqual(Utils.parseaddr(email_in.decode('utf-8')), ++ ('Honza Nov\xc3\xa1k', 'honza@example.com')) ++ + def test_getaddresses_nasty(self): + for addresses, expected in ( + ([u'"Sürname, Firstname" '], diff --git a/python-base.spec b/python-base.spec index 16bd9d6..59a626a 100644 --- a/python-base.spec +++ b/python-base.spec @@ -167,6 +167,9 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch +# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com +# email.utils.parseaddr should accept unicode string +Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) BuildRequires: automake @@ -324,6 +327,7 @@ other applications. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 +%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python-doc.spec b/python-doc.spec index e922e82..db492e6 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -163,6 +163,9 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch +# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com +# email.utils.parseaddr should accept unicode string +Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END Provides: pyth_doc = %{version} Provides: pyth_ps = %{version} @@ -255,6 +258,7 @@ Python, and Macintosh Module Reference in PDF format. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 +%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python.spec b/python.spec index 85425ff..305ff71 100644 --- a/python.spec +++ b/python.spec @@ -163,6 +163,9 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch +# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com +# email.utils.parseaddr should accept unicode string +Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END BuildRequires: automake BuildRequires: db-devel @@ -375,6 +378,7 @@ that rely on earlier non-verification behavior. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 +%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar From 5267a1835f5a803968b6194a043c8e7422dc25f1b2cab06efbc855e701dffc67 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Mon, 15 Apr 2024 22:17:01 +0000 Subject: [PATCH 02/10] Enable tests again. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=403 --- bsc1222537-py2-email-addr-parse.patch | 14 +++++++++++++- python-base.spec | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/bsc1222537-py2-email-addr-parse.patch b/bsc1222537-py2-email-addr-parse.patch index 91ffe78..a02130c 100644 --- a/bsc1222537-py2-email-addr-parse.patch +++ b/bsc1222537-py2-email-addr-parse.patch @@ -1,6 +1,7 @@ --- Lib/email/test/test_email.py | 7 +++++++ - 1 file changed, 7 insertions(+) + Lib/email/utils.py | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -18,3 +19,14 @@ def test_getaddresses_nasty(self): for addresses, expected in ( ([u'"Sürname, Firstname" '], +--- a/Lib/email/utils.py ++++ b/Lib/email/utils.py +@@ -307,7 +307,7 @@ def parseaddr(addr, strict=True): + if isinstance(addr, list): + addr = addr[0] + +- if not isinstance(addr, str): ++ if not isinstance(addr, basestring): + return ('', '') + + addr = _pre_parse_validation([addr])[0] diff --git a/python-base.spec b/python-base.spec index 59a626a..144b4ec 100644 --- a/python-base.spec +++ b/python-base.spec @@ -19,7 +19,7 @@ %define so_version 2_7-1_0 # We really don't care about quality of this package anymore, it # will be soon gone (bsc#1219306). -%bcond_with tests +%bcond_without tests Name: python-base Version: 2.7.18 From bfb85e8df721fc12ac47632e30b9f9239871c10a295872ec9693bcef42ffdbf4 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 16 Apr 2024 15:39:10 +0000 Subject: [PATCH 03/10] Update the patch OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=404 --- bsc1222537-py2-email-addr-parse.patch | 8 ++++---- python-base.spec | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/bsc1222537-py2-email-addr-parse.patch b/bsc1222537-py2-email-addr-parse.patch index a02130c..3fff5e0 100644 --- a/bsc1222537-py2-email-addr-parse.patch +++ b/bsc1222537-py2-email-addr-parse.patch @@ -11,10 +11,10 @@ + def test_parsing_unicode_str(self): + email_in = "Honza Novák " -+ self.assertEqual(Utils.parseaddr(email_in), -+ ('Honza Nov\xc3\xa1k', 'honza@example.com')) -+ self.assertEqual(Utils.parseaddr(email_in.decode('utf-8')), -+ ('Honza Nov\xc3\xa1k', 'honza@example.com')) ++ self.assertEqual(Utils.parseaddr("Honza str Novák "), ++ ('Honza str Nov\xc3\xa1k', 'honza@example.com')) ++ self.assertEqual(Utils.parseaddr(u"Honza unicode Novák "), ++ ('Honza unicode Nov\xe1k', 'honza@example.com')) + def test_getaddresses_nasty(self): for addresses, expected in ( diff --git a/python-base.spec b/python-base.spec index 144b4ec..a6519e9 100644 --- a/python-base.spec +++ b/python-base.spec @@ -383,7 +383,6 @@ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH \ make %{?_smp_mflags} $target %check -%if %{with test} # on hppa, the threading of glibc is quite broken. The tests just stop # at some point, and the machine does not build anything more until a # timeout several hours later. @@ -436,7 +435,6 @@ make test TESTOPTS="-l -w -x $EXCLUDE" TESTPYTHONOPTS="-R" #make test TESTOPTS="-l -u network -v" %endif # END OF CHECK SECTION -%endif %install # replace rest of /usr/local/bin/python or /usr/bin/python2.5 with /usr/bin/python From 86d87a86123c391a6dd204b5519fff99a9292cd254f055abd2724391e5434e81 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 16 Apr 2024 15:40:54 +0000 Subject: [PATCH 04/10] - Switch on tests again. - Add bsc1222537-py2-email-addr-parse.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=405 --- python-base.changes | 7 +++++++ python-doc.changes | 7 +++++++ python.changes | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/python-base.changes b/python-base.changes index 055e332..8a8562c 100644 --- a/python-base.changes +++ b/python-base.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl + +- Switch on tests again. +- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode + string handling in email.utils.parseaddr() (bsc#1222537). + ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl diff --git a/python-doc.changes b/python-doc.changes index 055e332..8a8562c 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl + +- Switch on tests again. +- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode + string handling in email.utils.parseaddr() (bsc#1222537). + ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl diff --git a/python.changes b/python.changes index 055e332..8a8562c 100644 --- a/python.changes +++ b/python.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl + +- Switch on tests again. +- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode + string handling in email.utils.parseaddr() (bsc#1222537). + ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl From c8f2c7a00322ace7325e03066020bc9203e18a41f2ab123f5ee45cf140c2f25b Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 16 Apr 2024 19:29:14 +0000 Subject: [PATCH 05/10] Update patches OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=406 --- bsc1222537-py2-email-addr-parse.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsc1222537-py2-email-addr-parse.patch b/bsc1222537-py2-email-addr-parse.patch index 3fff5e0..a17f7e1 100644 --- a/bsc1222537-py2-email-addr-parse.patch +++ b/bsc1222537-py2-email-addr-parse.patch @@ -14,7 +14,7 @@ + self.assertEqual(Utils.parseaddr("Honza str Novák "), + ('Honza str Nov\xc3\xa1k', 'honza@example.com')) + self.assertEqual(Utils.parseaddr(u"Honza unicode Novák "), -+ ('Honza unicode Nov\xe1k', 'honza@example.com')) ++ (u'Honza unicode Nov\xe1k', u'honza@example.com')) + def test_getaddresses_nasty(self): for addresses, expected in ( From 7ccba948f368b39bc6bcd27c8c6430375d630daba60cda1f13d3d9dc28c05900 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 16 Apr 2024 20:26:40 +0000 Subject: [PATCH 06/10] - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=407 --- CVE-2023-27043-email-parsing-errors.patch | 576 +++++++++++----------- bsc1222537-py2-email-addr-parse.patch | 32 -- python-base.changes | 5 +- python-base.spec | 7 +- python-doc.changes | 5 +- python-doc.spec | 7 +- python.changes | 5 +- python.spec | 7 +- 8 files changed, 302 insertions(+), 342 deletions(-) delete mode 100644 bsc1222537-py2-email-addr-parse.patch diff --git a/CVE-2023-27043-email-parsing-errors.patch b/CVE-2023-27043-email-parsing-errors.patch index 6de152c..40573d0 100644 --- a/CVE-2023-27043-email-parsing-errors.patch +++ b/CVE-2023-27043-email-parsing-errors.patch @@ -1,14 +1,13 @@ --- - Doc/library/email.utils.rst | 19 - - Lib/email/utils.py | 151 +++++++- - Lib/test/test_email/test_email.py | 187 +++++++++- + Doc/library/email.utils.rst | 19 + Lib/email/test/test_email.py | 192 +++++++++- + Lib/email/test/test_email_renamed.py | 50 ++ + Lib/email/utils.py | 155 +++++++- Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst | 8 - 4 files changed, 344 insertions(+), 21 deletions(-) + 5 files changed, 393 insertions(+), 31 deletions(-) -Index: Python-2.7.18/Doc/library/email.utils.rst -=================================================================== ---- Python-2.7.18.orig/Doc/library/email.utils.rst -+++ Python-2.7.18/Doc/library/email.utils.rst +--- a/Doc/library/email.utils.rst ++++ b/Doc/library/email.utils.rst @@ -21,13 +21,18 @@ There are several useful utilities provi begins with angle brackets, they are stripped off. @@ -58,10 +57,284 @@ Index: Python-2.7.18/Doc/library/email.utils.rst .. function:: parsedate(date) -Index: Python-2.7.18/Lib/email/utils.py -=================================================================== ---- Python-2.7.18.orig/Lib/email/utils.py -+++ Python-2.7.18/Lib/email/utils.py +--- a/Lib/email/test/test_email.py ++++ b/Lib/email/test/test_email.py +@@ -1,3 +1,4 @@ ++# -*- coding: utf-8 -*- + # Copyright (C) 2001-2010 Python Software Foundation + # Contact: email-sig@python.org + # email package unit tests +@@ -2414,15 +2415,142 @@ Foo + [('Al Person', 'aperson@dom.ain'), + ('Bud Person', 'bperson@dom.ain')]) + ++ def test_parsing_errors(self): ++ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" ++ alice = 'alice@example.org' ++ bob = 'bob@example.com' ++ empty = ('', '') ++ ++ # Test Utils.getaddresses() and Utils.parseaddr() on malformed email ++ # addresses: default behavior (strict=True) rejects malformed address, ++ # and strict=False which tolerates malformed address. ++ for invalid_separator, expected_non_strict in ( ++ ('(', [('<%s>' % bob, alice)]), ++ (')', [('', alice), empty, ('', bob)]), ++ ('<', [('', alice), empty, ('', bob), empty]), ++ ('>', [('', alice), empty, ('', bob)]), ++ ('[', [('', '%s[<%s>]' % (alice, bob))]), ++ (']', [('', alice), empty, ('', bob)]), ++ ('@', [empty, empty, ('', bob)]), ++ (';', [('', alice), empty, ('', bob)]), ++ (':', [('', alice), ('', bob)]), ++ ('.', [('', alice + '.'), ('', bob)]), ++ ('"', [('', alice), ('', '<%s>' % bob)]), ++ ): ++ address = '%s%s<%s>' % (alice, invalid_separator, bob) ++ self.assertEqual(Utils.getaddresses([address]), ++ [empty]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), ++ expected_non_strict) ++ ++ self.assertEqual(Utils.parseaddr([address]), ++ empty) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Comma (',') is treated differently depending on strict parameter. ++ # Comma without quotes. ++ address = '%s,<%s>' % (alice, bob) ++ self.assertEqual(Utils.getaddresses([address]), ++ [('', alice), ('', bob)]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), ++ [('', alice), ('', bob)]) ++ self.assertEqual(Utils.parseaddr([address]), ++ empty) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Real name between quotes containing comma. ++ address = '"Alice, alice@example.org" ' ++ expected_strict = ('Alice, alice@example.org', 'bob@example.com') ++ self.assertEqual(Utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(Utils.parseaddr([address]), expected_strict) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Valid parenthesis in comments. ++ address = 'alice@example.org (Alice)' ++ expected_strict = ('Alice', 'alice@example.org') ++ self.assertEqual(Utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(Utils.parseaddr([address]), expected_strict) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Invalid parenthesis in comments. ++ address = 'alice@example.org )Alice(' ++ self.assertEqual(Utils.getaddresses([address]), [empty]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), ++ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) ++ self.assertEqual(Utils.parseaddr([address]), empty) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Two addresses with quotes separated by comma. ++ address = '"Jane Doe" , "John Doe" ' ++ self.assertEqual(Utils.getaddresses([address]), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(Utils.getaddresses([address], strict=False), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(Utils.parseaddr([address]), empty) ++ self.assertEqual(Utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Test Utils.supports_strict_parsing attribute ++ self.assertEqual(Utils.supports_strict_parsing, True) ++ ++ def test_parsing_unicode_str(self): ++ email_in = "Honza Novák " ++ self.assertEqual(Utils.parseaddr("Honza str Novák "), ++ ('Honza str Nov\xc3\xa1k', 'honza@example.com')) ++ self.assertEqual(Utils.parseaddr(u"Honza unicode Novák "), ++ (u'Honza unicode Nov\xe1k', u'honza@example.com')) ++ + def test_getaddresses_nasty(self): +- eq = self.assertEqual +- eq(Utils.getaddresses(['foo: ;']), [('', '')]) +- eq(Utils.getaddresses( +- ['[]*-- =~$']), +- [('', ''), ('', ''), ('', '*--')]) +- eq(Utils.getaddresses( +- ['foo: ;', '"Jason R. Mastaler" ']), +- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) ++ for addresses, expected in ( ++ ([u'"Sürname, Firstname" '], ++ [(u'Sürname, Firstname', 'to@example.com')]), ++ ++ (['foo: ;'], ++ [('', '')]), ++ ++ (['foo: ;', '"Jason R. Mastaler" '], ++ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), ++ ++ ([r'Pete(A nice \) chap) '], ++ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), ++ ++ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], ++ [('', '')]), ++ ++ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], ++ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), ++ ++ (['John Doe '], ++ [('John Doe (comment)', 'jdoe@machine.example')]), ++ ++ (['"Mary Smith: Personal Account" '], ++ [('Mary Smith: Personal Account', 'smith@home.example')]), ++ ++ (['Undisclosed recipients:;'], ++ [('', '')]), ++ ++ ([r', "Giant; \"Big\" Box" '], ++ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), ++ ): ++ self.assertEqual(Utils.getaddresses(addresses), ++ expected) ++ self.assertEqual(Utils.getaddresses(addresses, strict=False), ++ expected) ++ ++ addresses = ['[]*-- =~$'] ++ self.assertEqual(Utils.getaddresses(addresses), ++ [('', '')]) ++ self.assertEqual(Utils.getaddresses(addresses, strict=False), ++ [('', ''), ('', ''), ('', '*--')]) + + def test_getaddresses_embedded_comment(self): + """Test proper handling of a nested comment""" +@@ -2430,6 +2558,54 @@ Foo + addrs = Utils.getaddresses(['User ((nested comment)) ']) + eq(addrs[0][1], 'foo@bar.com') + ++ def test_iter_escaped_chars(self): ++ self.assertEqual(list(Utils._iter_escaped_chars(r'a\\b\"c\\"d')), ++ [(0, 'a'), ++ (2, '\\\\'), ++ (3, 'b'), ++ (5, '\\"'), ++ (6, 'c'), ++ (8, '\\\\'), ++ (9, '"'), ++ (10, 'd')]) ++ self.assertEqual(list(Utils._iter_escaped_chars('a\\')), ++ [(0, 'a'), (1, '\\')]) ++ ++ def test_strip_quoted_realnames(self): ++ def check(addr, expected): ++ self.assertEqual(Utils._strip_quoted_realnames(addr), expected) ++ ++ check('"Jane Doe" , "John Doe" ', ++ ' , ') ++ check(r'"Jane \"Doe\"." ', ++ ' ') ++ ++ # special cases ++ check(r'before"name"after', 'beforeafter') ++ check(r'before"name"', 'before') ++ check(r'b"name"', 'b') # single char ++ check(r'"name"after', 'after') ++ check(r'"name"a', 'a') # single char ++ check(r'"name"', '') ++ ++ # no change ++ for addr in ( ++ 'Jane Doe , John Doe ', ++ 'lone " quote', ++ ): ++ self.assertEqual(Utils._strip_quoted_realnames(addr), addr) ++ ++ def test_check_parenthesis(self): ++ addr = 'alice@example.net' ++ self.assertTrue(Utils._check_parenthesis('%s (Alice)' % addr)) ++ self.assertFalse(Utils._check_parenthesis('%s )Alice(' % addr)) ++ self.assertFalse(Utils._check_parenthesis('%s (Alice))' % addr)) ++ self.assertFalse(Utils._check_parenthesis('%s ((Alice)' % addr)) ++ ++ # Ignore real name between quotes ++ self.assertTrue(Utils._check_parenthesis('")Alice((" %s' % addr)) ++ ++ + def test_make_msgid_collisions(self): + # Test make_msgid uniqueness, even with multiple threads + class MsgidsThread(Thread): +--- a/Lib/email/test/test_email_renamed.py ++++ b/Lib/email/test/test_email_renamed.py +@@ -1,3 +1,4 @@ ++# -*- coding: utf-8 -*- + # Copyright (C) 2001-2007 Python Software Foundation + # Contact: email-sig@python.org + # email package unit tests +@@ -2276,14 +2277,47 @@ Foo + ('Bud Person', 'bperson@dom.ain')]) + + def test_getaddresses_nasty(self): +- eq = self.assertEqual +- eq(utils.getaddresses(['foo: ;']), [('', '')]) +- eq(utils.getaddresses( +- ['[]*-- =~$']), +- [('', ''), ('', ''), ('', '*--')]) +- eq(utils.getaddresses( +- ['foo: ;', '"Jason R. Mastaler" ']), +- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) ++ for addresses, expected in ( ++ ([u'"Sürname, Firstname" '], ++ [(u'Sürname, Firstname', 'to@example.com')]), ++ ++ (['foo: ;'], ++ [('', '')]), ++ ++ (['foo: ;', '"Jason R. Mastaler" '], ++ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), ++ ++ ([r'Pete(A nice \) chap) '], ++ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), ++ ++ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], ++ [('', '')]), ++ ++ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], ++ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), ++ ++ (['John Doe '], ++ [('John Doe (comment)', 'jdoe@machine.example')]), ++ ++ (['"Mary Smith: Personal Account" '], ++ [('Mary Smith: Personal Account', 'smith@home.example')]), ++ ++ (['Undisclosed recipients:;'], ++ [('', '')]), ++ ++ ([r', "Giant; \"Big\" Box" '], ++ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), ++ ): ++ self.assertEqual(utils.getaddresses(addresses), ++ expected) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ expected) ++ ++ addresses = ['[]*-- =~$'] ++ self.assertEqual(utils.getaddresses(addresses), ++ [('', '')]) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ [('', ''), ('', ''), ('', '*--')]) + + def test_getaddresses_embedded_comment(self): + """Test proper handling of a nested comment""" +--- a/Lib/email/utils.py ++++ b/Lib/email/utils.py @@ -100,15 +100,93 @@ def formataddr(pair): return address @@ -190,7 +463,7 @@ Index: Python-2.7.18/Lib/email/utils.py + if isinstance(addr, list): + addr = addr[0] + -+ if not isinstance(addr, str): ++ if not isinstance(addr, basestring): + return ('', '') + + addr = _pre_parse_validation([addr])[0] @@ -242,10 +515,8 @@ Index: Python-2.7.18/Lib/email/utils.py # rfc822.unquote() doesn't properly de-backslash-ify in Python pre-2.3. def unquote(str): """Remove quotes from a string.""" -Index: Python-2.7.18/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst -=================================================================== --- /dev/null -+++ Python-2.7.18/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst ++++ b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst @@ -0,0 +1,8 @@ +:func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now +return ``('', '')`` 2-tuples in more situations where invalid email @@ -255,276 +526,3 @@ Index: Python-2.7.18/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-10298 +``getattr(email.utils, 'supports_strict_parsing', False)`` can be use to check +if the *strict* paramater is available. Patch by Thomas Dwyer and Victor +Stinner to improve the CVE-2023-27043 fix. -Index: Python-2.7.18/Lib/email/test/test_email.py -=================================================================== ---- Python-2.7.18.orig/Lib/email/test/test_email.py -+++ Python-2.7.18/Lib/email/test/test_email.py -@@ -1,3 +1,4 @@ -+# -*- coding: utf-8 -*- - # Copyright (C) 2001-2010 Python Software Foundation - # Contact: email-sig@python.org - # email package unit tests -@@ -2414,15 +2415,135 @@ Foo - [('Al Person', 'aperson@dom.ain'), - ('Bud Person', 'bperson@dom.ain')]) - -+ def test_parsing_errors(self): -+ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" -+ alice = 'alice@example.org' -+ bob = 'bob@example.com' -+ empty = ('', '') -+ -+ # Test Utils.getaddresses() and Utils.parseaddr() on malformed email -+ # addresses: default behavior (strict=True) rejects malformed address, -+ # and strict=False which tolerates malformed address. -+ for invalid_separator, expected_non_strict in ( -+ ('(', [('<%s>' % bob, alice)]), -+ (')', [('', alice), empty, ('', bob)]), -+ ('<', [('', alice), empty, ('', bob), empty]), -+ ('>', [('', alice), empty, ('', bob)]), -+ ('[', [('', '%s[<%s>]' % (alice, bob))]), -+ (']', [('', alice), empty, ('', bob)]), -+ ('@', [empty, empty, ('', bob)]), -+ (';', [('', alice), empty, ('', bob)]), -+ (':', [('', alice), ('', bob)]), -+ ('.', [('', alice + '.'), ('', bob)]), -+ ('"', [('', alice), ('', '<%s>' % bob)]), -+ ): -+ address = '%s%s<%s>' % (alice, invalid_separator, bob) -+ self.assertEqual(Utils.getaddresses([address]), -+ [empty]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), -+ expected_non_strict) -+ -+ self.assertEqual(Utils.parseaddr([address]), -+ empty) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Comma (',') is treated differently depending on strict parameter. -+ # Comma without quotes. -+ address = '%s,<%s>' % (alice, bob) -+ self.assertEqual(Utils.getaddresses([address]), -+ [('', alice), ('', bob)]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), -+ [('', alice), ('', bob)]) -+ self.assertEqual(Utils.parseaddr([address]), -+ empty) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Real name between quotes containing comma. -+ address = '"Alice, alice@example.org" ' -+ expected_strict = ('Alice, alice@example.org', 'bob@example.com') -+ self.assertEqual(Utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(Utils.parseaddr([address]), expected_strict) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Valid parenthesis in comments. -+ address = 'alice@example.org (Alice)' -+ expected_strict = ('Alice', 'alice@example.org') -+ self.assertEqual(Utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(Utils.parseaddr([address]), expected_strict) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Invalid parenthesis in comments. -+ address = 'alice@example.org )Alice(' -+ self.assertEqual(Utils.getaddresses([address]), [empty]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), -+ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) -+ self.assertEqual(Utils.parseaddr([address]), empty) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Two addresses with quotes separated by comma. -+ address = '"Jane Doe" , "John Doe" ' -+ self.assertEqual(Utils.getaddresses([address]), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(Utils.getaddresses([address], strict=False), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(Utils.parseaddr([address]), empty) -+ self.assertEqual(Utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Test Utils.supports_strict_parsing attribute -+ self.assertEqual(Utils.supports_strict_parsing, True) -+ - def test_getaddresses_nasty(self): -- eq = self.assertEqual -- eq(Utils.getaddresses(['foo: ;']), [('', '')]) -- eq(Utils.getaddresses( -- ['[]*-- =~$']), -- [('', ''), ('', ''), ('', '*--')]) -- eq(Utils.getaddresses( -- ['foo: ;', '"Jason R. Mastaler" ']), -- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) -+ for addresses, expected in ( -+ ([u'"Sürname, Firstname" '], -+ [(u'Sürname, Firstname', 'to@example.com')]), -+ -+ (['foo: ;'], -+ [('', '')]), -+ -+ (['foo: ;', '"Jason R. Mastaler" '], -+ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), -+ -+ ([r'Pete(A nice \) chap) '], -+ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), -+ -+ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], -+ [('', '')]), -+ -+ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], -+ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), -+ -+ (['John Doe '], -+ [('John Doe (comment)', 'jdoe@machine.example')]), -+ -+ (['"Mary Smith: Personal Account" '], -+ [('Mary Smith: Personal Account', 'smith@home.example')]), -+ -+ (['Undisclosed recipients:;'], -+ [('', '')]), -+ -+ ([r', "Giant; \"Big\" Box" '], -+ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), -+ ): -+ self.assertEqual(Utils.getaddresses(addresses), -+ expected) -+ self.assertEqual(Utils.getaddresses(addresses, strict=False), -+ expected) -+ -+ addresses = ['[]*-- =~$'] -+ self.assertEqual(Utils.getaddresses(addresses), -+ [('', '')]) -+ self.assertEqual(Utils.getaddresses(addresses, strict=False), -+ [('', ''), ('', ''), ('', '*--')]) - - def test_getaddresses_embedded_comment(self): - """Test proper handling of a nested comment""" -@@ -2430,6 +2551,54 @@ Foo - addrs = Utils.getaddresses(['User ((nested comment)) ']) - eq(addrs[0][1], 'foo@bar.com') - -+ def test_iter_escaped_chars(self): -+ self.assertEqual(list(Utils._iter_escaped_chars(r'a\\b\"c\\"d')), -+ [(0, 'a'), -+ (2, '\\\\'), -+ (3, 'b'), -+ (5, '\\"'), -+ (6, 'c'), -+ (8, '\\\\'), -+ (9, '"'), -+ (10, 'd')]) -+ self.assertEqual(list(Utils._iter_escaped_chars('a\\')), -+ [(0, 'a'), (1, '\\')]) -+ -+ def test_strip_quoted_realnames(self): -+ def check(addr, expected): -+ self.assertEqual(Utils._strip_quoted_realnames(addr), expected) -+ -+ check('"Jane Doe" , "John Doe" ', -+ ' , ') -+ check(r'"Jane \"Doe\"." ', -+ ' ') -+ -+ # special cases -+ check(r'before"name"after', 'beforeafter') -+ check(r'before"name"', 'before') -+ check(r'b"name"', 'b') # single char -+ check(r'"name"after', 'after') -+ check(r'"name"a', 'a') # single char -+ check(r'"name"', '') -+ -+ # no change -+ for addr in ( -+ 'Jane Doe , John Doe ', -+ 'lone " quote', -+ ): -+ self.assertEqual(Utils._strip_quoted_realnames(addr), addr) -+ -+ def test_check_parenthesis(self): -+ addr = 'alice@example.net' -+ self.assertTrue(Utils._check_parenthesis('%s (Alice)' % addr)) -+ self.assertFalse(Utils._check_parenthesis('%s )Alice(' % addr)) -+ self.assertFalse(Utils._check_parenthesis('%s (Alice))' % addr)) -+ self.assertFalse(Utils._check_parenthesis('%s ((Alice)' % addr)) -+ -+ # Ignore real name between quotes -+ self.assertTrue(Utils._check_parenthesis('")Alice((" %s' % addr)) -+ -+ - def test_make_msgid_collisions(self): - # Test make_msgid uniqueness, even with multiple threads - class MsgidsThread(Thread): -Index: Python-2.7.18/Lib/email/test/test_email_renamed.py -=================================================================== ---- Python-2.7.18.orig/Lib/email/test/test_email_renamed.py -+++ Python-2.7.18/Lib/email/test/test_email_renamed.py -@@ -1,3 +1,4 @@ -+# -*- coding: utf-8 -*- - # Copyright (C) 2001-2007 Python Software Foundation - # Contact: email-sig@python.org - # email package unit tests -@@ -2276,14 +2277,47 @@ Foo - ('Bud Person', 'bperson@dom.ain')]) - - def test_getaddresses_nasty(self): -- eq = self.assertEqual -- eq(utils.getaddresses(['foo: ;']), [('', '')]) -- eq(utils.getaddresses( -- ['[]*-- =~$']), -- [('', ''), ('', ''), ('', '*--')]) -- eq(utils.getaddresses( -- ['foo: ;', '"Jason R. Mastaler" ']), -- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) -+ for addresses, expected in ( -+ ([u'"Sürname, Firstname" '], -+ [(u'Sürname, Firstname', 'to@example.com')]), -+ -+ (['foo: ;'], -+ [('', '')]), -+ -+ (['foo: ;', '"Jason R. Mastaler" '], -+ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), -+ -+ ([r'Pete(A nice \) chap) '], -+ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), -+ -+ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], -+ [('', '')]), -+ -+ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], -+ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), -+ -+ (['John Doe '], -+ [('John Doe (comment)', 'jdoe@machine.example')]), -+ -+ (['"Mary Smith: Personal Account" '], -+ [('Mary Smith: Personal Account', 'smith@home.example')]), -+ -+ (['Undisclosed recipients:;'], -+ [('', '')]), -+ -+ ([r', "Giant; \"Big\" Box" '], -+ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), -+ ): -+ self.assertEqual(utils.getaddresses(addresses), -+ expected) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ expected) -+ -+ addresses = ['[]*-- =~$'] -+ self.assertEqual(utils.getaddresses(addresses), -+ [('', '')]) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ [('', ''), ('', ''), ('', '*--')]) - - def test_getaddresses_embedded_comment(self): - """Test proper handling of a nested comment""" diff --git a/bsc1222537-py2-email-addr-parse.patch b/bsc1222537-py2-email-addr-parse.patch deleted file mode 100644 index a17f7e1..0000000 --- a/bsc1222537-py2-email-addr-parse.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- - Lib/email/test/test_email.py | 7 +++++++ - Lib/email/utils.py | 2 +- - 2 files changed, 8 insertions(+), 1 deletion(-) - ---- a/Lib/email/test/test_email.py -+++ b/Lib/email/test/test_email.py -@@ -2502,6 +2502,13 @@ Foo - # Test Utils.supports_strict_parsing attribute - self.assertEqual(Utils.supports_strict_parsing, True) - -+ def test_parsing_unicode_str(self): -+ email_in = "Honza Novák " -+ self.assertEqual(Utils.parseaddr("Honza str Novák "), -+ ('Honza str Nov\xc3\xa1k', 'honza@example.com')) -+ self.assertEqual(Utils.parseaddr(u"Honza unicode Novák "), -+ (u'Honza unicode Nov\xe1k', u'honza@example.com')) -+ - def test_getaddresses_nasty(self): - for addresses, expected in ( - ([u'"Sürname, Firstname" '], ---- a/Lib/email/utils.py -+++ b/Lib/email/utils.py -@@ -307,7 +307,7 @@ def parseaddr(addr, strict=True): - if isinstance(addr, list): - addr = addr[0] - -- if not isinstance(addr, str): -+ if not isinstance(addr, basestring): - return ('', '') - - addr = _pre_parse_validation([addr])[0] diff --git a/python-base.changes b/python-base.changes index 8a8562c..45656c2 100644 --- a/python-base.changes +++ b/python-base.changes @@ -2,8 +2,9 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Switch on tests again. -- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode - string handling in email.utils.parseaddr() (bsc#1222537). +- Modify CVE-2023-27043-email-parsing-errors.patch to fix the + unicode string handling in email.utils.parseaddr() + (bsc#1222537). ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl diff --git a/python-base.spec b/python-base.spec index a6519e9..d4d36ba 100644 --- a/python-base.spec +++ b/python-base.spec @@ -154,7 +154,8 @@ Patch75: CVE-2023-24329-blank-URL-bypass.patch Patch76: PygmentsBridge-trime_doctest_flags.patch # PATCH-FIX-UPSTREAM CVE-2023-27043-email-parsing-errors.patch bsc#1210638 mcepl@suse.com # Detect email address parsing errors and return empty tuple to -# indicate the parsing error (old API) +# indicate the parsing error (old API), modified for fixing bsc#1222537, +# so that email.utils.parseaddr accepts unicode string Patch77: CVE-2023-27043-email-parsing-errors.patch # PATCH-FIX-UPSTREAM CVE-2022-48565-plistlib-XML-vulns.patch bsc#1214685 mcepl@suse.com # Reject entity declarations in plists @@ -167,9 +168,6 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch -# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com -# email.utils.parseaddr should accept unicode string -Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) BuildRequires: automake @@ -327,7 +325,6 @@ other applications. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 -%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python-doc.changes b/python-doc.changes index 8a8562c..45656c2 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -2,8 +2,9 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Switch on tests again. -- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode - string handling in email.utils.parseaddr() (bsc#1222537). +- Modify CVE-2023-27043-email-parsing-errors.patch to fix the + unicode string handling in email.utils.parseaddr() + (bsc#1222537). ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl diff --git a/python-doc.spec b/python-doc.spec index db492e6..661658f 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -150,7 +150,8 @@ Patch75: CVE-2023-24329-blank-URL-bypass.patch Patch76: PygmentsBridge-trime_doctest_flags.patch # PATCH-FIX-UPSTREAM CVE-2023-27043-email-parsing-errors.patch bsc#1210638 mcepl@suse.com # Detect email address parsing errors and return empty tuple to -# indicate the parsing error (old API) +# indicate the parsing error (old API), modified for fixing bsc#1222537, +# so that email.utils.parseaddr accepts unicode string Patch77: CVE-2023-27043-email-parsing-errors.patch # PATCH-FIX-UPSTREAM CVE-2022-48565-plistlib-XML-vulns.patch bsc#1214685 mcepl@suse.com # Reject entity declarations in plists @@ -163,9 +164,6 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch -# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com -# email.utils.parseaddr should accept unicode string -Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END Provides: pyth_doc = %{version} Provides: pyth_ps = %{version} @@ -258,7 +256,6 @@ Python, and Macintosh Module Reference in PDF format. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 -%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar diff --git a/python.changes b/python.changes index 8a8562c..45656c2 100644 --- a/python.changes +++ b/python.changes @@ -2,8 +2,9 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Switch on tests again. -- Add bsc1222537-py2-email-addr-parse.patch to fix the unicode - string handling in email.utils.parseaddr() (bsc#1222537). +- Modify CVE-2023-27043-email-parsing-errors.patch to fix the + unicode string handling in email.utils.parseaddr() + (bsc#1222537). ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl diff --git a/python.spec b/python.spec index 305ff71..30932f8 100644 --- a/python.spec +++ b/python.spec @@ -150,7 +150,8 @@ Patch75: CVE-2023-24329-blank-URL-bypass.patch Patch76: PygmentsBridge-trime_doctest_flags.patch # PATCH-FIX-UPSTREAM CVE-2023-27043-email-parsing-errors.patch bsc#1210638 mcepl@suse.com # Detect email address parsing errors and return empty tuple to -# indicate the parsing error (old API) +# indicate the parsing error (old API), modified for fixing bsc#1222537, +# so that email.utils.parseaddr accepts unicode string Patch77: CVE-2023-27043-email-parsing-errors.patch # PATCH-FIX-UPSTREAM CVE-2022-48565-plistlib-XML-vulns.patch bsc#1214685 mcepl@suse.com # Reject entity declarations in plists @@ -163,9 +164,6 @@ Patch80: CVE-2022-48566-compare_digest-more-constant.patch # PATCH-FIX-UPSTREAM CVE-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com # fix use after free in heapq.heappushpop() Patch81: CVE-2022-48560-after-free-heappushpop.patch -# PATCH-FIX-UPSTREAM bsc1222537-py2-email-addr-parse.patch bsc#1222537 mcepl@suse.com -# email.utils.parseaddr should accept unicode string -Patch82: bsc1222537-py2-email-addr-parse.patch # COMMON-PATCH-END BuildRequires: automake BuildRequires: db-devel @@ -378,7 +376,6 @@ that rely on earlier non-verification behavior. %patch -P 79 -p1 %patch -P 80 -p1 %patch -P 81 -p1 -%patch -P 82 -p1 # For patch 66 cp -v %{SOURCE66} Lib/test/recursion.tar From 39b345bbe23036dcc3c4ba2f206d5132df5ee95dc7f996b27f662c12f582c37a Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 16 Apr 2024 21:24:47 +0000 Subject: [PATCH 07/10] Switch off tests again. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=408 --- python-base.changes | 1 - python-base.spec | 4 +++- python-doc.changes | 1 - python.changes | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/python-base.changes b/python-base.changes index 45656c2..ae99db1 100644 --- a/python-base.changes +++ b/python-base.changes @@ -1,7 +1,6 @@ ------------------------------------------------------------------- Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl -- Switch on tests again. - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). diff --git a/python-base.spec b/python-base.spec index d4d36ba..9ca35cb 100644 --- a/python-base.spec +++ b/python-base.spec @@ -19,7 +19,7 @@ %define so_version 2_7-1_0 # We really don't care about quality of this package anymore, it # will be soon gone (bsc#1219306). -%bcond_without tests +%bcond_with test Name: python-base Version: 2.7.18 @@ -380,6 +380,7 @@ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH \ make %{?_smp_mflags} $target %check +%if %{with test} # on hppa, the threading of glibc is quite broken. The tests just stop # at some point, and the machine does not build anything more until a # timeout several hours later. @@ -431,6 +432,7 @@ make test TESTOPTS="-l -w -x $EXCLUDE" TESTPYTHONOPTS="-R" # use network, be verbose: #make test TESTOPTS="-l -u network -v" %endif +%endif # END OF CHECK SECTION %install diff --git a/python-doc.changes b/python-doc.changes index 45656c2..ae99db1 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -1,7 +1,6 @@ ------------------------------------------------------------------- Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl -- Switch on tests again. - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). diff --git a/python.changes b/python.changes index 45656c2..ae99db1 100644 --- a/python.changes +++ b/python.changes @@ -1,7 +1,6 @@ ------------------------------------------------------------------- Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl -- Switch on tests again. - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). From 6c006a7c74d5a8de103cc9bb6c24b7c822d7f8fafe66000342126390252921ab Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Wed, 17 Apr 2024 10:46:39 +0000 Subject: [PATCH 08/10] Remove superfluous CVE-2022-48560-after-free-heappushpop.patch. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=409 --- python-base.changes | 3 --- python-base.spec | 4 ---- python-doc.changes | 3 --- python-doc.spec | 4 ---- python.changes | 3 --- python.spec | 4 ---- 6 files changed, 21 deletions(-) diff --git a/python-base.changes b/python-base.changes index ae99db1..8402af4 100644 --- a/python-base.changes +++ b/python-base.changes @@ -24,9 +24,6 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl -- Add CVE-2022-48560-after-free-heappushpop.patch fixing - use-after-free in Python via heappushpop in heapq (bsc#1214675, - CVE-2022-48560). - switch from %patchN style to the %patch -P N one. ------------------------------------------------------------------- diff --git a/python-base.spec b/python-base.spec index 9ca35cb..820c20e 100644 --- a/python-base.spec +++ b/python-base.spec @@ -165,9 +165,6 @@ 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-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com -# fix use after free in heapq.heappushpop() -Patch81: CVE-2022-48560-after-free-heappushpop.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) BuildRequires: automake @@ -324,7 +321,6 @@ 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 ae99db1..8402af4 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -24,9 +24,6 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl -- Add CVE-2022-48560-after-free-heappushpop.patch fixing - use-after-free in Python via heappushpop in heapq (bsc#1214675, - CVE-2022-48560). - switch from %patchN style to the %patch -P N one. ------------------------------------------------------------------- diff --git a/python-doc.spec b/python-doc.spec index 661658f..cce64ff 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -161,9 +161,6 @@ 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-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com -# fix use after free in heapq.heappushpop() -Patch81: CVE-2022-48560-after-free-heappushpop.patch # COMMON-PATCH-END Provides: pyth_doc = %{version} Provides: pyth_ps = %{version} @@ -255,7 +252,6 @@ 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 ae99db1..8402af4 100644 --- a/python.changes +++ b/python.changes @@ -24,9 +24,6 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl -- Add CVE-2022-48560-after-free-heappushpop.patch fixing - use-after-free in Python via heappushpop in heapq (bsc#1214675, - CVE-2022-48560). - switch from %patchN style to the %patch -P N one. ------------------------------------------------------------------- diff --git a/python.spec b/python.spec index 30932f8..bd33603 100644 --- a/python.spec +++ b/python.spec @@ -161,9 +161,6 @@ 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-2022-48560-after-free-heappushpop.patch bsc#1214675 mcepl@suse.com -# fix use after free in heapq.heappushpop() -Patch81: CVE-2022-48560-after-free-heappushpop.patch # COMMON-PATCH-END BuildRequires: automake BuildRequires: db-devel @@ -375,7 +372,6 @@ 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 From bd965ddc0d88bd2e6b0cfa6138ea5c15d907b3debec16a86619d360981003868 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Wed, 17 Apr 2024 10:47:07 +0000 Subject: [PATCH 09/10] REmove the patch OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=410 --- CVE-2022-48560-after-free-heappushpop.patch | 132 -------------------- 1 file changed, 132 deletions(-) delete mode 100644 CVE-2022-48560-after-free-heappushpop.patch diff --git a/CVE-2022-48560-after-free-heappushpop.patch b/CVE-2022-48560-after-free-heappushpop.patch deleted file mode 100644 index 94d2448..0000000 --- a/CVE-2022-48560-after-free-heappushpop.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 5179d30710e6185dc7e6a6098ab23fe068b0d85b Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Thu, 23 Nov 2023 13:25:44 +0100 -Subject: [PATCH] 00408-cve-2022-48560.patch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Security fix for CVE-2022-48560: python3: use after free in heappushpop() -of heapq module -Resolved upstream: https://github.com/python/cpython/issues/83602 - -Backported from Python 3.6.11. - -Co-authored-by: Pablo Galindo -Co-authored-by: Lumír Balhar ---- - Lib/test/test_heapq.py | 32 ++++++++++++++++++++++++++++++++ - Modules/_heapqmodule.c | 31 ++++++++++++++++++++++++------- - 2 files changed, 56 insertions(+), 7 deletions(-) - ---- a/Lib/test/test_heapq.py -+++ b/Lib/test/test_heapq.py -@@ -396,6 +396,38 @@ class TestErrorHandling(TestCase): - with self.assertRaises((IndexError, RuntimeError)): - self.module.heappop(heap) - -+ def test_comparison_operator_modifiying_heap(self): -+ # See bpo-39421: Strong references need to be taken -+ # when comparing objects as they can alter the heap -+ class EvilClass(int): -+ def __lt__(self, o): -+ heap[:] = [] -+ return NotImplemented -+ -+ heap = [] -+ self.module.heappush(heap, EvilClass(0)) -+ self.assertRaises(IndexError, self.module.heappushpop, heap, 1) -+ -+ def test_comparison_operator_modifiying_heap_two_heaps(self): -+ -+ class h(int): -+ def __lt__(self, o): -+ list2[:] = [] -+ return NotImplemented -+ -+ class g(int): -+ def __lt__(self, o): -+ list1[:] = [] -+ return NotImplemented -+ -+ list1, list2 = [], [] -+ -+ self.module.heappush(list1, h(0)) -+ self.module.heappush(list2, g(0)) -+ -+ self.assertRaises((IndexError, RuntimeError), self.module.heappush, list1, g(1)) -+ self.assertRaises((IndexError, RuntimeError), self.module.heappush, list2, h(1)) -+ - - class TestErrorHandlingPython(TestErrorHandling): - module = py_heapq ---- a/Modules/_heapqmodule.c -+++ b/Modules/_heapqmodule.c -@@ -52,7 +52,11 @@ _siftdown(PyListObject *heap, Py_ssize_t - while (pos > startpos) { - parentpos = (pos - 1) >> 1; - parent = PyList_GET_ITEM(heap, parentpos); -+ Py_INCREF(newitem); -+ Py_INCREF(parent); - cmp = cmp_lt(newitem, parent); -+ Py_DECREF(parent); -+ Py_DECREF(newitem); - if (cmp == -1) - return -1; - if (size != PyList_GET_SIZE(heap)) { -@@ -93,9 +97,13 @@ _siftup(PyListObject *heap, Py_ssize_t p - childpos = 2*pos + 1; /* leftmost child position */ - rightpos = childpos + 1; - if (rightpos < endpos) { -- cmp = cmp_lt( -- PyList_GET_ITEM(heap, childpos), -- PyList_GET_ITEM(heap, rightpos)); -+ PyObject* a = PyList_GET_ITEM(heap, childpos); -+ PyObject* b = PyList_GET_ITEM(heap, rightpos); -+ Py_INCREF(a); -+ Py_INCREF(b); -+ cmp = cmp_lt(a, b); -+ Py_DECREF(a); -+ Py_DECREF(b); - if (cmp == -1) - return -1; - if (cmp == 0) -@@ -236,7 +244,10 @@ heappushpop(PyObject *self, PyObject *ar - return item; - } - -- cmp = cmp_lt(PyList_GET_ITEM(heap, 0), item); -+ PyObject* top = PyList_GET_ITEM(heap, 0); -+ Py_INCREF(top); -+ cmp = cmp_lt(top, item); -+ Py_DECREF(top); - if (cmp == -1) - return NULL; - if (cmp == 0) { -@@ -395,7 +406,9 @@ _siftdownmax(PyListObject *heap, Py_ssiz - while (pos > startpos){ - parentpos = (pos - 1) >> 1; - parent = PyList_GET_ITEM(heap, parentpos); -+ Py_INCREF(parent); - cmp = cmp_lt(parent, newitem); -+ Py_DECREF(parent); - if (cmp == -1) { - Py_DECREF(newitem); - return -1; -@@ -436,9 +449,13 @@ _siftupmax(PyListObject *heap, Py_ssize_ - childpos = 2*pos + 1; /* leftmost child position */ - rightpos = childpos + 1; - if (rightpos < endpos) { -- cmp = cmp_lt( -- PyList_GET_ITEM(heap, rightpos), -- PyList_GET_ITEM(heap, childpos)); -+ PyObject* a = PyList_GET_ITEM(heap, rightpos); -+ PyObject* b = PyList_GET_ITEM(heap, childpos); -+ Py_INCREF(a); -+ Py_INCREF(b); -+ cmp = cmp_lt(a, b); -+ Py_DECREF(a); -+ Py_DECREF(b); - if (cmp == -1) { - Py_DECREF(newitem); - return -1; From 93c812d4486237447f07866b5124ba38cbe8e25c426dfca8b4d5aea00a486df1 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Tue, 23 Apr 2024 15:53:53 +0000 Subject: [PATCH 10/10] - Revert CVE-2022-48560-after-free-heappushpop.patch, the fix was unneeded. - Add CVE-2022-48560-after-free-heappushpop.patch fixing use-after-free in Python via heappushpop in heapq (bsc#1214675, CVE-2022-48560). OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=411 --- python-base.changes | 5 +++++ python-doc.changes | 5 +++++ python.changes | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/python-base.changes b/python-base.changes index 8402af4..092c6ec 100644 --- a/python-base.changes +++ b/python-base.changes @@ -4,6 +4,8 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). +- Revert CVE-2022-48560-after-free-heappushpop.patch, the fix was + unneeded. ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl @@ -24,6 +26,9 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl +- Add CVE-2022-48560-after-free-heappushpop.patch fixing + use-after-free in Python via heappushpop in heapq (bsc#1214675, + CVE-2022-48560). - switch from %patchN style to the %patch -P N one. ------------------------------------------------------------------- diff --git a/python-doc.changes b/python-doc.changes index 8402af4..092c6ec 100644 --- a/python-doc.changes +++ b/python-doc.changes @@ -4,6 +4,8 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). +- Revert CVE-2022-48560-after-free-heappushpop.patch, the fix was + unneeded. ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl @@ -24,6 +26,9 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl +- Add CVE-2022-48560-after-free-heappushpop.patch fixing + use-after-free in Python via heappushpop in heapq (bsc#1214675, + CVE-2022-48560). - switch from %patchN style to the %patch -P N one. ------------------------------------------------------------------- diff --git a/python.changes b/python.changes index 8402af4..092c6ec 100644 --- a/python.changes +++ b/python.changes @@ -4,6 +4,8 @@ Tue Apr 16 15:39:24 UTC 2024 - Matej Cepl - Modify CVE-2023-27043-email-parsing-errors.patch to fix the unicode string handling in email.utils.parseaddr() (bsc#1222537). +- Revert CVE-2022-48560-after-free-heappushpop.patch, the fix was + unneeded. ------------------------------------------------------------------- Mon Mar 18 09:54:20 UTC 2024 - Matej Cepl @@ -24,6 +26,9 @@ Mon Jan 8 10:00:07 UTC 2024 - Daniel Garcia ------------------------------------------------------------------- Mon Nov 27 16:30:33 UTC 2023 - Matej Cepl +- Add CVE-2022-48560-after-free-heappushpop.patch fixing + use-after-free in Python via heappushpop in heapq (bsc#1214675, + CVE-2022-48560). - switch from %patchN style to the %patch -P N one. -------------------------------------------------------------------