From 6fb703f3ec9c603438120a19e7f5e6318007cd49 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 15 Apr 2026 11:44:12 +0200 Subject: [PATCH] gh-148292: Update SSLSocket.read() for OpenSSL 4 Add _got_eof attribute to avoid calling SSL_read_ex() again after SSL_ERROR_EOF. --- Lib/ssl.py | 24 +++++++++++++------ ...-04-15-11-47-30.gh-issue-148292.sT3JZE.rst | 2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-15-11-47-30.gh-issue-148292.sT3JZE.rst diff --git a/Lib/ssl.py b/Lib/ssl.py index 896db17baeb3db..31f4b3cd76a0d0 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -1037,6 +1037,7 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True, self.server_hostname = context._encode_hostname(server_hostname) self.do_handshake_on_connect = do_handshake_on_connect self.suppress_ragged_eofs = suppress_ragged_eofs + self._got_eof = False # See if we are connected try: @@ -1149,19 +1150,28 @@ def read(self, len=1024, buffer=None): self._checkClosed() if self._sslobj is None: raise ValueError("Read on closed or unwrapped SSL socket.") + if self._got_eof: + # gh-148292: On OpenSSL 4, calling SSL_read_ex() again after + # SSL_ERROR_EOF fails with "A failure in the SSL library occurred" + if buffer is not None: + return 0 + else: + return b'' + try: if buffer is not None: return self._sslobj.read(len, buffer) else: return self._sslobj.read(len) except SSLError as x: - if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: - if buffer is not None: - return 0 - else: - return b'' - else: - raise + if x.args[0] == SSL_ERROR_EOF: + self._got_eof = True + if self.suppress_ragged_eofs: + if buffer is not None: + return 0 + else: + return b'' + raise def write(self, data): """Write DATA to the underlying SSL channel. Returns diff --git a/Misc/NEWS.d/next/Library/2026-04-15-11-47-30.gh-issue-148292.sT3JZE.rst b/Misc/NEWS.d/next/Library/2026-04-15-11-47-30.gh-issue-148292.sT3JZE.rst new file mode 100644 index 00000000000000..496683f0822863 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-15-11-47-30.gh-issue-148292.sT3JZE.rst @@ -0,0 +1,2 @@ +Update :meth:`ssl.SSLSocket.read` for OpenSSL 4: no longer call +``SSL_read_ex()`` after ``SSL_ERROR_EOF``. Patch by Victor Stinner.