gh-146139: Disable socketpair authentication on WASI (#146140)

Calling `connect(2)` on a non-blocking socket on WASI may leave the socket in a
"connecting" but not yet "connected" state.  In the former case, calling
`getpeername(2)` on it will fail, leading to an unhandled exception in Python.

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Brett Cannon <brett@python.org>
This commit is contained in:
Joel Dice 2026-04-13 15:06:36 -06:00 committed by GitHub
parent d22922c8a7
commit a5b76d53bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -649,18 +649,22 @@ def _fallback_socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
# Authenticating avoids using a connection from something else
# able to connect to {host}:{port} instead of us.
# We expect only AF_INET and AF_INET6 families.
try:
if (
ssock.getsockname() != csock.getpeername()
or csock.getsockname() != ssock.getpeername()
):
raise ConnectionError("Unexpected peer connection")
except:
# getsockname() and getpeername() can fail
# if either socket isn't connected.
ssock.close()
csock.close()
raise
#
# Note that we skip this on WASI because on that platorm the client socket
# may not have finished connecting by the time we've reached this point (gh-146139).
if sys.platform != "wasi":
try:
if (
ssock.getsockname() != csock.getpeername()
or csock.getsockname() != ssock.getpeername()
):
raise ConnectionError("Unexpected peer connection")
except:
# getsockname() and getpeername() can fail
# if either socket isn't connected.
ssock.close()
csock.close()
raise
return (ssock, csock)