mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-115627: Fix PySSL_SetError handling SSL_ERROR_SYSCALL (GH-115628)
Python 3.10 changed from using SSL_write() and SSL_read() to SSL_write_ex() and SSL_read_ex(), but did not update handling of the return value. Change error handling so that the return value is not examined. OSError (not EOF) is now returned when retval is 0. According to *recent* man pages of all functions for which we call PySSL_SetError, (in OpenSSL 3.0 and 1.1.1), their return value should be used to determine whether an error happened (i.e. if PySSL_SetError should be called), but not what kind of error happened (so, PySSL_SetError shouldn't need retval). To get the error, we need to use SSL_get_error. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
parent
d52bdfb19f
commit
ea9a296fce
3 changed files with 35 additions and 43 deletions
|
|
@ -599,7 +599,7 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) {
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
|
||||
PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno)
|
||||
{
|
||||
PyObject *type;
|
||||
char *errstr = NULL;
|
||||
|
|
@ -612,7 +612,6 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
|
|||
_sslmodulestate *state = get_state_sock(sslsock);
|
||||
type = state->PySSLErrorObject;
|
||||
|
||||
assert(ret <= 0);
|
||||
e = ERR_peek_last_error();
|
||||
|
||||
if (sslsock->ssl != NULL) {
|
||||
|
|
@ -645,32 +644,21 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
|
|||
case SSL_ERROR_SYSCALL:
|
||||
{
|
||||
if (e == 0) {
|
||||
PySocketSockObject *s = GET_SOCKET(sslsock);
|
||||
if (ret == 0 || (((PyObject *)s) == Py_None)) {
|
||||
/* underlying BIO reported an I/O error */
|
||||
ERR_clear_error();
|
||||
#ifdef MS_WINDOWS
|
||||
if (err.ws) {
|
||||
return PyErr_SetFromWindowsErr(err.ws);
|
||||
}
|
||||
#endif
|
||||
if (err.c) {
|
||||
errno = err.c;
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
else {
|
||||
p = PY_SSL_ERROR_EOF;
|
||||
type = state->PySSLEOFErrorObject;
|
||||
errstr = "EOF occurred in violation of protocol";
|
||||
} else if (s && ret == -1) {
|
||||
/* underlying BIO reported an I/O error */
|
||||
ERR_clear_error();
|
||||
#ifdef MS_WINDOWS
|
||||
if (err.ws) {
|
||||
return PyErr_SetFromWindowsErr(err.ws);
|
||||
}
|
||||
#endif
|
||||
if (err.c) {
|
||||
errno = err.c;
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
else {
|
||||
p = PY_SSL_ERROR_EOF;
|
||||
type = state->PySSLEOFErrorObject;
|
||||
errstr = "EOF occurred in violation of protocol";
|
||||
}
|
||||
} else { /* possible? */
|
||||
p = PY_SSL_ERROR_SYSCALL;
|
||||
type = state->PySSLSyscallErrorObject;
|
||||
errstr = "Some I/O error occurred";
|
||||
}
|
||||
} else {
|
||||
if (ERR_GET_LIB(e) == ERR_LIB_SSL &&
|
||||
|
|
@ -1030,7 +1018,7 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
|
|||
err.ssl == SSL_ERROR_WANT_WRITE);
|
||||
Py_XDECREF(sock);
|
||||
if (ret < 1)
|
||||
return PySSL_SetError(self, ret, __FILE__, __LINE__);
|
||||
return PySSL_SetError(self, __FILE__, __LINE__);
|
||||
if (PySSL_ChainExceptions(self) < 0)
|
||||
return NULL;
|
||||
Py_RETURN_NONE;
|
||||
|
|
@ -2437,7 +2425,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
|
|||
|
||||
Py_XDECREF(sock);
|
||||
if (retval == 0)
|
||||
return PySSL_SetError(self, retval, __FILE__, __LINE__);
|
||||
return PySSL_SetError(self, __FILE__, __LINE__);
|
||||
if (PySSL_ChainExceptions(self) < 0)
|
||||
return NULL;
|
||||
return PyLong_FromSize_t(count);
|
||||
|
|
@ -2467,7 +2455,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self)
|
|||
self->err = err;
|
||||
|
||||
if (count < 0)
|
||||
return PySSL_SetError(self, count, __FILE__, __LINE__);
|
||||
return PySSL_SetError(self, __FILE__, __LINE__);
|
||||
else
|
||||
return PyLong_FromLong(count);
|
||||
}
|
||||
|
|
@ -2590,7 +2578,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
|
|||
err.ssl == SSL_ERROR_WANT_WRITE);
|
||||
|
||||
if (retval == 0) {
|
||||
PySSL_SetError(self, retval, __FILE__, __LINE__);
|
||||
PySSL_SetError(self, __FILE__, __LINE__);
|
||||
goto error;
|
||||
}
|
||||
if (self->exc != NULL)
|
||||
|
|
@ -2716,7 +2704,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
|
|||
}
|
||||
if (ret < 0) {
|
||||
Py_XDECREF(sock);
|
||||
PySSL_SetError(self, ret, __FILE__, __LINE__);
|
||||
PySSL_SetError(self, __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
if (self->exc != NULL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue