From db12c082ea01237d711d54e52d1589397c8c5b75 Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Fri, 12 Jan 2024 11:10:52 +0800 Subject: [PATCH] Fix CVE-2024-21647 --- CVE-2024-21647.patch | 103 +++++++++++++++++++++++++++++++++++++++++++ rubygem-puma.spec | 7 ++- 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 CVE-2024-21647.patch diff --git a/CVE-2024-21647.patch b/CVE-2024-21647.patch new file mode 100644 index 0000000..7925db0 --- /dev/null +++ b/CVE-2024-21647.patch @@ -0,0 +1,103 @@ +From bbb880ffb6debbfdea535b4b3eb2204d49ae151d Mon Sep 17 00:00:00 2001 +From: Nate Berkopec +Date: Mon, 8 Jan 2024 14:48:43 +0900 +Subject: [PATCH] Merge pull request from GHSA-c2f4-cvqm-65w2 + +Origin: https://github.com/puma/puma/commit/bbb880ffb6debbfdea535b4b3eb2204d49ae151d + +Co-authored-by: MSP-Greg +Co-authored-by: Patrik Ragnarsson +Co-authored-by: Evan Phoenix + +--- + lib/puma/client.rb | 27 +++++++++++++++++++++++++++ + test/test_puma_server.rb | 14 ++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/lib/puma/client.rb b/lib/puma/client.rb +index 0741107..9746bd4 100644 +--- a/lib/puma/client.rb ++++ b/lib/puma/client.rb +@@ -40,6 +40,14 @@ module Puma + # no body share this one object since it has no state. + EmptyBody = NullIO.new + ++ # The maximum number of bytes we'll buffer looking for a valid ++ # chunk header. ++ MAX_CHUNK_HEADER_SIZE = 4096 ++ ++ # The maximum amount of excess data the client sends ++ # using chunk size extensions before we abort the connection. ++ MAX_CHUNK_EXCESS = 16 * 1024 ++ + include Puma::Const + extend Forwardable + +@@ -427,6 +435,7 @@ module Puma + @chunked_body = true + @partial_part_left = 0 + @prev_chunk = "" ++ @excess_cr = 0 + + @body = Tempfile.new(Const::PUMA_TMP_BASE) + @body.unlink +@@ -496,6 +505,20 @@ module Puma + end + end + ++ # Track the excess as a function of the size of the ++ # header vs the size of the actual data. Excess can ++ # go negative (and is expected to) when the body is ++ # significant. ++ # The additional of chunk_hex.size and 2 compensates ++ # for a client sending 1 byte in a chunked body over ++ # a long period of time, making sure that that client ++ # isn't accidentally eventually punished. ++ @excess_cr += (line.size - len - chunk_hex.size - 2) ++ ++ if @excess_cr >= MAX_CHUNK_EXCESS ++ raise HttpParserError, "Maximum chunk excess detected" ++ end ++ + len += 2 + + part = io.read(len) +@@ -518,6 +541,10 @@ module Puma + @partial_part_left = len - part.size + end + else ++ if @prev_chunk.size + chunk.size >= MAX_CHUNK_HEADER_SIZE ++ raise HttpParserError, "maximum size of chunk header exceeded" ++ end ++ + @prev_chunk = line + return false + end +diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb +index bfa2b97..f179757 100644 +--- a/test/test_puma_server.rb ++++ b/test/test_puma_server.rb +@@ -645,6 +645,20 @@ EOF + end + end + ++ def test_large_chunked_request_header ++ server_run(environment: :production) { |env| ++ [200, {}, [""]] ++ } ++ ++ max_chunk_header_size = Puma::Client::MAX_CHUNK_HEADER_SIZE ++ header = "GET / HTTP/1.1\r\nConnection: close\r\nContent-Length: 200\r\nTransfer-Encoding: chunked\r\n\r\n" ++ socket = send_http "#{header}1;t#{'x' * (max_chunk_header_size + 2)}" ++ ++ data = socket.read ++ ++ assert_match "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\n\r\n", data ++ end ++ + def test_chunked_request_pause_before_value + body = nil + content_length = nil +-- +2.33.0 + diff --git a/rubygem-puma.spec b/rubygem-puma.spec index 86fa6b6..a97db29 100644 --- a/rubygem-puma.spec +++ b/rubygem-puma.spec @@ -2,7 +2,7 @@ %bcond_with ragel Name: rubygem-%{gem_name} Version: 5.5.2 -Release: 2 +Release: 3 Summary: A simple, fast, threaded, and highly concurrent HTTP 1.1 server License: BSD-3-Clause URL: http://puma.io @@ -14,6 +14,7 @@ Patch0: rubygem-puma-3.6.0-crypto-policy-cipher-list.patch Patch1: Support-for-cert_pem-and-key_pem-with-ssl_bind-DSL.patch # https://github.com/puma/puma/commit/b70f451fe8abc0cff192c065d549778452e155bb Patch2: CVE-2022-23634.patch +Patch3: CVE-2024-21647.patch BuildRequires: openssl-devel ruby(release) rubygems-devel ruby-devel rubygem(rack) BuildRequires: rubygem(minitest) rubygem(sd_notify) @@ -38,6 +39,7 @@ Documentation for %{name}. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %if %{with ragel} rm -f ext/puma_http11/http11_parser.c @@ -122,6 +124,9 @@ ruby -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' %{gem_instdir}/tools %changelog +* Fri Jan 12 2024 wangkai <13474090681@163.com> - 5.5.2-3 +- Fix CVE-2024-21647 + * Tue Dec 19 2023 yaoxin - 5.5.2-2 - Fix CVE-2022-23634 -- Gitee