File CVE-2019-16770.patch of Package rubygem-puma.16022

From 62969a4cdc741fbcb8455204772ffd9a11876cc6 Mon Sep 17 00:00:00 2001
From: Nate Berkopec <nate.berkopec@gmail.com>
Date: Thu, 5 Dec 2019 14:19:32 +0700
Subject: [PATCH] Merge pull request from GHSA-7xx3-m584-x994

could monopolize a thread. Previously, this could make a DoS attack more
severe.

Co-authored-by: Evan Phoenix <evan@phx.io>
---
 lib/puma/const.rb  |  7 +++++++
 lib/puma/server.rb | 16 +++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/lib/puma/const.rb b/lib/puma/const.rb
index 3597bb03..a2c5be05 100644
--- a/lib/puma/const.rb
+++ b/lib/puma/const.rb
@@ -116,6 +116,13 @@ module Puma
     # sending data back
     WRITE_TIMEOUT = 10
 
+    # How many requests to attempt inline before sending a client back to
+    # the reactor to be subject to normal ordering. The idea here is that
+    # we amortize the cost of going back to the reactor for a well behaved
+    # but very "greedy" client across 10 requests. This prevents a not
+    # well behaved client from monopolizing the thread forever.
+    MAX_FAST_INLINE = 10
+
     # The original URI requested by the client.
     REQUEST_URI= 'REQUEST_URI'.freeze
     REQUEST_PATH = 'REQUEST_PATH'.freeze
diff --git a/lib/puma/server.rb b/lib/puma/server.rb
index fe5eb070..293342c1 100644
--- a/lib/puma/server.rb
+++ b/lib/puma/server.rb
@@ -442,6 +442,8 @@ module Puma
         clean_thread_locals = @options[:clean_thread_locals]
         close_socket = true
 
+        requests = 0
+
         while true
           case handle_request(client, buffer)
           when false
@@ -455,7 +457,19 @@ module Puma
 
             ThreadPool.clean_thread_locals if clean_thread_locals
 
-            unless client.reset(@status == :run)
+            requests += 1
+
+            check_for_more_data = @status == :run
+
+            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
+
+            unless client.reset(check_for_more_data)
               close_socket = false
               client.set_timeout @persistent_timeout
               @reactor.add client
-- 
2.26.2

openSUSE Build Service is sponsored by