File 0001-Fix-CVE-2025-13836-CVE-2025-12084-and-CVE-2025-13837.patch of Package python3.42041

From 532519872b4ba51479f55dd419ce77f1537f676a1589f4960590547689e58358 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@cepl.eu>
Date: Thu, 18 Dec 2025 16:07:31 +0100
Subject: [PATCH] Fix CVE-2025-13836, CVE-2025-12084, and CVE-2025-13837.

- Add CVE-2025-13836-http-resp-cont-len.patch (bsc#1254400,
  CVE-2025-13836) to prevent reading an HTTP response from
  a server, if no read amount is specified, with using
  Content-Length per default as the length.
- Add CVE-2025-12084-minidom-quad-search.patch prevent quadratic
  behavior in node ID cache clearing (CVE-2025-12084,
  bsc#1254997).
- Add CVE-2025-13837-plistlib-mailicious-length.patch protect
  against OOM when loading malicious content (CVE-2025-13837,
  bsc#1254401).
---
 CVE-2025-12084-minidom-quad-search.patch      |  93 +++++++
 CVE-2025-13836-http-resp-cont-len.patch       | 258 ++++++++++++++++++
 ...025-13837-plistlib-mailicious-length.patch | 161 +++++++++++
 python36.changes                              |  14 +
 python36.spec                                 |   9 +
 5 files changed, 535 insertions(+)
 create mode 100644 CVE-2025-12084-minidom-quad-search.patch
 create mode 100644 CVE-2025-13836-http-resp-cont-len.patch
 create mode 100644 CVE-2025-13837-plistlib-mailicious-length.patch

diff --git a/CVE-2025-12084-minidom-quad-search.patch b/CVE-2025-12084-minidom-quad-search.patch
new file mode 100644
index 0000000..adc9631
--- /dev/null
+++ b/CVE-2025-12084-minidom-quad-search.patch
@@ -0,0 +1,93 @@
+From f4eb9ab014545b521fb261b80adfa6d138e7e092 Mon Sep 17 00:00:00 2001
+From: Seth Michael Larson <seth@python.org>
+Date: Wed, 3 Dec 2025 01:16:37 -0600
+Subject: [PATCH] gh-142145: Remove quadratic behavior in node ID cache
+ clearing (GH-142146)
+
+* Remove quadratic behavior in node ID cache clearing
+
+Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com>
+
+* Add news fragment
+
+---------
+(cherry picked from commit 08d8e18ad81cd45bc4a27d6da478b51ea49486e4)
+
+Co-authored-by: Seth Michael Larson <seth@python.org>
+Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com>
+---
+ Lib/test/test_minidom.py                                                 |   18 ++++++++++
+ Lib/xml/dom/minidom.py                                                   |    9 -----
+ Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst |    1
+ 3 files changed, 20 insertions(+), 8 deletions(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst
+
+Index: Python-3.6.15/Lib/test/test_minidom.py
+===================================================================
+--- Python-3.6.15.orig/Lib/test/test_minidom.py	2025-12-20 20:02:31.594672148 +0100
++++ Python-3.6.15/Lib/test/test_minidom.py	2025-12-20 20:04:27.310278898 +0100
+@@ -2,6 +2,7 @@
+
+ import copy
+ import pickle
++import time
+ from test import support
+ import unittest
+
+@@ -171,6 +172,23 @@
+         self.confirm(dom.documentElement.childNodes[-1].data == "Hello")
+         dom.unlink()
+
++    def testAppendChildNoQuadraticComplexity(self):
++        impl = getDOMImplementation()
++
++        newdoc = impl.createDocument(None, "some_tag", None)
++        top_element = newdoc.documentElement
++        children = [newdoc.createElement(f"child-{i}") for i in range(1, 2 ** 15 + 1)]
++        element = top_element
++
++        start = time.time()
++        for child in children:
++            element.appendChild(child)
++            element = child
++        end = time.time()
++
++        # This example used to take at least 30 seconds.
++        self.assertLess(end - start, 1)
++
+     def testAppendChildFragment(self):
+         dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
+         dom.documentElement.appendChild(frag)
+Index: Python-3.6.15/Lib/xml/dom/minidom.py
+===================================================================
+--- Python-3.6.15.orig/Lib/xml/dom/minidom.py	2025-12-20 20:02:31.594672148 +0100
++++ Python-3.6.15/Lib/xml/dom/minidom.py	2025-12-20 20:04:27.311120771 +0100
+@@ -291,13 +291,6 @@
+     childNodes.append(node)
+     node.parentNode = self
+
+-def _in_document(node):
+-    # return True iff node is part of a document tree
+-    while node is not None:
+-        if node.nodeType == Node.DOCUMENT_NODE:
+-            return True
+-        node = node.parentNode
+-    return False
+
+ def _write_data(writer, data):
+     "Writes datachars to writer."
+@@ -1512,7 +1505,7 @@
+     if node.nodeType == Node.DOCUMENT_NODE:
+         node._id_cache.clear()
+         node._id_search_stack = None
+-    elif _in_document(node):
++    elif node.ownerDocument:
+         node.ownerDocument._id_cache.clear()
+         node.ownerDocument._id_search_stack= None
+
+Index: Python-3.6.15/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ Python-3.6.15/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst	2025-12-20 20:04:27.311549530 +0100
+@@ -0,0 +1 @@
++Remove quadratic behavior in ``xml.minidom`` node ID cache clearing.
diff --git a/CVE-2025-13836-http-resp-cont-len.patch b/CVE-2025-13836-http-resp-cont-len.patch
new file mode 100644
index 0000000..dc731fd
--- /dev/null
+++ b/CVE-2025-13836-http-resp-cont-len.patch
@@ -0,0 +1,258 @@
+From b3a7998115e195c40e00cfa662bcaa899d937c05 Mon Sep 17 00:00:00 2001
+From: Serhiy Storchaka <storchaka@gmail.com>
+Date: Mon, 1 Dec 2025 17:26:07 +0200
+Subject: [PATCH] gh-119451: Fix a potential denial of service in http.client
+ (GH-119454)
+
+Reading the whole body of the HTTP response could cause OOM if
+the Content-Length value is too large even if the server does not send
+a large amount of data. Now the HTTP client reads large data by chunks,
+therefore the amount of consumed memory is proportional to the amount
+of sent data.
+(cherry picked from commit 5a4c4a033a4a54481be6870aa1896fad732555b5)
+
+Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
+---
+ Lib/http/client.py                                                       |   32 ++
+ Lib/test/test_httplib.py                                                 |  116 ++++++++++
+ Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst |    5
+ Lib/http/client.py                                                       |   32 +++-
+ Lib/socket.py                                                            |   56 ++++++++
+ Lib/test/test_httplib.py                                                 |   67 ++++++++++
+ Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst |    5
+ Lib/http/client.py                                                       |   32 +++-
+ Lib/socket.py                                                            |   55 ++++++++
+ Lib/test/test_httplib.py                                                 |   67 ++++++++++
+ Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst |    5
+ Lib/http/client.py                                                       |   32 +++-
+ Lib/socket.py                                                            |   55 ++++++++
+ Lib/test/test_httplib.py                                                 |   67 ++++++++++
+ Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst |    5
+ Lib/http/client.py                                                       |   32 +++-
+ Lib/socket.py                                                            |   63 ++++++++-
+ Lib/test/test_httplib.py                                                 |   67 ++++++++++
+ Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst |    5 
+ 4 files changed, 154 insertions(+), 13 deletions(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst
+
+Index: Python-3.6.15/Lib/http/client.py
+===================================================================
+--- Python-3.6.15.orig/Lib/http/client.py	2025-12-20 21:50:29.594974409 +0100
++++ Python-3.6.15/Lib/http/client.py	2025-12-20 21:51:56.521473590 +0100
+@@ -113,6 +113,11 @@
+ _MAXLINE = 65536
+ _MAXHEADERS = 100
+ 
++# Data larger than this will be read in chunks, to prevent extreme
++# overallocation.
++_MIN_READ_BUF_SIZE = 1 << 20
++
++
+ # Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
+ #
+ # VCHAR          = %x21-7E
+@@ -625,14 +630,25 @@
+         reading. If the bytes are truly not available (due to EOF), then the
+         IncompleteRead exception can be used to detect the problem.
+         """
+-        s = []
+-        while amt > 0:
+-            chunk = self.fp.read(min(amt, MAXAMOUNT))
+-            if not chunk:
+-                raise IncompleteRead(b''.join(s), amt)
+-            s.append(chunk)
+-            amt -= len(chunk)
+-        return b"".join(s)
++        cursize = min(amt, _MIN_READ_BUF_SIZE)
++        data = self.fp.read(cursize)
++        if len(data) >= amt:
++            return data
++        if len(data) < cursize:
++            raise IncompleteRead(data, amt - len(data))
++
++        data = io.BytesIO(data)
++        data.seek(0, 2)
++        while True:
++            # This is a geometric increase in read size (never more than
++            # doubling out the current length of data per loop iteration).
++            delta = min(cursize, amt - cursize)
++            data.write(self.fp.read(delta))
++            if data.tell() >= amt:
++                return data.getvalue()
++            cursize += delta
++            if data.tell() < cursize:
++                raise IncompleteRead(data.getvalue(), amt - data.tell())
+ 
+     def _safe_readinto(self, b):
+         """Same as _safe_read, but for reading into a buffer."""
+Index: Python-3.6.15/Lib/socket.py
+===================================================================
+--- Python-3.6.15.orig/Lib/socket.py	2025-12-20 21:50:28.817654367 +0100
++++ Python-3.6.15/Lib/socket.py	2025-12-20 23:21:42.522134097 +0100
+@@ -26,6 +26,7 @@
+ socket.setdefaulttimeout() -- set the default timeout value
+ create_connection() -- connects to an address, with an optional timeout and
+                        optional source address.
++create_server() -- create a TCP socket and bind it to a specified address.
+ 
+  [*] not available on all platforms!
+ 
+@@ -742,9 +743,61 @@
+     # We override this function since we want to translate the numeric family
+     # and socket type values to enum constants.
+     addrlist = []
+-    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
++
++
++def create_server(address, family=None, backlog=None, reuse_port=False):
++    """Convenience function which creates a SOCK_STREAM type socket
++    bound to *address* (a 2-tuple (host, port)) and return the socket
++    object.
++
++    *family* should be either AF_INET or AF_INET6.
++    *backlog* is the queue size passed to socket.listen().
++    *reuse_port* dictates whether to use the SO_REUSEPORT socket option.
++    *dualstack_ipv6*: if true and the platform supports it, it will
++    create an AF_INET6 socket able to accept both IPv4 or IPv6
++    connections. When false it will explicitly disable this option on
++    platforms that enable it by default (e.g. Linux).
++
++    >>> with create_server(('', 8000)) as server:
++    ...     while True:
++    ...         conn, addr = server.accept()
++    ...         # handle new connection
++    """
++    if family is None:
++        family = getattr(socket, 'AF_UNSPEC', 0)
++    host, port = address
++    # Use getaddrinfo to resolve the address and automatically handle family.
++    # AI_PASSIVE is used for server-side bind() calls.
++    err = None
++
++    try:
++        addr_infos = socket.getaddrinfo( host, port, family, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
++    except socket.gaierror as e:
++        raise OSError("getaddrinfo failed for {}: {}".format(address, e))
++    for res in addr_infos:
+         af, socktype, proto, canonname, sa = res
+-        addrlist.append((_intenum_converter(af, AddressFamily),
+-                         _intenum_converter(socktype, SocketKind),
+-                         proto, canonname, sa))
+-    return addrlist
++        sock = None
++        try:
++            sock = socket.socket(af, socktype, proto)
++
++            # Set SO_REUSEADDR, which is critical for server sockets
++            # to allow reuse of the address soon after a close.
++            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
++
++            if reuse_port:
++                if hasattr(socket, "SO_REUSEPORT"):
++                    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
++
++            sock.bind(sa)
++            sock.listen(backlog if backlog is not None else socket.SOMAXCONN)
++
++            return sock  # Return the successfully bound socket
++        except OSError as e:
++            err = e
++            if sock is not None:
++                sock.close()
++
++    # If we get here, no address worked
++    if err is not None:
++        raise err
++    raise OSError("getaddrinfo failed for address {}".format(address))
+Index: Python-3.6.15/Lib/test/test_httplib.py
+===================================================================
+--- Python-3.6.15.orig/Lib/test/test_httplib.py	2025-12-20 21:50:31.087796745 +0100
++++ Python-3.6.15/Lib/test/test_httplib.py	2025-12-20 21:51:56.523473580 +0100
+@@ -1167,6 +1167,72 @@
+         thread.join()
+         self.assertEqual(result, b"proxied data\n")
+ 
++    def test_large_content_length(self):
++        serv = socket.create_server((HOST, 0))
++        self.addCleanup(serv.close)
++
++        def run_server():
++            [conn, address] = serv.accept()
++            with conn:
++                while conn.recv(1024):
++                    conn.sendall(
++                        b"HTTP/1.1 200 Ok\r\n"
++                        b"Content-Length: %d\r\n"
++                        b"\r\n" % size)
++                    conn.sendall(b'A' * (size//3))
++                    conn.sendall(b'B' * (size - size//3))
++
++        thread = threading.Thread(target=run_server)
++        thread.start()
++        self.addCleanup(thread.join, 1.0)
++
++        conn = client.HTTPConnection(*serv.getsockname())
++        try:
++            for w in range(15, 27):
++                size = 1 << w
++                conn.request("GET", "/")
++                with conn.getresponse() as response:
++                    self.assertEqual(len(response.read()), size)
++        finally:
++            conn.close()
++            thread.join(1.0)
++
++    def test_large_content_length_truncated(self):
++        serv = socket.create_server((HOST, 0))
++        self.addCleanup(serv.close)
++
++        def run_server():
++            while True:
++                [conn, address] = serv.accept()
++                with conn:
++                    conn.recv(1024)
++                    if not size:
++                        break
++                    conn.sendall(
++                        b"HTTP/1.1 200 Ok\r\n"
++                        b"Content-Length: %d\r\n"
++                        b"\r\n"
++                        b"Text" % size)
++
++        thread = threading.Thread(target=run_server)
++        thread.start()
++        self.addCleanup(thread.join, 1.0)
++
++        conn = client.HTTPConnection(*serv.getsockname())
++        try:
++            for w in range(18, 65):
++                size = 1 << w
++                conn.request("GET", "/")
++                with conn.getresponse() as response:
++                    self.assertRaises(client.IncompleteRead, response.read)
++                conn.close()
++        finally:
++            conn.close()
++            size = 0
++            conn.request("GET", "/")
++            conn.close()
++            thread.join(1.0)
++
+     def test_putrequest_override_domain_validation(self):
+         """
+         It should be possible to override the default validation
+@@ -1991,3 +2057,4 @@
+ 
+ if __name__ == '__main__':
+     unittest.main(verbosity=2)
++
+Index: Python-3.6.15/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ Python-3.6.15/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst	2025-12-20 21:51:56.524131559 +0100
+@@ -0,0 +1,5 @@
++Fix a potential memory denial of service in the :mod:`http.client` module.
++When connecting to a malicious server, it could cause
++an arbitrary amount of memory to be allocated.
++This could have led to symptoms including a :exc:`MemoryError`, swapping, out
++of memory (OOM) killed processes or containers, or even system crashes.
diff --git a/CVE-2025-13837-plistlib-mailicious-length.patch b/CVE-2025-13837-plistlib-mailicious-length.patch
new file mode 100644
index 0000000..0408b7f
--- /dev/null
+++ b/CVE-2025-13837-plistlib-mailicious-length.patch
@@ -0,0 +1,161 @@
+From e99059d800b741504ef18693803927a0dc062be4 Mon Sep 17 00:00:00 2001
+From: Serhiy Storchaka <storchaka@gmail.com>
+Date: Mon, 1 Dec 2025 17:28:15 +0200
+Subject: [PATCH] [3.10] gh-119342: Fix a potential denial of service in
+ plistlib (GH-119343)
+
+Reading a specially prepared small Plist file could cause OOM because file's
+read(n) preallocates a bytes object for reading the specified amount of
+data. Now plistlib reads large data by chunks, therefore the upper limit of
+consumed memory is proportional to the size of the input file.
+(cherry picked from commit 694922cf40aa3a28f898b5f5ee08b71b4922df70)
+
+Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
+---
+ Lib/plistlib.py                                                          |   31 +++++---
+ Lib/test/test_plistlib.py                                                |   37 +++++++++-
+ Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst |    5 +
+ 3 files changed, 59 insertions(+), 14 deletions(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst
+
+Index: Python-3.6.15/Lib/plistlib.py
+===================================================================
+--- Python-3.6.15.orig/Lib/plistlib.py	2025-12-20 20:02:29.313682401 +0100
++++ Python-3.6.15/Lib/plistlib.py	2025-12-20 20:04:29.519412772 +0100
+@@ -64,6 +64,9 @@
+ from warnings import warn
+ from xml.parsers.expat import ParserCreate
+
++# Data larger than this will be read in chunks, to prevent extreme
++# overallocation.
++_MIN_READ_BUF_SIZE = 1 << 20
+
+ PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__)
+ globals().update(PlistFormat.__members__)
+@@ -646,12 +649,24 @@
+
+         return tokenL
+
++    def _read(self, size):
++        cursize = min(size, _MIN_READ_BUF_SIZE)
++        data = self._fp.read(cursize)
++        while True:
++            if len(data) != cursize:
++                raise InvalidFileException
++            if cursize == size:
++                return data
++            delta = min(cursize, size - cursize)
++            data += self._fp.read(delta)
++            cursize += delta
++
+     def _read_ints(self, n, size):
+-        data = self._fp.read(size * n)
++        data = self._read(size * n)
+         if size in _BINARY_FORMAT:
+             return struct.unpack(f'>{n}{_BINARY_FORMAT[size]}', data)
+         else:
+-            if not size or len(data) != size * n:
++            if not size:
+                 raise InvalidFileException()
+             return tuple(int.from_bytes(data[i: i + size], 'big')
+                          for i in range(0, size * n, size))
+@@ -708,24 +723,18 @@
+
+         elif tokenH == 0x40:  # data
+             s = self._get_size(tokenL)
+-            result = self._fp.read(s)
+-            if len(result) != s:
+-                raise InvalidFileException()
++            result = self._read(s)
+             if not self._use_builtin_types:
+                 result = Data(result)
+
+         elif tokenH == 0x50:  # ascii string
+             s = self._get_size(tokenL)
+-            data = self._fp.read(s)
+-            if len(data) != s:
+-                raise InvalidFileException()
++            data = self._read(s)
+             result = data.decode('ascii')
+
+         elif tokenH == 0x60:  # unicode string
+             s = self._get_size(tokenL) * 2
+-            data = self._fp.read(s)
+-            if len(data) != s:
+-                raise InvalidFileException()
++            data = self._read(s)
+             result = data.decode('utf-16be')
+
+         # tokenH == 0x80 is documented as 'UID' and appears to be used for
+Index: Python-3.6.15/Lib/test/test_plistlib.py
+===================================================================
+--- Python-3.6.15.orig/Lib/test/test_plistlib.py	2025-12-20 20:02:29.313682401 +0100
++++ Python-3.6.15/Lib/test/test_plistlib.py	2025-12-20 20:04:29.519870516 +0100
+@@ -745,8 +745,7 @@
+
+ class TestBinaryPlistlib(unittest.TestCase):
+
+-    @staticmethod
+-    def decode(*objects, offset_size=1, ref_size=1):
++    def build(self, *objects, offset_size=1, ref_size=1):
+         data = [b'bplist00']
+         offset = 8
+         offsets = []
+@@ -758,7 +757,11 @@
+                            len(objects), 0, offset)
+         data.extend(offsets)
+         data.append(tail)
+-        return plistlib.loads(b''.join(data), fmt=plistlib.FMT_BINARY)
++        return b''.join(data)
++
++    def decode(self, *objects, offset_size=1, ref_size=1):
++        data = self.build(*objects, offset_size=offset_size, ref_size=ref_size)
++        return plistlib.loads(data, fmt=plistlib.FMT_BINARY)
+
+     def test_nonstandard_refs_size(self):
+         # Issue #21538: Refs and offsets are 24-bit integers
+@@ -868,6 +871,34 @@
+                 with self.assertRaises(plistlib.InvalidFileException):
+                     plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
+
++    def test_truncated_large_data(self):
++        self.addCleanup(support.unlink, support.TESTFN)
++        def check(data):
++            with open(support.TESTFN, 'wb') as f:
++                f.write(data)
++            # buffered file
++            with open(support.TESTFN, 'rb') as f:
++                with self.assertRaises(plistlib.InvalidFileException):
++                    plistlib.load(f, fmt=plistlib.FMT_BINARY)
++            # unbuffered file
++            with open(support.TESTFN, 'rb', buffering=0) as f:
++                with self.assertRaises(plistlib.InvalidFileException):
++                    plistlib.load(f, fmt=plistlib.FMT_BINARY)
++        for w in range(20, 64):
++            s = 1 << w
++            # data
++            check(self.build(b'\x4f\x13' + s.to_bytes(8, 'big')))
++            # ascii string
++            check(self.build(b'\x5f\x13' + s.to_bytes(8, 'big')))
++            # unicode string
++            check(self.build(b'\x6f\x13' + s.to_bytes(8, 'big')))
++            # array
++            check(self.build(b'\xaf\x13' + s.to_bytes(8, 'big')))
++            # dict
++            check(self.build(b'\xdf\x13' + s.to_bytes(8, 'big')))
++            # number of objects
++            check(b'bplist00' + struct.pack('>6xBBQQQ', 1, 1, s, 0, 8))
++
+
+ class TestPlistlibDeprecated(unittest.TestCase):
+     def test_io_deprecated(self):
+Index: Python-3.6.15/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ Python-3.6.15/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst	2025-12-20 20:04:29.520190112 +0100
+@@ -0,0 +1,5 @@
++Fix a potential memory denial of service in the :mod:`plistlib` module.
++When reading a Plist file received from untrusted source, it could cause
++an arbitrary amount of memory to be allocated.
++This could have led to symptoms including a :exc:`MemoryError`, swapping, out
++of memory (OOM) killed processes or containers, or even system crashes.
diff --git a/python36.changes b/python36.changes
index 23917eb..5f236ad 100644
--- a/python36.changes
+++ b/python36.changes
@@ -1,3 +1,17 @@
+-------------------------------------------------------------------
+Thu Dec 18 10:33:44 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
+
+- Add CVE-2025-13836-http-resp-cont-len.patch (bsc#1254400,
+  CVE-2025-13836) to prevent reading an HTTP response from
+  a server, if no read amount is specified, with using
+  Content-Length per default as the length.
+- Add CVE-2025-12084-minidom-quad-search.patch prevent quadratic
+  behavior in node ID cache clearing (CVE-2025-12084,
+  bsc#1254997).
+- Add CVE-2025-13837-plistlib-mailicious-length.patch protect
+  against OOM when loading malicious content (CVE-2025-13837,
+  bsc#1254401).
+
 -------------------------------------------------------------------
 Thu Nov 13 23:45:30 UTC 2025 - Matej Cepl <mcepl@suse.com>
 
diff --git a/python36.spec b/python36.spec
index 6f6dd5e..1a49929 100644
--- a/python36.spec
+++ b/python36.spec
@@ -206,6 +206,15 @@ Patch78:        CVE-2025-8291-consistency-zip64.patch
 # PATCH-FIX-UPSTREAM CVE-2025-6075-expandvars-perf-degrad.patch bsc#1252974 mcepl@suse.com
 # Avoid potential quadratic complexity vulnerabilities in path modules
 Patch79:        CVE-2025-6075-expandvars-perf-degrad.patch
+# PATCH-FIX-UPSTREAM CVE-2025-13836-http-resp-cont-len.patch bsc#1254400 mcepl@suse.com
+# Avoid loading possibly compromised length of HTTP response
+Patch80:         CVE-2025-13836-http-resp-cont-len.patch
+# PATCH-FIX-UPSTREAM CVE-2025-12084-minidom-quad-search.patch bsc#1254997 mcepl@suse.com
+# prevent quadratic behavior in node ID cache clearing
+Patch81:        CVE-2025-12084-minidom-quad-search.patch
+# PATCH-FIX-UPSTREAM CVE-2025-13837-plistlib-mailicious-length.patch bsc#1254401 mcepl@suse.com
+# protect against OOM when loading malicious content
+Patch82:        CVE-2025-13837-plistlib-mailicious-length.patch
 BuildRequires:  automake
 BuildRequires:  fdupes
 BuildRequires:  gmp-devel
-- 
2.52.0

openSUSE Build Service is sponsored by