Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-124984: Fix ssl thread safety#124993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
gh-124984: Fix ssl thread safety
#124993
Changes from all commits
132a2dd572e48fb0cd0050629acd3712d05eb06e0530fce360d63bfb7268ebb28004f1caa205a578d40ac601906014a95aebb8b40a3ff154591535f53e6d59cd047ba3f3715bd808932df26ffe288c9a3c8df91823aa4f992d9525eff01dbf678df1e96bf31028bb6af578c8e80aea327d7662144a8c486e13fed2424f679b91bc0c0377ebbe02857fe362d4fe088d6f9ae852eb61a84b9c2732ae25f654950f45fee2d4f6449c95a0fc8388c4e20d44f1782216c318701bf00ffc4879ebd621b3b81e78e7e0f478cf4992d9152af07f848cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -4,6 +4,7 @@ | ||
| import unittest | ||
| import unittest.mock | ||
| from ast import literal_eval | ||
| from threading import Thread | ||
| from test import support | ||
| from test.support import import_helper | ||
| from test.support import os_helper | ||
| @@ -277,11 +278,19 @@ def test_wrap_socket(sock, *, | ||
| return context.wrap_socket(sock, **kwargs) | ||
| USE_SAME_TEST_CONTEXT = False | ||
| _TEST_CONTEXT = None | ||
| def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): | ||
| """Create context | ||
| client_context, server_context, hostname = testing_context() | ||
| """ | ||
| global _TEST_CONTEXT | ||
| if USE_SAME_TEST_CONTEXT: | ||
| if _TEST_CONTEXT is not None: | ||
| return _TEST_CONTEXT | ||
| if server_cert == SIGNED_CERTFILE: | ||
| hostname = SIGNED_CERTFILE_HOSTNAME | ||
| elif server_cert == SIGNED_CERTFILE2: | ||
| @@ -299,6 +308,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): | ||
| if server_chain: | ||
| server_context.load_verify_locations(SIGNING_CA) | ||
| if USE_SAME_TEST_CONTEXT: | ||
| if _TEST_CONTEXT is not None: | ||
| _TEST_CONTEXT = client_context, server_context, hostname | ||
| return client_context, server_context, hostname | ||
| @@ -2800,6 +2813,44 @@ def test_echo(self): | ||
| 'Cannot create a client socket with a PROTOCOL_TLS_SERVER context', | ||
| str(e.exception)) | ||
| @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") | ||
| def test_ssl_in_multiple_threads(self): | ||
| # See GH-124984: OpenSSL is not thread safe. | ||
| threads = [] | ||
| global USE_SAME_TEST_CONTEXT | ||
| USE_SAME_TEST_CONTEXT = True | ||
| try: | ||
| for func in ( | ||
| self.test_echo, | ||
| self.test_alpn_protocols, | ||
| self.test_getpeercert, | ||
| self.test_crl_check, | ||
| self.test_check_hostname_idn, | ||
| self.test_wrong_cert_tls12, | ||
| self.test_wrong_cert_tls13, | ||
| ): | ||
| # Be careful with the number of threads here. | ||
| # Too many can result in failing tests. | ||
| for num in range(5): | ||
ZeroIntensity marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| with self.subTest(func=func, num=num): | ||
| threads.append(Thread(target=func)) | ||
ZeroIntensity marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| with threading_helper.catch_threading_exception() as cm: | ||
| for thread in threads: | ||
| with self.subTest(thread=thread): | ||
| thread.start() | ||
| for thread in threads: | ||
| with self.subTest(thread=thread): | ||
| thread.join() | ||
| if cm.exc_value is not None: | ||
| # Some threads can skip their test | ||
| if not isinstance(cm.exc_value, unittest.SkipTest): | ||
| raise cm.exc_value | ||
| finally: | ||
| USE_SAME_TEST_CONTEXT = False | ||
| def test_getpeercert(self): | ||
| if support.verbose: | ||
| sys.stdout.write("\n") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fixed thread safety in :mod:`ssl` in the free-threaded build. OpenSSL operations are now protected by a per-object lock. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.