Version in base suite: 9.0.43-2~deb11u6 Version in overlay suite: 9.0.43-2~deb11u8 Base version: tomcat9_9.0.43-2~deb11u8 Target version: tomcat9_9.0.43-2~deb11u9 Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/tomcat9/tomcat9_9.0.43-2~deb11u8.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/t/tomcat9/tomcat9_9.0.43-2~deb11u9.dsc changelog | 8 +++ patches/CVE-2023-44487.patch | 100 +++++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 36 deletions(-) diff -Nru tomcat9-9.0.43/debian/changelog tomcat9-9.0.43/debian/changelog --- tomcat9-9.0.43/debian/changelog 2023-10-12 15:32:21.000000000 +0000 +++ tomcat9-9.0.43/debian/changelog 2023-10-16 12:51:43.000000000 +0000 @@ -1,7 +1,13 @@ +tomcat9 (9.0.43-2~deb11u9) bullseye-security; urgency=high + + * More HTTP/2 overhead protection adjustments + + -- Emmanuel Bourg Mon, 16 Oct 2023 14:51:43 +0200 + tomcat9 (9.0.43-2~deb11u8) bullseye-security; urgency=high * Fixed the HTTP/2 overhead protection triggered on data frames. - (Closes: #1053820 + (Closes: #1053820) -- Emmanuel Bourg Thu, 12 Oct 2023 17:32:21 +0200 diff -Nru tomcat9-9.0.43/debian/patches/CVE-2023-44487.patch tomcat9-9.0.43/debian/patches/CVE-2023-44487.patch --- tomcat9-9.0.43/debian/patches/CVE-2023-44487.patch 2023-10-12 15:32:21.000000000 +0000 +++ tomcat9-9.0.43/debian/patches/CVE-2023-44487.patch 2023-10-16 12:51:43.000000000 +0000 @@ -1,6 +1,7 @@ Description: Improvements to HTTP/2 overhead protection. Origin: backport, https://github.com/apache/tomcat/commit/30cae120a61f075b1712f2e8da4daa23f1135c83 https://github.com/apache/tomcat/commit/94480483910f2d19561e88fb194d7b415bb527da + https://github.com/apache/tomcat/commit/caafb952f77107fb4730546e60bf5d7756ef4c5a https://github.com/apache/tomcat/commit/3f0efca913b09fa3a3d9c246cc29045ac8a2befe https://github.com/apache/tomcat/commit/c551ecaa1ba4ffe50a67009a9c94efb03439ae8b https://github.com/apache/tomcat/commit/6d1a9fd6642387969e4410b9989c85856b74917a @@ -54,7 +55,31 @@ } --- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java +++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java -@@ -349,7 +349,7 @@ +@@ -143,7 +143,7 @@ + private Queue queuedRunnable = null; + + // Track 'overhead' frames vs 'request/response' frames +- private final AtomicLong overheadCount = new AtomicLong(-10); ++ private final AtomicLong overheadCount; + private volatile int lastNonFinalDataPayload; + private volatile int lastWindowUpdate; + +@@ -154,6 +154,14 @@ + this.adapter = adapter; + this.connectionId = Integer.toString(connectionIdGenerator.getAndIncrement()); + ++ // Defaults to -10 * the count factor. ++ // i.e. when the connection opens, 10 'overhead' frames in a row will ++ // cause the connection to be closed. ++ // Over time the count should be a slowly decreasing negative number. ++ // Therefore, the longer a connection is 'well-behaved', the greater ++ // tolerance it will have for a period of 'bad' behaviour. ++ overheadCount = new AtomicLong(-10 * protocol.getOverheadCountFactor()); ++ + lastNonFinalDataPayload = protocol.getOverheadDataThreshold() * 2; + lastWindowUpdate = protocol.getOverheadWindowUpdateThreshold() * 2; + +@@ -349,7 +357,7 @@ stream.close(se); } } finally { @@ -63,7 +88,7 @@ throw new ConnectionException( sm.getString("upgradeHandler.tooMuchOverhead", connectionId), Http2Error.ENHANCE_YOUR_CALM); -@@ -750,7 +750,7 @@ +@@ -750,7 +758,7 @@ Integer.toString(len))); } @@ -72,7 +97,7 @@ // Need to check this now since sending end of stream will change this. boolean writeable = stream.canWrite(); -@@ -1362,13 +1362,54 @@ +@@ -1362,13 +1370,54 @@ } @@ -87,11 +112,9 @@ + // Requests and responses with bodies will create additional + // non-overhead frames, further reducing the overhead count. + updateOverheadCount(frameType, Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR); - } - - -- private void increaseOverheadCount() { -- overheadCount.addAndGet(getProtocol().getOverheadCountFactor()); ++ } ++ ++ + private void increaseOverheadCount(FrameType frameType) { + // An overhead frame increases the overhead count by + // overheadCountFactor. By default, this means an overhead frame @@ -123,15 +146,17 @@ + log.debug(sm.getString("upgradeHandler.overheadChange", + connectionId, getIdAsString(), frameType.name(), Long.valueOf(newOverheadCount))); + } -+ } -+ -+ + } + + +- private void increaseOverheadCount() { +- overheadCount.addAndGet(getProtocol().getOverheadCountFactor()); + boolean isOverheadLimitExceeded() { + return overheadCount.get() > 0; } -@@ -1427,7 +1468,7 @@ +@@ -1427,7 +1476,7 @@ @Override public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize, boolean endOfStream) throws Http2Exception { // DATA frames reduce the overhead count ... @@ -140,7 +165,7 @@ // .. but lots of small payloads are inefficient so that will increase // the overhead count unless it is the final DATA frame where small -@@ -1446,7 +1487,7 @@ +@@ -1446,7 +1495,7 @@ average = 1; } if (average < overheadThreshold) { @@ -149,7 +174,7 @@ } } -@@ -1521,7 +1562,7 @@ +@@ -1521,7 +1570,7 @@ log.debug(sm.getString("upgradeHandler.noNewStreams", connectionId, Integer.toString(streamId))); } @@ -158,7 +183,7 @@ // Stateless so a static can be used to save on GC return HEADER_SINK; } -@@ -1549,7 +1590,7 @@ +@@ -1549,7 +1598,7 @@ getConnectionId(), Integer.valueOf(streamId)), Http2Error.PROTOCOL_ERROR); } @@ -167,7 +192,7 @@ AbstractNonZeroStream abstractNonZeroStream = getStreamMayBeClosed(streamId, false); if (abstractNonZeroStream == null) { -@@ -1575,9 +1616,9 @@ +@@ -1575,9 +1624,9 @@ if (payloadSize < overheadThreshold) { if (payloadSize == 0) { // Avoid division by zero @@ -179,7 +204,7 @@ } } } -@@ -1596,13 +1637,13 @@ +@@ -1596,13 +1645,13 @@ if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) { setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet()); // Ignoring maxConcurrentStreams increases the overhead count @@ -195,7 +220,7 @@ processStreamOnContainerThread(stream); } -@@ -1624,6 +1665,7 @@ +@@ -1624,6 +1673,7 @@ log.debug(sm.getString("upgradeHandler.reset.receive", getConnectionId(), Integer.toString(streamId), Long.toString(errorCode))); } @@ -203,7 +228,7 @@ AbstractNonZeroStream abstractNonZeroStream = getStreamMayBeClosed(streamId, true); abstractNonZeroStream.checkState(FrameType.RST); if (abstractNonZeroStream instanceof Stream) { -@@ -1640,7 +1682,7 @@ +@@ -1640,7 +1690,7 @@ @Override public void setting(Setting setting, long value) throws ConnectionException { @@ -212,7 +237,7 @@ // Possible with empty settings frame if (setting == null) { -@@ -1689,7 +1731,7 @@ +@@ -1689,7 +1739,7 @@ @Override public void pingReceive(byte[] payload, boolean ack) throws IOException { if (!ack) { @@ -221,7 +246,7 @@ } pingManager.receivePing(payload, ack); } -@@ -1725,7 +1767,7 @@ +@@ -1725,7 +1775,7 @@ // Check for small increments which are inefficient if (average < overheadThreshold) { // The smaller the increment, the larger the overhead @@ -230,7 +255,7 @@ } incrementWindowSize(increment); -@@ -1739,7 +1781,7 @@ +@@ -1739,7 +1789,7 @@ BacklogTracker tracker = backLogStreams.get(stream); if (tracker == null || increment < tracker.getRemainingReservation()) { // The smaller the increment, the larger the overhead @@ -279,20 +304,25 @@ if (state == CompletionState.DONE) { --- a/webapps/docs/config/http2.xml +++ b/webapps/docs/config/http2.xml -@@ -230,6 +230,13 @@ +@@ -219,12 +219,12 @@ + +

The factor to apply when counting overhead frames to determine if a + connection has too high an overhead and should be closed. The overhead +- count starts at -10. The count is decreased for each +- data frame sent or received and each headers frame received. The count is +- increased by the overheadCountFactorfor each setting +- received, priority frame received and ping received. If the overhead count +- exceeds zero, the connection is closed. A value of less than +- 1 disables this protection. In normal usage a value of ++ count starts at -10 * overheadCountFactor. The count is ++ decreased by 2 for each data frame sent or received and each headers frame ++ received. The count is increased by the overheadCountFactor ++ for each setting received, priority frame received and ping received. If ++ the overhead count exceeds zero, the connection is closed. A value of less ++ than 1 disables this protection. In normal usage a value of + 3 or more will close the connection before any streams can + complete. If not specified, a default value of 1 will be used.

-
- -+ -+

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.

-+
-+ - -

The threshold below which the average payload size of the current and - previous non-final DATA frames will trigger an increase in --- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java +++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java @@ -203,6 +203,9 @@