Fix locking in cert_store_stats and get_ca_certs
Fix xml tree assert error Update openssl version for test case
This commit is contained in:
parent
90d2230471
commit
38559af9fc
@ -0,0 +1,177 @@
|
||||
From b228655c227b2ca298a8ffac44d14ce3d22f6faa Mon Sep 17 00:00:00 2001
|
||||
From: Seth Michael Larson <seth@python.org>
|
||||
Date: Fri, 10 May 2024 06:46:12 -0500
|
||||
Subject: [PATCH] [3.9] gh-114572: Fix locking in cert_store_stats and
|
||||
get_ca_certs (#118109)
|
||||
|
||||
---
|
||||
...-04-19-11-21-13.gh-issue-114572.t1QMQD.rst | 4 +
|
||||
Modules/_ssl.c | 91 ++++++++++++++++++-
|
||||
2 files changed, 92 insertions(+), 3 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst
|
||||
|
||||
diff --git a/Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst b/Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst
|
||||
new file mode 100644
|
||||
index 0000000000..b4f9fe64db
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst
|
||||
@@ -0,0 +1,4 @@
|
||||
+:meth:`ssl.SSLContext.cert_store_stats` and
|
||||
+:meth:`ssl.SSLContext.get_ca_certs` now correctly lock access to the
|
||||
+certificate store, when the :class:`ssl.SSLContext` is shared across
|
||||
+multiple threads.
|
||||
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
|
||||
index 3f95d3e103..5e0be34d6f 100644
|
||||
--- a/Modules/_ssl.c
|
||||
+++ b/Modules/_ssl.c
|
||||
@@ -166,6 +166,10 @@ extern const SSL_METHOD *TLSv1_2_method(void);
|
||||
# define PY_OPENSSL_1_1_API 1
|
||||
#endif
|
||||
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
+# define OPENSSL_VERSION_3_3 1
|
||||
+#endif
|
||||
+
|
||||
/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f
|
||||
* This includes the SSL_set_SSL_CTX() function.
|
||||
*/
|
||||
@@ -210,6 +214,16 @@ extern const SSL_METHOD *TLSv1_2_method(void);
|
||||
#define HAVE_OPENSSL_CRYPTO_LOCK
|
||||
#endif
|
||||
|
||||
+/* OpenSSL 1.1+ allows locking X509_STORE, 1.0.2 doesn't. */
|
||||
+#ifdef OPENSSL_VERSION_1_1
|
||||
+#define HAVE_OPENSSL_X509_STORE_LOCK
|
||||
+#endif
|
||||
+
|
||||
+/* OpenSSL 3.3 added the X509_STORE_get1_objects API */
|
||||
+#ifdef OPENSSL_VERSION_3_3
|
||||
+#define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
|
||||
+#endif
|
||||
+
|
||||
#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2)
|
||||
#define OPENSSL_NO_SSL2
|
||||
#endif
|
||||
@@ -4675,6 +4689,54 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
|
||||
#endif
|
||||
}
|
||||
|
||||
+/* Shim of X509_STORE_get1_objects API from OpenSSL 3.3
|
||||
+ * Only available with the X509_STORE_lock() API */
|
||||
+#if defined(HAVE_OPENSSL_X509_STORE_LOCK) && !defined(OPENSSL_VERSION_3_3)
|
||||
+#define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
|
||||
+
|
||||
+static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj)
|
||||
+{
|
||||
+ int ok;
|
||||
+ X509_OBJECT *ret = X509_OBJECT_new();
|
||||
+ if (ret == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ switch (X509_OBJECT_get_type(obj)) {
|
||||
+ case X509_LU_X509:
|
||||
+ ok = X509_OBJECT_set1_X509(ret, X509_OBJECT_get0_X509(obj));
|
||||
+ break;
|
||||
+ case X509_LU_CRL:
|
||||
+ /* X509_OBJECT_get0_X509_CRL was not const-correct prior to 3.0.*/
|
||||
+ ok = X509_OBJECT_set1_X509_CRL(
|
||||
+ ret, X509_OBJECT_get0_X509_CRL((X509_OBJECT *)obj));
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* We cannot duplicate unrecognized types in a polyfill, but it is
|
||||
+ * safe to leave an empty object. The caller will ignore it. */
|
||||
+ ok = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!ok) {
|
||||
+ X509_OBJECT_free(ret);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static STACK_OF(X509_OBJECT) *
|
||||
+X509_STORE_get1_objects(X509_STORE *store)
|
||||
+{
|
||||
+ STACK_OF(X509_OBJECT) *ret;
|
||||
+ if (!X509_STORE_lock(store)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ ret = sk_X509_OBJECT_deep_copy(X509_STORE_get0_objects(store),
|
||||
+ x509_object_dup, X509_OBJECT_free);
|
||||
+ X509_STORE_unlock(store);
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
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\
|
||||
@@ -4704,7 +4766,15 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
int x509 = 0, crl = 0, ca = 0, i;
|
||||
|
||||
store = SSL_CTX_get_cert_store(self->ctx);
|
||||
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
|
||||
+ objs = X509_STORE_get1_objects(store);
|
||||
+ if (objs == NULL) {
|
||||
+ PyErr_SetString(PyExc_MemoryError, "failed to query cert store");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+#else
|
||||
objs = X509_STORE_get0_objects(store);
|
||||
+#endif
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
obj = sk_X509_OBJECT_value(objs, i);
|
||||
switch (X509_OBJECT_get_type(obj)) {
|
||||
@@ -4718,12 +4788,13 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||
crl++;
|
||||
break;
|
||||
default:
|
||||
- /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
|
||||
- * As far as I can tell they are internal states and never
|
||||
- * stored in a cert store */
|
||||
+ /* Ignore unrecognized types. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
|
||||
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
|
||||
+#endif
|
||||
return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl,
|
||||
"x509_ca", ca);
|
||||
}
|
||||
@@ -4755,7 +4826,15 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
}
|
||||
|
||||
store = SSL_CTX_get_cert_store(self->ctx);
|
||||
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
|
||||
+ objs = X509_STORE_get1_objects(store);
|
||||
+ if (objs == NULL) {
|
||||
+ PyErr_SetString(PyExc_MemoryError, "failed to query cert store");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+#else
|
||||
objs = X509_STORE_get0_objects(store);
|
||||
+#endif
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
X509_OBJECT *obj;
|
||||
X509 *cert;
|
||||
@@ -4783,9 +4862,15 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||
}
|
||||
Py_CLEAR(ci);
|
||||
}
|
||||
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
|
||||
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
|
||||
+#endif
|
||||
return rlist;
|
||||
|
||||
error:
|
||||
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
|
||||
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
|
||||
+#endif
|
||||
Py_XDECREF(ci);
|
||||
Py_XDECREF(rlist);
|
||||
return NULL;
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
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")
|
||||
17
python3.spec
17
python3.spec
@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language
|
||||
URL: https://www.python.org/
|
||||
|
||||
Version: 3.9.9
|
||||
Release: 28
|
||||
Release: 29
|
||||
License: Python-2.0
|
||||
|
||||
%global branchversion 3.9
|
||||
@ -109,6 +109,9 @@ Patch6015: backport-CVE-2007-4559.patch
|
||||
Patch6016: backport-CVE-2023-40217.patch
|
||||
Patch6017: backport-3.9-gh-104049-do-not-expose-on-disk-location-from-Si.patch
|
||||
Patch6018: backport-3.9-gh-99889-Fix-directory-traversal-security-flaw-i.patch
|
||||
Patch6019: backport-3.9-gh-114572-Fix-locking-in-cert_store_stats-and-ge.patch
|
||||
Patch6020: backport-fix_xml_tree_assert_error.patch
|
||||
Patch6021: update-openssl-version-for-test-case.patch
|
||||
|
||||
Patch9000: add-the-sm3-method-for-obtaining-the-salt-value.patch
|
||||
Patch9001: python3-Add-sw64-architecture.patch
|
||||
@ -216,6 +219,9 @@ rm -r Modules/expat
|
||||
%patch6016 -p1
|
||||
%patch6017 -p1
|
||||
%patch6018 -p1
|
||||
%patch6019 -p1
|
||||
%patch6020 -p1
|
||||
%patch6021 -p1
|
||||
|
||||
%patch9000 -p1
|
||||
%patch9001 -p1
|
||||
@ -843,6 +849,15 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
|
||||
%{_mandir}/*/*
|
||||
|
||||
%changelog
|
||||
* Web Jul 10 2024 xinsheng <xinsheng3@huawei.com> - 3.9.9-29
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:backport upstream patches
|
||||
- Fix locking in cert_store_stats and get_ca_certs
|
||||
- Fix xml tree assert error
|
||||
- Update openssl version for test case
|
||||
|
||||
* Wed Oct 25 zhuofeng <zhuofeng2@huawei.com> - 3.9.9-28
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
25
update-openssl-version-for-test-case.patch
Normal file
25
update-openssl-version-for-test-case.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From d7a637e43086c51d0e2b4cd2f9324f1c60eced50 Mon Sep 17 00:00:00 2001
|
||||
From: xinsheng3 <xinsheng3@huawei.com>
|
||||
Date: Thu, 20 Jun 2024 15:29:05 +0800
|
||||
Subject: [PATCH] update openssl version for test case.patch
|
||||
|
||||
---
|
||||
Lib/test/test_ssl.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
||||
index 2c71c27..d95f0ef 100644
|
||||
--- a/Lib/test/test_ssl.py
|
||||
+++ b/Lib/test/test_ssl.py
|
||||
@@ -589,7 +589,7 @@ class BasicSocketTests(unittest.TestCase):
|
||||
self.assertGreaterEqual(fix, 0)
|
||||
self.assertLess(fix, 256)
|
||||
self.assertGreaterEqual(patch, 0)
|
||||
- self.assertLessEqual(patch, 63)
|
||||
+ self.assertLessEqual(patch, 128)
|
||||
self.assertGreaterEqual(status, 0)
|
||||
self.assertLessEqual(status, 15)
|
||||
# Version string as returned by {Open,Libre}SSL, the format might change
|
||||
--
|
||||
2.33.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user