rubygem-puma/CVE-2021-29509.patch

46 lines
1.9 KiB
Diff
Raw Normal View History

2021-05-31 11:50:26 +08:00
From 2e9cf0b63b8de904d6ebca9fb1474cf0f979c53b Mon Sep 17 00:00:00 2001
From: Nate Berkopec <nate.berkopec@gmail.com>
Date: Tue, 11 May 2021 07:43:32 -0600
Subject: [PATCH] Close keepalive connections after MAX_FAST_INLINE requests
---
lib/puma/server.rb | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/lib/puma/server.rb b/lib/puma/server.rb
index 5b2cd94..4ce0c74 100644
--- a/lib/puma/server.rb
+++ b/lib/puma/server.rb
@@ -487,15 +487,20 @@ module Puma
requests += 1
- check_for_more_data = @status == :run
+ # Closing keepalive sockets after they've made a reasonable
+ # number of requests allows Puma to service many connections
+ # fairly, even when the number of concurrent connections exceeds
+ # the size of the threadpool. It also allows cluster mode Pumas
+ # to keep load evenly distributed across workers, because clients
+ # are randomly assigned a new worker when opening a new connection.
+ #
+ # Previously, Puma would kick connections in this conditional back
+ # to the reactor. However, because this causes the todo set to increase
+ # in size, the wait_until_full mutex would never unlock, leaving
+ # any additional connections unserviced.
+ break if requests >= MAX_FAST_INLINE
- if requests >= MAX_FAST_INLINE
- # This will mean that reset will only try to use the data it already
- # has buffered and won't try to read more data. What this means is that
- # every client, independent of their request speed, gets treated like a slow
- # one once every MAX_FAST_INLINE requests.
- check_for_more_data = false
- end
+ check_for_more_data = @status == :run
unless client.reset(check_for_more_data)
close_socket = false
--
2.23.0