43
43
/* Redefined below for Windows debug builds after important #includes */
44
44
#define _PySSL_FIX_ERRNO
45
45
46
- #define PySSL_BEGIN_ALLOW_THREADS_S (save ) \
47
- do { (save) = PyEval_SaveThread(); } while(0)
48
- #define PySSL_END_ALLOW_THREADS_S (save ) \
49
- do { PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0)
50
- #define PySSL_BEGIN_ALLOW_THREADS { \
46
+ #define PySSL_BEGIN_ALLOW_THREADS_S (save , mutex ) \
47
+ do { (save) = PyEval_SaveThread(); PyMutex_Lock(mutex); } while(0)
48
+ #define PySSL_END_ALLOW_THREADS_S (save , mutex ) \
49
+ do { PyMutex_Unlock(mutex); PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0)
50
+ #define PySSL_BEGIN_ALLOW_THREADS ( self ) { \
51
51
PyThreadState *_save = NULL; \
52
- PySSL_BEGIN_ALLOW_THREADS_S(_save);
53
- #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); }
52
+ PySSL_BEGIN_ALLOW_THREADS_S(_save, &self->tstate_mutex );
53
+ #define PySSL_END_ALLOW_THREADS ( self ) PySSL_END_ALLOW_THREADS_S(_save, &self->tstate_mutex ); }
54
54
55
55
#if defined(HAVE_POLL_H )
56
56
#include <poll.h>
@@ -309,6 +309,9 @@ typedef struct {
309
309
PyObject * psk_client_callback ;
310
310
PyObject * psk_server_callback ;
311
311
#endif
312
+ /* Lock to synchronize calls when the thread state is detached.
313
+ See also gh-134698. */
314
+ PyMutex tstate_mutex ;
312
315
} PySSLContext ;
313
316
314
317
#define PySSLContext_CAST (op ) ((PySSLContext *)(op))
@@ -889,9 +892,9 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
889
892
/* Make sure the SSL error state is initialized */
890
893
ERR_clear_error ();
891
894
892
- PySSL_BEGIN_ALLOW_THREADS
895
+ PySSL_BEGIN_ALLOW_THREADS ( sslctx )
893
896
self -> ssl = SSL_new (ctx );
894
- PySSL_END_ALLOW_THREADS
897
+ PySSL_END_ALLOW_THREADS ( sslctx )
895
898
if (self -> ssl == NULL) {
896
899
Py_DECREF (self );
897
900
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
@@ -960,12 +963,12 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
960
963
BIO_set_nbio (SSL_get_wbio (self -> ssl ), 1 );
961
964
}
962
965
963
- PySSL_BEGIN_ALLOW_THREADS
966
+ Py_BEGIN_ALLOW_THREADS ;
964
967
if (socket_type == PY_SSL_CLIENT )
965
968
SSL_set_connect_state (self -> ssl );
966
969
else
967
970
SSL_set_accept_state (self -> ssl );
968
- PySSL_END_ALLOW_THREADS
971
+ Py_END_ALLOW_THREADS ;
969
972
970
973
self -> socket_type = socket_type ;
971
974
if (sock != NULL ) {
@@ -1034,10 +1037,11 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
1034
1037
/* Actually negotiate SSL connection */
1035
1038
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
1036
1039
do {
1037
- PySSL_BEGIN_ALLOW_THREADS
1040
+ Py_BEGIN_ALLOW_THREADS
1038
1041
ret = SSL_do_handshake (self -> ssl );
1039
1042
err = _PySSL_errno (ret < 1 , self -> ssl , ret );
1040
- PySSL_END_ALLOW_THREADS
1043
+ Py_END_ALLOW_THREADS ;
1044
+ _PySSL_FIX_ERRNO ;
1041
1045
self -> err = err ;
1042
1046
1043
1047
if (PyErr_CheckSignals ())
@@ -2414,9 +2418,10 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout)
2414
2418
ms = (int )_PyTime_AsMilliseconds (timeout , _PyTime_ROUND_CEILING );
2415
2419
assert (ms <= INT_MAX );
2416
2420
2417
- PySSL_BEGIN_ALLOW_THREADS
2421
+ Py_BEGIN_ALLOW_THREADS
2418
2422
rc = poll (& pollfd , 1 , (int )ms );
2419
- PySSL_END_ALLOW_THREADS
2423
+ Py_END_ALLOW_THREADS
2424
+ _PySSL_FIX_ERRNO ;
2420
2425
#else
2421
2426
/* Guard against socket too large for select*/
2422
2427
if (!_PyIsSelectable_fd (s -> sock_fd ))
@@ -2428,13 +2433,14 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout)
2428
2433
FD_SET (s -> sock_fd , & fds );
2429
2434
2430
2435
/* Wait until the socket becomes ready */
2431
- PySSL_BEGIN_ALLOW_THREADS
2436
+ Py_BEGIN_ALLOW_THREADS
2432
2437
nfds = Py_SAFE_DOWNCAST (s -> sock_fd + 1 , SOCKET_T , int );
2433
2438
if (writing )
2434
2439
rc = select (nfds , NULL , & fds , NULL , & tv );
2435
2440
else
2436
2441
rc = select (nfds , & fds , NULL , NULL , & tv );
2437
- PySSL_END_ALLOW_THREADS
2442
+ Py_END_ALLOW_THREADS
2443
+ _PySSL_FIX_ERRNO ;
2438
2444
#endif
2439
2445
2440
2446
/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
@@ -2505,10 +2511,11 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
2505
2511
}
2506
2512
2507
2513
do {
2508
- PySSL_BEGIN_ALLOW_THREADS
2514
+ Py_BEGIN_ALLOW_THREADS ;
2509
2515
retval = SSL_write_ex (self -> ssl , b -> buf , (size_t )b -> len , & count );
2510
2516
err = _PySSL_errno (retval == 0 , self -> ssl , retval );
2511
- PySSL_END_ALLOW_THREADS
2517
+ Py_END_ALLOW_THREADS ;
2518
+ _PySSL_FIX_ERRNO ;
2512
2519
self -> err = err ;
2513
2520
2514
2521
if (PyErr_CheckSignals ())
@@ -2566,10 +2573,11 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self)
2566
2573
int count = 0 ;
2567
2574
_PySSLError err ;
2568
2575
2569
- PySSL_BEGIN_ALLOW_THREADS
2576
+ Py_BEGIN_ALLOW_THREADS ;
2570
2577
count = SSL_pending (self -> ssl );
2571
2578
err = _PySSL_errno (count < 0 , self -> ssl , count );
2572
- PySSL_END_ALLOW_THREADS
2579
+ Py_END_ALLOW_THREADS ;
2580
+ _PySSL_FIX_ERRNO ;
2573
2581
self -> err = err ;
2574
2582
2575
2583
if (count < 0 )
@@ -2660,10 +2668,11 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
2660
2668
deadline = _PyDeadline_Init (timeout );
2661
2669
2662
2670
do {
2663
- PySSL_BEGIN_ALLOW_THREADS
2671
+ Py_BEGIN_ALLOW_THREADS ;
2664
2672
retval = SSL_read_ex (self -> ssl , mem , (size_t )len , & count );
2665
2673
err = _PySSL_errno (retval == 0 , self -> ssl , retval );
2666
- PySSL_END_ALLOW_THREADS
2674
+ Py_END_ALLOW_THREADS ;
2675
+ _PySSL_FIX_ERRNO ;
2667
2676
self -> err = err ;
2668
2677
2669
2678
if (PyErr_CheckSignals ())
@@ -2762,7 +2771,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
2762
2771
}
2763
2772
2764
2773
while (1 ) {
2765
- PySSL_BEGIN_ALLOW_THREADS
2774
+ Py_BEGIN_ALLOW_THREADS ;
2766
2775
/* Disable read-ahead so that unwrap can work correctly.
2767
2776
* Otherwise OpenSSL might read in too much data,
2768
2777
* eating clear text data that happens to be
@@ -2775,7 +2784,8 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
2775
2784
SSL_set_read_ahead (self -> ssl , 0 );
2776
2785
ret = SSL_shutdown (self -> ssl );
2777
2786
err = _PySSL_errno (ret < 0 , self -> ssl , ret );
2778
- PySSL_END_ALLOW_THREADS
2787
+ Py_END_ALLOW_THREADS ;
2788
+ _PySSL_FIX_ERRNO ;
2779
2789
self -> err = err ;
2780
2790
2781
2791
/* If err == 1, a secure shutdown with SSL_shutdown() is complete */
@@ -3167,9 +3177,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
3167
3177
// no other thread can be touching this object yet.
3168
3178
// (Technically, we can't even lock if we wanted to, as the
3169
3179
// lock hasn't been initialized yet.)
3170
- PySSL_BEGIN_ALLOW_THREADS
3180
+ Py_BEGIN_ALLOW_THREADS
3171
3181
ctx = SSL_CTX_new (method );
3172
- PySSL_END_ALLOW_THREADS
3182
+ Py_END_ALLOW_THREADS
3183
+ _PySSL_FIX_ERRNO ;
3173
3184
3174
3185
if (ctx == NULL ) {
3175
3186
_setSSLError (get_ssl_state (module ), NULL , 0 , __FILE__ , __LINE__ );
@@ -3194,6 +3205,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
3194
3205
self -> psk_client_callback = NULL ;
3195
3206
self -> psk_server_callback = NULL ;
3196
3207
#endif
3208
+ self -> tstate_mutex = (PyMutex ){0 };
3197
3209
3198
3210
/* Don't check host name by default */
3199
3211
if (proto_version == PY_SSL_VERSION_TLS_CLIENT ) {
@@ -3312,9 +3324,10 @@ context_clear(PyObject *op)
3312
3324
Py_CLEAR (self -> psk_server_callback );
3313
3325
#endif
3314
3326
if (self -> keylog_bio != NULL ) {
3315
- PySSL_BEGIN_ALLOW_THREADS
3327
+ Py_BEGIN_ALLOW_THREADS
3316
3328
BIO_free_all (self -> keylog_bio );
3317
- PySSL_END_ALLOW_THREADS
3329
+ Py_END_ALLOW_THREADS
3330
+ _PySSL_FIX_ERRNO ;
3318
3331
self -> keylog_bio = NULL ;
3319
3332
}
3320
3333
return 0 ;
@@ -4037,7 +4050,8 @@ _password_callback(char *buf, int size, int rwflag, void *userdata)
4037
4050
_PySSLPasswordInfo * pw_info = (_PySSLPasswordInfo * ) userdata ;
4038
4051
PyObject * fn_ret = NULL ;
4039
4052
4040
- PySSL_END_ALLOW_THREADS_S (pw_info -> thread_state );
4053
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
4054
+ _PySSL_FIX_ERRNO ;
4041
4055
4042
4056
if (pw_info -> error ) {
4043
4057
/* already failed previously. OpenSSL 3.0.0-alpha14 invokes the
@@ -4067,13 +4081,13 @@ _password_callback(char *buf, int size, int rwflag, void *userdata)
4067
4081
goto error ;
4068
4082
}
4069
4083
4070
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info -> thread_state );
4084
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
4071
4085
memcpy (buf , pw_info -> password , pw_info -> size );
4072
4086
return pw_info -> size ;
4073
4087
4074
4088
error :
4075
4089
Py_XDECREF (fn_ret );
4076
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info -> thread_state );
4090
+ pw_info -> thread_state = PyThreadState_Swap (pw_info -> thread_state );
4077
4091
pw_info -> error = 1 ;
4078
4092
return -1 ;
4079
4093
}
@@ -4126,10 +4140,10 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4126
4140
SSL_CTX_set_default_passwd_cb (self -> ctx , _password_callback );
4127
4141
SSL_CTX_set_default_passwd_cb_userdata (self -> ctx , & pw_info );
4128
4142
}
4129
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4143
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4130
4144
r = SSL_CTX_use_certificate_chain_file (self -> ctx ,
4131
4145
PyBytes_AS_STRING (certfile_bytes ));
4132
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4146
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4133
4147
if (r != 1 ) {
4134
4148
if (pw_info .error ) {
4135
4149
ERR_clear_error ();
@@ -4144,11 +4158,11 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4144
4158
}
4145
4159
goto error ;
4146
4160
}
4147
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4161
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4148
4162
r = SSL_CTX_use_PrivateKey_file (self -> ctx ,
4149
4163
PyBytes_AS_STRING (keyfile ? keyfile_bytes : certfile_bytes ),
4150
4164
SSL_FILETYPE_PEM );
4151
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4165
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4152
4166
Py_CLEAR (keyfile_bytes );
4153
4167
Py_CLEAR (certfile_bytes );
4154
4168
if (r != 1 ) {
@@ -4165,9 +4179,9 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
4165
4179
}
4166
4180
goto error ;
4167
4181
}
4168
- PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state );
4182
+ PySSL_BEGIN_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4169
4183
r = SSL_CTX_check_private_key (self -> ctx );
4170
- PySSL_END_ALLOW_THREADS_S (pw_info .thread_state );
4184
+ PySSL_END_ALLOW_THREADS_S (pw_info .thread_state , & self -> tstate_mutex );
4171
4185
if (r != 1 ) {
4172
4186
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
4173
4187
goto error ;
@@ -4384,9 +4398,9 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self,
4384
4398
cafile_buf = PyBytes_AS_STRING (cafile_bytes );
4385
4399
if (capath )
4386
4400
capath_buf = PyBytes_AS_STRING (capath_bytes );
4387
- PySSL_BEGIN_ALLOW_THREADS
4401
+ PySSL_BEGIN_ALLOW_THREADS ( self )
4388
4402
r = SSL_CTX_load_verify_locations (self -> ctx , cafile_buf , capath_buf );
4389
- PySSL_END_ALLOW_THREADS
4403
+ PySSL_END_ALLOW_THREADS ( self )
4390
4404
if (r != 1 ) {
4391
4405
if (errno != 0 ) {
4392
4406
PyErr_SetFromErrno (PyExc_OSError );
@@ -4438,10 +4452,11 @@ _ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath)
4438
4452
return NULL ;
4439
4453
4440
4454
errno = 0 ;
4441
- PySSL_BEGIN_ALLOW_THREADS
4455
+ Py_BEGIN_ALLOW_THREADS
4442
4456
dh = PEM_read_DHparams (f , NULL , NULL , NULL );
4443
4457
fclose (f );
4444
- PySSL_END_ALLOW_THREADS
4458
+ Py_END_ALLOW_THREADS
4459
+ _PySSL_FIX_ERRNO ;
4445
4460
if (dh == NULL ) {
4446
4461
if (errno != 0 ) {
4447
4462
PyErr_SetFromErrnoWithFilenameObject (PyExc_OSError , filepath );
@@ -4593,6 +4608,7 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self)
4593
4608
Py_BEGIN_ALLOW_THREADS
4594
4609
rc = SSL_CTX_set_default_verify_paths (self -> ctx );
4595
4610
Py_END_ALLOW_THREADS
4611
+ _PySSL_FIX_ERRNO ;
4596
4612
if (!rc ) {
4597
4613
_setSSLError (get_state_ctx (self ), NULL , 0 , __FILE__ , __LINE__ );
4598
4614
return NULL ;
0 commit comments