From b4ad7681b59aaac81f79efbf269b3e4c95ec673c Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Wed, 3 Apr 2024 01:06:27 +0800 Subject: [PATCH] Fix CVE-2024-31309 (cherry picked from commit 7958294bf09fa1decd0960001fa0cc93c76b8379) --- CVE-2024-31309.patch | 407 +++++++++++++++++++++++++++++++++++++++++++ trafficserver.spec | 6 +- 2 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 CVE-2024-31309.patch diff --git a/CVE-2024-31309.patch b/CVE-2024-31309.patch new file mode 100644 index 0000000..621c849 --- /dev/null +++ b/CVE-2024-31309.patch @@ -0,0 +1,407 @@ +From b8c6a23b74af1772e5cb0de25b38c234a418cb1d Mon Sep 17 00:00:00 2001 +From: Masakazu Kitajo +Date: Wed, 3 Apr 2024 09:31:37 -0600 +Subject: [PATCH] proxy.config.http2.max_continuation_frames_per_minute + (#11206) + +Origin: https://github.com/apache/trafficserver/commit/b8c6a23b74af1772e5cb0de25b38c234a418cb1d + +This adds the ability to rate limite HTTP/2 CONTINUATION frames per +stream per minute. + +Co-authored-by: Brian Neradt +--- + doc/admin-guide/files/records.config.en.rst | 11 +++- + .../statistics/core/http-connection.en.rst | 11 +++- + iocore/net/P_SNIActionPerformer.h | 17 +++++ + iocore/net/SSLSNIConfig.cc | 4 ++ + iocore/net/TLSSNISupport.h | 1 + + iocore/net/YamlSNIConfig.cc | 4 ++ + iocore/net/YamlSNIConfig.h | 2 + + mgmt/RecordsConfig.cc | 2 + + proxy/http2/HTTP2.cc | 66 ++++++++++--------- + proxy/http2/HTTP2.h | 2 + + proxy/http2/Http2ConnectionState.cc | 36 ++++++++-- + proxy/http2/Http2ConnectionState.h | 12 ++-- + 12 files changed, 126 insertions(+), 42 deletions(-) + +diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst +index f3df888708e..979c8bda2f4 100644 +--- a/doc/admin-guide/files/records.config.en.rst ++++ b/doc/admin-guide/files/records.config.en.rst +@@ -4287,8 +4287,15 @@ HTTP/2 Configuration +-.. ts:cv:: CONFIG proxy.config.http2.max_rst_stream_frames_per_minute INT 14 ++.. ts:cv:: CONFIG proxy.config.http2.max_rst_stream_frames_per_minute INT 200 + :reloadable: + +- Specifies how many RST_STREAM frames |TS| receives for a minute at maximum. +- Clients exceeded this limit will be immediately disconnected with an error ++ Specifies how many RST_STREAM frames |TS| receives per minute at maximum. ++ Clients exceeding this limit will be immediately disconnected with an error ++ code of ENHANCE_YOUR_CALM. ++ ++.. ts:cv:: CONFIG proxy.config.http2.max_continuation_frames_per_minute INT 120 ++ :reloadable: ++ ++ Specifies how many CONTINUATION frames |TS| receives per minute at maximum. ++ Clients exceeding this limit will be immediately disconnected with an error + code of ENHANCE_YOUR_CALM. + + .. ts:cv:: CONFIG proxy.config.http2.min_avg_window_update FLOAT 2560.0 +diff --git a/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst b/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst +index b22da8e1c66..ee47a147c01 100644 +--- a/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst ++++ b/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst +@@ -263,10 +263,17 @@ HTTP/2 + .. ts:stat:: global proxy.process.http2.max_rst_stream_frames_per_minute_exceeded integer + :type: counter + +- Represents the total number of closed HTTP/2 connections for exceeding the +- maximum allowed number of rst_stream frames per minute limit which is configured by ++ Represents the total number of HTTP/2 connections closed for exceeding the ++ maximum allowed number of ``RST_STREAM`` frames per minute limit which is configured by + :ts:cv:`proxy.config.http2.max_rst_stream_frames_per_minute`. + ++.. ts:stat:: global proxy.process.http2.max_continuation_frames_per_minute_exceeded integer ++ :type: counter ++ ++ Represents the total number of HTTP/2 connections closed for exceeding the ++ maximum allowed number of ``CONTINUATION`` frames per minute limit which is ++ configured by :ts:cv:`proxy.config.http2.max_continuation_frames_per_minute`. ++ + .. ts:stat:: global proxy.process.http2.insufficient_avg_window_update integer + :type: counter + +diff --git a/iocore/net/P_SNIActionPerformer.h b/iocore/net/P_SNIActionPerformer.h +index e223ac7d0ba..eebe44b75a1 100644 +--- a/iocore/net/P_SNIActionPerformer.h ++++ b/iocore/net/P_SNIActionPerformer.h +@@ -186,6 +186,23 @@ class HTTP2MaxRstStreamFramesPerMinute : public ActionItem + int value = -1; + }; + ++class HTTP2MaxContinuationFramesPerMinute : public ActionItem ++{ ++public: ++ HTTP2MaxContinuationFramesPerMinute(int value) : value(value) {} ++ ~HTTP2MaxContinuationFramesPerMinute() override {} ++ ++ int ++ SNIAction(TLSSNISupport *snis, const Context &ctx) const override ++ { ++ snis->hints_from_sni.http2_max_continuation_frames_per_minute = value; ++ return SSL_TLSEXT_ERR_OK; ++ } ++ ++private: ++ int value = -1; ++}; ++ + class TunnelDestination : public ActionItem + { + public: +diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc +index a7071013f6a..942e6c420f0 100644 +--- a/iocore/net/SSLSNIConfig.cc ++++ b/iocore/net/SSLSNIConfig.cc +@@ -151,6 +151,10 @@ SNIConfigParams::load_sni_config() + ai->actions.push_back( + std::make_unique(item.http2_max_rst_stream_frames_per_minute.value())); + } ++ if (item.http2_max_continuation_frames_per_minute.has_value()) { ++ ai->actions.push_back( ++ std::make_unique(item.http2_max_continuation_frames_per_minute.value())); ++ } + + ai->actions.push_back(std::make_unique(item.ip_allow, item.fqdn)); + +diff --git a/iocore/net/TLSSNISupport.h b/iocore/net/TLSSNISupport.h +index ba2d13e9300..e8614ffa9b8 100644 +--- a/iocore/net/TLSSNISupport.h ++++ b/iocore/net/TLSSNISupport.h +@@ -56,6 +56,7 @@ class TLSSNISupport + std::optional http2_max_ping_frames_per_minute; + std::optional http2_max_priority_frames_per_minute; + std::optional http2_max_rst_stream_frames_per_minute; ++ std::optional http2_max_continuation_frames_per_minute; + } hints_from_sni; + + protected: +diff --git a/iocore/net/YamlSNIConfig.cc b/iocore/net/YamlSNIConfig.cc +index 9a777b806f2..7286197c9c7 100644 +--- a/iocore/net/YamlSNIConfig.cc ++++ b/iocore/net/YamlSNIConfig.cc +@@ -148,6 +148,7 @@ std::set valid_sni_config_keys = {TS_fqdn, + TS_http2_max_ping_frames_per_minute, + TS_http2_max_priority_frames_per_minute, + TS_http2_max_rst_stream_frames_per_minute, ++ TS_http2_max_continuation_frames_per_minute, + TS_ip_allow, + #if TS_USE_HELLO_CB || defined(OPENSSL_IS_BORINGSSL) + TS_valid_tls_versions_in, +@@ -193,6 +194,9 @@ template <> struct convert { + if (node[TS_http2_max_rst_stream_frames_per_minute]) { + item.http2_max_rst_stream_frames_per_minute = node[TS_http2_max_rst_stream_frames_per_minute].as(); + } ++ if (node[TS_http2_max_continuation_frames_per_minute]) { ++ item.http2_max_continuation_frames_per_minute = node[TS_http2_max_continuation_frames_per_minute].as(); ++ } + + // enum + if (node[TS_verify_client]) { +diff --git a/iocore/net/YamlSNIConfig.h b/iocore/net/YamlSNIConfig.h +index b297bd5c16e..8165dc336c5 100644 +--- a/iocore/net/YamlSNIConfig.h ++++ b/iocore/net/YamlSNIConfig.h +@@ -60,6 +60,7 @@ TSDECL(http2_max_settings_frames_per_minute); + TSDECL(http2_max_ping_frames_per_minute); + TSDECL(http2_max_priority_frames_per_minute); + TSDECL(http2_max_rst_stream_frames_per_minute); ++TSDECL(http2_max_continuation_frames_per_minute); + TSDECL(host_sni_policy); + #undef TSDECL + +@@ -94,6 +95,7 @@ struct YamlSNIConfig { + std::optional http2_max_ping_frames_per_minute; + std::optional http2_max_priority_frames_per_minute; + std::optional http2_max_rst_stream_frames_per_minute; ++ std::optional http2_max_continuation_frames_per_minute; + + bool tunnel_prewarm_srv = false; + uint32_t tunnel_prewarm_min = 0; +diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc +index b63e0523c2b..a3752ea8359 100644 +--- a/mgmt/RecordsConfig.cc ++++ b/mgmt/RecordsConfig.cc +@@ -1395,6 +1395,8 @@ static const RecordElement RecordsConfig[] = + , + {RECT_CONFIG, "proxy.config.http2.max_rst_stream_frames_per_minute", RECD_INT, "200", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} + , ++ {RECT_CONFIG, "proxy.config.http2.max_continuation_frames_per_minute", RECD_INT, "120", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} ++ , + {RECT_CONFIG, "proxy.config.http2.min_avg_window_update", RECD_FLOAT, "2560.0", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} + , + {RECT_CONFIG, "proxy.config.http2.header_table_size_limit", RECD_INT, "65536", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} +diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc +index 04813d2212b..a3a5a0ac781 100644 +--- a/proxy/http2/HTTP2.cc ++++ b/proxy/http2/HTTP2.cc +@@ -85,6 +85,8 @@ static const char *const HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED_NAME + "proxy.process.http2.max_priority_frames_per_minute_exceeded"; + static const char *const HTTP2_STAT_MAX_RST_STREAM_FRAMES_PER_MINUTE_EXCEEDED_NAME = + "proxy.process.http2.max_rst_stream_frames_per_minute_exceeded"; ++static const char *const HTTP2_STAT_MAX_CONTINUATION_FRAMES_PER_MINUTE_EXCEEDED_NAME = ++ "proxy.process.http2.max_continuation_frames_per_minute_exceeded"; + static const char *const HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE_NAME = "proxy.process.http2.insufficient_avg_window_update"; + static const char *const HTTP2_STAT_MAX_CONCURRENT_STREAMS_EXCEEDED_IN_NAME = + "proxy.process.http2.max_concurrent_streams_exceeded_in"; +@@ -798,36 +800,37 @@ http2_decode_header_blocks(HTTPHdr *hdr, const uint8_t *buf_start, const uint32_ + } + + // Initialize this subsystem with librecords configs (for now) +-uint32_t Http2::max_concurrent_streams_in = 100; +-uint32_t Http2::min_concurrent_streams_in = 10; +-uint32_t Http2::max_active_streams_in = 0; +-bool Http2::throttling = false; +-uint32_t Http2::stream_priority_enabled = 0; +-uint32_t Http2::initial_window_size = 65535; +-uint32_t Http2::max_frame_size = 16384; +-uint32_t Http2::header_table_size = 4096; +-uint32_t Http2::max_header_list_size = 4294967295; +-uint32_t Http2::accept_no_activity_timeout = 120; +-uint32_t Http2::no_activity_timeout_in = 120; +-uint32_t Http2::active_timeout_in = 0; +-uint32_t Http2::push_diary_size = 256; +-uint32_t Http2::zombie_timeout_in = 0; +-float Http2::stream_error_rate_threshold = 0.1; +-uint32_t Http2::stream_error_sampling_threshold = 10; +-uint32_t Http2::max_settings_per_frame = 7; +-uint32_t Http2::max_settings_per_minute = 14; +-uint32_t Http2::max_settings_frames_per_minute = 14; +-uint32_t Http2::max_ping_frames_per_minute = 60; +-uint32_t Http2::max_priority_frames_per_minute = 120; +-uint32_t Http2::max_rst_stream_frames_per_minute = 200; +-float Http2::min_avg_window_update = 2560.0; +-uint32_t Http2::con_slow_log_threshold = 0; +-uint32_t Http2::stream_slow_log_threshold = 0; +-uint32_t Http2::header_table_size_limit = 65536; +-uint32_t Http2::write_buffer_block_size = 262144; +-float Http2::write_size_threshold = 0.5; +-uint32_t Http2::write_time_threshold = 100; +-uint32_t Http2::buffer_water_mark = 0; ++uint32_t Http2::max_concurrent_streams_in = 100; ++uint32_t Http2::min_concurrent_streams_in = 10; ++uint32_t Http2::max_active_streams_in = 0; ++bool Http2::throttling = false; ++uint32_t Http2::stream_priority_enabled = 0; ++uint32_t Http2::initial_window_size = 65535; ++uint32_t Http2::max_frame_size = 16384; ++uint32_t Http2::header_table_size = 4096; ++uint32_t Http2::max_header_list_size = 4294967295; ++uint32_t Http2::accept_no_activity_timeout = 120; ++uint32_t Http2::no_activity_timeout_in = 120; ++uint32_t Http2::active_timeout_in = 0; ++uint32_t Http2::push_diary_size = 256; ++uint32_t Http2::zombie_timeout_in = 0; ++float Http2::stream_error_rate_threshold = 0.1; ++uint32_t Http2::stream_error_sampling_threshold = 10; ++uint32_t Http2::max_settings_per_frame = 7; ++uint32_t Http2::max_settings_per_minute = 14; ++uint32_t Http2::max_settings_frames_per_minute = 14; ++uint32_t Http2::max_ping_frames_per_minute = 60; ++uint32_t Http2::max_priority_frames_per_minute = 120; ++uint32_t Http2::max_rst_stream_frames_per_minute = 200; ++uint32_t Http2::max_continuation_frames_per_minute = 120; ++float Http2::min_avg_window_update = 2560.0; ++uint32_t Http2::con_slow_log_threshold = 0; ++uint32_t Http2::stream_slow_log_threshold = 0; ++uint32_t Http2::header_table_size_limit = 65536; ++uint32_t Http2::write_buffer_block_size = 262144; ++float Http2::write_size_threshold = 0.5; ++uint32_t Http2::write_time_threshold = 100; ++uint32_t Http2::buffer_water_mark = 0; + + void + Http2::init() +@@ -853,6 +856,7 @@ Http2::init() + REC_EstablishStaticConfigInt32U(max_ping_frames_per_minute, "proxy.config.http2.max_ping_frames_per_minute"); + REC_EstablishStaticConfigInt32U(max_priority_frames_per_minute, "proxy.config.http2.max_priority_frames_per_minute"); + REC_EstablishStaticConfigInt32U(max_rst_stream_frames_per_minute, "proxy.config.http2.max_rst_stream_frames_per_minute"); ++ REC_EstablishStaticConfigInt32U(max_continuation_frames_per_minute, "proxy.config.http2.max_continuation_frames_per_minute"); + REC_EstablishStaticConfigFloat(min_avg_window_update, "proxy.config.http2.min_avg_window_update"); + REC_EstablishStaticConfigInt32U(con_slow_log_threshold, "proxy.config.http2.connection.slow.log.threshold"); + REC_EstablishStaticConfigInt32U(stream_slow_log_threshold, "proxy.config.http2.stream.slow.log.threshold"); +@@ -923,6 +927,8 @@ Http2::init() + static_cast(HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum); + RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_RST_STREAM_FRAMES_PER_MINUTE_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT, + static_cast(HTTP2_STAT_MAX_RST_STREAM_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum); ++ RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_CONTINUATION_FRAMES_PER_MINUTE_EXCEEDED_NAME, RECD_INT, ++ RECP_PERSISTENT, static_cast(HTTP2_STAT_MAX_CONTINUATION_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum); + RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE_NAME, RECD_INT, RECP_PERSISTENT, + static_cast(HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE), RecRawStatSyncSum); + RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_CONCURRENT_STREAMS_EXCEEDED_IN_NAME, RECD_INT, RECP_PERSISTENT, +diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h +index 5847865a9a4..857b199c05d 100644 +--- a/proxy/http2/HTTP2.h ++++ b/proxy/http2/HTTP2.h +@@ -105,6 +105,7 @@ enum { + HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED, + HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED, + HTTP2_STAT_MAX_RST_STREAM_FRAMES_PER_MINUTE_EXCEEDED, ++ HTTP2_STAT_MAX_CONTINUATION_FRAMES_PER_MINUTE_EXCEEDED, + HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE, + HTTP2_STAT_MAX_CONCURRENT_STREAMS_EXCEEDED_IN, + HTTP2_STAT_MAX_CONCURRENT_STREAMS_EXCEEDED_OUT, +@@ -404,6 +405,7 @@ class Http2 + static uint32_t max_ping_frames_per_minute; + static uint32_t max_priority_frames_per_minute; + static uint32_t max_rst_stream_frames_per_minute; ++ static uint32_t max_continuation_frames_per_minute; + static float min_avg_window_update; + static uint32_t con_slow_log_threshold; + static uint32_t stream_slow_log_threshold; +diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc +index b36e5c11793..b089048eb1d 100644 +--- a/proxy/http2/Http2ConnectionState.cc ++++ b/proxy/http2/Http2ConnectionState.cc +@@ -924,6 +924,18 @@ rcv_continuation_frame(Http2ConnectionState &cstate, const Http2Frame &frame) + } + } + ++ // Update CONTINUATION frame count per minute. ++ cstate.increment_received_continuation_frame_count(); ++ // Close this connection if its CONTINUATION frame count exceeds a limit. ++ if (cstate.configured_max_continuation_frames_per_minute != 0 && ++ cstate.get_received_continuation_frame_count() > cstate.configured_max_continuation_frames_per_minute) { ++ HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_CONTINUATION_FRAMES_PER_MINUTE_EXCEEDED, this_ethread()); ++ Http2StreamDebug(cstate.session, stream_id, "Observed too frequent CONTINUATION frames: %u frames within a last minute", ++ cstate.get_received_continuation_frame_count()); ++ return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM, ++ "reset too frequent CONTINUATION frames"); ++ } ++ + uint32_t header_blocks_offset = stream->header_blocks_length; + stream->header_blocks_length += payload_length; + +@@ -1088,10 +1100,11 @@ Http2ConnectionState::init(Http2CommonSession *ssn) + dependency_tree = new DependencyTree(Http2::max_concurrent_streams_in); + } + +- configured_max_settings_frames_per_minute = Http2::max_settings_frames_per_minute; +- configured_max_ping_frames_per_minute = Http2::max_ping_frames_per_minute; +- configured_max_priority_frames_per_minute = Http2::max_priority_frames_per_minute; +- configured_max_rst_stream_frames_per_minute = Http2::max_rst_stream_frames_per_minute; ++ configured_max_settings_frames_per_minute = Http2::max_settings_frames_per_minute; ++ configured_max_ping_frames_per_minute = Http2::max_ping_frames_per_minute; ++ configured_max_priority_frames_per_minute = Http2::max_priority_frames_per_minute; ++ configured_max_rst_stream_frames_per_minute = Http2::max_rst_stream_frames_per_minute; ++ configured_max_continuation_frames_per_minute = Http2::max_continuation_frames_per_minute; + if (auto snis = dynamic_cast(session->get_netvc()); snis) { + if (snis->hints_from_sni.http2_max_settings_frames_per_minute.has_value()) { + configured_max_settings_frames_per_minute = snis->hints_from_sni.http2_max_settings_frames_per_minute.value(); +@@ -1105,6 +1118,9 @@ Http2ConnectionState::init(Http2CommonSession *ssn) + if (snis->hints_from_sni.http2_max_rst_stream_frames_per_minute.has_value()) { + configured_max_rst_stream_frames_per_minute = snis->hints_from_sni.http2_max_rst_stream_frames_per_minute.value(); + } ++ if (snis->hints_from_sni.http2_max_continuation_frames_per_minute.has_value()) { ++ configured_max_continuation_frames_per_minute = snis->hints_from_sni.http2_max_continuation_frames_per_minute.value(); ++ } + } + + _cop = ActivityCop(this->mutex, &stream_list, 1); +@@ -2140,6 +2156,18 @@ Http2ConnectionState::get_received_rst_stream_frame_count() + return this->_received_rst_stream_frame_counter.get_count(); + } + ++void ++Http2ConnectionState::increment_received_continuation_frame_count() ++{ ++ this->_received_continuation_frame_counter.increment(); ++} ++ ++uint32_t ++Http2ConnectionState::get_received_continuation_frame_count() ++{ ++ return this->_received_continuation_frame_counter.get_count(); ++} ++ + // Return min_concurrent_streams_in when current client streams number is larger than max_active_streams_in. + // Main purpose of this is preventing DDoS Attacks. + unsigned +diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h +index 76d2e2a8e17..fff7763f2a1 100644 +--- a/proxy/http2/Http2ConnectionState.h ++++ b/proxy/http2/Http2ConnectionState.h +@@ -102,10 +102,11 @@ class Http2ConnectionState : public Continuation + Http2ConnectionSettings server_settings; + Http2ConnectionSettings client_settings; + +- uint32_t configured_max_settings_frames_per_minute = 0; +- uint32_t configured_max_ping_frames_per_minute = 0; +- uint32_t configured_max_priority_frames_per_minute = 0; +- uint32_t configured_max_rst_stream_frames_per_minute = 0; ++ uint32_t configured_max_settings_frames_per_minute = 0; ++ uint32_t configured_max_ping_frames_per_minute = 0; ++ uint32_t configured_max_priority_frames_per_minute = 0; ++ uint32_t configured_max_rst_stream_frames_per_minute = 0; ++ uint32_t configured_max_continuation_frames_per_minute = 0; + + void init(Http2CommonSession *ssn); + void send_connection_preface(); +@@ -174,6 +175,8 @@ class Http2ConnectionState : public Continuation + uint32_t get_received_priority_frame_count(); + void increment_received_rst_stream_frame_count(); + uint32_t get_received_rst_stream_frame_count(); ++ void increment_received_continuation_frame_count(); ++ uint32_t get_received_continuation_frame_count(); + + ssize_t client_rwnd() const; + Http2ErrorCode increment_client_rwnd(size_t amount); +@@ -220,6 +223,7 @@ class Http2ConnectionState : public Continuation + Http2FrequencyCounter _received_ping_frame_counter; + Http2FrequencyCounter _received_priority_frame_counter; + Http2FrequencyCounter _received_rst_stream_frame_counter; ++ Http2FrequencyCounter _received_continuation_frame_counter; + + // NOTE: Id of stream which MUST receive CONTINUATION frame. + // - [RFC 7540] 6.2 HEADERS diff --git a/trafficserver.spec b/trafficserver.spec index c6b9c4d..85c7b4a 100644 --- a/trafficserver.spec +++ b/trafficserver.spec @@ -1,7 +1,7 @@ %define _hardened_build 1 Name: trafficserver Version: 9.2.3 -Release: 1 +Release: 2 Summary: Apache Traffic Server, a reverse, forward and transparent HTTP proxy cache License: Apache-2.0 URL: https://trafficserver.apache.org/ @@ -12,6 +12,7 @@ Patch0002: Fix-log-in-debug-mode.patch Patch0003: config-layout-openEuler.patch Patch0004: Modify-storage.config-for-traffic_cache_tool.patch Patch0005: add-riscv-support.patch +Patch0006: CVE-2024-31309.patch BuildRequires: expat-devel hwloc-devel openssl-devel pcre-devel zlib-devel xz-devel BuildRequires: libcurl-devel ncurses-devel gcc gcc-c++ perl-ExtUtils-MakeMaker BuildRequires: libcap-devel cmake libunwind-devel automake chrpath @@ -132,6 +133,9 @@ getent passwd ats >/dev/null || useradd -r -u 176 -g ats -d / -s /sbin/nologin - %{_datadir}/pkgconfig/trafficserver.pc %changelog +* Sun Apr 07 2024 wangkai <13474090681@163.com> - 9.2.3-2 +- Fix CVE-2024-31309 + * Thu Oct 26 2023 wulei - 9.2.3-1 - Update to 9.2.3 -- Gitee