-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
gh-109534: fix reference leak when SSL handshake fails #114074
Changes from 1 commit
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 |
---|---|---|
|
@@ -461,7 +461,7 @@ def eof_received(self): | |
logger.debug("%r received EOF", self) | ||
|
||
if self._state == SSLProtocolState.DO_HANDSHAKE: | ||
self._on_handshake_complete(ConnectionResetError) | ||
self._on_handshake_complete(ConnectionResetError()) | ||
|
||
elif self._state == SSLProtocolState.WRAPPED: | ||
self._set_state(SSLProtocolState.FLUSHING) | ||
|
@@ -571,21 +571,17 @@ def _on_handshake_complete(self, handshake_exc): | |
self._handshake_timeout_handle = None | ||
|
||
sslobj = self._sslobj | ||
try: | ||
if handshake_exc is None: | ||
self._set_state(SSLProtocolState.WRAPPED) | ||
else: | ||
raise handshake_exc | ||
|
||
if handshake_exc is None: | ||
self._set_state(SSLProtocolState.WRAPPED) | ||
peercert = sslobj.getpeercert() | ||
except Exception as exc: | ||
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. The exception handler here is intended to (also) catch exceptions raised by 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. In other words: you can't avoid using a 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. Ah! This was my misunderstanding of the problem. It turns out that setting the original try:
if handshake_exc is None:
self._set_state(SSLProtocolState.WRAPPED)
else:
raise handshake_exc
peercert = sslobj.getpeercert()
except Exception as exc:
handshake_exc = None # <--- fixes the problem |
||
else: | ||
self._set_state(SSLProtocolState.UNWRAPPED) | ||
if isinstance(exc, ssl.CertificateError): | ||
if isinstance(handshake_exc, ssl.CertificateError): | ||
msg = 'SSL handshake failed on verifying the certificate' | ||
else: | ||
msg = 'SSL handshake failed' | ||
self._fatal_error(exc, msg) | ||
self._wakeup_waiter(exc) | ||
self._fatal_error(handshake_exc, msg) | ||
self._wakeup_waiter(handshake_exc) | ||
return | ||
|
||
if self._loop.get_debug(): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Fix a reference leak in | ||
:class:`asyncio.selector_events.BaseSelectorEventLoop` when SSL handshakes | ||
fail. Patch contributed by Jamie Phan. |
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.
Hi @mjpieters; This fix caused the ssl-over-ssl test from GH-113214 (PR #113334) to fail and want to make sure I did not break anything on your end.
The test will raise
ConnectionResetError
(viaSSLProtocol.eof_received
) and normally this won'tbe caught by the exception handler in
SSLProtocol._fatal_error
because it is of instanceOSError
. But because we no longer raise the exception inSSLProtocol._on_handshake_complete(exc)
, the exception object is never initialised and theisinstance
doesn't work as intended. ChangedSSLProtocol.eof_received
to pass an exception object and not class to fix this.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.
I'm not an expert in this area, but passing in an instance instead of the class looks fine by me. I did leave a comment on the removal of the
try...except
block however as this did more than just handleraise handshake_exc
.