Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python311 for openSUSE:Factory 
checked in at 2024-06-28 15:46:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python311 (Old)
 and      /work/SRC/openSUSE:Factory/.python311.new.18349 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python311"

Fri Jun 28 15:46:47 2024 rev:35 rq:1183510 version:3.11.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/python311/python311.changes      2024-05-03 
00:05:28.869784381 +0200
+++ /work/SRC/openSUSE:Factory/.python311.new.18349/python311.changes   
2024-06-28 15:48:06.480332013 +0200
@@ -1,0 +2,7 @@
+Tue Jun 25 21:57:40 UTC 2024 - Matej Cepl <mc...@cepl.eu>
+
+- Add CVE-2024-4032-private-IP-addrs.patch to fix bsc#1226448
+  (CVE-2024-4032) rearranging definition of private v global IP
+  addresses.
+
+-------------------------------------------------------------------
@@ -46 +53 @@
-      multiple threads.
+      multiple threads (bsc#1226447, CVE-2024-0397).

New:
----
  CVE-2024-4032-private-IP-addrs.patch

BETA DEBUG BEGIN:
  New:
- Add CVE-2024-4032-private-IP-addrs.patch to fix bsc#1226448
  (CVE-2024-4032) rearranging definition of private v global IP
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python311.spec ++++++
--- /var/tmp/diff_new_pack.nkj9zv/_old  2024-06-28 15:48:16.516699179 +0200
+++ /var/tmp/diff_new_pack.nkj9zv/_new  2024-06-28 15:48:16.532699765 +0200
@@ -171,6 +171,9 @@
 # by SUSE
 Patch16:        CVE-2023-52425-libexpat-2.6.0-backport.patch
 Patch17:        CVE-2023-52425-remove-reparse_deferral-tests.patch
+# PATCH-FIX-UPSTREAM CVE-2024-4032-private-IP-addrs.patch bsc#1226448 
mc...@suse.com
+# rearrange definition of private v global IP addresses
+Patch18:        CVE-2024-4032-private-IP-addrs.patch
 BuildRequires:  autoconf-archive
 BuildRequires:  automake
 BuildRequires:  fdupes
@@ -432,6 +435,7 @@
 %patch -p1 -P 15
 %patch -p1 -P 16
 %patch -p1 -P 17
+%patch -p1 -P 18
 
 # drop Autoconf version requirement
 sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac

++++++ CVE-2024-4032-private-IP-addrs.patch ++++++
>From b47c766d6085d7918edd7715750d135868fdafd6 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <encu...@gmail.com>
Date: Wed, 24 Apr 2024 14:29:30 +0200
Subject: [PATCH] gh-113171: gh-65056: Fix "private" (non-global) IP address
 ranges (GH-113179) (GH-113186) (GH-118177)

* GH-113171: Fix "private" (non-global) IP address ranges (GH-113179)

The _private_networks variables, used by various is_private
implementations, were missing some ranges and at the same time had
overly strict ranges (where there are more specific ranges considered
globally reachable by the IANA registries).

This patch updates the ranges with what was missing or otherwise
incorrect.

100.64.0.0/10 is left alone, for now, as it's been made special in [1].

The _address_exclude_many() call returns 8 networks for IPv4, 121
networks for IPv6.

[1] https://github.com/python/cpython/issues/61602

* GH-65056: Improve the IP address' is_global/is_private documentation 
(GH-113186)

It wasn't clear what the semantics of is_global/is_private are and, when
one gets to the bottom of it, it's not quite so simple (hence the
exceptions listed).

(cherry picked from commit 2a4cbf17af19a01d942f9579342f77c39fbd23c4)
(cherry picked from commit 40d75c2b7f5c67e254d0a025e0f2e2c7ada7f69f)

---------

(cherry picked from commit f86b17ac511e68192ba71f27e752321a3252cee3)

Co-authored-by: Jakub Stasiak <ja...@stasiak.at>
---
 Doc/library/ipaddress.rst                                               |   43 
+++-
 Doc/whatsnew/3.11.rst                                                   |    9 
 Lib/ipaddress.py                                                        |  105 
+++++++---
 Lib/test/test_ipaddress.py                                              |   21 
+-
 Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst |    9 
 5 files changed, 160 insertions(+), 27 deletions(-)
 create mode 100644 
Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst

--- a/Doc/library/ipaddress.rst
+++ b/Doc/library/ipaddress.rst
@@ -178,18 +178,53 @@ write code that handles both IP versions
 
    .. 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)
--- 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``.
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -1086,7 +1086,11 @@ class _BaseNetwork(_IPAddressBase):
         """
         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 @@ class IPv4Address(_BaseV4, _BaseAddress)
     @property
     @functools.lru_cache()
     def is_private(self):
-        """Test if this address is allocated for private networks.
-
-        Returns:
-            A boolean, True if the address is reserved per
-            iana-ipv4-special-registry.
-
-        """
-        return any(self in net for net in self._constants._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:
+
+        * ``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)
+            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 @@ class IPv6Address(_BaseV6, _BaseAddress)
     @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:
+
+        * ``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`)::
 
-        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.
+                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:
+
+        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`)::
 
-        Returns:
-            A boolean, true if the address is not reserved per
-            iana-ipv6-special-registry.
+            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'),
--- a/Lib/test/test_ipaddress.py
+++ b/Lib/test/test_ipaddress.py
@@ -2269,6 +2269,10 @@ class IpaddrUnitTest(unittest.TestCase):
         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 @@ class IpaddrUnitTest(unittest.TestCase):
         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 @@ class IpaddrUnitTest(unittest.TestCase):
         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 @@ class IpaddrUnitTest(unittest.TestCase):
         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)
--- /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.

Reply via email to