-
Notifications
You must be signed in to change notification settings - Fork 548
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
206 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
From 732c7d512e7cdf656a3f02a38c329b14a14a8573 Mon Sep 17 00:00:00 2001 | ||
From: Seth Michael Larson <[email protected]> | ||
Date: Fri, 19 Apr 2024 11:21:40 -0700 | ||
Subject: [PATCH] [3.9] gh-114572: Fix locking in cert_store_stats and | ||
get_ca_certs | ||
|
||
--- | ||
...-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 00000000000000..b4f9fe64db0615 | ||
--- /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 3f95d3e10374d8..5e0be34d6f3fe3 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ | |
Summary: A high-level scripting language | ||
Name: python3 | ||
Version: 3.9.19 | ||
Release: 2%{?dist} | ||
Release: 3%{?dist} | ||
License: PSF | ||
Vendor: Microsoft Corporation | ||
Distribution: Mariner | ||
|
@@ -22,6 +22,7 @@ Source0: https://www.python.org/ftp/python/%{version}/Python-%{version}.t | |
Patch0: cgi3.patch | ||
# Backport https://github.com/python/cpython/commit/069fefdaf42490f1e00243614fb5f3d5d2614b81 from 3.10 to 3.9 | ||
Patch1: 0001-gh-95231-Disable-md5-crypt-modules-if-FIPS-is-enable.patch | ||
Patch2: CVE-2024-0397.patch | ||
# Patch for setuptools, resolved in 65.5.1 | ||
Patch1000: CVE-2022-40897.patch | ||
Patch1001: CVE-2024-6345.patch | ||
|
@@ -161,6 +162,7 @@ The test package contains all regression tests for Python as well as the modules | |
# We use the CI to validate the toolchain manifests, which means we need to parse this .spec file | ||
%patch0 -p1 | ||
%patch1 -p1 | ||
%patch2 -p1 | ||
|
||
%build | ||
# Remove GCC specs and build environment linker scripts | ||
|
@@ -316,6 +318,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__ | |
%{_libdir}/python%{majmin}/test/* | ||
|
||
%changelog | ||
* Tue Jul 23 2024 Rohit Rawat <[email protected]> - 3.9.19-3 | ||
- Patch for CVE-2024-0397 | ||
|
||
* Mon Jul 22 2024 Sindhu Karri <[email protected]> - 3.9.19-2 | ||
- Patch for CVE-2024-6345 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters