42
42
/* Redefined below for Windows debug builds after important #includes */
43
43
#define _PySSL_FIX_ERRNO
44
44
45
- #define PySSL_BEGIN_ALLOW_THREADS_S (save ) \
46
- do { (save) = PyEval_SaveThread(); } while(0)
47
- #define PySSL_END_ALLOW_THREADS_S (save ) \
48
- do { PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0)
49
- #define PySSL_BEGIN_ALLOW_THREADS { \
45
+ #define PySSL_BEGIN_ALLOW_THREADS_S (save , mutex ) \
46
+ do { (save) = PyEval_SaveThread(); PyMutex_Lock(mutex); } while(0)
47
+ #define PySSL_END_ALLOW_THREADS_S (save , mutex ) \
48
+ do { PyMutex_Unlock(mutex); PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0)
49
+ #define PySSL_BEGIN_ALLOW_THREADS ( self ) { \
50
50
PyThreadState *_save = NULL; \
51
- PySSL_BEGIN_ALLOW_THREADS_S(_save);
52
- #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); }
51
+ PySSL_BEGIN_ALLOW_THREADS_S(_save, &self->tstate_mutex );
52
+ #define PySSL_END_ALLOW_THREADS ( self ) PySSL_END_ALLOW_THREADS_S(_save, &self->tstate_mutex ); }
53
53
54
54
#if defined(HAVE_POLL_H )
55
55
#include <poll.h>
@@ -304,6 +304,9 @@ typedef struct {
304
304
PyObject * psk_client_callback ;
305
305
PyObject * psk_server_callback ;
306
306
#endif
307
+ /* Lock to synchronize calls when the thread state is detached.
308
+ See also gh-134698. */
309
+ PyMutex tstate_mutex ;
307
310
} PySSLContext ;
308
311
309
312
typedef struct {
@@ -329,6 +332,9 @@ typedef struct {
329
332
* and shutdown methods check for chained exceptions.
330
333
*/
331
334
PyObject * exc ;
335
+ /* Lock to synchronize calls when the thread state is detached.
336
+ See also gh-134698. */
337
+ PyMutex tstate_mutex ;
332
338
} PySSLSocket ;
333
339
334
340
typedef struct {
@@ -840,13 +846,14 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
840
846
self -> server_hostname = NULL ;
841
847
self -> err = err ;
842
848
self -> exc = NULL ;
849
+ self -> tstate_mutex = (PyMutex ){0 };
843
850
844
851
/* Make sure the SSL error state is initialized */
845
852
ERR_clear_error ();
846
853
847
- PySSL_BEGIN_ALLOW_THREADS
854
+ PySSL_BEGIN_ALLOW_THREADS ( sslctx )
848
855
self -> ssl = SSL_new (ctx );
849
- PySSL_END_ALLOW_THREADS
856
+ PySSL_END_ALLOW_THREADS ( sslctx )
850
857
if (self -> ssl == NULL) {
851
858
Py_DECREF (self );
852
859
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
@@ -912,12 +919,12 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
912
919
BIO_set_nbio (SSL_get_wbio (self -> ssl ), 1 );
913
920
}
914
921
915
- PySSL_BEGIN_ALLOW_THREADS
922
+ PySSL_BEGIN_ALLOW_THREADS ( self )
916
923
if (socket_type == PY_SSL_CLIENT )
917
924
SSL_set_connect_state (self - > ssl );
918
925
else
919
926
SSL_set_accept_state (self -> ssl );
920
- PySSL_END_ALLOW_THREADS
927
+ PySSL_END_ALLOW_THREADS ( self )
921
928
922
929
self -> socket_type = socket_type ;
923
930
if (sock != NULL ) {
@@ -986,10 +993,10 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
986
993
/* Actually negotiate SSL connection */
987
994
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
988
995
do {
989
- PySSL_BEGIN_ALLOW_THREADS
996
+ PySSL_BEGIN_ALLOW_THREADS ( self )
990
997
ret = SSL_do_handshake (self -> ssl );
991
998
err = _PySSL_errno (ret < 1 , self -> ssl , ret );
992
- PySSL_END_ALLOW_THREADS
999
+ PySSL_END_ALLOW_THREADS ( self )
993
1000
self -> err = err ;
994
1001
995
1002
if (PyErr_CheckSignals ())
@@ -2362,9 +2369,10 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout)
2362
2369
ms = (int )_PyTime_AsMilliseconds (timeout , _PyTime_ROUND_CEILING );
2363
2370
assert (ms <= INT_MAX );
2364
2371
2365
- PySSL_BEGIN_ALLOW_THREADS
2372
+ Py_BEGIN_ALLOW_THREADS
2366
2373
rc = poll (& pollfd , 1 , (int )ms );
2367
- PySSL_END_ALLOW_THREADS
2374
+ Py_END_ALLOW_THREADS
2375
+ _PySSL_FIX_ERRNO ;
2368
2376
#else
2369
2377
/* Guard against socket too large for select*/
2370
2378
if (!_PyIsSelectable_fd (s -> sock_fd ))
@@ -2376,13 +2384,14 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout)
2376
2384
FD_SET (s -> sock_fd , & fds );
2377
2385
2378
2386
/* Wait until the socket becomes ready */
2379
- PySSL_BEGIN_ALLOW_THREADS
2387
+ Py_BEGIN_ALLOW_THREADS
2380
2388
nfds = Py_SAFE_DOWNCAST (s -> sock_fd + 1 , SOCKET_T , int );
2381
2389
if (writing )
2382
2390
rc = select (nfds , NULL , & fds , NULL , & tv );
2383
2391
else
2384
2392
rc = select (nfds , & fds , NULL , NULL , & tv );
2385
- PySSL_END_ALLOW_THREADS
2393
+ Py_END_ALLOW_THREADS
2394
+ _PySSL_FIX_ERRNO ;
2386
2395
#endif
2387
2396
2388
2397
/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
@@ -2453,10 +2462,10 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
2453
2462
}
2454
2463
2455
2464
do {
2456
- PySSL_BEGIN_ALLOW_THREADS
2465
+ PySSL_BEGIN_ALLOW_THREADS ( self )
2457
2466
retval = SSL_write_ex (self -> ssl , b -> buf , (size_t )b -> len , & count );
2458
2467
err = _PySSL_errno (retval == 0 , self -> ssl , retval );
2459
- PySSL_END_ALLOW_THREADS
2468
+ PySSL_END_ALLOW_THREADS ( self )
2460
2469
self -> err = err ;
2461
2470
2462
2471
if (PyErr_CheckSignals ())
@@ -2514,10 +2523,10 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self)
2514
2523
int count = 0 ;
2515
2524
_PySSLError err ;
2516
2525
2517
- PySSL_BEGIN_ALLOW_THREADS
2526
+ PySSL_BEGIN_ALLOW_THREADS ( self )
2518
2527
count = SSL_pending (self -> ssl );
2519
2528
err = _PySSL_errno (count < 0 , self -> ssl , count );
2520
- PySSL_END_ALLOW_THREADS
2529
+ PySSL_END_ALLOW_THREADS ( self )
2521
2530
self -> err = err ;
2522
2531
2523
2532
if (count < 0 )
@@ -2608,10 +2617,10 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
2608
2617
deadline = _PyDeadline_Init (timeout );
2609
2618
2610
2619
do {
2611
- PySSL_BEGIN_ALLOW_THREADS
2620
+ PySSL_BEGIN_ALLOW_THREADS ( self )
2612
2621
retval = SSL_read_ex (self -> ssl , mem , (size_t )len , & count );
2613
2622
err = _PySSL_errno (retval == 0 , self -> ssl , retval );
2614
- PySSL_END_ALLOW_THREADS
2623
+ PySSL_END_ALLOW_THREADS ( self )
2615
2624
self -> err = err ;
2616
2625
2617
2626
if (PyErr_CheckSignals ())
@@ -2710,7 +2719,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
2710
2719
}
2711
2720
2712
2721
while (1 ) {
2713
- PySSL_BEGIN_ALLOW_THREADS
2722
+ PySSL_BEGIN_ALLOW_THREADS ( self )
2714
2723
/* Disable read-ahead so that unwrap can work correctly.
2715
2724
* Otherwise OpenSSL might read in too much data,
2716
2725
* eating clear text data that happens to be
@@ -2723,7 +2732,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
2723
2732
SSL_set_read_ahead (self - > ssl , 0 );
2724
2733
ret = SSL_shutdown (self -> ssl );
2725
2734
err = _PySSL_errno (ret < 0 , self -> ssl , ret );
2726
- PySSL_END_ALLOW_THREADS
2735
+ PySSL_END_ALLOW_THREADS ( self )
2727
2736
self -> err = err ;
2728
2737
2729
2738
/* If err == 1, a secure shutdown with SSL_shutdown() is complete */
@@ -3115,9 +3124,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
3115
3124
// no other thread can be touching this object yet.
3116
3125
// (Technically, we can't even lock if we wanted to, as the
3117
3126
// lock hasn't been initialized yet.)
3118
- PySSL_BEGIN_ALLOW_THREADS
3127
+ Py_BEGIN_ALLOW_THREADS
3119
3128
ctx = SSL_CTX_new (method );
3120
- PySSL_END_ALLOW_THREADS
3129
+ Py_END_ALLOW_THREADS
3130
+ _PySSL_FIX_ERRNO ;
3121
3131
3122
3132
if (ctx == NULL ) {
3123
3133
_setSSLError (get_ssl_state (module ), NULL , 0 , __FILE__ , __LINE__ );
@@ -3143,6 +3153,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
3143
3153
self -> psk_client_callback = NULL ;
3144
3154
self -> psk_server_callback = NULL ;
3145
3155
#endif
3156
+ self -> tstate_mutex = (PyMutex ){0 };
3146
3157
3147
3158
/* Don't check host name by default */
3148
3159
if (proto_version == PY_SSL_VERSION_TLS_CLIENT ) {
@@ -3259,9 +3270,10 @@ context_clear(PySSLContext *self)
3259
3270
Py_CLEAR (self -> psk_server_callback );
3260
3271
#endif
3261
3272
if (self -> keylog_bio != NULL ) {
3262
- PySSL_BEGIN_ALLOW_THREADS
3273
+ Py_BEGIN_ALLOW_THREADS
3263
3274
BIO_free_all (self -> keylog_bio );
3264
- PySSL_END_ALLOW_THREADS
3275
+ Py_END_ALLOW_THREADS
3276
+ _PySSL_FIX_ERRNO ;
3265
3277
self -> keylog_bio = NULL ;
3266
3278
}
3267
3279
return 0 ;
@@ -3980,7 +3992,8 @@ _password_callback(char *buf, int size, int rwflag, void *userdata)
3980
3992
_PySSLPasswordInfo * pw_info = (_PySSLPasswordInfo * ) userdata ;
3981
3993
PyObject * fn_ret = NULL ;
3982
3994
3983
- PySSL_END_ALLOW_THREADS_S (pw_info -> thread_state );
3995
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
3996
+ _PySSL_FIX_ERRNO ;
3984
3997
3985
3998
if (pw_info -> error ) {
3986
3999
/* already failed previously. OpenSSL 3.0.0-alpha14 invokes the
@@ -4010,13 +4023,13 @@ _password_callback(char *buf, int size, int rwflag, void *userdata)
4010
4023
goto error ;
4011
4024
}
4012
4025
4013
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info -> thread_state );
4026
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
4014
4027
memcpy (buf , pw_info -> password , pw_info -> size );
4015
4028
return pw_info -> size ;
4016
4029
4017
4030
error :
4018
4031
Py_XDECREF (fn_ret );
4019
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info -> thread_state );
4032
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
4020
4033
pw_info -> error = 1 ;
4021
4034
return -1 ;
4022
4035
}
@@ -4069,10 +4082,10 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4069
4082
SSL_CTX_set_default_passwd_cb (self -> ctx , _password_callback );
4070
4083
SSL_CTX_set_default_passwd_cb_userdata (self -> ctx , & pw_info );
4071
4084
}
4072
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4085
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4073
4086
r = SSL_CTX_use_certificate_chain_file (self -> ctx ,
4074
4087
PyBytes_AS_STRING (certfile_bytes ));
4075
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4088
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4076
4089
if (r != 1 ) {
4077
4090
if (pw_info .error ) {
4078
4091
ERR_clear_error ();
@@ -4087,11 +4100,11 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4087
4100
}
4088
4101
goto error ;
4089
4102
}
4090
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4103
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4091
4104
r = SSL_CTX_use_PrivateKey_file (self -> ctx ,
4092
4105
PyBytes_AS_STRING (keyfile ? keyfile_bytes : certfile_bytes ),
4093
4106
SSL_FILETYPE_PEM );
4094
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4107
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4095
4108
Py_CLEAR (keyfile_bytes );
4096
4109
Py_CLEAR (certfile_bytes );
4097
4110
if (r != 1 ) {
@@ -4108,9 +4121,9 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4108
4121
}
4109
4122
goto error ;
4110
4123
}
4111
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4124
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4112
4125
r = SSL_CTX_check_private_key (self -> ctx );
4113
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4126
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4114
4127
if (r != 1 ) {
4115
4128
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
4116
4129
goto error ;
@@ -4327,9 +4340,9 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self,
4327
4340
cafile_buf = PyBytes_AS_STRING (cafile_bytes );
4328
4341
if (capath )
4329
4342
capath_buf = PyBytes_AS_STRING (capath_bytes );
4330
- PySSL_BEGIN_ALLOW_THREADS
4343
+ PySSL_BEGIN_ALLOW_THREADS ( self )
4331
4344
r = SSL_CTX_load_verify_locations (self -> ctx , cafile_buf , capath_buf );
4332
- PySSL_END_ALLOW_THREADS
4345
+ PySSL_END_ALLOW_THREADS ( self )
4333
4346
if (r != 1 ) {
4334
4347
if (errno != 0 ) {
4335
4348
PyErr_SetFromErrno (PyExc_OSError );
@@ -4381,10 +4394,11 @@ _ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath)
4381
4394
return NULL ;
4382
4395
4383
4396
errno = 0 ;
4384
- PySSL_BEGIN_ALLOW_THREADS
4397
+ Py_BEGIN_ALLOW_THREADS
4385
4398
dh = PEM_read_DHparams (f , NULL , NULL , NULL );
4386
4399
fclose (f );
4387
- PySSL_END_ALLOW_THREADS
4400
+ Py_END_ALLOW_THREADS
4401
+ _PySSL_FIX_ERRNO ;
4388
4402
if (dh == NULL ) {
4389
4403
if (errno != 0 ) {
4390
4404
PyErr_SetFromErrnoWithFilenameObject (PyExc_OSError , filepath );
@@ -4536,6 +4550,7 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self)
4536
4550
Py_BEGIN_ALLOW_THREADS
4537
4551
rc = SSL_CTX_set_default_verify_paths (self -> ctx );
4538
4552
Py_END_ALLOW_THREADS
4553
+ _PySSL_FIX_ERRNO ;
4539
4554
if (!rc ) {
4540
4555
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
4541
4556
return NULL ;
0 commit comments