From 4bf911932c583a30d73aa2974a59590a0d13861b Mon Sep 17 00:00:00 2001 From: fly_fzc <2385803914@qq.com> Date: Tue, 16 Dec 2025 16:48:07 +0800 Subject: [PATCH] fix CVE-2025-12084 CVE-2025-13836 CVE-2025-13837 --- ...emove-quadratic-behavior-in-node-ID-.patch | 100 +++++++++++ ...ix-a-potential-denial-of-service-in-.patch | 161 ++++++++++++++++++ ...potential-denial-of-service-in-plist.patch | 160 +++++++++++++++++ ...-optimize-HTTPResponse.read-GH-12698.patch | 92 ++++++++++ python3.spec | 12 +- 5 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2025-12084-3.14-gh-142145-Remove-quadratic-behavior-in-node-ID-.patch create mode 100644 backport-CVE-2025-13836-3.13-gh-119451-Fix-a-potential-denial-of-service-in-.patch create mode 100644 backport-CVE-2025-13837-gh-119342-Fix-a-potential-denial-of-service-in-plist.patch create mode 100644 backport-pre-CVE-2025-13836-bpo-36050-optimize-HTTPResponse.read-GH-12698.patch diff --git a/backport-CVE-2025-12084-3.14-gh-142145-Remove-quadratic-behavior-in-node-ID-.patch b/backport-CVE-2025-12084-3.14-gh-142145-Remove-quadratic-behavior-in-node-ID-.patch new file mode 100644 index 0000000..fe398d3 --- /dev/null +++ b/backport-CVE-2025-12084-3.14-gh-142145-Remove-quadratic-behavior-in-node-ID-.patch @@ -0,0 +1,100 @@ +From 027f21e417b26eed4505ac2db101a4352b7c51a0 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Wed, 3 Dec 2025 20:09:44 +0100 +Subject: [PATCH] [3.14] gh-142145: Remove quadratic behavior in node ID cache + clearing (GH-142146) (#142209) + +gh-142145: Remove quadratic behavior in node ID cache clearing (GH-142146) + +* Remove quadratic behavior in node ID cache clearing + + + +* Add news fragment + +--------- +(cherry picked from commit 08d8e18ad81cd45bc4a27d6da478b51ea49486e4) + +Co-authored-by: Seth Michael Larson +Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com> +--- + Lib/test/test_minidom.py | 18 ++++++++++++++++++ + Lib/xml/dom/minidom.py | 9 +-------- + ...5-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 + +diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py +index 4f25e9c2a03..4fa5a4e6768 100644 +--- a/Lib/test/test_minidom.py ++++ b/Lib/test/test_minidom.py +@@ -2,6 +2,7 @@ + + import copy + import pickle ++import time + import io + from test import support + import unittest +@@ -173,6 +174,23 @@ def testAppendChild(self): + 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) +diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py +index db51f350ea0..0a2ccc00f18 100644 +--- a/Lib/xml/dom/minidom.py ++++ b/Lib/xml/dom/minidom.py +@@ -292,13 +292,6 @@ def _append_child(self, node): + 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." +@@ -1555,7 +1548,7 @@ def _clear_id_cache(node): + 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 + +diff --git a/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst +new file mode 100644 +index 00000000000..440bc7794c6 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst +@@ -0,0 +1 @@ ++Remove quadratic behavior in ``xml.minidom`` node ID cache clearing. +-- +2.33.0 + diff --git a/backport-CVE-2025-13836-3.13-gh-119451-Fix-a-potential-denial-of-service-in-.patch b/backport-CVE-2025-13836-3.13-gh-119451-Fix-a-potential-denial-of-service-in-.patch new file mode 100644 index 0000000..ab27a38 --- /dev/null +++ b/backport-CVE-2025-13836-3.13-gh-119451-Fix-a-potential-denial-of-service-in-.patch @@ -0,0 +1,161 @@ +From 289f29b0fe38baf2d7cb5854f4bb573cc34a6a15 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Fri, 5 Dec 2025 16:21:57 +0100 +Subject: [PATCH] [3.13] gh-119451: Fix a potential denial of service in + http.client (GH-119454) (#142139) + +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 +--- + Lib/http/client.py | 28 ++++++-- + Lib/test/test_httplib.py | 66 +++++++++++++++++++ + ...-05-23-11-47-48.gh-issue-119451.qkJe9-.rst | 5 ++ + 3 files changed, 95 insertions(+), 4 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst + +diff --git a/Lib/http/client.py b/Lib/http/client.py +index 8a728438439..dd5f4136e9e 100644 +--- a/Lib/http/client.py ++++ b/Lib/http/client.py +@@ -111,6 +111,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 +@@ -639,10 +644,25 @@ def _safe_read(self, amt): + reading. If the bytes are truly not available (due to EOF), then the + IncompleteRead exception can be used to detect the problem. + """ +- data = self.fp.read(amt) +- if len(data) < amt: +- raise IncompleteRead(data, amt-len(data)) +- return data ++ 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.""" +diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py +index 84e99a15603..5267d2fe011 100644 +--- a/Lib/test/test_httplib.py ++++ b/Lib/test/test_httplib.py +@@ -1455,6 +1455,72 @@ def run_server(): + 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 +diff --git a/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst b/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst +new file mode 100644 +index 00000000000..6d6f25cd2f8 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst +@@ -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. +-- +2.33.0 + diff --git a/backport-CVE-2025-13837-gh-119342-Fix-a-potential-denial-of-service-in-plist.patch b/backport-CVE-2025-13837-gh-119342-Fix-a-potential-denial-of-service-in-plist.patch new file mode 100644 index 0000000..8b29fb5 --- /dev/null +++ b/backport-CVE-2025-13837-gh-119342-Fix-a-potential-denial-of-service-in-plist.patch @@ -0,0 +1,160 @@ +From 694922cf40aa3a28f898b5f5ee08b71b4922df70 Mon Sep 17 00:00:00 2001 +From: Serhiy Storchaka +Date: Mon, 1 Dec 2025 17:28:15 +0200 +Subject: [PATCH] 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. +--- + Lib/plistlib.py | 31 ++++++++++------ + Lib/test/test_plistlib.py | 37 +++++++++++++++++-- + ...-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 + +diff --git a/Lib/plistlib.py b/Lib/plistlib.py +index 67e832db217..655c51eea3d 100644 +--- a/Lib/plistlib.py ++++ b/Lib/plistlib.py +@@ -73,6 +73,9 @@ + PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__) + globals().update(PlistFormat.__members__) + ++# Data larger than this will be read in chunks, to prevent extreme ++# overallocation. ++_MIN_READ_BUF_SIZE = 1 << 20 + + class UID: + def __init__(self, data): +@@ -508,12 +511,24 @@ def _get_size(self, tokenL): + + 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)) +@@ -573,22 +588,16 @@ def _read_object(self, ref): + + elif tokenH == 0x40: # data + s = self._get_size(tokenL) +- result = self._fp.read(s) +- if len(result) != s: +- raise InvalidFileException() ++ result = self._read(s) + + 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') + + elif tokenH == 0x80: # UID +diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py +index a0c76e5dec5..de2a2fd1fc3 100644 +--- a/Lib/test/test_plistlib.py ++++ b/Lib/test/test_plistlib.py +@@ -903,8 +903,7 @@ def test_dump_naive_datetime_with_aware_datetime_option(self): + + 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 = [] +@@ -916,7 +915,11 @@ def decode(*objects, offset_size=1, ref_size=1): + 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 +@@ -1024,6 +1027,34 @@ def test_invalid_binary(self): + 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 TestKeyedArchive(unittest.TestCase): + def test_keyed_archive_data(self): +diff --git a/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst b/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst +new file mode 100644 +index 00000000000..04fd8faca4c +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst +@@ -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. +-- +2.33.0 + diff --git a/backport-pre-CVE-2025-13836-bpo-36050-optimize-HTTPResponse.read-GH-12698.patch b/backport-pre-CVE-2025-13836-bpo-36050-optimize-HTTPResponse.read-GH-12698.patch new file mode 100644 index 0000000..acd54ca --- /dev/null +++ b/backport-pre-CVE-2025-13836-bpo-36050-optimize-HTTPResponse.read-GH-12698.patch @@ -0,0 +1,92 @@ +From d6bf6f2d0c83f0c64ce86e7b9340278627798090 Mon Sep 17 00:00:00 2001 +From: Inada Naoki +Date: Sat, 6 Apr 2019 18:06:19 +0900 +Subject: [PATCH] bpo-36050: optimize HTTPResponse.read() (GH-12698) + +* No need to chunking for now. +* No need to partial read caused by EINTR for now. +--- + Lib/http/client.py | 42 +++++-------------- + .../2019-04-05-21-29-53.bpo-36050.x9DRKE.rst | 2 + + 2 files changed, 12 insertions(+), 32 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2019-04-05-21-29-53.bpo-36050.x9DRKE.rst + +diff --git a/Lib/http/client.py b/Lib/http/client.py +index 1de151c38e9..5a2225276b1 100644 +--- a/Lib/http/client.py ++++ b/Lib/http/client.py +@@ -105,9 +105,6 @@ + # Mapping status codes to official W3C names + responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()} + +-# maximal amount of data to read at one time in _safe_read +-MAXAMOUNT = 1048576 +- + # maximal line length when calling readline(). + _MAXLINE = 65536 + _MAXHEADERS = 100 +@@ -592,43 +589,24 @@ def _readinto_chunked(self, b): + raise IncompleteRead(bytes(b[0:total_bytes])) + + def _safe_read(self, amt): +- """Read the number of bytes requested, compensating for partial reads. +- +- Normally, we have a blocking socket, but a read() can be interrupted +- by a signal (resulting in a partial read). +- +- Note that we cannot distinguish between EOF and an interrupt when zero +- bytes have been read. IncompleteRead() will be raised in this +- situation. ++ """Read the number of bytes requested. + + This function should be used when bytes "should" be present for + 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) ++ data = self.fp.read(amt) ++ if len(data) < amt: ++ raise IncompleteRead(data, amt-len(data)) ++ return data + + def _safe_readinto(self, b): + """Same as _safe_read, but for reading into a buffer.""" +- total_bytes = 0 +- mvb = memoryview(b) +- while total_bytes < len(b): +- if MAXAMOUNT < len(mvb): +- temp_mvb = mvb[0:MAXAMOUNT] +- n = self.fp.readinto(temp_mvb) +- else: +- n = self.fp.readinto(mvb) +- if not n: +- raise IncompleteRead(bytes(mvb[0:total_bytes]), len(b)) +- mvb = mvb[n:] +- total_bytes += n +- return total_bytes ++ amt = len(b) ++ n = self.fp.readinto(b) ++ if n < amt: ++ raise IncompleteRead(bytes(b[:n]), amt-n) ++ return n + + def read1(self, n=-1): + """Read with at most one underlying system call. If at least one +diff --git a/Misc/NEWS.d/next/Library/2019-04-05-21-29-53.bpo-36050.x9DRKE.rst b/Misc/NEWS.d/next/Library/2019-04-05-21-29-53.bpo-36050.x9DRKE.rst +new file mode 100644 +index 00000000000..92318f877b6 +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2019-04-05-21-29-53.bpo-36050.x9DRKE.rst +@@ -0,0 +1,2 @@ ++Optimized ``http.client.HTTPResponse.read()`` for large response. Patch by ++Inada Naoki. +-- +2.33.0 + diff --git a/python3.spec b/python3.spec index 27c8adb..b868944 100644 --- a/python3.spec +++ b/python3.spec @@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language URL: https://www.python.org/ Version: 3.9.9 -Release: 45 +Release: 46 License: Python-2.0 %global branchversion 3.9 @@ -135,6 +135,10 @@ Patch6041: backport-CVE-2025-6069.patch Patch6042: backport-CVE-2025-8291.patch Patch6043: backport-CVE-2024-5642.patch Patch6044: backport-CVE-2025-6075.patch +Patch6045: backport-CVE-2025-12084-3.14-gh-142145-Remove-quadratic-behavior-in-node-ID-.patch +Patch6046: backport-pre-CVE-2025-13836-bpo-36050-optimize-HTTPResponse.read-GH-12698.patch +Patch6047: backport-CVE-2025-13836-3.13-gh-119451-Fix-a-potential-denial-of-service-in-.patch +Patch6048: backport-CVE-2025-13837-gh-119342-Fix-a-potential-denial-of-service-in-plist.patch Patch9000: add-the-sm3-method-for-obtaining-the-salt-value.patch Patch9001: python3-Add-sw64-architecture.patch @@ -845,6 +849,12 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP" %{_mandir}/*/* %changelog +* Tue Dec 16 2025 fuanan - 3.9.9-46 +- Type:CVE +- CVE:CVE-2025-12084 CVE-2025-13836 CVE-2025-13837 +- SUG:NA +- DESC:fix CVE-2025-12084 CVE-2025-13836 CVE-2025-13837 + * Wed Nov 05 2025 lipengyu - 3.9.9-45 - Type:CVE - CVE:CVE-2025-6075 -- Gitee