[Git][java-team/tomcat9][buster] Import Debian changes 9.0.31-1~deb10u9

Markus Koschany (@apo) gitlab at salsa.debian.org
Sat Oct 14 15:52:16 BST 2023



Markus Koschany pushed to branch buster at Debian Java Maintainers / tomcat9


Commits:
e71e6118 by Markus Koschany at 2023-10-14T16:51:42+02:00
Import Debian changes 9.0.31-1~deb10u9

tomcat9 (9.0.31-1~deb10u9) buster-security; urgency=high
.
  * Team upload.
  * Fix CVE-2023-45648: Request smuggling. Tomcat did not correctly parse HTTP
    trailer headers. A specially crafted, invalid trailer header could cause
    Tomcat to treat a single request as multiple requests leading to the
    possibility of request smuggling when behind a reverse proxy.
  * Fix CVE-2023-44487: DoS caused by HTTP/2 frame overhead (Rapid Reset Attack)
  * Fix CVE-2023-42795: Information Disclosure. When recycling various internal
    objects, including the request and the response, prior to re-use by the
    next request/response, an error could cause Tomcat to skip some parts of
    the recycling process leading to information leaking from the current
    request/response to the next.
  * Fix CVE-2023-41080: Open redirect. If the ROOT (default) web application
    is configured to use FORM authentication then it is possible that a
    specially crafted URL could be used to trigger a redirect to an URL of the
    attackers choice.
  * Fix CVE-2023-28709: Denial of Service. If non-default HTTP connector
    settings were used such that the maxParameterCount could be reached using
    query string parameters and a request was submitted that supplied exactly
    maxParameterCount parameters in the query string, the limit for uploaded
    request parts could be bypassed with the potential for a denial of service
    to occur.
  * Fix CVE-2023-24998: Denial of service. Tomcat uses a packaged renamed copy
    of Apache Commons FileUpload to provide the file upload functionality
    defined in the Jakarta Servlet specification. Apache Tomcat was, therefore,
    also vulnerable to the Commons FileUpload vulnerability CVE-2023-24998 as
    there was no limit to the number of request parts processed. This resulted
    in the possibility of an attacker triggering a DoS with a malicious upload
    or series of uploads.

- - - - -


8 changed files:

- debian/changelog
- + debian/patches/CVE-2023-24998.patch
- + debian/patches/CVE-2023-28709.patch
- + debian/patches/CVE-2023-41080.patch
- + debian/patches/CVE-2023-42795.patch
- + debian/patches/CVE-2023-44487.patch
- + debian/patches/CVE-2023-45648.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,36 @@
+tomcat9 (9.0.31-1~deb10u9) buster-security; urgency=high
+
+  * Team upload.
+  * Fix CVE-2023-45648: Request smuggling. Tomcat did not correctly parse HTTP
+    trailer headers. A specially crafted, invalid trailer header could cause
+    Tomcat to treat a single request as multiple requests leading to the
+    possibility of request smuggling when behind a reverse proxy.
+  * Fix CVE-2023-44487: DoS caused by HTTP/2 frame overhead (Rapid Reset Attack)
+  * Fix CVE-2023-42795: Information Disclosure. When recycling various internal
+    objects, including the request and the response, prior to re-use by the
+    next request/response, an error could cause Tomcat to skip some parts of
+    the recycling process leading to information leaking from the current
+    request/response to the next.
+  * Fix CVE-2023-41080: Open redirect. If the ROOT (default) web application
+    is configured to use FORM authentication then it is possible that a
+    specially crafted URL could be used to trigger a redirect to an URL of the
+    attackers choice.
+  * Fix CVE-2023-28709: Denial of Service. If non-default HTTP connector
+    settings were used such that the maxParameterCount could be reached using
+    query string parameters and a request was submitted that supplied exactly
+    maxParameterCount parameters in the query string, the limit for uploaded
+    request parts could be bypassed with the potential for a denial of service
+    to occur.
+  * Fix CVE-2023-24998: Denial of service. Tomcat uses a packaged renamed copy
+    of Apache Commons FileUpload to provide the file upload functionality
+    defined in the Jakarta Servlet specification. Apache Tomcat was, therefore,
+    also vulnerable to the Commons FileUpload vulnerability CVE-2023-24998 as
+    there was no limit to the number of request parts processed. This resulted
+    in the possibility of an attacker triggering a DoS with a malicious upload
+    or series of uploads.
+
+ -- Markus Koschany <apo at debian.org>  Wed, 11 Oct 2023 17:17:28 +0200
+
 tomcat9 (9.0.31-1~deb10u8) buster-security; urgency=high
 
   * Team upload.


=====================================
debian/patches/CVE-2023-24998.patch
=====================================
@@ -0,0 +1,229 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:14:41 +0200
+Subject: CVE-2023-24998
+
+Origin: https://github.com/apache/tomcat/commit/cf77cc545de0488fb89e24294151504a7432df74
+---
+ java/org/apache/catalina/connector/Request.java    | 10 ++++-
+ java/org/apache/tomcat/util/http/Parameters.java   |  5 +++
+ .../util/http/fileupload/FileUploadBase.java       | 29 +++++++++++++
+ .../impl/FileCountLimitExceededException.java      | 50 ++++++++++++++++++++++
+ webapps/docs/config/ajp.xml                        | 15 ++++---
+ webapps/docs/config/http.xml                       | 15 ++++---
+ 6 files changed, 111 insertions(+), 13 deletions(-)
+ create mode 100644 java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java
+
+diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
+index 619fdce..37944bb 100644
+--- a/java/org/apache/catalina/connector/Request.java
++++ b/java/org/apache/catalina/connector/Request.java
+@@ -2810,8 +2810,9 @@ public class Request implements HttpServletRequest {
+             }
+         }
+ 
++        int maxParameterCount = getConnector().getMaxParameterCount();
+         Parameters parameters = coyoteRequest.getParameters();
+-        parameters.setLimit(getConnector().getMaxParameterCount());
++        parameters.setLimit(maxParameterCount);
+ 
+         boolean success = false;
+         try {
+@@ -2863,6 +2864,13 @@ public class Request implements HttpServletRequest {
+             upload.setFileItemFactory(factory);
+             upload.setFileSizeMax(mce.getMaxFileSize());
+             upload.setSizeMax(mce.getMaxRequestSize());
++            if (maxParameterCount > -1) {
++                // There is a limit. The limit for parts needs to be reduced by
++                // the number of parameters we have already parsed.
++                // Must be under the limit else parsing parameters would have
++                // triggered an exception.
++                upload.setFileCountMax(maxParameterCount - parameters.size());
++            }
+ 
+             parts = new ArrayList<>();
+             try {
+diff --git a/java/org/apache/tomcat/util/http/Parameters.java b/java/org/apache/tomcat/util/http/Parameters.java
+index 5bd9ba7..6a8a0fc 100644
+--- a/java/org/apache/tomcat/util/http/Parameters.java
++++ b/java/org/apache/tomcat/util/http/Parameters.java
+@@ -125,6 +125,11 @@ public final class Parameters {
+     }
+ 
+ 
++    public int size() {
++        return parameterCount;
++    }
++
++
+     public void recycle() {
+         parameterCount = 0;
+         paramHashValues.clear();
+diff --git a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
+index 4a68be2..6c1fdfe 100644
+--- a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
++++ b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
+@@ -24,6 +24,7 @@ import java.util.List;
+ import java.util.Locale;
+ import java.util.Map;
+ 
++import org.apache.tomcat.util.http.fileupload.impl.FileCountLimitExceededException;
+ import org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl;
+ import org.apache.tomcat.util.http.fileupload.impl.FileItemStreamImpl;
+ import org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException;
+@@ -131,6 +132,12 @@ public abstract class FileUploadBase {
+      */
+     private long fileSizeMax = -1;
+ 
++    /**
++     * The maximum permitted number of files that may be uploaded in a single
++     * request. A value of -1 indicates no maximum.
++     */
++    private long fileCountMax = -1;
++
+     /**
+      * The content encoding to use when reading part headers.
+      */
+@@ -207,6 +214,24 @@ public abstract class FileUploadBase {
+         this.fileSizeMax = fileSizeMax;
+     }
+ 
++    /**
++     * Returns the maximum number of files allowed in a single request.
++     *
++     * @return The maximum number of files allowed in a single request.
++     */
++    public long getFileCountMax() {
++        return fileCountMax;
++    }
++
++    /**
++     * Sets the maximum number of files allowed per request/
++     *
++     * @param fileCountMax The new limit. {@code -1} means no limit.
++     */
++    public void setFileCountMax(long fileCountMax) {
++        this.fileCountMax = fileCountMax;
++    }
++
+     /**
+      * Retrieves the character encoding used when reading the headers of an
+      * individual part. When not specified, or <code>null</code>, the request
+@@ -283,6 +308,10 @@ public abstract class FileUploadBase {
+                 throw new NullPointerException("No FileItemFactory has been set.");
+             }
+             while (iter.hasNext()) {
++                if (items.size() == fileCountMax) {
++                    // The next item will exceed the limit.
++                    throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax());
++                }
+                 final FileItemStream item = iter.next();
+                 // Don't use getName() here to prevent an InvalidFileNameException.
+                 final String fileName = ((FileItemStreamImpl) item).getName();
+diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java
+new file mode 100644
+index 0000000..958f681
+--- /dev/null
++++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java
+@@ -0,0 +1,50 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.tomcat.util.http.fileupload.impl;
++
++import org.apache.tomcat.util.http.fileupload.FileUploadException;
++
++/**
++ * This exception is thrown if a request contains more files than the specified
++ * limit.
++ */
++public class FileCountLimitExceededException extends FileUploadException {
++
++    private static final long serialVersionUID = 2408766352570556046L;
++
++    private final long limit;
++
++    /**
++     * Creates a new instance.
++     *
++     * @param message The detail message
++     * @param limit The limit that was exceeded
++     */
++    public FileCountLimitExceededException(final String message, final long limit) {
++        super(message);
++        this.limit = limit;
++    }
++
++    /**
++     * Retrieves the limit that was exceeded.
++     *
++     * @return The limit that was exceeded by the request
++     */
++    public long getLimit() {
++        return limit;
++    }
++}
+diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
+index 801920a..bd87774 100644
+--- a/webapps/docs/config/ajp.xml
++++ b/webapps/docs/config/ajp.xml
+@@ -121,12 +121,15 @@
+     </attribute>
+ 
+     <attribute name="maxParameterCount" required="false">
+-      <p>The maximum number of parameter and value pairs (GET plus POST) which
+-      will be automatically parsed by the container. Parameter and value pairs
+-      beyond this limit will be ignored. A value of less than 0 means no limit.
+-      If not specified, a default of 10000 is used. Note that
+-      <code>FailedRequestFilter</code> <a href="filter.html">filter</a> can be
+-      used to reject requests that hit the limit.</p>
++      <p>The maximum total number of request parameters (including uploaded
++      files) obtained from the query string and, for POST requests, the request
++      body if the content type is
++      <code>application/x-www-form-urlencoded</code> or
++      <code>multipart/form-data</code>. Request parameters beyond this limit
++      will be ignored. A value of less than 0 means no limit. If not specified,
++      a default of 10000 is used. Note that <code>FailedRequestFilter</code>
++      <a href="filter.html">filter</a> can be used to reject requests that
++      exceed the limit.</p>
+     </attribute>
+ 
+     <attribute name="maxPostSize" required="false">
+diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
+index b15853d..54b1c03 100644
+--- a/webapps/docs/config/http.xml
++++ b/webapps/docs/config/http.xml
+@@ -122,12 +122,15 @@
+     </attribute>
+ 
+     <attribute name="maxParameterCount" required="false">
+-      <p>The maximum number of parameter and value pairs (GET plus POST) which
+-      will be automatically parsed by the container. Parameter and value pairs
+-      beyond this limit will be ignored. A value of less than 0 means no limit.
+-      If not specified, a default of 10000 is used. Note that
+-      <code>FailedRequestFilter</code> <a href="filter.html">filter</a> can be
+-      used to reject requests that hit the limit.</p>
++      <p>The maximum total number of request parameters (including uploaded
++      files) obtained from the query string and, for POST requests, the request
++      body if the content type is
++      <code>application/x-www-form-urlencoded</code> or
++      <code>multipart/form-data</code>. Request parameters beyond this limit
++      will be ignored. A value of less than 0 means no limit. If not specified,
++      a default of 10000 is used. Note that <code>FailedRequestFilter</code>
++      <a href="filter.html">filter</a> can be used to reject requests that
++      exceed the limit.</p>
+     </attribute>
+ 
+     <attribute name="maxPostSize" required="false">


=====================================
debian/patches/CVE-2023-28709.patch
=====================================
@@ -0,0 +1,30 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:15:06 +0200
+Subject: CVE-2023-28709
+
+Origin: https://github.com/apache/tomcat/commit/fbd81421629afe8b8a3922d59020cde81caea861
+---
+ java/org/apache/tomcat/util/http/Parameters.java | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/java/org/apache/tomcat/util/http/Parameters.java b/java/org/apache/tomcat/util/http/Parameters.java
+index 6a8a0fc..a64697a 100644
+--- a/java/org/apache/tomcat/util/http/Parameters.java
++++ b/java/org/apache/tomcat/util/http/Parameters.java
+@@ -206,14 +206,14 @@ public final class Parameters {
+             return;
+         }
+ 
+-        parameterCount ++;
+-        if (limit > -1 && parameterCount > limit) {
++        if (limit > -1 && parameterCount >= limit) {
+             // Processing this parameter will push us over the limit. ISE is
+             // what Request.parseParts() uses for requests that are too big
+             setParseFailedReason(FailReason.TOO_MANY_PARAMETERS);
+             throw new IllegalStateException(sm.getString(
+                     "parameters.maxCountFail", Integer.valueOf(limit)));
+         }
++        parameterCount++;
+ 
+         ArrayList<String> values = paramHashValues.get(key);
+         if (values == null) {


=====================================
debian/patches/CVE-2023-41080.patch
=====================================
@@ -0,0 +1,26 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:15:33 +0200
+Subject: CVE-2023-41080
+
+Origin: https://github.com/apache/tomcat/commit/77c0ce2d169efa248b64b992e547aad549ec906b
+---
+ java/org/apache/catalina/authenticator/FormAuthenticator.java | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/java/org/apache/catalina/authenticator/FormAuthenticator.java b/java/org/apache/catalina/authenticator/FormAuthenticator.java
+index 4a508f6..dbeefeb 100644
+--- a/java/org/apache/catalina/authenticator/FormAuthenticator.java
++++ b/java/org/apache/catalina/authenticator/FormAuthenticator.java
+@@ -720,6 +720,12 @@ public class FormAuthenticator
+             sb.append('?');
+             sb.append(saved.getQueryString());
+         }
++
++        // Avoid protocol relative redirects
++        while (sb.length() > 1 && sb.charAt(1) == '/') {
++            sb.deleteCharAt(0);
++        }
++
+         return sb.toString();
+     }
+ }


=====================================
debian/patches/CVE-2023-42795.patch
=====================================
@@ -0,0 +1,267 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:37:54 +0200
+Subject: CVE-2023-42795
+
+Origin: https://github.com/apache/tomcat/commit/44d05d75d696ca10ce251e4e370511e38f20ae75
+---
+ .../org/apache/catalina/connector/LocalStrings.properties |  1 +
+ java/org/apache/catalina/connector/Request.java           |  7 ++++---
+ java/org/apache/catalina/core/ApplicationHttpRequest.java |  8 +++++++-
+ java/org/apache/catalina/core/LocalStrings.properties     |  1 +
+ java/org/apache/catalina/core/LocalStrings_cs.properties  |  2 ++
+ java/org/apache/catalina/core/LocalStrings_es.properties  |  2 ++
+ java/org/apache/catalina/core/LocalStrings_fr.properties  |  2 ++
+ java/org/apache/catalina/core/LocalStrings_ja.properties  |  2 ++
+ java/org/apache/catalina/core/LocalStrings_ko.properties  |  2 ++
+ .../apache/catalina/core/LocalStrings_zh_CN.properties    |  2 ++
+ java/org/apache/tomcat/util/buf/B2CConverter.java         | 11 ++++++++++-
+ java/org/apache/tomcat/util/buf/C2BConverter.java         | 15 ++++++++++++++-
+ java/org/apache/tomcat/util/buf/LocalStrings.properties   |  3 +++
+ 13 files changed, 52 insertions(+), 6 deletions(-)
+
+diff --git a/java/org/apache/catalina/connector/LocalStrings.properties b/java/org/apache/catalina/connector/LocalStrings.properties
+index 1cc68af..e20835c 100644
+--- a/java/org/apache/catalina/connector/LocalStrings.properties
++++ b/java/org/apache/catalina/connector/LocalStrings.properties
+@@ -44,6 +44,7 @@ coyoteRequest.attributeEvent=Exception thrown by attributes event listener
+ coyoteRequest.authenticate.ise=Cannot call authenticate() after the response has been committed
+ coyoteRequest.changeSessionId=Cannot change session ID. There is no session associated with this request.
+ coyoteRequest.chunkedPostTooLarge=Parameters were not parsed because the size of the posted data was too big. Because this request was a chunked request, it could not be processed further. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
++coyoteRequest.deletePartFailed=Failed to deleted temporary file used for part [{0}]
+ coyoteRequest.filterAsyncSupportUnknown=Unable to determine if any filters do not support async processing
+ coyoteRequest.getContextPath.ise=Unable to find match between the canonical context path [{0}] and the URI presented by the user agent [{1}]
+ coyoteRequest.getInputStream.ise=getReader() has already been called for this request
+diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
+index 37944bb..9841f1d 100644
+--- a/java/org/apache/catalina/connector/Request.java
++++ b/java/org/apache/catalina/connector/Request.java
+@@ -471,8 +471,9 @@ public class Request implements HttpServletRequest {
+             for (Part part: parts) {
+                 try {
+                     part.delete();
+-                } catch (IOException ignored) {
+-                    // ApplicationPart.delete() never throws an IOEx
++                } catch (Throwable t) {
++                    ExceptionUtils.handleThrowable(t);
++                    log.warn(sm.getString("coyoteRequest.deletePartFailed", part.getName()), t);
+                 }
+             }
+             parts = null;
+@@ -524,8 +525,8 @@ public class Request implements HttpServletRequest {
+         asyncSupported = null;
+         if (asyncContext!=null) {
+             asyncContext.recycle();
++            asyncContext = null;
+         }
+-        asyncContext = null;
+     }
+ 
+ 
+diff --git a/java/org/apache/catalina/core/ApplicationHttpRequest.java b/java/org/apache/catalina/core/ApplicationHttpRequest.java
+index e049e83..5dec356 100644
+--- a/java/org/apache/catalina/core/ApplicationHttpRequest.java
++++ b/java/org/apache/catalina/core/ApplicationHttpRequest.java
+@@ -49,6 +49,7 @@ import org.apache.catalina.connector.RequestFacade;
+ import org.apache.catalina.util.ParameterMap;
+ import org.apache.catalina.util.RequestUtil;
+ import org.apache.catalina.util.URLEncoder;
++import org.apache.tomcat.util.ExceptionUtils;
+ import org.apache.tomcat.util.buf.B2CConverter;
+ import org.apache.tomcat.util.buf.MessageBytes;
+ import org.apache.tomcat.util.http.Parameters;
+@@ -644,7 +645,12 @@ class ApplicationHttpRequest extends HttpServletRequestWrapper {
+      */
+     public void recycle() {
+         if (session != null) {
+-            session.endAccess();
++            try {
++                session.endAccess();
++            } catch (Throwable t) {
++                ExceptionUtils.handleThrowable(t);
++                context.getLogger().warn(sm.getString("applicationHttpRequest.sessionEndAccessFail"), t);
++            }
+         }
+     }
+ 
+diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties
+index fda5ec3..07b916b 100644
+--- a/java/org/apache/catalina/core/LocalStrings.properties
++++ b/java/org/apache/catalina/core/LocalStrings.properties
+@@ -59,6 +59,7 @@ applicationFilterRegistration.nullInitParam=Unable to set initialisation paramet
+ applicationFilterRegistration.nullInitParams=Unable to set initialisation parameters for filter due to null name and/or value. Name [{0}], Value [{1}]
+ 
+ applicationHttpRequest.fragmentInDispatchPath=The fragment in dispatch path [{0}] has been removed
++applicationHttpRequest.sessionEndAccessFail=Exception triggered ending access to session while recycling request
+ 
+ applicationPushBuilder.methodInvalid=The HTTP method for a push request must be both cacheable and safe but [{0}] is not
+ applicationPushBuilder.methodNotToken=HTTP methods must be tokens but [{0}] contains a non-token character
+diff --git a/java/org/apache/catalina/core/LocalStrings_cs.properties b/java/org/apache/catalina/core/LocalStrings_cs.properties
+index d7b676a..9bf2c12 100644
+--- a/java/org/apache/catalina/core/LocalStrings_cs.properties
++++ b/java/org/apache/catalina/core/LocalStrings_cs.properties
+@@ -24,6 +24,8 @@ applicationDispatcher.specViolation.response=Původní ServletResponse nebo zapo
+ 
+ applicationFilterRegistration.nullInitParams=Není možné nastavit inicializační parametry pro filtr kvůli hodnotě null ve jménu či hodnotě. Jméno [{0}], Hodnota [{1}]
+ 
++applicationHttpRequest.sessionEndAccessFail=Výjimka vyvolala ukoncení prístupu k session behem recykllování dotazu
++
+ aprListener.initializingFIPS=Inicializace FIPS módu...
+ 
+ containerBase.backgroundProcess.cluster=Výjimka při zpracování procesu na pozadí v clusteru [{0}]
+diff --git a/java/org/apache/catalina/core/LocalStrings_es.properties b/java/org/apache/catalina/core/LocalStrings_es.properties
+index a5c7d1c..2697328 100644
+--- a/java/org/apache/catalina/core/LocalStrings_es.properties
++++ b/java/org/apache/catalina/core/LocalStrings_es.properties
+@@ -50,6 +50,8 @@ applicationFilterConfig.jmxUnregisterFail=Ha fallado el desregistro JMX para el
+ applicationFilterRegistration.nullInitParam=No puedo poner el parámetro de inicialización para el filtro debido a un nombre nulo y/o valor. Nombre [{0}], Valor [{1}]
+ applicationFilterRegistration.nullInitParams=No puedo poner los parámetros de inicialización para el filtro debido a un nombre nulo y/o valor. Nombre [{0}], Valor [{1}]
+ 
++applicationHttpRequest.sessionEndAccessFail=Excepción disparada acabando acceso a sesión mientras se reciclaba el requerimiento
++
+ applicationServletRegistration.setServletSecurity.iae=Se ha especificado restricción Null para el servlet [{0}] desplegado en el contexto con el nombre [{1}]
+ applicationServletRegistration.setServletSecurity.ise=No se pueden añadir restricciones de seguridad al servlet [{0}] desplegado en el contexto con el nombre [{1}] ya que el contexto ya ha sido inicializado.
+ 
+diff --git a/java/org/apache/catalina/core/LocalStrings_fr.properties b/java/org/apache/catalina/core/LocalStrings_fr.properties
+index cfec4e1..40affff 100644
+--- a/java/org/apache/catalina/core/LocalStrings_fr.properties
++++ b/java/org/apache/catalina/core/LocalStrings_fr.properties
+@@ -60,6 +60,8 @@ applicationFilterRegistration.nullInitParams=Impossible de fixer les paramètres
+ 
+ applicationHttpRequest.fragmentInDispatchPath=Le fragment dans le chemin de dispatch [{0}] a été enlevé
+ 
++applicationHttpRequest.sessionEndAccessFail=Exception lancée durant l'arrêt de l'accès à la session durant le recyclage de la requête
++
+ applicationPushBuilder.methodInvalid=La méthode HTTP pour une requête push doit être à la fois être sans danger et pouvoir être mise en cache, mais [{0}] ne correspond pas
+ applicationPushBuilder.methodNotToken=Les méthodes HTTP doivent être des "token", mais [{0}] contient un caractère invalide dans un token.
+ 
+diff --git a/java/org/apache/catalina/core/LocalStrings_ja.properties b/java/org/apache/catalina/core/LocalStrings_ja.properties
+index 33b3b20..7c7529d 100644
+--- a/java/org/apache/catalina/core/LocalStrings_ja.properties
++++ b/java/org/apache/catalina/core/LocalStrings_ja.properties
+@@ -66,6 +66,8 @@ applicationServletRegistration.setServletSecurity.ise=コンテキストが既
+ 
+ applicationSessionCookieConfig.ise=コンテキスト[{1}]が初期化済みなので、プロパティ[{0}]をSessionCookieConfigに追加することはできません。
+ 
++applicationHttpRequest.sessionEndAccessFail=リクエストの再利用中に行ったセッションへのアクセス終了処理で例外が送出されました。
++
+ aprListener.aprDestroy=APRベースのApache Tomcatネイティブライブラリのシャットダウンに失敗しました。
+ aprListener.aprInit=商用環境に最適な性能を発揮する APR ベースの Tomcat ネイティブライブラリが java.library.path [{0}] に存在しません。
+ aprListener.aprInitDebug=APRベースのApache Tomcatネイティブライブラリは、java.library.path [{1}]上の名前[{0}]を使用して見つかりませんでした。 報告されたエラーは[{2}]
+diff --git a/java/org/apache/catalina/core/LocalStrings_ko.properties b/java/org/apache/catalina/core/LocalStrings_ko.properties
+index 43ce1b7..2e20725 100644
+--- a/java/org/apache/catalina/core/LocalStrings_ko.properties
++++ b/java/org/apache/catalina/core/LocalStrings_ko.properties
+@@ -58,6 +58,8 @@ applicationFilterConfig.release=타입이 [{1}](이)고 이름이 [{0}]인 필
+ applicationFilterRegistration.nullInitParam=이름 또는 값 또는 둘 다 널이어서, 필터를 위한 초기화 파라미터를 설정할 수 없습니다. 이름: [{0}], 값: [{1}]
+ applicationFilterRegistration.nullInitParams=널인 이름 또는 값 때문에, 필터의 초기화 파라미터를 설정할 수 없습니다. 이름: [{0}], 값: [{1}]
+ 
++applicationHttpRequest.sessionEndAccessFail=요청을 참조 해제하는 과정에서, 세션에 대한 접근을 종료시키려 개시하는 중 예외 발생
++
+ applicationHttpRequest.fragmentInDispatchPath=디스패치 경로 [{0}](으)로부터 URI fragment를 제거했습니다.
+ 
+ applicationPushBuilder.methodInvalid=PUSH 요청을 위한 HTTP 메소드는 반드시 캐시 가능하고 안전해야 하는데, [{0}]은(는) 그렇지 않습니다.
+diff --git a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
+index ea8941d..93575d8 100644
+--- a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
++++ b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
+@@ -41,6 +41,8 @@ applicationPushBuilder.methodNotToken=HTTP方法必须是令牌(token),但 [{0
+ 
+ applicationServletRegistration.setServletSecurity.iae=为部署到名为[{1}]的上下文的Servlet[{0}]指定的空约束
+ 
++applicationHttpRequest.sessionEndAccessFail=在回收请求时,异常触发了对会话的结束访问。
++
+ aprListener.aprInitError=基于APR的本地库加载失败.错误报告为[{0}]
+ aprListener.config=APR/OpenSSL配置:useAprConnector[{0}],useOpenSSL[{1}]
+ aprListener.enterAlreadyInFIPSMode=AprLifecycleListener 配置为强制进入FIPS模式,但库已处于FIPS模式[{0}]
+diff --git a/java/org/apache/tomcat/util/buf/B2CConverter.java b/java/org/apache/tomcat/util/buf/B2CConverter.java
+index 532c209..98f989b 100644
+--- a/java/org/apache/tomcat/util/buf/B2CConverter.java
++++ b/java/org/apache/tomcat/util/buf/B2CConverter.java
+@@ -27,6 +27,9 @@ import java.nio.charset.CodingErrorAction;
+ import java.nio.charset.StandardCharsets;
+ import java.util.Locale;
+ 
++import org.apache.juli.logging.Log;
++import org.apache.juli.logging.LogFactory;
++import org.apache.tomcat.util.ExceptionUtils;
+ import org.apache.tomcat.util.res.StringManager;
+ 
+ /**
+@@ -34,6 +37,7 @@ import org.apache.tomcat.util.res.StringManager;
+  */
+ public class B2CConverter {
+ 
++    private static final Log log = LogFactory.getLog(B2CConverter.class);
+     private static final StringManager sm = StringManager.getManager(B2CConverter.class);
+ 
+     private static final CharsetCache charsetCache = new CharsetCache();
+@@ -106,7 +110,12 @@ public class B2CConverter {
+      * Reset the decoder state.
+      */
+     public void recycle() {
+-        decoder.reset();
++        try {
++            decoder.reset();
++        } catch (Throwable t) {
++            ExceptionUtils.handleThrowable(t);
++            log.warn(sm.getString("b2cConverter.decoderResetFail", decoder.charset()), t);
++        }
+         leftovers.position(0);
+     }
+ 
+diff --git a/java/org/apache/tomcat/util/buf/C2BConverter.java b/java/org/apache/tomcat/util/buf/C2BConverter.java
+index 4b27f6c..df23d5b 100644
+--- a/java/org/apache/tomcat/util/buf/C2BConverter.java
++++ b/java/org/apache/tomcat/util/buf/C2BConverter.java
+@@ -24,11 +24,19 @@ import java.nio.charset.CharsetEncoder;
+ import java.nio.charset.CoderResult;
+ import java.nio.charset.CodingErrorAction;
+ 
++import org.apache.juli.logging.Log;
++import org.apache.juli.logging.LogFactory;
++import org.apache.tomcat.util.ExceptionUtils;
++import org.apache.tomcat.util.res.StringManager;
++
+ /**
+  * NIO based character encoder.
+  */
+ public final class C2BConverter {
+ 
++    private static final Log log = LogFactory.getLog(C2BConverter.class);
++    private static final StringManager sm = StringManager.getManager(C2BConverter.class);
++
+     private final CharsetEncoder encoder;
+     private ByteBuffer bb = null;
+     private CharBuffer cb = null;
+@@ -50,7 +58,12 @@ public final class C2BConverter {
+      * Reset the encoder state.
+      */
+     public void recycle() {
+-        encoder.reset();
++        try {
++            encoder.reset();
++        } catch (Throwable t) {
++            ExceptionUtils.handleThrowable(t);
++            log.warn(sm.getString("c2bConverter.decoderResetFail", encoder.charset()), t);
++        }
+         leftovers.position(0);
+     }
+ 
+diff --git a/java/org/apache/tomcat/util/buf/LocalStrings.properties b/java/org/apache/tomcat/util/buf/LocalStrings.properties
+index 7badd5b..b92a20c 100644
+--- a/java/org/apache/tomcat/util/buf/LocalStrings.properties
++++ b/java/org/apache/tomcat/util/buf/LocalStrings.properties
+@@ -16,10 +16,13 @@
+ asn1Parser.lengthInvalid=Invalid length [{0}] bytes reported when the input data length is [{1}] bytes
+ asn1Parser.tagMismatch=Expected to find value [{0}] but found value [{1}]
+ 
++b2cConverter.decoderResetFail=Failed to reset instance of decoder for character set [{0}]
+ b2cConverter.unknownEncoding=The character encoding [{0}] is not supported
+ 
+ byteBufferUtils.cleaner=Cannot use direct ByteBuffer cleaner, memory leaking may occur
+ 
++c2bConverter.encoderResetFail=Failed to reset instance of encoder for character set [{0}]
++
+ chunk.overflow=Buffer overflow and no sink is set, limit [{0}] and buffer length [{1}]
+ 
+ hexUtils.fromHex.nonHex=The input must consist only of hex digits


=====================================
debian/patches/CVE-2023-44487.patch
=====================================
@@ -0,0 +1,331 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:48:12 +0200
+Subject: CVE-2023-44487
+
+Origin: https://github.com/apache/tomcat/commit/30cae120a61f075b1712f2e8da4daa23f1135c83
+Origin: https://github.com/apache/tomcat/commit/94480483910f2d19561e88fb194d7b415bb527da
+Origin: https://github.com/apache/tomcat/commit/3f0efca913b09fa3a3d9c246cc29045ac8a2befe
+Origin: https://github.com/apache/tomcat/commit/6d1a9fd6642387969e4410b9989c85856b74917a
+Origin: https://github.com/apache/tomcat/commit/c551ecaa1ba4ffe50a67009a9c94efb03439ae8b
+---
+ java/org/apache/coyote/http2/Http2AsyncParser.java |  9 ++-
+ .../coyote/http2/Http2AsyncUpgradeHandler.java     |  3 +
+ java/org/apache/coyote/http2/Http2Protocol.java    | 25 ++++++-
+ .../apache/coyote/http2/Http2UpgradeHandler.java   | 78 +++++++++++++++++-----
+ .../apache/coyote/http2/LocalStrings.properties    |  1 +
+ webapps/docs/config/http2.xml                      |  7 ++
+ 6 files changed, 100 insertions(+), 23 deletions(-)
+
+diff --git a/java/org/apache/coyote/http2/Http2AsyncParser.java b/java/org/apache/coyote/http2/Http2AsyncParser.java
+index 827105a..c088e1e 100644
+--- a/java/org/apache/coyote/http2/Http2AsyncParser.java
++++ b/java/org/apache/coyote/http2/Http2AsyncParser.java
+@@ -275,6 +275,7 @@ class Http2AsyncParser extends Http2Parser {
+                                 readUnknownFrame(streamId, frameType, flags, payloadSize, payload);
+                             }
+                         }
++                        if (!upgradeHandler.isOverheadLimitExceeded()) {
+                         // See if there is a new 9 byte header and continue parsing if possible
+                         if (payload.remaining() >= 9) {
+                             int position = payload.position();
+@@ -298,12 +299,14 @@ class Http2AsyncParser extends Http2Parser {
+                                 }
+                             }
+                         }
++                        }
+                     } while (continueParsing);
+                 } catch (RuntimeException | IOException | Http2Exception e) {
+                     error = e;
+-                }
+-                if (payload.hasRemaining()) {
+-                    socketWrapper.unRead(payload);
++                } finally {
++                    if (payload.hasRemaining()) {
++                        socketWrapper.unRead(payload);
++                    }
+                 }
+             }
+             if (state == CompletionState.DONE) {
+diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+index 545292f..9ae89ad 100644
+--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
++++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+@@ -201,6 +201,9 @@ public class Http2AsyncUpgradeHandler extends Http2UpgradeHandler {
+             log.debug(sm.getString("upgradeHandler.writeBody", connectionId, stream.getIdentifier(),
+                     Integer.toString(len)));
+         }
++
++        reduceOverheadCount(FrameType.DATA);
++
+         // Need to check this now since sending end of stream will change this.
+         boolean writeable = stream.canWrite();
+         byte[] header = new byte[9];
+diff --git a/java/org/apache/coyote/http2/Http2Protocol.java b/java/org/apache/coyote/http2/Http2Protocol.java
+index ed23505..2ff219b 100644
+--- a/java/org/apache/coyote/http2/Http2Protocol.java
++++ b/java/org/apache/coyote/http2/Http2Protocol.java
+@@ -52,8 +52,14 @@ public class Http2Protocol implements UpgradeProtocol {
+     // Maximum amount of streams which can be concurrently executed over
+     // a single connection
+     static final int DEFAULT_MAX_CONCURRENT_STREAM_EXECUTION = 20;
+-
+-    static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 1;
++    // Default factor used when adjusting overhead count for overhead frames
++    static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 10;
++    // Default factor used when adjusting overhead count for reset frames
++    static final int DEFAULT_OVERHEAD_RESET_FACTOR = 50;
++    // Not currently configurable. This makes the practical limit for
++    // overheadCountFactor to be ~20. The exact limit will vary with traffic
++    // patterns.
++    static final int DEFAULT_OVERHEAD_REDUCTION_FACTOR = -20;
+     static final int DEFAULT_OVERHEAD_CONTINUATION_THRESHOLD = 1024;
+     static final int DEFAULT_OVERHEAD_DATA_THRESHOLD = 1024;
+     static final int DEFAULT_OVERHEAD_WINDOW_UPDATE_THRESHOLD = 1024;
+@@ -84,6 +90,7 @@ public class Http2Protocol implements UpgradeProtocol {
+     private int maxTrailerCount = Constants.DEFAULT_MAX_TRAILER_COUNT;
+     private int maxTrailerSize = Constants.DEFAULT_MAX_TRAILER_SIZE;
+     private int overheadCountFactor = DEFAULT_OVERHEAD_COUNT_FACTOR;
++    private int overheadResetFactor = DEFAULT_OVERHEAD_RESET_FACTOR;
+     private int overheadContinuationThreshold = DEFAULT_OVERHEAD_CONTINUATION_THRESHOLD;
+     private int overheadDataThreshold = DEFAULT_OVERHEAD_DATA_THRESHOLD;
+     private int overheadWindowUpdateThreshold = DEFAULT_OVERHEAD_WINDOW_UPDATE_THRESHOLD;
+@@ -327,6 +334,20 @@ public class Http2Protocol implements UpgradeProtocol {
+     }
+ 
+ 
++    public int getOverheadResetFactor() {
++        return overheadResetFactor;
++    }
++
++
++    public void setOverheadResetFactor(int overheadResetFactor) {
++        if (overheadResetFactor < 0) {
++            this.overheadResetFactor = 0;
++        } else {
++            this.overheadResetFactor = overheadResetFactor;
++        }
++    }
++
++
+     public int getOverheadContinuationThreshold() {
+         return overheadContinuationThreshold;
+     }
+diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+index 1a72851..348d706 100644
+--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
++++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+@@ -342,7 +342,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                                 stream.close(se);
+                             }
+                         }
+-                        if (overheadCount.get() > 0) {
++                        if (isOverheadLimitExceeded()) {
+                             throw new ConnectionException(
+                                     sm.getString("upgradeHandler.tooMuchOverhead", connectionId),
+                                     Http2Error.ENHANCE_YOUR_CALM);
+@@ -742,7 +742,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                     Integer.toString(len)));
+         }
+ 
+-        reduceOverheadCount();
++        reduceOverheadCount(FrameType.DATA);
+ 
+         // Need to check this now since sending end of stream will change this.
+         boolean writeable = stream.canWrite();
+@@ -1307,13 +1307,54 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+     }
+ 
+ 
+-    private void reduceOverheadCount() {
+-        overheadCount.decrementAndGet();
++    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 remain unchanged 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);
+     }
+ 
+ 
+-    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
++        // increases the overhead count by 1. 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
++        // remain unchanged for each simple request.
++        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.
++        updateOverheadCount(frameType, increment);
++    }
++
++
++    private void updateOverheadCount(FrameType frameType, int increment) {
++        long newOverheadCount = overheadCount.addAndGet(increment);
++        if (log.isDebugEnabled()) {
++            log.debug(sm.getString("upgradeHandler.overheadChange",
++                    connectionId, frameType.name(), Long.valueOf(newOverheadCount)));
++        }
++    }
++
++
++    boolean isOverheadLimitExceeded() {
++        return overheadCount.get() > 0;
+     }
+ 
+ 
+@@ -1372,7 +1413,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+     @Override
+     public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize, boolean endOfStream) throws Http2Exception {
+         // DATA frames reduce the overhead count ...
+-        reduceOverheadCount();
++        reduceOverheadCount(FrameType.DATA);
+ 
+         // .. but lots of small payloads are inefficient so that will increase
+         // the overhead count unless it is the final DATA frame where small
+@@ -1391,7 +1432,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                 average = 1;
+             }
+             if (average < overheadThreshold) {
+-                overheadCount.addAndGet(overheadThreshold / average);
++                increaseOverheadCount(FrameType.DATA, overheadThreshold / average);
+             }
+         }
+ 
+@@ -1457,7 +1498,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                 log.debug(sm.getString("upgradeHandler.noNewStreams",
+                         connectionId, Integer.toString(streamId)));
+             }
+-            reduceOverheadCount();
++            reduceOverheadCount(FrameType.HEADERS);
+             // Stateless so a static can be used to save on GC
+             return HEADER_SINK;
+         }
+@@ -1483,7 +1524,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                     getConnectionId(), Integer.valueOf(streamId)), Http2Error.PROTOCOL_ERROR);
+         }
+ 
+-        increaseOverheadCount();
++        increaseOverheadCount(FrameType.PRIORITY);
+ 
+         Stream stream = getStream(streamId, false);
+         if (stream == null) {
+@@ -1508,9 +1549,9 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+             if (payloadSize < overheadThreshold) {
+                 if (payloadSize == 0) {
+                     // Avoid division by zero
+-                    overheadCount.addAndGet(overheadThreshold);
++                    increaseOverheadCount(FrameType.HEADERS, overheadThreshold);
+                 } else {
+-                    overheadCount.addAndGet(overheadThreshold / payloadSize);
++                    increaseOverheadCount(FrameType.HEADERS, overheadThreshold / payloadSize);
+                 }
+             }
+         }
+@@ -1528,13 +1569,13 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                     if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
+                         setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
+                         // Ignoring maxConcurrentStreams increases the overhead count
+-                        increaseOverheadCount();
++                        increaseOverheadCount(FrameType.HEADERS);
+                         throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
+                                 Long.toString(localSettings.getMaxConcurrentStreams())),
+                                 Http2Error.REFUSED_STREAM, streamId);
+                     }
+                     // Valid new stream reduces the overhead count
+-                    reduceOverheadCount();
++                    reduceOverheadCount(FrameType.HEADERS);
+ 
+                     processStreamOnContainerThread(stream);
+                 }
+@@ -1552,6 +1593,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+ 
+     @Override
+     public void reset(int streamId, long errorCode) throws Http2Exception  {
++        increaseOverheadCount(FrameType.RST);
+         Stream stream = getStream(streamId, true);
+         stream.checkState(FrameType.RST);
+         stream.receiveReset(errorCode);
+@@ -1561,7 +1603,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+     @Override
+     public void setting(Setting setting, long value) throws ConnectionException {
+ 
+-        increaseOverheadCount();
++        increaseOverheadCount(FrameType.SETTINGS);
+ 
+         // Possible with empty settings frame
+         if (setting == null) {
+@@ -1610,7 +1652,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+     @Override
+     public void pingReceive(byte[] payload, boolean ack) throws IOException {
+         if (!ack) {
+-            increaseOverheadCount();
++            increaseOverheadCount(FrameType.PING);
+         }
+         pingManager.receivePing(payload, ack);
+     }
+@@ -1646,7 +1688,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+             // Check for small increments which are inefficient
+             if (average < overheadThreshold) {
+                 // The smaller the increment, the larger the overhead
+-                overheadCount.addAndGet(overheadThreshold / average);
++                increaseOverheadCount(FrameType.WINDOW_UPDATE, overheadThreshold / average);
+             }
+ 
+             incrementWindowSize(increment);
+@@ -1660,7 +1702,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
+                 BacklogTracker tracker = backLogStreams.get(stream);
+                 if (tracker == null || increment < tracker.getRemainingReservation()) {
+                     // The smaller the increment, the larger the overhead
+-                    overheadCount.addAndGet(overheadThreshold / average);
++                    increaseOverheadCount(FrameType.WINDOW_UPDATE, overheadThreshold / average);
+                 }
+             }
+ 
+diff --git a/java/org/apache/coyote/http2/LocalStrings.properties b/java/org/apache/coyote/http2/LocalStrings.properties
+index f9ef251..bb15aa0 100644
+--- a/java/org/apache/coyote/http2/LocalStrings.properties
++++ b/java/org/apache/coyote/http2/LocalStrings.properties
+@@ -123,6 +123,7 @@ upgradeHandler.invalidPreface=Connection [{0}], Invalid connection preface
+ upgradeHandler.ioerror=Connection [{0}]
+ upgradeHandler.noAllocation=Connection [{0}], Stream [{1}], Timeout waiting for allocation
+ upgradeHandler.noNewStreams=Connection [{0}], Stream [{1}], Stream ignored as no new streams are permitted on this connection
++upgradeHandler.overheadChange=Connection [{0}], Stream [{1}], Frame type [{2}] resulted in new overhead count of [{3}]
+ upgradeHandler.pause.entry=Connection [{0}] Pausing
+ upgradeHandler.pingFailed=Connection [{0}] Failed to send ping to client
+ upgradeHandler.prefaceReceived=Connection [{0}], Connection preface received from client
+diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml
+index 00f75cb..a18885e 100644
+--- a/webapps/docs/config/http2.xml
++++ b/webapps/docs/config/http2.xml
+@@ -221,6 +221,13 @@
+       used.</p>
+     </attribute>
+ 
++    <attribute name="overheadResetFactor" required="false">
++      <p>The amount by which the overhead count (see
++      <strong>overheadCountFactor</strong>) will be increased for each reset
++      frame received. If not specified, a default value of <code>50</code> will
++      be used. A value of less than zero will be treated as zero.</p>
++    </attribute>
++
+     <attribute name="overheadDataThreshold" required="false">
+       <p>The threshold below which the average payload size of the current and
+       previous non-final <code>DATA</code> frames will trigger an increase in


=====================================
debian/patches/CVE-2023-45648.patch
=====================================
@@ -0,0 +1,97 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 11 Oct 2023 11:52:29 +0200
+Subject: CVE-2023-45648
+
+Origin: https://github.com/apache/tomcat/commit/59583245639d8c42ae0009f4a4a70464d3ea70a0
+---
+ java/org/apache/coyote/http11/Http11InputBuffer.java      |  8 +++++++-
+ .../apache/coyote/http11/filters/ChunkedInputFilter.java  | 15 ++++++++++++++-
+ .../apache/coyote/http11/filters/LocalStrings.properties  |  2 ++
+ 3 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java b/java/org/apache/coyote/http11/Http11InputBuffer.java
+index 4e311de..00779ed 100644
+--- a/java/org/apache/coyote/http11/Http11InputBuffer.java
++++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
+@@ -764,6 +764,12 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
+         byte chr = 0;
+         byte prevChr = 0;
+ 
++        /*
++         * Implementation note: Any changes to this method probably need to be echoed in
++         * ChunkedInputFilter.parseHeader(). Why not use a common implementation? In short, this code uses non-blocking
++         * reads whereas ChunkedInputFilter using blocking reads. The code is just different enough that a common
++         * implementation wasn't viewed as practical.
++         */
+         while (headerParsePos == HeaderParsePosition.HEADER_START) {
+ 
+             // Read new bytes if needed
+@@ -896,7 +902,7 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
+                     } else if (prevChr == Constants.CR) {
+                         // Invalid value - also need to delete header
+                         return skipLine(true);
+-                    } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
++                    } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
+                         // Invalid value - also need to delete header
+                         return skipLine(true);
+                     } else if (chr == Constants.SP || chr == Constants.HT) {
+diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+index c806ead..e5ef4f4 100644
+--- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
++++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+@@ -30,6 +30,7 @@ import org.apache.coyote.http11.Constants;
+ import org.apache.coyote.http11.InputFilter;
+ import org.apache.tomcat.util.buf.ByteChunk;
+ import org.apache.tomcat.util.buf.HexUtils;
++import org.apache.tomcat.util.http.parser.HttpParser;
+ import org.apache.tomcat.util.net.ApplicationBufferHandler;
+ import org.apache.tomcat.util.res.StringManager;
+ 
+@@ -434,6 +435,13 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler
+ 
+     private boolean parseHeader() throws IOException {
+ 
++        /*
++         * Implementation note: Any changes to this method probably need to be echoed in
++         * Http11InputBuffer.parseHeader(). Why not use a common implementation? In short, this code uses blocking
++         * reads whereas Http11InputBuffer using non-blocking reads. The code is just different enough that a common
++         * implementation wasn't viewed as practical.
++         */
++
+         Map<String,String> headers = request.getTrailerFields();
+ 
+         byte chr = 0;
+@@ -480,6 +488,9 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler
+ 
+             if (chr == Constants.COLON) {
+                 colon = true;
++            } else if (!HttpParser.isToken(chr)) {
++                // Non-token characters are illegal in header names
++                throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderName"));
+             } else {
+                 trailingHeaders.append(chr);
+             }
+@@ -541,7 +552,9 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler
+                 if (chr == Constants.CR || chr == Constants.LF) {
+                     parseCRLF(true);
+                     eol = true;
+-                } else if (chr == Constants.SP) {
++                } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
++                    throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderValue"));
++                } else if (chr == Constants.SP || chr == Constants.HT) {
+                     trailingHeaders.append(chr);
+                 } else {
+                     trailingHeaders.append(chr);
+diff --git a/java/org/apache/coyote/http11/filters/LocalStrings.properties b/java/org/apache/coyote/http11/filters/LocalStrings.properties
+index c0dc9d1..aa1b19d 100644
+--- a/java/org/apache/coyote/http11/filters/LocalStrings.properties
++++ b/java/org/apache/coyote/http11/filters/LocalStrings.properties
+@@ -21,6 +21,8 @@ chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR)
+ chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF)
+ chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
+ chunkedInputFilter.invalidHeader=Invalid chunk header
++chunkedInputFilter.invalidTrailerHeaderName=Invalid trailer header name (non-token character in name)
++chunkedInputFilter.invalidTrailerHeaderValue=Invalid trailer header value (control character in value)
+ chunkedInputFilter.maxExtension=maxExtensionSize exceeded
+ chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
+ 


=====================================
debian/patches/series
=====================================
@@ -29,3 +29,9 @@ CVE-2022-23181.patch
 CVE-2022-29885.patch
 CVE-2022-42252.patch
 CVE-2023-28708.patch
+CVE-2023-24998.patch
+CVE-2023-28709.patch
+CVE-2023-41080.patch
+CVE-2023-42795.patch
+CVE-2023-44487.patch
+CVE-2023-45648.patch



View it on GitLab: https://salsa.debian.org/java-team/tomcat9/-/commit/e71e6118d788a4fdc846cc3dd0773b056b6e93c0

-- 
View it on GitLab: https://salsa.debian.org/java-team/tomcat9/-/commit/e71e6118d788a4fdc846cc3dd0773b056b6e93c0
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/20231014/5ce94d92/attachment.htm>


More information about the pkg-java-commits mailing list