fix CVE-2024-4032, CVE-2024-0397
This commit is contained in:
parent
ee4fdfe7da
commit
3afa904638
@ -0,0 +1,346 @@
|
||||
From ba431579efdcbaed7a96f2ac4ea0775879a332fb Mon Sep 17 00:00:00 2001
|
||||
From: Petr Viktorin <encukou@gmail.com>
|
||||
Date: Thu, 25 Apr 2024 14:45:48 +0200
|
||||
Subject: [PATCH] [3.11] gh-113171: gh-65056: Fix "private" (non-global) IP
|
||||
address ranges (GH-113179) (GH-113186) (GH-118177) (#118227)
|
||||
|
||||
---
|
||||
Doc/library/ipaddress.rst | 43 +++++++-
|
||||
Doc/whatsnew/3.11.rst | 9 ++
|
||||
Lib/ipaddress.py | 99 +++++++++++++++----
|
||||
Lib/test/test_ipaddress.py | 21 +++-
|
||||
...-03-14-01-38-44.gh-issue-113171.VFnObz.rst | 9 ++
|
||||
5 files changed, 157 insertions(+), 24 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst
|
||||
|
||||
diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst
|
||||
index 03dc956cd1..f57fa15aa5 100644
|
||||
--- a/Doc/library/ipaddress.rst
|
||||
+++ b/Doc/library/ipaddress.rst
|
||||
@@ -178,18 +178,53 @@ write code that handles both IP versions correctly. Address objects are
|
||||
|
||||
.. attribute:: is_private
|
||||
|
||||
- ``True`` if the address is allocated for private networks. See
|
||||
+ ``True`` if the address is defined as not globally reachable by
|
||||
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
- (for IPv6).
|
||||
+ (for IPv6) with the following exceptions:
|
||||
+
|
||||
+ * ``is_private`` is ``False`` for the shared address space (``100.64.0.0/10``)
|
||||
+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
+
|
||||
+ address.is_private == address.ipv4_mapped.is_private
|
||||
+
|
||||
+ ``is_private`` has value opposite to :attr:`is_global`, except for the shared address space
|
||||
+ (``100.64.0.0/10`` range) where they are both ``False``.
|
||||
+
|
||||
+ .. versionchanged:: 3.11.10
|
||||
+
|
||||
+ Fixed some false positives and false negatives.
|
||||
+
|
||||
+ * ``192.0.0.0/24`` is considered private with the exception of ``192.0.0.9/32`` and
|
||||
+ ``192.0.0.10/32`` (previously: only the ``192.0.0.0/29`` sub-range was considered private).
|
||||
+ * ``64:ff9b:1::/48`` is considered private.
|
||||
+ * ``2002::/16`` is considered private.
|
||||
+ * There are exceptions within ``2001::/23`` (otherwise considered private): ``2001:1::1/128``,
|
||||
+ ``2001:1::2/128``, ``2001:3::/32``, ``2001:4:112::/48``, ``2001:20::/28``, ``2001:30::/28``.
|
||||
+ The exceptions are not considered private.
|
||||
|
||||
.. attribute:: is_global
|
||||
|
||||
- ``True`` if the address is allocated for public networks. See
|
||||
+ ``True`` if the address is defined as globally reachable by
|
||||
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
- (for IPv6).
|
||||
+ (for IPv6) with the following exception:
|
||||
+
|
||||
+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
+
|
||||
+ address.is_global == address.ipv4_mapped.is_global
|
||||
+
|
||||
+ ``is_global`` has value opposite to :attr:`is_private`, except for the shared address space
|
||||
+ (``100.64.0.0/10`` range) where they are both ``False``.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
+ .. versionchanged:: 3.11.10
|
||||
+
|
||||
+ Fixed some false positives and false negatives, see :attr:`is_private` for details.
|
||||
+
|
||||
.. attribute:: is_unspecified
|
||||
|
||||
``True`` if the address is unspecified. See :RFC:`5735` (for IPv4)
|
||||
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
|
||||
index f670fa1f09..42b61c75c7 100644
|
||||
--- a/Doc/whatsnew/3.11.rst
|
||||
+++ b/Doc/whatsnew/3.11.rst
|
||||
@@ -2727,3 +2727,12 @@ OpenSSL
|
||||
* Windows builds and macOS installers from python.org now use OpenSSL 3.0.
|
||||
|
||||
.. _libb2: https://www.blake2.net/
|
||||
+
|
||||
+Notable changes in 3.11.10
|
||||
+==========================
|
||||
+
|
||||
+ipaddress
|
||||
+---------
|
||||
+
|
||||
+* Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``,
|
||||
+ ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``.
|
||||
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
|
||||
index 16ba16cd7d..567beb37e0 100644
|
||||
--- a/Lib/ipaddress.py
|
||||
+++ b/Lib/ipaddress.py
|
||||
@@ -1086,7 +1086,11 @@ def is_private(self):
|
||||
"""
|
||||
return any(self.network_address in priv_network and
|
||||
self.broadcast_address in priv_network
|
||||
- for priv_network in self._constants._private_networks)
|
||||
+ for priv_network in self._constants._private_networks) and all(
|
||||
+ self.network_address not in network and
|
||||
+ self.broadcast_address not in network
|
||||
+ for network in self._constants._private_networks_exceptions
|
||||
+ )
|
||||
|
||||
@property
|
||||
def is_global(self):
|
||||
@@ -1333,18 +1337,41 @@ def is_reserved(self):
|
||||
@property
|
||||
@functools.lru_cache()
|
||||
def is_private(self):
|
||||
- """Test if this address is allocated for private networks.
|
||||
+ """``True`` if the address is defined as not globally reachable by
|
||||
+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
+ (for IPv6) with the following exceptions:
|
||||
|
||||
- Returns:
|
||||
- A boolean, True if the address is reserved per
|
||||
- iana-ipv4-special-registry.
|
||||
+ * ``is_private`` is ``False`` for ``100.64.0.0/10``
|
||||
+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
|
||||
+ address.is_private == address.ipv4_mapped.is_private
|
||||
+
|
||||
+ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
|
||||
+ IPv4 range where they are both ``False``.
|
||||
"""
|
||||
- return any(self in net for net in self._constants._private_networks)
|
||||
+ return (
|
||||
+ any(self in net for net in self._constants._private_networks)
|
||||
+ and all(self not in net for net in self._constants._private_networks_exceptions)
|
||||
+ )
|
||||
|
||||
@property
|
||||
@functools.lru_cache()
|
||||
def is_global(self):
|
||||
+ """``True`` if the address is defined as globally reachable by
|
||||
+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
+ (for IPv6) with the following exception:
|
||||
+
|
||||
+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
+
|
||||
+ address.is_global == address.ipv4_mapped.is_global
|
||||
+
|
||||
+ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
|
||||
+ IPv4 range where they are both ``False``.
|
||||
+ """
|
||||
return self not in self._constants._public_network and not self.is_private
|
||||
|
||||
@property
|
||||
@@ -1548,13 +1575,15 @@ class _IPv4Constants:
|
||||
|
||||
_public_network = IPv4Network('100.64.0.0/10')
|
||||
|
||||
+ # Not globally reachable address blocks listed on
|
||||
+ # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
|
||||
_private_networks = [
|
||||
IPv4Network('0.0.0.0/8'),
|
||||
IPv4Network('10.0.0.0/8'),
|
||||
IPv4Network('127.0.0.0/8'),
|
||||
IPv4Network('169.254.0.0/16'),
|
||||
IPv4Network('172.16.0.0/12'),
|
||||
- IPv4Network('192.0.0.0/29'),
|
||||
+ IPv4Network('192.0.0.0/24'),
|
||||
IPv4Network('192.0.0.170/31'),
|
||||
IPv4Network('192.0.2.0/24'),
|
||||
IPv4Network('192.168.0.0/16'),
|
||||
@@ -1565,6 +1594,11 @@ class _IPv4Constants:
|
||||
IPv4Network('255.255.255.255/32'),
|
||||
]
|
||||
|
||||
+ _private_networks_exceptions = [
|
||||
+ IPv4Network('192.0.0.9/32'),
|
||||
+ IPv4Network('192.0.0.10/32'),
|
||||
+ ]
|
||||
+
|
||||
_reserved_network = IPv4Network('240.0.0.0/4')
|
||||
|
||||
_unspecified_address = IPv4Address('0.0.0.0')
|
||||
@@ -2010,27 +2044,42 @@ def is_site_local(self):
|
||||
@property
|
||||
@functools.lru_cache()
|
||||
def is_private(self):
|
||||
- """Test if this address is allocated for private networks.
|
||||
+ """``True`` if the address is defined as not globally reachable by
|
||||
+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
+ (for IPv6) with the following exceptions:
|
||||
|
||||
- Returns:
|
||||
- A boolean, True if the address is reserved per
|
||||
- iana-ipv6-special-registry, or is ipv4_mapped and is
|
||||
- reserved in the iana-ipv4-special-registry.
|
||||
+ * ``is_private`` is ``False`` for ``100.64.0.0/10``
|
||||
+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
|
||||
+ address.is_private == address.ipv4_mapped.is_private
|
||||
+
|
||||
+ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
|
||||
+ IPv4 range where they are both ``False``.
|
||||
"""
|
||||
ipv4_mapped = self.ipv4_mapped
|
||||
if ipv4_mapped is not None:
|
||||
return ipv4_mapped.is_private
|
||||
- return any(self in net for net in self._constants._private_networks)
|
||||
+ return (
|
||||
+ any(self in net for net in self._constants._private_networks)
|
||||
+ and all(self not in net for net in self._constants._private_networks_exceptions)
|
||||
+ )
|
||||
|
||||
@property
|
||||
def is_global(self):
|
||||
- """Test if this address is allocated for public networks.
|
||||
+ """``True`` if the address is defined as globally reachable by
|
||||
+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
|
||||
+ (for IPv6) with the following exception:
|
||||
|
||||
- Returns:
|
||||
- A boolean, true if the address is not reserved per
|
||||
- iana-ipv6-special-registry.
|
||||
+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
|
||||
+ semantics of the underlying IPv4 addresses and the following condition holds
|
||||
+ (see :attr:`IPv6Address.ipv4_mapped`)::
|
||||
+
|
||||
+ address.is_global == address.ipv4_mapped.is_global
|
||||
|
||||
+ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
|
||||
+ IPv4 range where they are both ``False``.
|
||||
"""
|
||||
return not self.is_private
|
||||
|
||||
@@ -2271,19 +2320,31 @@ class _IPv6Constants:
|
||||
|
||||
_multicast_network = IPv6Network('ff00::/8')
|
||||
|
||||
+ # Not globally reachable address blocks listed on
|
||||
+ # https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
|
||||
_private_networks = [
|
||||
IPv6Network('::1/128'),
|
||||
IPv6Network('::/128'),
|
||||
IPv6Network('::ffff:0:0/96'),
|
||||
+ IPv6Network('64:ff9b:1::/48'),
|
||||
IPv6Network('100::/64'),
|
||||
IPv6Network('2001::/23'),
|
||||
- IPv6Network('2001:2::/48'),
|
||||
IPv6Network('2001:db8::/32'),
|
||||
- IPv6Network('2001:10::/28'),
|
||||
+ # IANA says N/A, let's consider it not globally reachable to be safe
|
||||
+ IPv6Network('2002::/16'),
|
||||
IPv6Network('fc00::/7'),
|
||||
IPv6Network('fe80::/10'),
|
||||
]
|
||||
|
||||
+ _private_networks_exceptions = [
|
||||
+ IPv6Network('2001:1::1/128'),
|
||||
+ IPv6Network('2001:1::2/128'),
|
||||
+ IPv6Network('2001:3::/32'),
|
||||
+ IPv6Network('2001:4:112::/48'),
|
||||
+ IPv6Network('2001:20::/28'),
|
||||
+ IPv6Network('2001:30::/28'),
|
||||
+ ]
|
||||
+
|
||||
_reserved_networks = [
|
||||
IPv6Network('::/8'), IPv6Network('100::/8'),
|
||||
IPv6Network('200::/7'), IPv6Network('400::/6'),
|
||||
diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
|
||||
index fc27628af1..16c34163a0 100644
|
||||
--- a/Lib/test/test_ipaddress.py
|
||||
+++ b/Lib/test/test_ipaddress.py
|
||||
@@ -2269,6 +2269,10 @@ def testReservedIpv4(self):
|
||||
self.assertEqual(True, ipaddress.ip_address(
|
||||
'172.31.255.255').is_private)
|
||||
self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private)
|
||||
+ self.assertFalse(ipaddress.ip_address('192.0.0.0').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('192.0.0.9').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('192.0.0.10').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('192.0.0.255').is_global)
|
||||
|
||||
self.assertEqual(True,
|
||||
ipaddress.ip_address('169.254.100.200').is_link_local)
|
||||
@@ -2294,6 +2298,7 @@ def testPrivateNetworks(self):
|
||||
self.assertEqual(True, ipaddress.ip_network("169.254.0.0/16").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("172.16.0.0/12").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("192.0.0.0/29").is_private)
|
||||
+ self.assertEqual(False, ipaddress.ip_network("192.0.0.9/32").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("192.0.0.170/31").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("192.0.2.0/24").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("192.168.0.0/16").is_private)
|
||||
@@ -2310,8 +2315,8 @@ def testPrivateNetworks(self):
|
||||
self.assertEqual(True, ipaddress.ip_network("::/128").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("::ffff:0:0/96").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("100::/64").is_private)
|
||||
- self.assertEqual(True, ipaddress.ip_network("2001::/23").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("2001:2::/48").is_private)
|
||||
+ self.assertEqual(False, ipaddress.ip_network("2001:3::/48").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("2001:db8::/32").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("2001:10::/28").is_private)
|
||||
self.assertEqual(True, ipaddress.ip_network("fc00::/7").is_private)
|
||||
@@ -2390,6 +2395,20 @@ def testReservedIpv6(self):
|
||||
self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified)
|
||||
self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified)
|
||||
|
||||
+ self.assertFalse(ipaddress.ip_address('64:ff9b:1::').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2001::').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:1::1').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:1::2').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2001:2::').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:3::').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2001:4::').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:4:112::').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2001:10::').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:20::').is_global)
|
||||
+ self.assertTrue(ipaddress.ip_address('2001:30::').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2001:40::').is_global)
|
||||
+ self.assertFalse(ipaddress.ip_address('2002::').is_global)
|
||||
+
|
||||
# some generic IETF reserved addresses
|
||||
self.assertEqual(True, ipaddress.ip_address('100::').is_reserved)
|
||||
self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved)
|
||||
diff --git a/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst
|
||||
new file mode 100644
|
||||
index 0000000000..f9a72473be
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst
|
||||
@@ -0,0 +1,9 @@
|
||||
+Fixed various false positives and false negatives in
|
||||
+
|
||||
+* :attr:`ipaddress.IPv4Address.is_private` (see these docs for details)
|
||||
+* :attr:`ipaddress.IPv4Address.is_global`
|
||||
+* :attr:`ipaddress.IPv6Address.is_private`
|
||||
+* :attr:`ipaddress.IPv6Address.is_global`
|
||||
+
|
||||
+Also in the corresponding :class:`ipaddress.IPv4Network` and :class:`ipaddress.IPv6Network`
|
||||
+attributes.
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
From bce693111bff906ccf9281c22371331aaff766ab Mon Sep 17 00:00:00 2001
|
||||
From: David Benjamin <davidben@google.com>
|
||||
Date: Thu, 15 Feb 2024 19:24:51 -0500
|
||||
Subject: [PATCH] gh-114572: Fix locking in cert_store_stats and get_ca_certs
|
||||
(#114573)
|
||||
From 01c37f1d0714f5822d34063ca7180b595abf589d Mon Sep 17 00:00:00 2001
|
||||
From: "Miss Islington (bot)"
|
||||
<31488909+miss-islington@users.noreply.github.com>
|
||||
Date: Tue, 20 Feb 2024 17:34:44 +0100
|
||||
Subject: [PATCH] [3.11] gh-114572: Fix locking in cert_store_stats and
|
||||
get_ca_certs (GH-114573) (#115549)
|
||||
|
||||
gh-114572: Fix locking in cert_store_stats and get_ca_certs (GH-114573)
|
||||
|
||||
* gh-114572: Fix locking in cert_store_stats and get_ca_certs
|
||||
|
||||
@ -19,6 +22,9 @@ polyfill it with X509_STORE_lock and X509_STORE_unlock.
|
||||
* Add missing X509_STORE_get1_objects failure check
|
||||
|
||||
* Add blurb
|
||||
(cherry picked from commit bce693111bff906ccf9281c22371331aaff766ab)
|
||||
|
||||
Co-authored-by: David Benjamin <davidben@google.com>
|
||||
---
|
||||
...-01-26-22-14-09.gh-issue-114572.t1QMQD.rst | 4 ++
|
||||
Modules/_ssl.c | 65 +++++++++++++++++--
|
||||
@ -36,10 +42,10 @@ index 0000000000..b4f9fe64db
|
||||
+certificate store, when the :class:`ssl.SSLContext` is shared across
|
||||
+multiple threads.
|
||||
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
|
||||
index bc30290942..950ee36630 100644
|
||||
index 67ce6e97af..81d36a6f11 100644
|
||||
--- a/Modules/_ssl.c
|
||||
+++ b/Modules/_ssl.c
|
||||
@@ -4553,6 +4553,50 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
|
||||
@@ -4529,6 +4529,50 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -90,7 +96,7 @@ index bc30290942..950ee36630 100644
|
||||
PyDoc_STRVAR(PySSLContext_sni_callback_doc,
|
||||
"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\
|
||||
\n\
|
||||
@@ -4582,7 +4626,12 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
@@ -4558,7 +4602,12 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
int x509 = 0, crl = 0, ca = 0, i;
|
||||
|
||||
store = SSL_CTX_get_cert_store(self->ctx);
|
||||
@ -104,7 +110,7 @@ index bc30290942..950ee36630 100644
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
obj = sk_X509_OBJECT_value(objs, i);
|
||||
switch (X509_OBJECT_get_type(obj)) {
|
||||
@@ -4596,12 +4645,11 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
@@ -4572,12 +4621,11 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
crl++;
|
||||
break;
|
||||
default:
|
||||
@ -119,7 +125,7 @@ index bc30290942..950ee36630 100644
|
||||
return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl,
|
||||
"x509_ca", ca);
|
||||
}
|
||||
@@ -4633,7 +4681,12 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
@@ -4609,7 +4657,12 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
}
|
||||
|
||||
store = SSL_CTX_get_cert_store(self->ctx);
|
||||
@ -133,7 +139,7 @@ index bc30290942..950ee36630 100644
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
X509_OBJECT *obj;
|
||||
X509 *cert;
|
||||
@@ -4661,9 +4714,11 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
@@ -4637,9 +4690,11 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
}
|
||||
Py_CLEAR(ci);
|
||||
}
|
||||
@ -146,5 +152,5 @@ index bc30290942..950ee36630 100644
|
||||
Py_XDECREF(rlist);
|
||||
return NULL;
|
||||
--
|
||||
2.45.1.windows.1
|
||||
2.27.0
|
||||
|
||||
89
backport-fix_xml_tree_assert_error.patch
Normal file
89
backport-fix_xml_tree_assert_error.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From 4a08e7b3431cd32a0daf22a33421cd3035343dc4 Mon Sep 17 00:00:00 2001
|
||||
From: Serhiy Storchaka <storchaka@gmail.com>
|
||||
Date: Sun, 11 Feb 2024 12:08:39 +0200
|
||||
Subject: [PATCH] gh-115133: Fix tests for XMLPullParser with Expat 2.6.0
|
||||
(GH-115164)
|
||||
|
||||
Feeding the parser by too small chunks defers parsing to prevent
|
||||
CVE-2023-52425. Future versions of Expat may be more reactive.
|
||||
|
||||
Other adaptation:
|
||||
For the expat version number, whether a feature exists in the header file is used to determine whether to execute a test case.
|
||||
|
||||
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
|
||||
index 142ce2c..a8d5c2d 100644
|
||||
--- a/Lib/test/test_xml_etree.py
|
||||
+++ b/Lib/test/test_xml_etree.py
|
||||
@@ -14,6 +14,8 @@ import locale
|
||||
import operator
|
||||
import os
|
||||
import pickle
|
||||
+import pyexpat
|
||||
+import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
import types
|
||||
@@ -96,6 +98,11 @@ ENTITY_XML = """\
|
||||
<document>&entity;</document>
|
||||
"""
|
||||
|
||||
+macro_to_find = 'XML_SetReparseDeferralEnabled'
|
||||
+header_file = '/usr/include/expat.h'
|
||||
+result = subprocess.run(['grep', '-q', macro_to_find, header_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
+fails_with_expat = (unittest.expectedFailure if result.returncode == 0 else lambda test: test)
|
||||
+
|
||||
EXTERNAL_ENTITY_XML = """\
|
||||
<!DOCTYPE points [
|
||||
<!ENTITY entity SYSTEM "file:///non-existing-file.xml">
|
||||
@@ -1410,27 +1417,38 @@ class XMLPullParserTest(unittest.TestCase):
|
||||
with self.assertRaises(StopIteration):
|
||||
next(it)
|
||||
|
||||
- def test_simple_xml_with_ns(self):
|
||||
+ def test_simple_xml(self, chunk_size=None):
|
||||
parser = ET.XMLPullParser()
|
||||
self.assert_event_tags(parser, [])
|
||||
- self._feed(parser, "<!-- comment -->\n")
|
||||
- self.assert_event_tags(parser, [])
|
||||
- self._feed(parser, "<root xmlns='namespace'>\n")
|
||||
+ self._feed(parser, "<!-- comment -->\n", chunk_size)
|
||||
self.assert_event_tags(parser, [])
|
||||
- self._feed(parser, "<element key='value'>text</element")
|
||||
+ self._feed(parser,
|
||||
+ "<root>\n <element key='value'>text</element",
|
||||
+ chunk_size)
|
||||
self.assert_event_tags(parser, [])
|
||||
- self._feed(parser, ">\n")
|
||||
- self.assert_event_tags(parser, [('end', '{namespace}element')])
|
||||
- self._feed(parser, "<element>text</element>tail\n")
|
||||
- self._feed(parser, "<empty-element/>\n")
|
||||
+ self._feed(parser, ">\n", chunk_size)
|
||||
+ self.assert_event_tags(parser, [('end', 'element')])
|
||||
+ self._feed(parser, "<element>text</element>tail\n", chunk_size)
|
||||
+ self._feed(parser, "<empty-element/>\n", chunk_size)
|
||||
self.assert_event_tags(parser, [
|
||||
- ('end', '{namespace}element'),
|
||||
- ('end', '{namespace}empty-element'),
|
||||
+ ('end', 'element'),
|
||||
+ ('end', 'empty-element'),
|
||||
])
|
||||
- self._feed(parser, "</root>\n")
|
||||
- self.assert_event_tags(parser, [('end', '{namespace}root')])
|
||||
+ self._feed(parser, "</root>\n", chunk_size)
|
||||
+ self.assert_event_tags(parser, [('end', 'root')])
|
||||
self.assertIsNone(parser.close())
|
||||
|
||||
+ @fails_with_expat
|
||||
+ def test_simple_xml_chunk_1(self):
|
||||
+ self.test_simple_xml(chunk_size=1)
|
||||
+
|
||||
+ @fails_with_expat
|
||||
+ def test_simple_xml_chunk_5(self):
|
||||
+ self.test_simple_xml(chunk_size=5)
|
||||
+
|
||||
+ def test_simple_xml_chunk_22(self):
|
||||
+ self.test_simple_xml(chunk_size=22)
|
||||
+
|
||||
def test_ns_events(self):
|
||||
parser = ET.XMLPullParser(events=('start-ns', 'end-ns'))
|
||||
self._feed(parser, "<!-- comment -->\n")
|
||||
15
python3.spec
15
python3.spec
@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language
|
||||
URL: https://www.python.org/
|
||||
|
||||
Version: 3.11.6
|
||||
Release: 3
|
||||
Release: 4
|
||||
License: Python-2.0
|
||||
|
||||
%global branchversion 3.11
|
||||
@ -88,7 +88,9 @@ Source1: pyconfig.h
|
||||
Patch1: 00001-rpath.patch
|
||||
Patch251: 00251-change-user-install-location.patch
|
||||
|
||||
Patch6000: backport-3.11-gh-114572-Fix-locking-in-cert_store_stats-and-get_ca.patch
|
||||
Patch6000: backport-3.11-gh-114572-Fix-locking-in-cert_store_stats-and-g.patch
|
||||
Patch6001: backport-3.11-gh-113171-gh-65056-Fix-private-non-global-IP-ad.patch
|
||||
Patch6002: backport-fix_xml_tree_assert_error.patch
|
||||
|
||||
Patch9000: add-the-sm3-method-for-obtaining-the-salt-value.patch
|
||||
Patch9001: 0001-add-loongarch64-support-for-python.patch
|
||||
@ -188,6 +190,9 @@ rm configure pyconfig.h.in
|
||||
%patch251 -p1
|
||||
|
||||
%patch6000 -p1
|
||||
%patch6001 -p1
|
||||
%patch6002 -p1
|
||||
|
||||
|
||||
%patch9000 -p1
|
||||
%patch9001 -p1
|
||||
@ -852,6 +857,12 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
|
||||
%{_mandir}/*/*
|
||||
|
||||
%changelog
|
||||
* Mon Jul 29 2024 xinsheng <xinsheng3@huawei.com> - 3.11.6-4
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-4032, CVE-2024-0397 and fix xml tree assert error
|
||||
|
||||
* Web Jul 10 2024 xinsheng <xinsheng3@huawei.com> - 3.11.6-3
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user