From d109bef5d2e35286556bb0a33112d861b08d77ac Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Tue, 23 Jan 2024 11:24:34 +0800 Subject: [PATCH] Fix CVE-2024-21733,CVE-2023-24998,CVE-2023-28709,CVE-2023-42795 (cherry picked from commit bd720aedf3533874321aa13f9122881a5f402d8b) --- CVE-2023-24998.patch | 253 ++++++++ CVE-2023-28709.patch | 35 ++ CVE-2023-42795.patch | 251 ++++++++ CVE-2024-21733.patch | 579 ++++++++++++++++++ ...e-commons-daemon-1.3.3-1.oe2309.x86_64.rpm | Bin 0 -> 60325 bytes tomcat.spec | 9 +- 6 files changed, 1126 insertions(+), 1 deletion(-) create mode 100644 CVE-2023-24998.patch create mode 100644 CVE-2023-28709.patch create mode 100644 CVE-2023-42795.patch create mode 100644 CVE-2024-21733.patch create mode 100644 apache-commons-daemon-1.3.3-1.oe2309.x86_64.rpm diff --git a/CVE-2023-24998.patch b/CVE-2023-24998.patch new file mode 100644 index 0000000..7920aa8 --- /dev/null +++ b/CVE-2023-24998.patch @@ -0,0 +1,253 @@ +From cf77cc545de0488fb89e24294151504a7432df74 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Tue, 13 Dec 2022 17:55:34 +0000 +Subject: [PATCH] Update packaged renamed fork of Commons File Upload + +Origin: https://github.com/apache/tomcat/commit/cf77cc545de0488fb89e24294151504a7432df74 + +--- + .../apache/catalina/connector/Request.java | 12 ++++- + .../apache/tomcat/util/http/Parameters.java | 4 ++ + .../util/http/fileupload/FileUploadBase.java | 29 +++++++++++ + .../impl/FileCountLimitExceededException.java | 50 +++++++++++++++++++ + webapps/docs/changelog.xml | 8 +++ + webapps/docs/config/ajp.xml | 15 +++--- + webapps/docs/config/http.xml | 15 +++--- + 7 files changed, 119 insertions(+), 14 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 889d5e7..87ab732 100644 +--- a/java/org/apache/catalina/connector/Request.java ++++ b/java/org/apache/catalina/connector/Request.java +@@ -2769,8 +2769,9 @@ public class Request implements HttpServletRequest { + } + } + +- Parameters parameters = coyoteRequest.getParameters(); +- parameters.setLimit(getConnector().getMaxParameterCount()); ++ int maxParameterCount = getConnector().getMaxParameterCount(); ++ Parameters parameters = coyoteRequest.getParameters(); ++ parameters.setLimit(maxParameterCount); + + boolean success = false; + try { +@@ -2814,6 +2815,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..08c6ffd 100644 +--- a/java/org/apache/tomcat/util/http/Parameters.java ++++ b/java/org/apache/tomcat/util/http/Parameters.java +@@ -124,6 +124,10 @@ public final class Parameters { + } + } + ++ public int size() { ++ return parameterCount; ++ } ++ + + public void recycle() { + parameterCount = 0; +diff --git a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java +index eb5a487..5506754 100644 +--- a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java ++++ b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java +@@ -26,6 +26,7 @@ import java.util.Locale; + import java.util.Map; + import java.util.NoSuchElementException; + ++import org.apache.tomcat.util.http.fileupload.impl.FileCountLimitExceededException; + import org.apache.tomcat.util.http.fileupload.MultipartStream.ItemInputStream; + import org.apache.tomcat.util.http.fileupload.util.Closeable; + import org.apache.tomcat.util.http.fileupload.util.FileItemHeadersImpl; +@@ -131,6 +132,12 @@ public abstract class FileUploadBase { + * to {@link #sizeMax}. A value of -1 indicates no maximum. + */ + 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. +@@ -208,6 +215,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 null, 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 = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; +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/changelog.xml b/webapps/docs/changelog.xml +index 835b0d0..0268d87 100644 +--- a/webapps/docs/changelog.xml ++++ b/webapps/docs/changelog.xml +@@ -44,6 +44,14 @@ + They eventually become mixed with the numbered issues. (I.e., numbered + issues do not "pop up" wrt. others). + --> ++ ++ ++ ++ Update the internal fork of Apache Commons FileUpload to 34eb241 ++ (2023-01-03, 2.0-SNAPSHOT). (markt) ++ ++ ++ +
+ + +diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml +index 622e7ca..38c5269 100644 +--- a/webapps/docs/config/ajp.xml ++++ b/webapps/docs/config/ajp.xml +@@ -114,12 +114,15 @@ + + + +-

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 +- FailedRequestFilter filter can be +- used to reject requests that hit the limit.

++

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 ++ application/x-www-form-urlencoded or ++ multipart/form-data. 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 FailedRequestFilter ++ filter can be used to reject requests that ++ exceed the limit.

+
+ + +diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml +index 3902c9a..52ad063 100644 +--- a/webapps/docs/config/http.xml ++++ b/webapps/docs/config/http.xml +@@ -111,12 +111,15 @@ + + + +-

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 +- FailedRequestFilter filter can be +- used to reject requests that hit the limit.

++

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 ++ application/x-www-form-urlencoded or ++ multipart/form-data. 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 FailedRequestFilter ++ filter can be used to reject requests that ++ exceed the limit.

+
+ + +-- +2.33.0 diff --git a/CVE-2023-28709.patch b/CVE-2023-28709.patch new file mode 100644 index 0000000..5768c20 --- /dev/null +++ b/CVE-2023-28709.patch @@ -0,0 +1,35 @@ +From fbd81421629afe8b8a3922d59020cde81caea861 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Tue, 11 Apr 2023 16:41:44 +0100 +Subject: [PATCH] Fix parameter counting logic + +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 08c6ffd..a19453d 100644 +--- a/java/org/apache/tomcat/util/http/Parameters.java ++++ b/java/org/apache/tomcat/util/http/Parameters.java +@@ -205,14 +205,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 values = paramHashValues.get(key); + if (values == null) { +-- +2.33.0 + diff --git a/CVE-2023-42795.patch b/CVE-2023-42795.patch new file mode 100644 index 0000000..2ac136b --- /dev/null +++ b/CVE-2023-42795.patch @@ -0,0 +1,251 @@ +From 44d05d75d696ca10ce251e4e370511e38f20ae75 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Thu, 5 Oct 2023 20:52:46 +0100 +Subject: [PATCH] Improve handling of failures during recycle() methods + +Origin: https://github.com/apache/tomcat/commit/44d05d75d696ca10ce251e4e370511e38f20ae75 + +--- + .../catalina/connector/LocalStrings.properties | 1 + + java/org/apache/catalina/connector/Request.java | 7 ++++--- + .../catalina/core/ApplicationHttpRequest.java | 16 ++++++++++++---- + .../apache/catalina/core/LocalStrings.properties | 1 + + .../catalina/core/LocalStrings_es.properties | 2 ++ + .../catalina/core/LocalStrings_fr.properties | 1 + + .../catalina/core/LocalStrings_ja.properties | 1 + + .../org/apache/tomcat/util/buf/B2CConverter.java | 11 ++++++++++- + .../org/apache/tomcat/util/buf/C2BConverter.java | 15 ++++++++++++++- + .../tomcat/util/buf/LocalStrings.properties | 3 +++ + 10 files changed, 49 insertions(+), 9 deletions(-) + +diff --git a/java/org/apache/catalina/connector/LocalStrings.properties b/java/org/apache/catalina/connector/LocalStrings.properties +index 86c6487..596805b 100644 +--- a/java/org/apache/catalina/connector/LocalStrings.properties ++++ b/java/org/apache/catalina/connector/LocalStrings.properties +@@ -47,6 +47,7 @@ coyoteRequest.setAttribute.namenull=Cannot call setAttribute with a null name + coyoteRequest.attributeEvent=Exception thrown by attributes event listener + coyoteRequest.parseParameters=Exception thrown whilst processing POSTed parameters + coyoteRequest.postTooLarge=Parameters were not parsed because the size of the posted data was too big. 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.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.alreadyAuthenticated=This request has already been authenticated + coyoteRequest.authenticate.ise=Cannot call authenticate() after the response has been committed +diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java +index 889d5e7..de53769 100644 +--- a/java/org/apache/catalina/connector/Request.java ++++ b/java/org/apache/catalina/connector/Request.java +@@ -465,8 +465,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; +@@ -518,8 +519,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 fc3a1d6..0b5b4f5 100644 +--- a/java/org/apache/catalina/core/ApplicationHttpRequest.java ++++ b/java/org/apache/catalina/core/ApplicationHttpRequest.java +@@ -29,6 +29,8 @@ import java.util.Enumeration; + import java.util.List; + import java.util.Map; + import java.util.NoSuchElementException; ++import java.util.Arrays; ++import java.util.HashMap; + + import javax.servlet.DispatcherType; + import javax.servlet.RequestDispatcher; +@@ -48,9 +50,12 @@ import org.apache.catalina.Session; + 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; ++import org.apache.tomcat.util.res.StringManager; + + + /** +@@ -70,9 +75,7 @@ import org.apache.tomcat.util.http.Parameters; + */ + class ApplicationHttpRequest extends HttpServletRequestWrapper { + +- +- // ------------------------------------------------------- Static Variables +- ++ private static final StringManager sm = StringManager.getManager(ApplicationHttpRequest.class); + + /** + * The set of attribute names that are special for request dispatchers. +@@ -626,7 +629,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 c5b55b1..0e17e3c 100644 +--- a/java/org/apache/catalina/core/LocalStrings.properties ++++ b/java/org/apache/catalina/core/LocalStrings.properties +@@ -55,6 +55,7 @@ applicationFilterConfig.release=Failed to destroy the filter named [{0}] of type + applicationFilterRegistration.nullInitParam=Unable to set initialisation parameter for filter due to null name and/or value. Name [{0}], Value [{1}] + applicationFilterRegistration.nullInitParams=Unable to set initialisation parameters for filter due to null name and/or value. Name [{0}], Value [{1}] + ++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 + applicationPushBuilder.noCoyoteRequest=Unable to find the underlying Coyote request object (which is required to create a push request) from the request of type [{0}] +diff --git a/java/org/apache/catalina/core/LocalStrings_es.properties b/java/org/apache/catalina/core/LocalStrings_es.properties +index f138d17..e6a9ab2 100644 +--- a/java/org/apache/catalina/core/LocalStrings_es.properties ++++ b/java/org/apache/catalina/core/LocalStrings_es.properties +@@ -43,6 +43,8 @@ applicationFilterConfig.jmxUnregister = Se ha completado el desregistro JMX para + applicationFilterConfig.jmxUnregisterFail = Ha fallado el desregistro JMX para el filtro del tipo [{0}] y nombre [{1}] + applicationFilterRegistration.nullInitParam = No puedo poner el par\u00E1metro de inicializaci\u00F3n para el filtro debido a un nombre nulo y/o valor. Nombre [{0}], Valor [{1}] + applicationFilterRegistration.nullInitParams = No puedo poner los par\u00E1metros de inicializaci\u00F3n 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\u00F3n Null para el servlet [{0}] desplegado en el contexto con el nombre [{1}] + applicationServletRegistration.setServletSecurity.ise = No se pueden a\u00F1adir restricciones de seguridad al servlet [{0}] desplegado en el contexto con el nombre [{1}] ya que el contexto ya ha sido inicializado. + aprListener.aprInit = La biblioteca nativa de Apache Tomcat basada en ARP que permite un rendimiento \u00F3ptimo en entornos de desarrollo no ha sido hallada en java.library.path: [{0}] +diff --git a/java/org/apache/catalina/core/LocalStrings_fr.properties b/java/org/apache/catalina/core/LocalStrings_fr.properties +index dfc1cf7..91ead47 100644 +--- a/java/org/apache/catalina/core/LocalStrings_fr.properties ++++ b/java/org/apache/catalina/core/LocalStrings_fr.properties +@@ -59,6 +59,7 @@ standardContext.startFailed=Erreur de d\u00e9marrage du contexte [{0}] suite aux + standardContext.startingContext=Exception lors du d\u00e9marrage du contexte [{0}] + standardContext.stoppingContext=Exception \u00e0 l''arr\u00eat du Context [{0}] + standardContext.resourcesStart=Erreur lors du d\u00e9marrage des ressources statiques ++applicationHttpRequest.sessionEndAccessFail=Exception lancée durant l'arrêt de l'accès à la session durant le recyclage de la requête + standardContext.urlPattern.patternWarning=ATTENTION: Le mod\u00e8le (pattern) URL [{0}] doit commencer par un ''/'' dans l''API Servlet 2.4 + standardEngine.noHost=Aucune h\u00f4te (host) ne correspond au nom de serveur [{0}] + standardEngine.notHost=Le fils d''un moteur (child of an Engine) doit \u00eatre un h\u00f4te +diff --git a/java/org/apache/catalina/core/LocalStrings_ja.properties b/java/org/apache/catalina/core/LocalStrings_ja.properties +index d34d598..ae85dd4 100644 +--- a/java/org/apache/catalina/core/LocalStrings_ja.properties ++++ b/java/org/apache/catalina/core/LocalStrings_ja.properties +@@ -66,6 +66,7 @@ standardEngine.notParent=\u30a8\u30f3\u30b8\u30f3\u306f\u89aa\u306e\u30b3\u30f3\ + standardHost.clientAbort=\u30ea\u30e2\u30fc\u30c8\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u4e2d\u6b62\u3057\u307e\u3057\u305f, IOException: [{0}] + standardHost.invalidErrorReportValveClass=\u6307\u5b9a\u3055\u308c\u305f\u30a8\u30e9\u30fc\u30ea\u30dd\u30fc\u30c8\u30d0\u30eb\u30d6\u30af\u30e9\u30b9\u3092\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093: [{0}] + standardHost.noContext=\u3053\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u51e6\u7406\u3059\u308b\u305f\u3081\u306b\u8a2d\u5b9a\u3055\u308c\u305f\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093 ++applicationHttpRequest.sessionEndAccessFail=リクエストの再利用中に行ったセッションへのアクセス終了処理で例外が送出されました。 + standardHost.notContext=\u30db\u30b9\u30c8\u306e\u5b50\u4f9b\u306f\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093 + standardHost.nullName=\u30db\u30b9\u30c8\u540d\u304c\u5fc5\u8981\u3067\u3059 + standardService.start.name=\u30b5\u30fc\u30d3\u30b9 [{0}] \u3092\u8d77\u52d5\u3057\u307e\u3059 +diff --git a/java/org/apache/tomcat/util/buf/B2CConverter.java b/java/org/apache/tomcat/util/buf/B2CConverter.java +index f046ad7..1e3e1f4 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.HashMap; + import java.util.Locale; ++import org.apache.juli.logging.Log; ++import org.apache.juli.logging.LogFactory; ++import org.apache.tomcat.util.ExceptionUtils; + import java.util.Map; + + import org.apache.tomcat.util.res.StringManager; +@@ -35,6 +38,7 @@ import org.apache.tomcat.util.res.StringManager; + * NIO based character decoder. + */ + public class B2CConverter { ++ private static final Log log = LogFactory.getLog(B2CConverter.class); + + private static final StringManager sm = StringManager.getManager(B2CConverter.class); + +@@ -120,7 +124,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 e5062de..f3b4dd7 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 c8a8d3b..574f6c2 100644 +--- a/java/org/apache/tomcat/util/buf/LocalStrings.properties ++++ b/java/org/apache/tomcat/util/buf/LocalStrings.properties +@@ -13,9 +13,12 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + ++b2cConverter.decoderResetFail=Failed to reset instance of decoder for character set [{0}] + b2cConverter.unknownEncoding=The character encoding [{0}] is not supported + c2bConverter.recycleFailed=Failed to recycle the C2B Converter. Creating new BufferedWriter, WriteConvertor and IntermediateOutputStream. + ++c2bConverter.encoderResetFail=Failed to reset instance of encoder for character set [{0}] ++ + hexUtils.fromHex.oddDigits=The input must consist of an even number of hex digits + hexUtils.fromHex.nonHex=The input must consist only of hex digits + +-- +2.33.0 diff --git a/CVE-2024-21733.patch b/CVE-2024-21733.patch new file mode 100644 index 0000000..d43417c --- /dev/null +++ b/CVE-2024-21733.patch @@ -0,0 +1,579 @@ +From ce4b154e7b48f66bd98858626347747cd2514311 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Thu, 18 Feb 2021 16:41:57 +0000 +Subject: [PATCH] Ensure ReadListener.onError() is fired if client drops the + connection + +Origin: +https://github.com/apache/tomcat/commit/659b28c00d94e2a9049e0a8ac1e02bd4d36dd005 +https://github.com/apache/tomcat/commit/f562edd3302866f34c0ca9fa97f6ff414450f1ae +https://github.com/apache/tomcat/commit/918146f9d04af67d904b47c440acaab14380521b +https://github.com/apache/tomcat/commit/504445cd2c618fb1edbfeda62e07e1c29b4d285c +https://github.com/apache/tomcat/commit/ce4b154e7b48f66bd98858626347747cd2514311 + +--- + .../catalina/core/StandardWrapperValve.java | 2 + + .../coyote/http11/Http11InputBuffer.java | 43 +++- + .../coyote/http11/Http11OutputBuffer.java | 15 +- + .../catalina/core/TestAsyncContextImpl.java | 172 +++++++++++++++- + .../nonblocking/TestNonBlockingAPI.java | 192 ++++++++++++++++++ + 5 files changed, 412 insertions(+), 12 deletions(-) + +diff --git a/java/org/apache/catalina/core/StandardWrapperValve.java b/java/org/apache/catalina/core/StandardWrapperValve.java +index 27f136a..89f5915 100644 +--- a/java/org/apache/catalina/core/StandardWrapperValve.java ++++ b/java/org/apache/catalina/core/StandardWrapperValve.java +@@ -29,6 +29,7 @@ import javax.servlet.ServletException; + import javax.servlet.UnavailableException; + import javax.servlet.http.HttpServletResponse; + ++import org.apache.catalina.Container; + import org.apache.catalina.Context; + import org.apache.catalina.Globals; + import org.apache.catalina.LifecycleException; +@@ -174,6 +175,7 @@ final class StandardWrapperValve + + // Call the filter chain for this request + // NOTE: This also calls the servlet's service() method ++ Container container = this.container; + try { + if ((servlet != null) && (filterChain != null)) { + // Swallow output if needed +diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java b/java/org/apache/coyote/http11/Http11InputBuffer.java +index 27392d4..db596b4 100644 +--- a/java/org/apache/coyote/http11/Http11InputBuffer.java ++++ b/java/org/apache/coyote/http11/Http11InputBuffer.java +@@ -22,6 +22,7 @@ import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.Arrays; + ++import org.apache.coyote.CloseNowException; + import org.apache.coyote.InputBuffer; + import org.apache.coyote.Request; + import org.apache.juli.logging.Log; +@@ -382,10 +383,6 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler + + parsingRequestLineStart = byteBuffer.position(); + parsingRequestLinePhase = 2; +- if (log.isDebugEnabled()) { +- log.debug("Received [" +- + new String(byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining(), StandardCharsets.ISO_8859_1) + "]"); +- } + } + if (parsingRequestLinePhase == 2) { + // +@@ -709,6 +706,16 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler + */ + private boolean fill(boolean block) throws IOException { + ++ if (log.isDebugEnabled()) { ++ log.debug("Before fill(): parsingHeader: [" + parsingHeader + ++ "], parsingRequestLine: [" + parsingRequestLine + ++ "], parsingRequestLinePhase: [" + parsingRequestLinePhase + ++ "], parsingRequestLineStart: [" + parsingRequestLineStart + ++ "], byteBuffer.position(): [" + byteBuffer.position() + ++ "], byteBuffer.limit(): [" + byteBuffer.limit() + ++ "], end: [" + end + "]"); ++ } ++ + if (parsingHeader) { + if (byteBuffer.limit() >= headerBufferSize) { + if (parsingRequestLine) { +@@ -721,13 +728,31 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler + byteBuffer.limit(end).position(end); + } + ++ int nRead = -1; + byteBuffer.mark(); +- if (byteBuffer.position() < byteBuffer.limit()) { +- byteBuffer.position(byteBuffer.limit()); ++ try { ++ if (byteBuffer.position() < byteBuffer.limit()) { ++ byteBuffer.position(byteBuffer.limit()); ++ } ++ byteBuffer.limit(byteBuffer.capacity()); ++ SocketWrapperBase socketWrapper = this.wrapper; ++ if (socketWrapper != null) { ++ nRead = socketWrapper.read(block, byteBuffer); ++ } else { ++ throw new CloseNowException(sm.getString("iib.eof.error")); ++ } ++ } finally { ++ // Ensure that the buffer limit and position are returned to a ++ // consistent "ready for read" state if an error occurs during in ++ // the above code block. ++ byteBuffer.limit(byteBuffer.position()).reset(); + } +- byteBuffer.limit(byteBuffer.capacity()); +- int nRead = wrapper.read(block, byteBuffer); +- byteBuffer.limit(byteBuffer.position()).reset(); ++ ++ if (log.isDebugEnabled()) { ++ log.debug("Received [" ++ + new String(byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining(), StandardCharsets.ISO_8859_1) + "]"); ++ } ++ + if (nRead > 0) { + return true; + } else if (nRead == -1) { +diff --git a/java/org/apache/coyote/http11/Http11OutputBuffer.java b/java/org/apache/coyote/http11/Http11OutputBuffer.java +index aa5ad48..c369837 100644 +--- a/java/org/apache/coyote/http11/Http11OutputBuffer.java ++++ b/java/org/apache/coyote/http11/Http11OutputBuffer.java +@@ -21,6 +21,7 @@ import java.nio.ByteBuffer; + import java.util.Arrays; + + import org.apache.coyote.ActionCode; ++import org.apache.coyote.CloseNowException; + import org.apache.coyote.Response; + import org.apache.tomcat.util.buf.ByteChunk; + import org.apache.tomcat.util.buf.MessageBytes; +@@ -303,7 +304,12 @@ public class Http11OutputBuffer implements HttpOutputBuffer { + // Sending the response header buffer + headerBuffer.flip(); + try { +- socketWrapper.write(isBlocking(), headerBuffer); ++ SocketWrapperBase socketWrapper = this.socketWrapper; ++ if (socketWrapper != null) { ++ socketWrapper.write(isBlocking(), headerBuffer); ++ } else { ++ throw new CloseNowException(sm.getString("iob.failedwrite")); ++ } + } finally { + headerBuffer.position(0).limit(headerBuffer.capacity()); + } +@@ -527,7 +533,12 @@ public class Http11OutputBuffer implements HttpOutputBuffer { + public int doWrite(ByteBuffer chunk) throws IOException { + try { + int len = chunk.remaining(); +- socketWrapper.write(isBlocking(), chunk); ++ SocketWrapperBase socketWrapper = Http11OutputBuffer.this.socketWrapper; ++ if (socketWrapper != null) { ++ socketWrapper.write(isBlocking(), chunk); ++ } else { ++ throw new CloseNowException(sm.getString("iob.failedwrite")); ++ } + len -= chunk.remaining(); + byteCount += len; + return len; +diff --git a/test/org/apache/catalina/core/TestAsyncContextImpl.java b/test/org/apache/catalina/core/TestAsyncContextImpl.java +index 3f6524b..4023a74 100644 +--- a/test/org/apache/catalina/core/TestAsyncContextImpl.java ++++ b/test/org/apache/catalina/core/TestAsyncContextImpl.java +@@ -17,6 +17,7 @@ + package org.apache.catalina.core; + + import java.io.IOException; ++import java.io.InputStream; + import java.io.PrintWriter; + import java.net.URI; + import java.net.URISyntaxException; +@@ -819,7 +820,7 @@ public class TestAsyncContextImpl extends TomcatBaseTest { + } + } + +- private static class TrackingListener implements AsyncListener { ++ public static class TrackingListener implements AsyncListener { + + private final boolean completeOnError; + private final boolean completeOnTimeout; +@@ -2653,4 +2654,173 @@ public class TestAsyncContextImpl extends TomcatBaseTest { + } + + } ++ ++ ++ ++ /* ++ * Tests an error on an async thread when the client closes the connection ++ * before fully writing the request body. ++ * ++ * Required sequence is: ++ * - enter Servlet's service() method ++ * - startAsync() ++ * - start async thread ++ * - read partial body ++ * - close client connection ++ * - read on async thread -> I/O error ++ * - exit Servlet's service() method ++ * ++ * This test makes extensive use of instance fields in the Servlet that ++ * would normally be considered very poor practice. It is only safe in this ++ * test as the Servlet only processes a single request. ++ */ ++ @Test ++ public void testCanceledPost() throws Exception { ++ CountDownLatch partialReadLatch = new CountDownLatch(1); ++ CountDownLatch clientCloseLatch = new CountDownLatch(1); ++ CountDownLatch threadCompleteLatch = new CountDownLatch(1); ++ ++ AtomicBoolean testFailed = new AtomicBoolean(true); ++ ++ // Setup Tomcat instance ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ PostServlet postServlet = new PostServlet(partialReadLatch, clientCloseLatch, threadCompleteLatch, testFailed); ++ Wrapper wrapper = Tomcat.addServlet(ctx, "postServlet", postServlet); ++ wrapper.setAsyncSupported(true); ++ ctx.addServletMappingDecoded("/*", "postServlet"); ++ ++ tomcat.start(); ++ ++ PostClient client = new PostClient(); ++ client.setPort(getPort()); ++ client.setRequest(new String[] { "POST / HTTP/1.1" + SimpleHttpClient.CRLF + ++ "Host: localhost:" + SimpleHttpClient.CRLF + ++ "Content-Length: 100" + SimpleHttpClient.CRLF + ++ SimpleHttpClient.CRLF + ++ "This is 16 bytes" ++ }); ++ client.connect(); ++ client.sendRequest(); ++ ++ // Wait server to read partial request body ++ partialReadLatch.await(); ++ ++ client.disconnect(); ++ ++ clientCloseLatch.countDown(); ++ ++ threadCompleteLatch.await(); ++ ++ Assert.assertFalse(testFailed.get()); ++ } ++ ++ ++ private static final class PostClient extends SimpleHttpClient { ++ ++ @Override ++ public boolean isResponseBodyOK() { ++ return true; ++ } ++ } ++ ++ ++ private static final class PostServlet extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ private final transient CountDownLatch partialReadLatch; ++ private final transient CountDownLatch clientCloseLatch; ++ private final transient CountDownLatch threadCompleteLatch; ++ private final AtomicBoolean testFailed; ++ ++ public PostServlet(CountDownLatch doPostLatch, CountDownLatch clientCloseLatch, ++ CountDownLatch threadCompleteLatch, AtomicBoolean testFailed) { ++ this.partialReadLatch = doPostLatch; ++ this.clientCloseLatch = clientCloseLatch; ++ this.threadCompleteLatch = threadCompleteLatch; ++ this.testFailed = testFailed; ++ } ++ ++ @Override ++ protected void doPost(HttpServletRequest req, HttpServletResponse resp) ++ throws ServletException, IOException { ++ ++ AsyncContext ac = req.startAsync(); ++ Thread t = new PostServletThread(ac, partialReadLatch, clientCloseLatch, threadCompleteLatch, testFailed); ++ t.start(); ++ ++ try { ++ threadCompleteLatch.await(); ++ } catch (InterruptedException e) { ++ // Ignore ++ } ++ } ++ } ++ ++ ++ private static final class PostServletThread extends Thread { ++ ++ private final AsyncContext ac; ++ private final CountDownLatch partialReadLatch; ++ private final CountDownLatch clientCloseLatch; ++ private final CountDownLatch threadCompleteLatch; ++ private final AtomicBoolean testFailed; ++ ++ public PostServletThread(AsyncContext ac, CountDownLatch partialReadLatch, CountDownLatch clientCloseLatch, ++ CountDownLatch threadCompleteLatch, AtomicBoolean testFailed) { ++ this.ac = ac; ++ this.partialReadLatch = partialReadLatch; ++ this.clientCloseLatch = clientCloseLatch; ++ this.threadCompleteLatch = threadCompleteLatch; ++ this.testFailed = testFailed; ++ } ++ ++ @Override ++ public void run() { ++ try { ++ int bytesRead = 0; ++ byte[] buffer = new byte[32]; ++ InputStream is = null; ++ ++ try { ++ is = ac.getRequest().getInputStream(); ++ ++ // Read the partial request body ++ while (bytesRead < 16) { ++ int read = is.read(buffer); ++ if (read == -1) { ++ // Error condition ++ return; ++ } ++ bytesRead += read; ++ } ++ } catch (IOException ioe) { ++ // Error condition ++ return; ++ } finally { ++ partialReadLatch.countDown(); ++ } ++ ++ // Wait for client to close connection ++ clientCloseLatch.await(); ++ ++ // Read again ++ try { ++ is.read(); ++ } catch (IOException e) { ++ e.printStackTrace(); ++ // Required. Clear the error marker. ++ testFailed.set(false); ++ } ++ } catch (InterruptedException e) { ++ // Ignore ++ } finally { ++ threadCompleteLatch.countDown(); ++ } ++ } ++ } + } +diff --git a/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java b/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java +index 7130b11..6868375 100644 +--- a/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java ++++ b/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java +@@ -32,6 +32,9 @@ import java.util.Map; + import java.util.Set; + import java.util.concurrent.CountDownLatch; + import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.logging.Level; ++import java.util.logging.LogManager; + + import javax.net.SocketFactory; + import javax.servlet.AsyncContext; +@@ -44,6 +47,7 @@ import javax.servlet.ServletInputStream; + import javax.servlet.ServletOutputStream; + import javax.servlet.WriteListener; + import javax.servlet.annotation.WebServlet; ++import javax.servlet.http.HttpServlet; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + +@@ -52,7 +56,9 @@ import org.junit.Ignore; + import org.junit.Test; + + import org.apache.catalina.Context; ++import org.apache.catalina.Wrapper; + import org.apache.catalina.startup.BytesStreamer; ++import org.apache.catalina.startup.SimpleHttpClient; + import org.apache.catalina.startup.TesterServlet; + import org.apache.catalina.startup.Tomcat; + import org.apache.catalina.startup.TomcatBaseTest; +@@ -997,4 +1003,190 @@ public class TestNonBlockingAPI extends TomcatBaseTest { + + } + } ++ ++ ++ /* ++ * Tests an error on an non-blocking read when the client closes the ++ * connection before fully writing the request body. ++ * ++ * Required sequence is: ++ * - enter Servlet's service() method ++ * - startAsync() ++ * - configure non-blocking read ++ * - read partial body ++ * - close client connection ++ * - error is triggered ++ * - exit Servlet's service() method ++ * ++ * This test makes extensive use of instance fields in the Servlet that ++ * would normally be considered very poor practice. It is only safe in this ++ * test as the Servlet only processes a single request. ++ */ ++ @Test ++ public void testCanceledPost() throws Exception { ++ ++ LogManager.getLogManager().getLogger("org.apache.coyote").setLevel(Level.ALL); ++ LogManager.getLogManager().getLogger("org.apache.tomcat.util.net").setLevel(Level.ALL); ++ ++ CountDownLatch partialReadLatch = new CountDownLatch(1); ++ CountDownLatch completeLatch = new CountDownLatch(1); ++ ++ AtomicBoolean testFailed = new AtomicBoolean(true); ++ ++ // Setup Tomcat instance ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ PostServlet postServlet = new PostServlet(partialReadLatch, completeLatch, testFailed); ++ Wrapper wrapper = Tomcat.addServlet(ctx, "postServlet", postServlet); ++ wrapper.setAsyncSupported(true); ++ ctx.addServletMappingDecoded("/*", "postServlet"); ++ ++ tomcat.start(); ++ ++ PostClient client = new PostClient(); ++ client.setPort(getPort()); ++ client.setRequest(new String[] { "POST / HTTP/1.1" + SimpleHttpClient.CRLF + ++ "Host: localhost:" + SimpleHttpClient.CRLF + ++ "Content-Length: 100" + SimpleHttpClient.CRLF + ++ SimpleHttpClient.CRLF + ++ "This is 16 bytes" ++ }); ++ client.connect(); ++ client.sendRequest(); ++ ++ // Wait server to read partial request body ++ partialReadLatch.await(); ++ ++ client.disconnect(); ++ ++ completeLatch.await(); ++ ++ Assert.assertFalse(testFailed.get()); ++ } ++ ++ ++ private static final class PostClient extends SimpleHttpClient { ++ ++ @Override ++ public boolean isResponseBodyOK() { ++ return true; ++ } ++ } ++ ++ ++ private static final class PostServlet extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ private final transient CountDownLatch partialReadLatch; ++ private final transient CountDownLatch completeLatch; ++ private final AtomicBoolean testFailed; ++ ++ public PostServlet(CountDownLatch doPostLatch, CountDownLatch completeLatch, AtomicBoolean testFailed) { ++ this.partialReadLatch = doPostLatch; ++ this.completeLatch = completeLatch; ++ this.testFailed = testFailed; ++ } ++ ++ @Override ++ protected void doPost(HttpServletRequest req, HttpServletResponse resp) ++ throws ServletException, IOException { ++ ++ AsyncContext ac = req.startAsync(); ++ ac.setTimeout(-1); ++ CanceledPostAsyncListener asyncListener = new CanceledPostAsyncListener(completeLatch); ++ ac.addListener(asyncListener); ++ ++ CanceledPostReadListener readListener = new CanceledPostReadListener(ac, partialReadLatch, testFailed); ++ req.getInputStream().setReadListener(readListener); ++ } ++ } ++ ++ ++ private static final class CanceledPostAsyncListener implements AsyncListener { ++ ++ private final transient CountDownLatch completeLatch; ++ ++ public CanceledPostAsyncListener(CountDownLatch completeLatch) { ++ this.completeLatch = completeLatch; ++ } ++ ++ @Override ++ public void onComplete(AsyncEvent event) throws IOException { ++ System.out.println("complete"); ++ completeLatch.countDown(); ++ } ++ ++ @Override ++ public void onTimeout(AsyncEvent event) throws IOException { ++ System.out.println("onTimeout"); ++ } ++ ++ @Override ++ public void onError(AsyncEvent event) throws IOException { ++ System.out.println("onError-async"); ++ } ++ ++ @Override ++ public void onStartAsync(AsyncEvent event) throws IOException { ++ System.out.println("onStartAsync"); ++ } ++ } ++ ++ private static final class CanceledPostReadListener implements ReadListener { ++ ++ private final AsyncContext ac; ++ private final CountDownLatch partialReadLatch; ++ private final AtomicBoolean testFailed; ++ private int totalRead = 0; ++ ++ public CanceledPostReadListener(AsyncContext ac, CountDownLatch partialReadLatch, AtomicBoolean testFailed) { ++ this.ac = ac; ++ this.partialReadLatch = partialReadLatch; ++ this.testFailed = testFailed; ++ } ++ ++ @Override ++ public void onDataAvailable() throws IOException { ++ ServletInputStream sis = ac.getRequest().getInputStream(); ++ boolean isReady; ++ ++ byte[] buffer = new byte[32]; ++ do { ++ if (partialReadLatch.getCount() == 0) { ++ System.out.println("debug"); ++ } ++ int bytesRead = sis.read(buffer); ++ ++ if (bytesRead == -1) { ++ return; ++ } ++ totalRead += bytesRead; ++ isReady = sis.isReady(); ++ System.out.println("Read [" + bytesRead + ++ "], buffer [" + new String(buffer, 0, bytesRead, StandardCharsets.UTF_8) + ++ "], total read [" + totalRead + ++ "], isReady [" + isReady + "]"); ++ } while (isReady); ++ if (totalRead == 16) { ++ partialReadLatch.countDown(); ++ } ++ } ++ ++ @Override ++ public void onAllDataRead() throws IOException { ++ ac.complete(); ++ } ++ ++ @Override ++ public void onError(Throwable throwable) { ++ throwable.printStackTrace(); ++ // This is the expected behaviour so clear the failed flag. ++ testFailed.set(false); ++ ac.complete(); ++ } ++ } + } +-- +2.33.0 + diff --git a/apache-commons-daemon-1.3.3-1.oe2309.x86_64.rpm b/apache-commons-daemon-1.3.3-1.oe2309.x86_64.rpm new file mode 100644 index 0000000000000000000000000000000000000000..5c5bad31f724b537f71872aaad4e9bcd32c21a1d GIT binary patch literal 60325 zcmeFZXIxaxvNt+pBnn6d89}1NVPF`7WRRRQh{FUJa*j%ppkzdlBq%{7N|Y=JiXupm zj1pBqGKl1G*C@|9d++nS`@HwV{dD)jUbX&R)z#hAYjsz3&(F2e_0I$#;KD<=BajYg zA*7p&i<_&L5DI|?sF0YjxUe{IcSA$OMd3KXe{;TW!*Sd9t0R;) z03{W&$K6_oH)%XVX{cfAu51Z=eJxD+eU{f6{&COyeeCE}hND|U5?7_azkybJ$UT6; zkw~;83?^;|he9C;DRC%DQWOKnz#teD3Im5A#i8P8geVFmAu5Uz6%&KO&=4spBorxu zguo;qQV?;dBvedH6cCaSLjbuF;z&D)q&Q3zDhdSzQ81(!3MPfd0D}PnjkW&WI8avr z;}EKFcbIIY7h)GL0L!^;ETFC2$9Tcdu0dXQEXA`}d%(3z!H(a5<_lqNvalS@C-dnz z;ziY}Y+_ED_q<6Xil7^v#om=DX3~&qUd9Qw&IzkuT)|xYB2};N+!M+_0Kr(L1Se|= z9miN}?h01)X>2xB<#vBD+7?HGJ@O|Hddd<)h69q4P7Jx{C1N|}v$vuMnJvidVZm}2 zH2L|Ywu!L=Zhb{EY{9AINss&s?Mugby85<7p)oK<`+dnvHFnYp@!A&$$o$r%YHa*( z_U+`iYu(u>(5R^i9#qS5reN8HZ#KB!lpuC_n7WsvSRNUu8zMbeMz(Ug9zz(5kHI`< zKQx3((l};5Eh}aoodDrw3H~^a^BD31T_9RK`-@o{zF+P8a-|EhoQ9P^y>_W=sX;>(=l<8!|HIX*eZ z4(Isv9J~I(gg{$=?;H99lni*p^%dAE#eZ^+aqYliU?1@}ACUPikLw>!o*bZnJ@Ik- zjW|s42NO1(W86L`PzT}CIi~)@C&G;dP98^r@eVMGPZN9 z0Z^bknaVjfKj-TM6xSb%bH4XEwmjz#02EiB)j9vK`mE3S-vElM&*l%G95)U)eDe>c z5dT97aqlV6UWx^P;`AZ^V9LKR>JO&UJ?Ep(vC%okoMY2-?0k-K{lMwNwHxR^6^`QS z_c_Pe=hzpZK>w-U02F8kq2C|=MVy^*^8V-8{Tv6J<8*)md*p0QCEO0Jxu@ z52&CqSXZ*v(TAX9PDujVIX8%@YOWxdH~ox&n4aAb;EWw=EFv?m%0ATiZ(*gtCYSp^;uf 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 literal 0 HcmV?d00001 diff --git a/tomcat.spec b/tomcat.spec index acbf3ed..e71fe5a 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -13,7 +13,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 30 +Release: 31 Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies License: ASL 2.0 URL: http://tomcat.apache.org/ @@ -106,6 +106,10 @@ Patch6071: CVE-2023-28708-pre.patch Patch6072: CVE-2023-28708.patch Patch6073: CVE-2023-41080.patch Patch6074: CVE-2023-45648.patch +Patch6075: CVE-2024-21733.patch +Patch6076: CVE-2023-24998.patch +Patch6077: CVE-2023-28709.patch +Patch6078: CVE-2023-42795.patch BuildRequires: ecj >= 1:4.6.1 findutils apache-commons-collections apache-commons-daemon BuildRequires: apache-commons-dbcp apache-commons-pool tomcat-taglibs-standard ant @@ -506,6 +510,9 @@ fi %{_javadocdir}/%{name} %changelog +* Tue Jan 23 2024 wangkai <13474090681@163.com> - 1:9.0.10-31 +- Fix CVE-2024-21733,CVE-2023-24998,CVE-2023-28709,CVE-2023-42795 + * Fri Oct 20 2023 wangkai <13474090681@163.com> - 1:9.0.10-30 - Fix CVE-2023-45648 -- Gitee