Skip to content

Commit b49a0e1

Browse files
xorduxCBL-Mariner-Bot
authored andcommitted
Python3 patch CVE-2024-0397 (#9912)
(cherry picked from commit f1b818c)
1 parent b9c5a1a commit b49a0e1

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

SPECS/python3/CVE-2024-0397.patch

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
From 732c7d512e7cdf656a3f02a38c329b14a14a8573 Mon Sep 17 00:00:00 2001
2+
From: Seth Michael Larson <seth@python.org>
3+
Date: Fri, 19 Apr 2024 11:21:40 -0700
4+
Subject: [PATCH] [3.9] gh-114572: Fix locking in cert_store_stats and
5+
get_ca_certs
6+
7+
---
8+
...-04-19-11-21-13.gh-issue-114572.t1QMQD.rst | 4 +
9+
Modules/_ssl.c | 91 ++++++++++++++++++-
10+
2 files changed, 92 insertions(+), 3 deletions(-)
11+
create mode 100644 Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst
12+
13+
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
14+
new file mode 100644
15+
index 00000000000000..b4f9fe64db0615
16+
--- /dev/null
17+
+++ b/Misc/NEWS.d/next/Security/2024-04-19-11-21-13.gh-issue-114572.t1QMQD.rst
18+
@@ -0,0 +1,4 @@
19+
+:meth:`ssl.SSLContext.cert_store_stats` and
20+
+:meth:`ssl.SSLContext.get_ca_certs` now correctly lock access to the
21+
+certificate store, when the :class:`ssl.SSLContext` is shared across
22+
+multiple threads.
23+
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
24+
index 3f95d3e10374d8..5e0be34d6f3fe3 100644
25+
--- a/Modules/_ssl.c
26+
+++ b/Modules/_ssl.c
27+
@@ -166,6 +166,10 @@ extern const SSL_METHOD *TLSv1_2_method(void);
28+
# define PY_OPENSSL_1_1_API 1
29+
#endif
30+
31+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && !defined(LIBRESSL_VERSION_NUMBER)
32+
+# define OPENSSL_VERSION_3_3 1
33+
+#endif
34+
+
35+
/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f
36+
* This includes the SSL_set_SSL_CTX() function.
37+
*/
38+
@@ -210,6 +214,16 @@ extern const SSL_METHOD *TLSv1_2_method(void);
39+
#define HAVE_OPENSSL_CRYPTO_LOCK
40+
#endif
41+
42+
+/* OpenSSL 1.1+ allows locking X509_STORE, 1.0.2 doesn't. */
43+
+#ifdef OPENSSL_VERSION_1_1
44+
+#define HAVE_OPENSSL_X509_STORE_LOCK
45+
+#endif
46+
+
47+
+/* OpenSSL 3.3 added the X509_STORE_get1_objects API */
48+
+#ifdef OPENSSL_VERSION_3_3
49+
+#define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
50+
+#endif
51+
+
52+
#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2)
53+
#define OPENSSL_NO_SSL2
54+
#endif
55+
@@ -4675,6 +4689,54 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
56+
#endif
57+
}
58+
59+
+/* Shim of X509_STORE_get1_objects API from OpenSSL 3.3
60+
+ * Only available with the X509_STORE_lock() API */
61+
+#if defined(HAVE_OPENSSL_X509_STORE_LOCK) && !defined(OPENSSL_VERSION_3_3)
62+
+#define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
63+
+
64+
+static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj)
65+
+{
66+
+ int ok;
67+
+ X509_OBJECT *ret = X509_OBJECT_new();
68+
+ if (ret == NULL) {
69+
+ return NULL;
70+
+ }
71+
+ switch (X509_OBJECT_get_type(obj)) {
72+
+ case X509_LU_X509:
73+
+ ok = X509_OBJECT_set1_X509(ret, X509_OBJECT_get0_X509(obj));
74+
+ break;
75+
+ case X509_LU_CRL:
76+
+ /* X509_OBJECT_get0_X509_CRL was not const-correct prior to 3.0.*/
77+
+ ok = X509_OBJECT_set1_X509_CRL(
78+
+ ret, X509_OBJECT_get0_X509_CRL((X509_OBJECT *)obj));
79+
+ break;
80+
+ default:
81+
+ /* We cannot duplicate unrecognized types in a polyfill, but it is
82+
+ * safe to leave an empty object. The caller will ignore it. */
83+
+ ok = 1;
84+
+ break;
85+
+ }
86+
+ if (!ok) {
87+
+ X509_OBJECT_free(ret);
88+
+ return NULL;
89+
+ }
90+
+ return ret;
91+
+}
92+
+
93+
+static STACK_OF(X509_OBJECT) *
94+
+X509_STORE_get1_objects(X509_STORE *store)
95+
+{
96+
+ STACK_OF(X509_OBJECT) *ret;
97+
+ if (!X509_STORE_lock(store)) {
98+
+ return NULL;
99+
+ }
100+
+ ret = sk_X509_OBJECT_deep_copy(X509_STORE_get0_objects(store),
101+
+ x509_object_dup, X509_OBJECT_free);
102+
+ X509_STORE_unlock(store);
103+
+ return ret;
104+
+}
105+
+#endif
106+
+
107+
PyDoc_STRVAR(PySSLContext_sni_callback_doc,
108+
"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\
109+
\n\
110+
@@ -4704,7 +4766,15 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
111+
int x509 = 0, crl = 0, ca = 0, i;
112+
113+
store = SSL_CTX_get_cert_store(self->ctx);
114+
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
115+
+ objs = X509_STORE_get1_objects(store);
116+
+ if (objs == NULL) {
117+
+ PyErr_SetString(PyExc_MemoryError, "failed to query cert store");
118+
+ return NULL;
119+
+ }
120+
+#else
121+
objs = X509_STORE_get0_objects(store);
122+
+#endif
123+
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
124+
obj = sk_X509_OBJECT_value(objs, i);
125+
switch (X509_OBJECT_get_type(obj)) {
126+
@@ -4718,12 +4788,13 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
127+
crl++;
128+
break;
129+
default:
130+
- /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
131+
- * As far as I can tell they are internal states and never
132+
- * stored in a cert store */
133+
+ /* Ignore unrecognized types. */
134+
break;
135+
}
136+
}
137+
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
138+
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
139+
+#endif
140+
return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl,
141+
"x509_ca", ca);
142+
}
143+
@@ -4755,7 +4826,15 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
144+
}
145+
146+
store = SSL_CTX_get_cert_store(self->ctx);
147+
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
148+
+ objs = X509_STORE_get1_objects(store);
149+
+ if (objs == NULL) {
150+
+ PyErr_SetString(PyExc_MemoryError, "failed to query cert store");
151+
+ return NULL;
152+
+ }
153+
+#else
154+
objs = X509_STORE_get0_objects(store);
155+
+#endif
156+
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
157+
X509_OBJECT *obj;
158+
X509 *cert;
159+
@@ -4783,9 +4862,15 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
160+
}
161+
Py_CLEAR(ci);
162+
}
163+
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
164+
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
165+
+#endif
166+
return rlist;
167+
168+
error:
169+
+#if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
170+
+ sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
171+
+#endif
172+
Py_XDECREF(ci);
173+
Py_XDECREF(rlist);
174+
return NULL;

SPECS/python3/python3.spec

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Source0: https://www.python.org/ftp/python/%{version}/Python-%{version}.t
2222
Patch0: cgi3.patch
2323
# Backport https://github.com/python/cpython/commit/069fefdaf42490f1e00243614fb5f3d5d2614b81 from 3.10 to 3.9
2424
Patch1: 0001-gh-95231-Disable-md5-crypt-modules-if-FIPS-is-enable.patch
25+
Patch2: CVE-2024-0397.patch
2526
# Patch for setuptools, resolved in 65.5.1
2627
Patch1000: CVE-2022-40897.patch
2728
Patch1001: CVE-2024-6345.patch
@@ -316,8 +317,13 @@ rm -rf %{buildroot}%{_bindir}/__pycache__
316317
%{_libdir}/python%{majmin}/test/*
317318

318319
%changelog
320+
<<<<<<< HEAD
319321
* Mon Jul 22 2024 Sindhu Karri <lakarri@microsoft.com> - 3.9.19-2
320322
- Patch for CVE-2024-6345
323+
=======
324+
* Tue Jul 23 2024 Rohit Rawat <rohitrawat@microsoft.com> - 3.9.19-2
325+
- Patch for CVE-2024-0397
326+
>>>>>>> f1b818c3c (Python3 patch CVE-2024-0397 (#9912))
321327

322328
* Fri Mar 22 2024 Binu Philip <bphilip@microsoft.com> - 3.9.19-1
323329
- Upgrade to python 3.9.19 for CVE-2023-6597 and other security fixes

0 commit comments

Comments
 (0)