GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Attach the passed socket before awaiting connection_made by bozhko-egor · Pull Request #786 · MagicStack/uvloop

Conversation

@bozhko-egor

@bozhko-egor bozhko-egor commented Oct 26, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Fixes #785

create_connection(sock=) and create_unix_connection(sock=) attached the passed socket to the transport only after await waiter. If the peer resets the connection before the TLS ClientHello is written, connection_lost() closes the transport before the coroutine resumes. The socket was then never detached: it kept the closed fd number and closed it again when garbage-collected, possibly closing an unrelated connection that reused the fd.

This PR attaches the socket right after tr._open(), so every close path detaches it, as on the success path. The existing sock.detach() in the except branch is unchanged; if the socket is already detached, it returns -1.

The same bug happens without TLS when the protocol aborts the transport in connection_made(): create_connection(sock=) then returns normally, but the socket keeps the closed fd number.

Tests:

  • test_create_connection_sock_abort_detaches (tests/test_tcp.py) and test_create_unix_connection_sock_abort_detaches (tests/test_unix.py): the protocol calls transport.abort() in connection_made().
  • test_create_connection_ssl_sock_reset_detaches (tests/test_tcp.py): the server resets the connection with SO_LINGER 0, and the client calls create_connection(sock=, ssl=) after the RST has arrived.
  • test_create_unix_connection_ssl_sock_closed_detaches (tests/test_unix.py): the same for a Unix socket, where the ClientHello write fails with EPIPE.

All tests check sock.fileno() == -1 and run for uvloop and asyncio. On master the uvloop variants fail with 13 != -1 on Linux. With this change they pass (also with PYTHONASYNCIODEBUG=1), and the full test suite passes (python:3.12-slim, 535 tests).

AI disclosure: the fix and tests were made with AI assistance (Claude). I ran them as described above.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
bozhko-egor added 2 commits October 26, 2026 19:51
@bozhko-egor
Attach the passed socket before awaiting connection_made
52cb56b
If the peer resets the connection before the TLS ClientHello is
written, connection_lost() closes the transport before
create_connection(sock=) resumes. The socket was attached only after
`await waiter`, so it was never detached: it kept the closed fd number
and closed it again when garbage-collected, possibly closing an
unrelated connection that reused the fd.

Attach the socket right after `tr._open()`, so every close path
detaches it. The same change is applied to create_unix_connection().

Fixes MagicStack#785
@bozhko-egor
Add non-TLS tests for aborting in connection_made
3ef819f
The same bug happens without TLS when the protocol aborts the
transport in connection_made(): create_connection(sock=) returns
normally, but the socket keeps the closed fd number.
@fed239

fed239 commented Oct 27, 2026

Copy link
Copy Markdown

@1st1 @elprans @fantix @graingert we need your help with this PR. We've spot the vulnerable behaviour in our application and we trust it affects other applications, so I'm calling for immediate attention. Thank you!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Vizonex
Vizonex approved these changes Nov 8, 2026
View reviewed changes

@Vizonex Vizonex left a comment

Copy link
Copy Markdown

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.

Seems to make sense to me why we would want to attach a socket to end of each pending connection. Unfortunately the other contributors are not here so I'll approve this PR in the meantime.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

1 more reviewer
@Vizonex Vizonex Vizonex approved these changes
Reviewers whose approvals may not affect merge requirements

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

create_connection(sock=, ssl=): reset before TLS handshake causes fd double-close and response leakage

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@bozhko-egor @fed239 @Vizonex
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.