[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