From 646d7bfa81185b961b4797965f5c7ff0e380bc5c Mon Sep 17 00:00:00 2001 From: Delta Regeer Date: Sun, 3 Mar 2024 16:16:48 -0700 Subject: [PATCH] Assume socket is not connected when passed to wasyncore.dispatcher No longer call getpeername() on the remote socket either, as it is not necessary for any of the places where waitress requires that self.addr in a subclass of the dispatcher needs it. This removes a race condition when setting up a HTTPChannel where we accepted the socket, and know the remote address, yet call getpeername() again which would have the unintended side effect of potentially setting self.connected to False because the remote has already shut down part of the socket. This issue was uncovered in #418, where the server would go into a hard loop because self.connected was used in various parts of the code base. CVE: CVE-2024-49769 Upstream-Status: Backport [https://github.com/Pylons/waitress/commit/840aebce1c4c1bfd9036f402c1f5d5a4d2f4a1c2] Signed-off-by: Gyorgy Sarvari --- src/waitress/wasyncore.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/waitress/wasyncore.py b/src/waitress/wasyncore.py index b3459e0..b5ddce2 100644 --- a/src/waitress/wasyncore.py +++ b/src/waitress/wasyncore.py @@ -298,22 +298,6 @@ class dispatcher: # get a socket from a blocking source. sock.setblocking(0) self.set_socket(sock, map) - self.connected = True - # The constructor no longer requires that the socket - # passed be connected. - try: - self.addr = sock.getpeername() - except OSError as err: - if err.args[0] in (ENOTCONN, EINVAL): - # To handle the case where we got an unconnected - # socket. - self.connected = False - else: - # The socket is broken in some unknown way, alert - # the user and remove it from the map (to prevent - # polling of broken sockets). - self.del_channel(map) - raise else: self.socket = None