From a0eb4fdc96bf85a81ad2fbaeb328dd6ddcc46b90 Mon Sep 17 00:00:00 2001 From: wang_yue111 <648774160@qq.com> Date: Mon, 19 Jul 2021 11:46:07 +0800 Subject: [PATCH] Fix CVE-2021-33037 (cherry picked from commit 4684794918ce02fe6e755127b48eb12ce0d403dd) --- CVE-2021-33037-1.patch | 160 +++++++++++++++++++++++++++++++++++++++++ CVE-2021-33037-2.patch | 81 +++++++++++++++++++++ CVE-2021-33037-3.patch | 137 +++++++++++++++++++++++++++++++++++ tomcat.spec | 8 ++- 4 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-33037-1.patch create mode 100644 CVE-2021-33037-2.patch create mode 100644 CVE-2021-33037-3.patch diff --git a/CVE-2021-33037-1.patch b/CVE-2021-33037-1.patch new file mode 100644 index 0000000..b86da63 --- /dev/null +++ b/CVE-2021-33037-1.patch @@ -0,0 +1,160 @@ +From 94a5f7b95adee95fbc945767a71c27e329970a80 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Mon, 10 May 2021 21:20:46 +0100 +Subject: [PATCH] Remove support for the identity T-E header value + +--- + .../apache/coyote/http11/Http11Processor.java | 7 +- + .../coyote/http11/TestHttp11Processor.java | 95 ++++++++++++++----- + webapps/docs/changelog.xml | 6 ++ + 3 files changed, 78 insertions(+), 30 deletions(-) + +diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java +index 86556ec..c840c83 100644 +--- a/java/org/apache/coyote/http11/Http11Processor.java ++++ b/java/org/apache/coyote/http11/Http11Processor.java +@@ -243,11 +243,8 @@ public class Http11Processor extends AbstractProcessor { + // encoding names are case insensitive. (RFC2616, section 3.6) + encodingName = encodingName.trim().toLowerCase(Locale.ENGLISH); + +- if (encodingName.equals("identity")) { +- // Skip +- } else if (encodingName.equals("chunked")) { +- inputBuffer.addActiveFilter +- (inputFilters[Constants.CHUNKED_FILTER]); ++ if (encodingName.equals("chunked")) { ++ inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]); + contentDelimitation = true; + } else { + for (int i = pluggableFilterIndex; i < inputFilters.length; i++) { +diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java +index 5357526..1d12007 100644 +--- a/test/org/apache/coyote/http11/TestHttp11Processor.java ++++ b/test/org/apache/coyote/http11/TestHttp11Processor.java +@@ -249,31 +249,6 @@ public class TestHttp11Processor extends TomcatBaseTest { + } + + +- @Test +- public void testWithTEIdentity() throws Exception { +- getTomcatInstanceTestWebapp(false, true); +- +- String request = +- "POST /test/echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF + +- "Host: any" + SimpleHttpClient.CRLF + +- "Transfer-encoding: identity" + SimpleHttpClient.CRLF + +- "Content-Length: 9" + SimpleHttpClient.CRLF + +- "Content-Type: application/x-www-form-urlencoded" + +- SimpleHttpClient.CRLF + +- "Connection: close" + SimpleHttpClient.CRLF + +- SimpleHttpClient.CRLF + +- "test=data"; +- +- Client client = new Client(getPort()); +- client.setRequest(new String[] {request}); +- +- client.connect(); +- client.processRequest(); +- Assert.assertTrue(client.isResponse200()); +- Assert.assertTrue(client.getResponseBody().contains("test - data")); +- } +- +- + @Test + public void testWithTESavedRequest() throws Exception { + getTomcatInstanceTestWebapp(false, true); +@@ -1308,4 +1283,74 @@ public class TestHttp11Processor extends TomcatBaseTest { + // Expected response is a 200 response. + Assert.assertTrue(client.isResponse200()); + } ++ ++ ++ @Test ++ public void testTEHeaderUnknown01() throws Exception { ++ doTestTEHeaderUnknown("identity"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown02() throws Exception { ++ doTestTEHeaderUnknown("identity, chunked"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown03() throws Exception { ++ doTestTEHeaderUnknown("unknown, chunked"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown04() throws Exception { ++ doTestTEHeaderUnknown("void"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown05() throws Exception { ++ doTestTEHeaderUnknown("void, chunked"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown06() throws Exception { ++ doTestTEHeaderUnknown("void, identity"); ++ } ++ ++ ++ @Test ++ public void testTEHeaderUnknown07() throws Exception { ++ doTestTEHeaderUnknown("identity, void"); ++ } ++ ++ ++ private void doTestTEHeaderUnknown(String headerValue) throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ // Add servlet ++ Tomcat.addServlet(ctx, "TesterServlet", new TesterServlet(false)); ++ ctx.addServletMappingDecoded("/foo", "TesterServlet"); ++ ++ tomcat.start(); ++ ++ String request = ++ "GET /foo HTTP/1.1" + SimpleHttpClient.CRLF + ++ "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + ++ "Transfer-Encoding: " + headerValue + SimpleHttpClient.CRLF + ++ SimpleHttpClient.CRLF; ++ ++ Client client = new Client(tomcat.getConnector().getLocalPort()); ++ client.setRequest(new String[] {request}); ++ ++ client.connect(); ++ client.processRequest(false); ++ ++ Assert.assertTrue(client.isResponse501()); ++ } + } +diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml +index bc37288..94a0d94 100644 +--- a/webapps/docs/changelog.xml ++++ b/webapps/docs/changelog.xml +@@ -309,6 +309,12 @@ + Enable host name verification when using TLS with the WebSocket client. + (markt) + ++ ++ Remove support for the identity transfer encoding. The ++ inclusion of this encoding in RFC 2616 was an error that was corrected ++ in 2001. Requests using this transfer encoding will now receive a 501 ++ response. (markt) ++ + + + +-- +2.23.0 + diff --git a/CVE-2021-33037-2.patch b/CVE-2021-33037-2.patch new file mode 100644 index 0000000..d1b5665 --- /dev/null +++ b/CVE-2021-33037-2.patch @@ -0,0 +1,81 @@ +From 66bd71277cedd04af2772942c697e15d5c401de9 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Mon, 10 May 2021 21:59:44 +0100 +Subject: [PATCH] Process T-E header from both HTTP 1.0 and HTTP 1.1.clients + +--- + .../apache/coyote/http11/Http11Processor.java | 4 ++- + .../coyote/http11/TestHttp11Processor.java | 28 +++++++++++++++++++ + webapps/docs/changelog.xml | 4 +++ + 3 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java +index c840c83..4021355 100644 +--- a/java/org/apache/coyote/http11/Http11Processor.java ++++ b/java/org/apache/coyote/http11/Http11Processor.java +@@ -766,7 +766,9 @@ public class Http11Processor extends AbstractProcessor { + InputFilter[] inputFilters = inputBuffer.getFilters(); + + // Parse transfer-encoding header +- if (http11) { ++ // HTTP specs say an HTTP 1.1 server should accept any recognised ++ // HTTP 1.x header from a 1.x client unless the specs says otherwise. ++ if (!http09) { + MessageBytes transferEncodingValueMB = headers.getValue("transfer-encoding"); + if (transferEncodingValueMB != null) { + String transferEncodingValue = transferEncodingValueMB.toString(); +diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java +index 1d12007..84fdd42 100644 +--- a/test/org/apache/coyote/http11/TestHttp11Processor.java ++++ b/test/org/apache/coyote/http11/TestHttp11Processor.java +@@ -1353,4 +1353,32 @@ public class TestHttp11Processor extends TomcatBaseTest { + + Assert.assertTrue(client.isResponse501()); + } ++ ++ ++ @Test ++ public void testWithTEChunkedHttp10() throws Exception { ++ ++ getTomcatInstanceTestWebapp(false, true); ++ ++ String request = ++ "POST /test/echo-params.jsp HTTP/1.0" + SimpleHttpClient.CRLF + ++ "Host: any" + SimpleHttpClient.CRLF + ++ "Transfer-encoding: chunked" + SimpleHttpClient.CRLF + ++ "Content-Type: application/x-www-form-urlencoded" + ++ SimpleHttpClient.CRLF + ++ "Connection: close" + SimpleHttpClient.CRLF + ++ SimpleHttpClient.CRLF + ++ "9" + SimpleHttpClient.CRLF + ++ "test=data" + SimpleHttpClient.CRLF + ++ "0" + SimpleHttpClient.CRLF + ++ SimpleHttpClient.CRLF; ++ ++ Client client = new Client(getPort()); ++ client.setRequest(new String[] {request}); ++ ++ client.connect(); ++ client.processRequest(); ++ Assert.assertTrue(client.isResponse200()); ++ Assert.assertTrue(client.getResponseBody().contains("test - data")); ++ } + } +diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml +index 94a0d94..e47f3d6 100644 +--- a/webapps/docs/changelog.xml ++++ b/webapps/docs/changelog.xml +@@ -315,6 +315,10 @@ + in 2001. Requests using this transfer encoding will now receive a 501 + response. (markt) + ++ ++ Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1 ++ clients. (markt) ++ + + + +-- +2.23.0 + diff --git a/CVE-2021-33037-3.patch b/CVE-2021-33037-3.patch new file mode 100644 index 0000000..055c80b --- /dev/null +++ b/CVE-2021-33037-3.patch @@ -0,0 +1,137 @@ +From 74888576a60ec58ee99454e4202a0eb1a7720d98 Mon Sep 17 00:00:00 2001 +From: Mark Thomas +Date: Mon, 10 May 2021 22:14:18 +0100 +Subject: [PATCH] Ensure chunked, if present, is the last encoding in the list + +--- + .../apache/coyote/http11/Http11Processor.java | 13 ++++++++- + .../coyote/http11/TestHttp11Processor.java | 28 +++++++++++++------ + webapps/docs/changelog.xml | 5 ++++ + 3 files changed, 36 insertions(+), 10 deletions(-) + +diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java +index 4021355..17932b9 100644 +--- a/java/org/apache/coyote/http11/Http11Processor.java ++++ b/java/org/apache/coyote/http11/Http11Processor.java +@@ -238,11 +238,22 @@ public class Http11Processor extends AbstractProcessor { + * supported, a 501 response will be returned to the client. + */ + private void addInputFilter(InputFilter[] inputFilters, String encodingName) { ++ if (contentDelimitation) { ++ // Chunked has already been specified and it must be the final ++ // encoding. ++ // 400 - Bad request ++ response.setStatus(400); ++ setErrorState(ErrorState.CLOSE_CLEAN, null); ++ if (log.isDebugEnabled()) { ++ log.debug(sm.getString("http11processor.request.prepare") + ++ " Tranfer encoding lists chunked before [" + encodingName + "]"); ++ } ++ return; ++ } + + // Trim provided encoding name and convert to lower case since transfer + // encoding names are case insensitive. (RFC2616, section 3.6) + encodingName = encodingName.trim().toLowerCase(Locale.ENGLISH); +- + if (encodingName.equals("chunked")) { + inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]); + contentDelimitation = true; +diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java +index 84fdd42..ceb2601 100644 +--- a/test/org/apache/coyote/http11/TestHttp11Processor.java ++++ b/test/org/apache/coyote/http11/TestHttp11Processor.java +@@ -1287,47 +1287,53 @@ public class TestHttp11Processor extends TomcatBaseTest { + + @Test + public void testTEHeaderUnknown01() throws Exception { +- doTestTEHeaderUnknown("identity"); ++ doTestTEHeaderInvalid("identity", false); + } + + + @Test + public void testTEHeaderUnknown02() throws Exception { +- doTestTEHeaderUnknown("identity, chunked"); ++ doTestTEHeaderInvalid("identity, chunked", false); + } + + + @Test + public void testTEHeaderUnknown03() throws Exception { +- doTestTEHeaderUnknown("unknown, chunked"); ++ doTestTEHeaderInvalid("unknown, chunked", false); + } + + + @Test + public void testTEHeaderUnknown04() throws Exception { +- doTestTEHeaderUnknown("void"); ++ doTestTEHeaderInvalid("void", false); + } + + + @Test + public void testTEHeaderUnknown05() throws Exception { +- doTestTEHeaderUnknown("void, chunked"); ++ doTestTEHeaderInvalid("void, chunked", false); + } + + + @Test + public void testTEHeaderUnknown06() throws Exception { +- doTestTEHeaderUnknown("void, identity"); ++ doTestTEHeaderInvalid("void, identity", false); + } + + + @Test + public void testTEHeaderUnknown07() throws Exception { +- doTestTEHeaderUnknown("identity, void"); ++ doTestTEHeaderInvalid("identity, void", false); + } + + +- private void doTestTEHeaderUnknown(String headerValue) throws Exception { ++ @Test ++ public void testTEHeaderChunkedNotLast01() throws Exception { ++ doTestTEHeaderInvalid("chunked, void", true); ++ } ++ ++ ++ private void doTestTEHeaderInvalid(String headerValue, boolean badRequest) throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // No file system docBase required +@@ -1351,7 +1357,11 @@ public class TestHttp11Processor extends TomcatBaseTest { + client.connect(); + client.processRequest(false); + +- Assert.assertTrue(client.isResponse501()); ++ if (badRequest) { ++ Assert.assertTrue(client.isResponse400()); ++ } else { ++ Assert.assertTrue(client.isResponse501()); ++ } + } + + +diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml +index e47f3d6..35b8eab 100644 +--- a/webapps/docs/changelog.xml ++++ b/webapps/docs/changelog.xml +@@ -319,6 +319,11 @@ + Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1 + clients. (markt) + ++ ++ Ensure that if the transfer encoding header contains the ++ chunked, that the chunked encoding is the ++ final encoding listed. (markt) ++ + + + +-- +2.23.0 + diff --git a/tomcat.spec b/tomcat.spec index 42d3cc5..e85fb66 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -13,7 +13,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 18 +Release: 19 Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies License: ASL 2.0 URL: http://tomcat.apache.org/ @@ -82,6 +82,9 @@ Patch6037: CVE-2021-25329-pre1.patch Patch6038: CVE-2021-25329-pre2.patch Patch6039: CVE-2021-25329-pre3.patch Patch6040: CVE-2021-25329.patch +Patch6041: CVE-2021-33037-1.patch +Patch6042: CVE-2021-33037-2.patch +Patch6043: CVE-2021-33037-3.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 @@ -483,6 +486,9 @@ fi %{_javadocdir}/%{name} %changelog +* Mon Jul 19 2021 wangyue - 1:9.0.10-19 +- Fix CVE-2021-33037 + * Fri Mar 12 2021 wangyue - 1:9.0.10-18 - Type:cve - ID: CVE-2021-25122 CVE-2021-25329 -- Gitee