This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: SSLWantWriteError being raised by blocking SSL socket
Type: behavior Stage:
Components: Library (Lib), SSL Versions: Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: alex, altendky, christian.heimes, dstufft, janssen, njs, pitrou
Priority: normal Keywords:

Created on 2017-12-05 04:01 by njs, last changed 2022-04-11 14:58 by admin.

Messages (6)
msg307634 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2017-12-05 04:01
I have a test case that sets up a blocking SSLSocket, and eventually calls unwrap() to do a proper SSL shutdown.

Every once in a while, the test blows up, because unwrap() unexpectedly raises SSLWantWriteError. This is very unexpected for a blocking socket.

Unfortunately, since this is intermittent, I don't have a reliable reproducer.

Both of the times I've seen this so far, it was on MacOS with CPython 3.6 (the official python.org build, so whichever openssl it uses), and it was specifically in unwrap():

    https://travis-ci.org/python-trio/trio/jobs/298164123
    https://travis-ci.org/python-trio/trio/jobs/311618077

Here's the code that fails -- as you can see it's just a straightforward blocking echo server using SSLContext.wrap_socket:

    https://github.com/python-trio/trio/blob/3e62bf64946b1dcbf42c2d03e39435d4b1ba00ac/trio/tests/test_ssl.py#L92
msg307636 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2017-12-05 04:05
Oh darn, I restarted the 311618077 build on Travis and apparently that makes it delete the log. Well, it was the same traceback as the one that's left, but triggered by a different test.
msg307648 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2017-12-05 08:44
You might want to add debugging code in _ssl__SSLSocket_shutdown_impl() (Modules/_ssl.c) and see what happens exactly.

Does your socket have a timeout?  If not, you may want to ask the OpenSSL mailing-list whether it's possible for SSL_shutdown to return SSL_ERROR_WANT_WRITE on a blocking socket...

PS: it seems the _ssl module doesn't retry I/O routines on EINTR. See also https://stackoverflow.com/questions/24188013/openssl-and-signals
msg307655 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2017-12-05 11:10
There's no timeout. The man page claims SSL_ERROR_WANT_WRITE can't happen on a blocking socket, but who knows...

Re: EINTR, this is all happening in a child thread. On Linux, this would mean that it almost certainly isn't receiving any signals. I'm not sure about MacOS, though. (POSIX allows signals to be delivered to any thread, but most Unixes are much more conservative in practice.)
msg391304 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-04-17 18:49
Nathaniel, is this still an issue with recent OpenSSL and Python versions?
msg391307 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2021-04-17 19:26
I don't know :-( After filing this upstream we started ignoring these exceptions, to make our CI less flaky: https://github.com/python-trio/trio/pull/365/files

But unfortunately that means I don't know if we've been hitting them since then or not.
History
Date User Action Args
2022-04-11 14:58:55adminsetgithub: 76400
2021-06-11 13:48:18altendkysetnosy: + altendky
2021-04-17 19:26:11njssetstatus: pending -> open

messages: + msg391307
2021-04-17 18:49:26christian.heimessetstatus: open -> pending

messages: + msg391304
2017-12-05 11:10:00njssetmessages: + msg307655
2017-12-05 08:44:10pitrousetversions: + Python 3.7
nosy: + pitrou

messages: + msg307648

components: + Library (Lib)
type: behavior
2017-12-05 04:05:42njssetmessages: + msg307636
2017-12-05 04:01:08njscreate