-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
bpo-37355: For nonblocking sockets, call SSL_read in a loop #25478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| When reading from a nonblocking TLS socket, drop the GIL once to read up to | ||
| the entire buffer. Previously we would read at most one TLS record (16 KB). | ||
| Patch by Josh Snyder. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2334,10 +2334,11 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, | |||||||||||||||||||||||||||||||||
| PyObject *dest = NULL; | ||||||||||||||||||||||||||||||||||
| char *mem; | ||||||||||||||||||||||||||||||||||
| size_t count = 0; | ||||||||||||||||||||||||||||||||||
| size_t got = 0; | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| int retval; | ||||||||||||||||||||||||||||||||||
| int sockstate; | ||||||||||||||||||||||||||||||||||
| _PySSLError err; | ||||||||||||||||||||||||||||||||||
| int nonblocking; | ||||||||||||||||||||||||||||||||||
| int nonblocking = 0; | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it necessary to initialize the variable with |
||||||||||||||||||||||||||||||||||
| PySocketSockObject *sock = GET_SOCKET(self); | ||||||||||||||||||||||||||||||||||
| _PyTime_t timeout, deadline = 0; | ||||||||||||||||||||||||||||||||||
| int has_timeout; | ||||||||||||||||||||||||||||||||||
|
|
@@ -2397,11 +2398,23 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| do { | ||||||||||||||||||||||||||||||||||
| PySSL_BEGIN_ALLOW_THREADS | ||||||||||||||||||||||||||||||||||
| retval = SSL_read_ex(self->ssl, mem, len, &count); | ||||||||||||||||||||||||||||||||||
| do { | ||||||||||||||||||||||||||||||||||
| retval = SSL_read_ex(self->ssl, mem + got, len, &count); | ||||||||||||||||||||||||||||||||||
| if(retval <= 0) { | ||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| got += count; | ||||||||||||||||||||||||||||||||||
| len -= count; | ||||||||||||||||||||||||||||||||||
| } while(nonblocking && len > 0); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+2402
to
+2409
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is it a good idea to have a potentially infinite loop here that ignores signals and timeouts? This smells like DoS vunlerable to be happen.
Suggested change
|
||||||||||||||||||||||||||||||||||
| err = _PySSL_errno(retval == 0, self->ssl, retval); | ||||||||||||||||||||||||||||||||||
| PySSL_END_ALLOW_THREADS | ||||||||||||||||||||||||||||||||||
| self->err = err; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if(got > 0) { | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (PyErr_CheckSignals()) | ||||||||||||||||||||||||||||||||||
| goto error; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -2415,7 +2428,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, | |||||||||||||||||||||||||||||||||
| } else if (err.ssl == SSL_ERROR_ZERO_RETURN && | ||||||||||||||||||||||||||||||||||
| SSL_get_shutdown(self->ssl) == SSL_RECEIVED_SHUTDOWN) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| count = 0; | ||||||||||||||||||||||||||||||||||
| got = 0; | ||||||||||||||||||||||||||||||||||
| goto done; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||
|
|
@@ -2431,7 +2444,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, | |||||||||||||||||||||||||||||||||
| } while (err.ssl == SSL_ERROR_WANT_READ || | ||||||||||||||||||||||||||||||||||
| err.ssl == SSL_ERROR_WANT_WRITE); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (retval == 0) { | ||||||||||||||||||||||||||||||||||
| if (got == 0) { | ||||||||||||||||||||||||||||||||||
| PySSL_SetError(self, retval, __FILE__, __LINE__); | ||||||||||||||||||||||||||||||||||
| goto error; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
@@ -2441,11 +2454,11 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, | |||||||||||||||||||||||||||||||||
| done: | ||||||||||||||||||||||||||||||||||
| Py_XDECREF(sock); | ||||||||||||||||||||||||||||||||||
| if (!group_right_1) { | ||||||||||||||||||||||||||||||||||
| _PyBytes_Resize(&dest, count); | ||||||||||||||||||||||||||||||||||
| _PyBytes_Resize(&dest, got); | ||||||||||||||||||||||||||||||||||
| return dest; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| return PyLong_FromSize_t(count); | ||||||||||||||||||||||||||||||||||
| return PyLong_FromSize_t(got); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| error: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.