[Git][java-team/tomcat9][buster] Import Debian changes 9.0.31-1~deb10u12
Markus Koschany (@apo)
gitlab at salsa.debian.org
Sat Apr 6 21:16:54 BST 2024
Markus Koschany pushed to branch buster at Debian Java Maintainers / tomcat9
Commits:
31b8bcd1 by Markus Koschany at 2024-04-06T22:16:34+02:00
Import Debian changes 9.0.31-1~deb10u12
tomcat9 (9.0.31-1~deb10u12) buster-security; urgency=high
.
* Team upload.
* Fix CVE-2024-24549:
Denial of Service due to improper input validation vulnerability for
HTTP/2. When processing an HTTP/2 request, if the request exceeded any of
the configured limits for headers, the associated HTTP/2 stream was not
reset until after all of the headers had been processed.
* Fix CVE-2024-23672:
Denial of Service via incomplete cleanup vulnerability. It was possible for
WebSocket clients to keep WebSocket connections open leading to increased
resource consumption.
- - - - -
4 changed files:
- debian/changelog
- + debian/patches/CVE-2024-23672.patch
- + debian/patches/CVE-2024-24549.patch
- debian/patches/series
Changes:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,18 @@
+tomcat9 (9.0.31-1~deb10u12) buster-security; urgency=high
+
+ * Team upload.
+ * Fix CVE-2024-24549:
+ Denial of Service due to improper input validation vulnerability for
+ HTTP/2. When processing an HTTP/2 request, if the request exceeded any of
+ the configured limits for headers, the associated HTTP/2 stream was not
+ reset until after all of the headers had been processed.
+ * Fix CVE-2024-23672:
+ Denial of Service via incomplete cleanup vulnerability. It was possible for
+ WebSocket clients to keep WebSocket connections open leading to increased
+ resource consumption.
+
+ -- Markus Koschany <apo at debian.org> Fri, 05 Apr 2024 12:14:58 +0200
+
tomcat9 (9.0.31-1~deb10u11) buster-security; urgency=high
* Team upload
=====================================
debian/patches/CVE-2024-23672.patch
=====================================
@@ -0,0 +1,225 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 20 Mar 2024 13:45:51 +0100
+Subject: CVE-2024-23672
+
+Origin: https://github.com/apache/tomcat/commit/52d6650e062d880704898d7d8c1b2b7a3efe8068
+Bug-Debian: https://bugs.debian.org/1066877
+---
+ java/org/apache/tomcat/websocket/Constants.java | 7 ++
+ java/org/apache/tomcat/websocket/WsSession.java | 66 +++++++++++++--
+ .../tomcat/websocket/WsWebSocketContainer.java | 9 +-
+ .../tomcat/websocket/server/WsServerContainer.java | 3 +-
+ .../websocket/TestWsSessionSuspendResume.java | 99 ++++++++++++++++++++++
+ webapps/docs/web-socket-howto.xml | 7 ++
+ 6 files changed, 182 insertions(+), 9 deletions(-)
+
+diff --git a/java/org/apache/tomcat/websocket/Constants.java b/java/org/apache/tomcat/websocket/Constants.java
+index fa01921..ca17371 100644
+--- a/java/org/apache/tomcat/websocket/Constants.java
++++ b/java/org/apache/tomcat/websocket/Constants.java
+@@ -19,6 +19,7 @@ package org.apache.tomcat.websocket;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.List;
++import java.util.concurrent.TimeUnit;
+
+ import javax.websocket.Extension;
+
+@@ -111,9 +112,15 @@ public class Constants {
+ // Configuration for blocking sends
+ public static final String BLOCKING_SEND_TIMEOUT_PROPERTY =
+ "org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT";
++
+ // Milliseconds so this is 20 seconds
+ public static final long DEFAULT_BLOCKING_SEND_TIMEOUT = 20 * 1000;
+
++ // Configuration for session close timeout
++ public static final String SESSION_CLOSE_TIMEOUT_PROPERTY = "org.apache.tomcat.websocket.SESSION_CLOSE_TIMEOUT";
++ // Default is 30 seconds - setting is in milliseconds
++ public static final long DEFAULT_SESSION_CLOSE_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
++
+ // Configuration for background processing checks intervals
+ static final int DEFAULT_PROCESS_PERIOD = Integer.getInteger(
+ "org.apache.tomcat.websocket.DEFAULT_PROCESS_PERIOD", 10)
+diff --git a/java/org/apache/tomcat/websocket/WsSession.java b/java/org/apache/tomcat/websocket/WsSession.java
+index 37bff32..501a8ff 100644
+--- a/java/org/apache/tomcat/websocket/WsSession.java
++++ b/java/org/apache/tomcat/websocket/WsSession.java
+@@ -28,6 +28,7 @@ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
++import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicLong;
+
+ import javax.websocket.CloseReason;
+@@ -99,6 +100,7 @@ public class WsSession implements Session {
+ private volatile long maxIdleTimeout = 0;
+ private volatile long lastActive = System.currentTimeMillis();
+ private Map<FutureToSendHandler, FutureToSendHandler> futures = new ConcurrentHashMap<>();
++ private volatile Long sessionCloseTimeoutExpiry;
+
+ /**
+ * Creates a new WebSocket session for communication between the two
+@@ -495,10 +497,18 @@ public class WsSession implements Session {
+ state = State.OUTPUT_CLOSED;
+
+ sendCloseMessage(closeReasonMessage);
++ fireEndpointOnClose(closeReasonLocal);
++
+ if (closeSocket) {
+- wsRemoteEndpoint.close();
++ closeConnection();
++ } else {
++ /*
++ * Set close timeout. If the client fails to send a close message response within the timeout, the session
++ * and the connection will be closed when the timeout expires.
++ */
++ sessionCloseTimeoutExpiry =
++ Long.valueOf(System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(getSessionCloseTimeout()));
+ }
+- fireEndpointOnClose(closeReasonLocal);
+ }
+
+ IOException ioe = new IOException(sm.getString("wsSession.messageFailed"));
+@@ -535,7 +545,48 @@ public class WsSession implements Session {
+ state = State.CLOSED;
+
+ // Close the socket
+- wsRemoteEndpoint.close();
++ closeConnection();
++ }
++ }
++ }
++
++ private void closeConnection() {
++ /*
++ * Close the network connection.
++ */
++ wsRemoteEndpoint.close();
++ /*
++ * Don't unregister the session until the connection is fully closed since webSocketContainer is responsible for
++ * tracking the session close timeout.
++ */
++ webSocketContainer.unregisterSession(getSessionMapKey(), this);
++ }
++
++ /*
++ * Returns the session close timeout in milliseconds
++ */
++ protected long getSessionCloseTimeout() {
++ long result = 0;
++ Object obj = userProperties.get(Constants.SESSION_CLOSE_TIMEOUT_PROPERTY);
++ if (obj instanceof Long) {
++ result = ((Long) obj).intValue();
++ }
++ if (result <= 0) {
++ result = Constants.DEFAULT_SESSION_CLOSE_TIMEOUT;
++ }
++ return result;
++ }
++
++
++ protected void checkCloseTimeout() {
++ // Skip the check if no session close timeout has been set.
++ if (sessionCloseTimeoutExpiry != null) {
++ // Check if the timeout has expired.
++ if (System.nanoTime() - sessionCloseTimeoutExpiry.longValue() > 0) {
++ // Check if the session has been closed in another thread while the timeout was being processed.
++ if (state == State.CLOSED) {
++ closeConnection();
++ }
+ }
+ }
+ }
+@@ -616,7 +667,7 @@ public class WsSession implements Session {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("wsSession.sendCloseFail", id), e);
+ }
+- wsRemoteEndpoint.close();
++ closeConnection();
+ // Failure to send a close message is not unexpected in the case of
+ // an abnormal closure (usually triggered by a failure to read/write
+ // from/to the client. In this case do not trigger the endpoint's
+@@ -624,8 +675,6 @@ public class WsSession implements Session {
+ if (closeCode != CloseCodes.CLOSED_ABNORMALLY) {
+ localEndpoint.onError(this, e);
+ }
+- } finally {
+- webSocketContainer.unregisterSession(getSessionMapKey(), this);
+ }
+ }
+
+@@ -756,6 +805,11 @@ public class WsSession implements Session {
+ @Override
+ public Principal getUserPrincipal() {
+ checkState();
++ return getUserPrincipalInternal();
++ }
++
++
++ public Principal getUserPrincipalInternal() {
+ return userPrincipal;
+ }
+
+diff --git a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
+index 4ea31fc..18c5c60 100644
+--- a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
++++ b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
+@@ -624,7 +624,12 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce
+ synchronized (endPointSessionMapLock) {
+ Set<WsSession> sessions = endpointSessionMap.get(key);
+ if (sessions != null) {
+- result.addAll(sessions);
++ // Some sessions may be in the process of closing
++ for (WsSession session : sessions) {
++ if (session.isOpen()) {
++ result.add(session);
++ }
++ }
+ }
+ }
+ return result;
+@@ -1078,8 +1083,10 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce
+ if (backgroundProcessCount >= processPeriod) {
+ backgroundProcessCount = 0;
+
++ // Check all registered sessions.
+ for (WsSession wsSession : sessions.keySet()) {
+ wsSession.checkExpiration();
++ wsSession.checkCloseTimeout();
+ }
+ }
+
+diff --git a/java/org/apache/tomcat/websocket/server/WsServerContainer.java b/java/org/apache/tomcat/websocket/server/WsServerContainer.java
+index 3221ddf..ad03990 100644
+--- a/java/org/apache/tomcat/websocket/server/WsServerContainer.java
++++ b/java/org/apache/tomcat/websocket/server/WsServerContainer.java
+@@ -415,8 +415,7 @@ public class WsServerContainer extends WsWebSocketContainer
+ */
+ @Override
+ protected void unregisterSession(Object key, WsSession wsSession) {
+- if (wsSession.getUserPrincipal() != null &&
+- wsSession.getHttpSessionId() != null) {
++ if (wsSession.getUserPrincipalInternal() != null && wsSession.getHttpSessionId() != null) {
+ unregisterAuthenticatedSession(wsSession,
+ wsSession.getHttpSessionId());
+ }
+diff --git a/webapps/docs/web-socket-howto.xml b/webapps/docs/web-socket-howto.xml
+index 69b8baf..9483b51 100644
+--- a/webapps/docs/web-socket-howto.xml
++++ b/webapps/docs/web-socket-howto.xml
+@@ -63,6 +63,13 @@
+ the timeout to use in milliseconds. For an infinite timeout, use
+ <code>-1</code>.</p>
+
++<p>The session close timeout defaults to 30000 milliseconds (30 seconds). This
++ may be changed by setting the property
++ <code>org.apache.tomcat.websocket.SESSION_CLOSE_TIMEOUT</code> in the user
++ properties collection attached to the WebSocket session. The value assigned
++ to this property should be a <code>Long</code> and represents the timeout to
++ use in milliseconds. Values less than or equal to zero will be ignored.</p>
++
+ <p>If the application does not define a <code>MessageHandler.Partial</code> for
+ incoming binary messages, any incoming binary messages must be buffered so
+ the entire message can be delivered in a single call to the registered
=====================================
debian/patches/CVE-2024-24549.patch
=====================================
@@ -0,0 +1,49 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 20 Mar 2024 13:51:46 +0100
+Subject: CVE-2024-24549
+
+Origin: https://github.com/apache/tomcat/commit/8e03be9f2698f2da9027d40b9e9c0c9429b74dc0
+Bug-Debian: https://bugs.debian.org/1066878
+
+NOTE: This causes a test regression in TestHttp2Limits.java which appears to be
+a simple string mismatch though.
+---
+ java/org/apache/coyote/http2/Http2Parser.java | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/java/org/apache/coyote/http2/Http2Parser.java b/java/org/apache/coyote/http2/Http2Parser.java
+index 38f0b13..0cc49ea 100644
+--- a/java/org/apache/coyote/http2/Http2Parser.java
++++ b/java/org/apache/coyote/http2/Http2Parser.java
+@@ -270,6 +270,9 @@ class Http2Parser {
+
+ swallow(streamId, padLength, true, buffer);
+
++ // Validate the headers so far
++ hpackDecoder.getHeaderEmitter().validateHeaders();
++
+ if (Flags.isEndOfHeaders(flags)) {
+ onHeadersComplete(streamId);
+ } else {
+@@ -437,6 +440,9 @@ class Http2Parser {
+
+ readHeaderPayload(streamId, payloadSize, buffer);
+
++ // Validate the headers so far
++ hpackDecoder.getHeaderEmitter().validateHeaders();
++
+ if (endOfHeaders) {
+ headersCurrentStream = -1;
+ onHeadersComplete(streamId);
+@@ -586,11 +592,6 @@ class Http2Parser {
+ Http2Error.COMPRESSION_ERROR);
+ }
+
+- // Delay validation (and triggering any exception) until this point
+- // since all the headers still have to be read if a StreamException is
+- // going to be thrown.
+- hpackDecoder.getHeaderEmitter().validateHeaders();
+-
+ synchronized (output) {
+ output.headersEnd(streamId);
+
=====================================
debian/patches/series
=====================================
@@ -38,3 +38,5 @@ CVE-2023-45648.patch
0038-Improve-error-handling-if-non-blocking-IO-code-swall.patch
0039-1-2-CVE-2023-46589-Differentiate-request-cancellatio.patch
0040-2-2-CVE-2023-46589-Ensure-IOException-on-request-rea.patch
+CVE-2024-23672.patch
+CVE-2024-24549.patch
View it on GitLab: https://salsa.debian.org/java-team/tomcat9/-/commit/31b8bcd1534b24973f18dbfe6e5b79b1fa5d399f
--
View it on GitLab: https://salsa.debian.org/java-team/tomcat9/-/commit/31b8bcd1534b24973f18dbfe6e5b79b1fa5d399f
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20240406/a2512443/attachment.htm>
More information about the pkg-java-commits
mailing list