Skip to content

Commit 9ad68af

Browse files
committed
gh-140795: Keep 'err' in local variable in _ssl.c
The error return code doesn't need to be mutable state on the SSLSocket. This simplifes thread-safety and avoids potential reentrancy issues.
1 parent b6b0e14 commit 9ad68af

File tree

1 file changed

+7
-19
lines changed

1 file changed

+7
-19
lines changed

Modules/_ssl.c

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ typedef struct {
360360
enum py_ssl_server_or_client socket_type;
361361
PyObject *owner; /* Python level "owner" passed to servername callback */
362362
PyObject *server_hostname;
363-
_PySSLError err; /* last seen error from various sources */
364363
/* Some SSL callbacks don't have error reporting. Callback wrappers
365364
* store exception information on the socket. The handshake, read, write,
366365
* and shutdown methods check for chained exceptions.
@@ -669,11 +668,10 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) {
669668
}
670669

671670
static PyObject *
672-
PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno)
671+
PySSL_SetError(PySSLSocket *sslsock, _PySSLError err, const char *filename, int lineno)
673672
{
674673
PyObject *type;
675674
char *errstr = NULL;
676-
_PySSLError err;
677675
enum py_ssl_error p = PY_SSL_ERROR_NONE;
678676
unsigned long e = 0;
679677

@@ -686,8 +684,6 @@ PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno)
686684
e = ERR_peek_last_error();
687685

688686
if (sslsock->ssl != NULL) {
689-
err = sslsock->err;
690-
691687
switch (err.ssl) {
692688
case SSL_ERROR_ZERO_RETURN:
693689
errstr = "TLS/SSL connection has been closed (EOF)";
@@ -885,7 +881,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
885881
{
886882
PySSLSocket *self;
887883
SSL_CTX *ctx = sslctx->ctx;
888-
_PySSLError err = { 0 };
889884

890885
if ((socket_type == PY_SSL_SERVER) &&
891886
(sslctx->protocol == PY_SSL_VERSION_TLS_CLIENT)) {
@@ -913,7 +908,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
913908
self->shutdown_seen_zero = 0;
914909
self->owner = NULL;
915910
self->server_hostname = NULL;
916-
self->err = err;
917911
self->exc = NULL;
918912

919913
/* Make sure the SSL error state is initialized */
@@ -1069,7 +1063,6 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
10691063
err = _PySSL_errno(ret < 1, self->ssl, ret);
10701064
Py_END_ALLOW_THREADS;
10711065
_PySSL_FIX_ERRNO;
1072-
self->err = err;
10731066

10741067
if (PyErr_CheckSignals())
10751068
goto error;
@@ -1105,7 +1098,7 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
11051098
Py_XDECREF(sock);
11061099

11071100
if (ret < 1)
1108-
return PySSL_SetError(self, __FILE__, __LINE__);
1101+
return PySSL_SetError(self, err, __FILE__, __LINE__);
11091102
if (PySSL_ChainExceptions(self) < 0)
11101103
return NULL;
11111104
Py_RETURN_NONE;
@@ -2672,7 +2665,6 @@ _ssl__SSLSocket_sendfile_impl(PySSLSocket *self, int fd, Py_off_t offset,
26722665
err = _PySSL_errno(retval < 0, self->ssl, (int)retval);
26732666
Py_END_ALLOW_THREADS;
26742667
_PySSL_FIX_ERRNO;
2675-
self->err = err;
26762668

26772669
if (PyErr_CheckSignals()) {
26782670
goto error;
@@ -2723,7 +2715,7 @@ _ssl__SSLSocket_sendfile_impl(PySSLSocket *self, int fd, Py_off_t offset,
27232715
}
27242716
Py_XDECREF(sock);
27252717
if (retval < 0) {
2726-
return PySSL_SetError(self, __FILE__, __LINE__);
2718+
return PySSL_SetError(self, err, __FILE__, __LINE__);
27272719
}
27282720
if (PySSL_ChainExceptions(self) < 0) {
27292721
return NULL;
@@ -2804,7 +2796,6 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
28042796
err = _PySSL_errno(retval == 0, self->ssl, retval);
28052797
Py_END_ALLOW_THREADS;
28062798
_PySSL_FIX_ERRNO;
2807-
self->err = err;
28082799

28092800
if (PyErr_CheckSignals())
28102801
goto error;
@@ -2837,7 +2828,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
28372828

28382829
Py_XDECREF(sock);
28392830
if (retval == 0)
2840-
return PySSL_SetError(self, __FILE__, __LINE__);
2831+
return PySSL_SetError(self, err, __FILE__, __LINE__);
28412832
if (PySSL_ChainExceptions(self) < 0)
28422833
return NULL;
28432834
return PyLong_FromSize_t(count);
@@ -2867,10 +2858,9 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self)
28672858
err = _PySSL_errno(count < 0, self->ssl, count);
28682859
Py_END_ALLOW_THREADS;
28692860
_PySSL_FIX_ERRNO;
2870-
self->err = err;
28712861

28722862
if (count < 0)
2873-
return PySSL_SetError(self, __FILE__, __LINE__);
2863+
return PySSL_SetError(self, err, __FILE__, __LINE__);
28742864
else
28752865
return PyLong_FromLong(count);
28762866
}
@@ -2964,7 +2954,6 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
29642954
err = _PySSL_errno(retval == 0, self->ssl, retval);
29652955
Py_END_ALLOW_THREADS;
29662956
_PySSL_FIX_ERRNO;
2967-
self->err = err;
29682957

29692958
if (PyErr_CheckSignals())
29702959
goto error;
@@ -2997,7 +2986,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
29972986
err.ssl == SSL_ERROR_WANT_WRITE);
29982987

29992988
if (retval == 0) {
3000-
PySSL_SetError(self, __FILE__, __LINE__);
2989+
PySSL_SetError(self, err, __FILE__, __LINE__);
30012990
goto error;
30022991
}
30032992
if (self->exc != NULL)
@@ -3077,7 +3066,6 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
30773066
err = _PySSL_errno(ret < 0, self->ssl, ret);
30783067
Py_END_ALLOW_THREADS;
30793068
_PySSL_FIX_ERRNO;
3080-
self->err = err;
30813069

30823070
/* If err == 1, a secure shutdown with SSL_shutdown() is complete */
30833071
if (ret > 0)
@@ -3125,7 +3113,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
31253113
}
31263114
if (ret < 0) {
31273115
Py_XDECREF(sock);
3128-
PySSL_SetError(self, __FILE__, __LINE__);
3116+
PySSL_SetError(self, err, __FILE__, __LINE__);
31293117
return NULL;
31303118
}
31313119
if (self->exc != NULL)

0 commit comments

Comments
 (0)