From a12b9bbd7437444058f879e5f591e28a4e08928e Mon Sep 17 00:00:00 2001 From: roy Date: Fri, 15 Aug 2025 14:41:05 +0800 Subject: [PATCH] Fix CVE-2025-48989 --- CVE-2025-48989.patch | 162 +++++++++++++++++++++++++++++++++++++++++++ tomcat.spec | 6 +- 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 CVE-2025-48989.patch diff --git a/CVE-2025-48989.patch b/CVE-2025-48989.patch new file mode 100644 index 0000000..8295491 --- /dev/null +++ b/CVE-2025-48989.patch @@ -0,0 +1,162 @@ +commit f36b8a4eea4ce8a0bc035079e1d259d29f5eb7bf +Author: Mark Thomas +Date: Thu Jul 31 14:53:16 2025 +0100 + + Update the HTTP/2 overhead documentation - particularly code comments +Origin: https://github.com/apache/tomcat/commit/f36b8a4eea4ce8a0bc035079e1d259d29f5eb7bf + +diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java +index e436fa6938..f2cfd339e0 100644 +--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java ++++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java +@@ -131,6 +131,9 @@ public class Http2AsyncUpgradeHandler extends Http2UpgradeHandler { + log.trace(sm.getString("upgradeHandler.rst.debug", connectionId, Integer.toString(se.getStreamId()), + se.getError(), se.getMessage())); + } ++ ++ increaseOverheadCount(FrameType.RST, getProtocol().getOverheadResetFactor()); ++ + // Write a RST frame + byte[] rstFrame = new byte[13]; + // Length +diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java +index 4f5c356dea..9628f48589 100644 +--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java ++++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java +@@ -582,6 +582,8 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH + se.getError(), se.getMessage())); + } + ++ increaseOverheadCount(FrameType.RST, getProtocol().getOverheadResetFactor()); ++ + // Write a RST frame + byte[] rstFrame = new byte[13]; + // Length +@@ -1411,39 +1413,59 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH + + + void reduceOverheadCount(FrameType frameType) { +- // A non-overhead frame reduces the overhead count by +- // Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR. A simple browser +- // request is likely to have one non-overhead frame (HEADERS) and one +- // overhead frame (REPRIORITISE). With the default settings the overhead +- // count will reduce by 10 for each simple request. +- // Requests and responses with bodies will create additional +- // non-overhead frames, further reducing the overhead count. ++ /* ++ * A non-overhead frame reduces the overhead count by {@code Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR}. ++ * ++ * A simple browser request is likely to have one non-overhead frame (HEADERS) that results in a response with ++ * one further non-overhead frame (DATA). With the default settings, the overhead count will reduce by 40 for ++ * each simple request. ++ * ++ * Requests and responses with bodies will create additional non-overhead frames, further reducing the overhead ++ * count. ++ */ + updateOverheadCount(frameType, Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR); + } + + + @Override + public void increaseOverheadCount(FrameType frameType) { +- // An overhead frame increases the overhead count by +- // overheadCountFactor. By default, this means an overhead frame +- // increases the overhead count by 10. A simple browser request is +- // likely to have one non-overhead frame (HEADERS) and one overhead +- // frame (REPRIORITISE). With the default settings the overhead count +- // will reduce by 10 for each simple request. ++ /* ++ * An overhead frame (SETTINGS, PRIORITY, PING) increases the overhead count by overheadCountFactor. By default, ++ * this means an overhead frame increases the overhead count by 10. ++ * ++ * If the client ignores maxConcurrentStreams then any HEADERS frame received will also increase the overhead ++ * count by overheadCountFactor. ++ * ++ * A simple browser request should not trigger any overhead frames. ++ */ + updateOverheadCount(frameType, getProtocol().getOverheadCountFactor()); + } + + +- private void increaseOverheadCount(FrameType frameType, int increment) { +- // Overhead frames that indicate inefficient (and potentially malicious) +- // use of small frames trigger an increase that is inversely +- // proportional to size. The default threshold for all three potential +- // areas for abuse (HEADERS, DATA, WINDOW_UPDATE) is 1024 bytes. Frames +- // with sizes smaller than this will trigger an increase of +- // threshold/size. +- // DATA and WINDOW_UPDATE take an average over the last two non-final +- // frames to allow for client buffering schemes that can result in some +- // small DATA payloads. ++ /** ++ * Used to increase the overhead for frames that don't use the {@code overheadCountFactor} ({@code CONTINUATION}, ++ * {@code DATA}, {@code WINDOW_UPDATE} and {@code RESET}). ++ * ++ * @param frameType The frame type triggering the overhead increase ++ * @param increment The amount by which the overhead is increased ++ */ ++ protected void increaseOverheadCount(FrameType frameType, int increment) { ++ /* ++ * Three types of frame are susceptible to inefficient (and potentially malicious) use of small frames. These ++ * trigger an increase in overhead that is inversely proportional to size. The default threshold for all three ++ * potential areas for abuse (CONTINUATION, DATA, WINDOW_UPDATE) is 1024 bytes. Frames with sizes smaller than ++ * this will trigger an increase of threshold/size. ++ * ++ * The check for DATA and WINDOW_UPDATE frames takes an average over the last two frames to allow for client ++ * buffering schemes that can result in some small DATA payloads. ++ * ++ * The CONTINUATION and DATA frames checks are skipped for end of headers (CONTINUATION) and end of stream ++ * (DATA) as those frames may be small for legitimate reasons. ++ * ++ * RESET frames (received or sent) trigger an increase of overheadResetFactor. ++ * ++ * In all cases, the calling method determines the extent to which the overhead count is increased. ++ */ + updateOverheadCount(frameType, increment); + } + +@@ -1652,9 +1674,9 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH + if (payloadSize < overheadThreshold) { + if (payloadSize == 0) { + // Avoid division by zero +- increaseOverheadCount(FrameType.HEADERS, overheadThreshold); ++ increaseOverheadCount(FrameType.CONTINUATION, overheadThreshold); + } else { +- increaseOverheadCount(FrameType.HEADERS, overheadThreshold / payloadSize); ++ increaseOverheadCount(FrameType.CONTINUATION, overheadThreshold / payloadSize); + } + } + } +diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml +index df1c90b7a7..0c1588a506 100644 +--- a/webapps/docs/changelog.xml ++++ b/webapps/docs/changelog.xml +@@ -125,6 +125,12 @@ + the session id if appropriate, and handle cross context with different + session configuration when using rewrite. (remm) + ++ ++ Update the HTTP/2 overhead documentation - particularly the code ++ comments - to reflect the deprecation of the PRIORITY frame ++ and clarify that a stream reset always triggers an overhead increase. ++ (markt) ++ + + + +diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml +index 0a0d98cb32..b2329a4fdb 100644 +--- a/webapps/docs/config/http2.xml ++++ b/webapps/docs/config/http2.xml +@@ -241,8 +241,9 @@ + +

The amount by which the overhead count (see + overheadCountFactor) will be increased for each reset +- frame received. If not specified, a default value of 50 will +- be used. A value of less than zero will be treated as zero.

++ frame received or sent. If not specified, a default value of ++ 50 will be used. A value of less than zero will be treated as ++ zero.

+
+ + diff --git a/tomcat.spec b/tomcat.spec index 9de5fd5..84c54e5 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -23,7 +23,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 7 +Release: 8 Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API License: Apache-2.0 @@ -65,6 +65,7 @@ Patch18: CVE-2025-52434.patch Patch19: CVE-2025-52520.patch Patch20: CVE-2025-53506.patch Patch21: CVE-2025-55668.patch +Patch22: CVE-2025-48989.patch BuildArch: noarch @@ -431,6 +432,9 @@ fi %{appdir}/docs %changelog +* Fri Aug 15 2025 Yu Peng - 1:9.0.100-8 +- Fix CVE-2025-48989 + * Thu Aug 14 2025 Yu Peng - 1:9.0.100-7 - Fix CVE-2025-55668 -- Gitee