From 5498d082575e35e9a093247f836e35d7404a50f0 Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Fri, 20 Oct 2023 10:07:41 +0800 Subject: [PATCH] Fix CVE-2023-45648 --- CVE-2023-45648.patch | 89 ++++++++++++++++++++++++++++++++++++++++++++ tomcat.spec | 6 ++- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 CVE-2023-45648.patch diff --git a/CVE-2023-45648.patch b/CVE-2023-45648.patch new file mode 100644 index 0000000..58c6e25 --- /dev/null +++ b/CVE-2023-45648.patch @@ -0,0 +1,89 @@ +Description: Align processing of trailer headers with standard processing +Origin: upstream, https://github.com/apache/tomcat/commit/59583245639d8c42ae0009f4a4a70464d3ea70a0 +--- a/java/org/apache/coyote/http11/Http11InputBuffer.java ++++ b/java/org/apache/coyote/http11/Http11InputBuffer.java +@@ -818,6 +818,12 @@ + */ + private HeaderParseStatus parseHeader() throws IOException { + ++ /* ++ * 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. ++ */ + // + // Check for blank line + // + + byte chr = 0; + byte prevChr = 0; + + while (headerParsePos == HeaderParsePosition.HEADER_START) { + + // Read new bytes if needed +@@ -950,7 +956,7 @@ + } 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) { +--- 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.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; + +@@ -443,6 +444,13 @@ + + 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 headers = request.getTrailerFields(); + + byte chr = 0; +@@ -489,6 +497,9 @@ + + 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); + } +@@ -550,7 +561,9 @@ + 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); +--- a/java/org/apache/coyote/http11/filters/LocalStrings.properties ++++ b/java/org/apache/coyote/http11/filters/LocalStrings.properties +@@ -21,6 +21,8 @@ + 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 + diff --git a/tomcat.spec b/tomcat.spec index 17e0bef..c619ab5 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -13,7 +13,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 31 +Release: 32 Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies License: ASL 2.0 URL: http://tomcat.apache.org/ @@ -105,6 +105,7 @@ Patch6070: CVE-2022-42252.patch Patch6071: CVE-2023-28708-pre.patch Patch6072: CVE-2023-28708.patch Patch6073: CVE-2023-41080.patch +Patch6074: CVE-2023-45648.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 @@ -505,6 +506,9 @@ fi %{_javadocdir}/%{name} %changelog +* Fri Oct 20 2023 wangkai <13474090681@163.com> - 1:9.0.10-32 +- Fix CVE-2023-45648 + * Thu Sep 07 2023 wangkai <13474090681@163.com> - 1:9.0.10-31 - Fix CVE-2023-41080 - Add requires apache-commons-dbcp,pool,collections for fix path error