-
Notifications
You must be signed in to change notification settings - Fork 180
Remove race condition when creating new HTTPChannel #435
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
Conversation
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.
Calling handle_close() multiple times does not hurt anything, and is safe.
ef3833d to
ff7e3c1
Compare
This avoids calling close() twice on the same socket if self.close() or self.handle_close() is called multiple times
ff7e3c1 to
9d99c89
Compare
|
@digitalresistor it's been running for a few weeks with no problem. the pentests still happen and we haven't see any problems. |
|
great, find and thanks for fixing this. We have been running a server at https://tests.stockfishchess.org/tests that almost reads like the description of the testcase in #418 (comment) and have seen this happen multiple times in the past, if the load on the server was high (with dropped connections by nginx / nginx reboots), almost on a daily basis (most recently discussed as official-stockfish/fishtest#2094 ... but we had no real clue). We'd be happy to upgrade waitress to an eventual 3.0.1 as mentioned in 3495674 . Is there a timeline for that (also in light of the green CI)? |
3.0.2 (2024-11-16) Security - When using Waitress to process trusted proxy headers, Waitress will now update the headers to drop any untrusted values, thereby making sure that WSGI apps only get trusted and validated values that Waitress itself used to update the environ. See Pylons/waitress#452 and Pylons/waitress#451 3.0.1 (2024-10-28) Backward Incompatibilities - Python 3.8 is no longer supported. See Pylons/waitress#445. Features - Added support for Python 3.13. See Pylons/waitress#445. Security - Fix a bug that would lead to Waitress busy looping on select() on a half-open socket due to a race condition that existed when creating a new HTTPChannel. See Pylons/waitress#435, Pylons/waitress#418 and GHSA-3f84-rpwh-47g6 With thanks to Dylan Jay and Dieter Maurer for their extensive debugging and helping track this down. - No longer strip the header values before passing them to the WSGI environ. See Pylons/waitress#434 and Pylons/waitress#432 - Fix a race condition in Waitress when `channel_request_lookahead` is enabled that could lead to HTTP request smuggling.
Both 3.0.1 and 3.0.2 fix security issues. In 3.0.1: * Fix a bug that would lead to Waitress busy looping on select() on a half-open socket due to a race condition that existed when creating a new HTTPChannel. See Pylons/waitress#435, Pylons/waitress#418 and GHSA-3f84-rpwh-47g6 * With thanks to Dylan Jay and Dieter Maurer for their extensive debugging and helping track this down. * No longer strip the header values before passing them to the WSGI environ. See Pylons/waitress#434 and Pylons/waitress#432 * Fix a race condition in Waitress when channel_request_lookahead is enabled that could lead to HTTP request smuggling. See GHSA-9298-4cf8-g4wj In 3.0.2: * When using Waitress to process trusted proxy headers, Waitress will now update the headers to drop any untrusted values, thereby making sure that WSGI apps only get trusted and validated values that Waitress itself used to update the environ. See Pylons/waitress#452 and Pylons/waitress#451 Full Changelog: https://docs.pylonsproject.org/projects/waitress/en/latest/#change-history Signed-off-by: Marcus Hoffmann <buildroot@bubu1.eu> Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
When we
accept()a connection we get the remote address and we pass it toHTTPChannel, then inwasyncore.dispatcherwe were callinggetpeername()again to get the same remote address that we already had.This would cause an issue if the remote client had sent data, but closed the connection before
getpeername()because thewasyncore.dispatcherwould set the channel to no longer being connected.Further down the line this would cause issues whereby
handle_writewould loop over and over because it would mark itself as selectable but the socket would never actually get torn down.Closes #418
Supersedes #419