File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1238,6 +1238,25 @@ def getpass(self):
12381238 # Make sure the password function isn't called if it isn't needed
12391239 ctx .load_cert_chain (CERTFILE , password = getpass_exception )
12401240
1241+ @threading_helper .requires_working_threading ()
1242+ def test_load_cert_chain_thread_safety (self ):
1243+ # gh-134698: _ssl detaches the thread state (and as such,
1244+ # releases the GIL and critical sections) around expensive
1245+ # OpenSSL calls. Unfortunately, OpenSSL structures aren't
1246+ # thread-safe, so executing these calls concurrently led
1247+ # to crashes.
1248+ ctx = ssl .create_default_context ()
1249+
1250+ def race ():
1251+ ctx .load_cert_chain ("./Lib/test/certdata/keycert.pem" )
1252+
1253+ threads = [threading .Thread (target = race ) for _ in range (8 )]
1254+ with threading_helper .catch_threading_exception () as cm :
1255+ with threading_helper .start_threads (threads ):
1256+ pass
1257+
1258+ self .assertIsNone (cm .exc_value )
1259+
12411260 def test_load_verify_locations (self ):
12421261 ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_SERVER )
12431262 ctx .load_verify_locations (CERTFILE )
You can’t perform that action at this time.
0 commit comments