classification
Title: ssl.SSLError: Invalid error code (_ssl.c:2217)
Type: behavior Stage: resolved
Components: SSL Versions: Python 3.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: SSLSocket read/write thread-unsafety
View: 32533
Assigned To: steve.dower Nosy List: christian.heimes, devkid, steve.dower
Priority: normal Keywords:

Created on 2018-03-16 21:22 by devkid, last changed 2018-09-21 20:48 by steve.dower. This issue is now closed.

Messages (2)
msg313973 - (view) Author: Alfred Krohmer (devkid) Date: 2018-03-16 21:22
OpenSSL version: 1.1.0.g-1
OS: Arch Linux

I'm creating an SSL socket like this:

    s = socket.create_connection((self.host, 443), 60)
    c = ssl.create_default_context()
    c.set_alpn_protocols(['spdy/2'])
    self.ss = c.wrap_socket(s, server_hostname=self.host)

I'm then reading from the socket in one thread and writing to it in another thread.

I'm experiencing strange behaviour.

Sometimes I randomly get the error message in the title when invoking self.ss.recv(). After investigating the exception, I found that exc.errno = 10, which, according to the OpenSSL documentation means SSL_ERROR_WANT_ASYNC_JOB. This constant is never used in the _ssl.c file in cpython. This seems to me like an OpenSSL error that needs to be handled in the Python implementation but is not.

Also sometimes I have random write timeouts when invoking self.ss.send() (in those cases it seems unlikely to me that those are caused by the server).

Also I found here:

https://github.com/python/cpython/blob/v3.6.4/Modules/_ssl.c#L2184

that Python uses SSL_get_error in an non-mutex locked section. But the OpenSSL documentation of SSL_get_error states the following:

    In addition to ssl and ret, SSL_get_error() inspects the current thread's OpenSSL error queue. Thus, SSL_get_error() must be used in the same thread that performed the TLS/SSL I/O operation, and no other OpenSSL function calls should appear in between. The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably.

According to that, shouldn't the _PySSL_UPDATE_ERRNO_IF macro be called *after* PySSL_END_ALLOW_THREADS?
msg313993 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2018-03-17 10:38
Steve, this sounds like a duplicate of #32533.
History
Date User Action Args
2018-09-21 20:48:13steve.dowersetstatus: open -> closed
superseder: SSLSocket read/write thread-unsafety
resolution: duplicate
stage: resolved
2018-03-17 10:38:52christian.heimessetassignee: christian.heimes -> steve.dower

messages: + msg313993
nosy: + steve.dower
2018-03-16 21:22:01devkidcreate