File tomcat-9.0.36-CVE-2022-42252.patch of Package tomcat.30728
From 4c7f4fd09d2cc1692112ef70b8ee23a7a037ae77 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 3 Oct 2022 11:59:01 +0100
Subject: [PATCH] Requests with invalid content-length should always be
rejected
---
Index: apache-tomcat-9.0.36-src/java/org/apache/coyote/http11/Http11InputBuffer.java
===================================================================
--- apache-tomcat-9.0.36-src.orig/java/org/apache/coyote/http11/Http11InputBuffer.java
+++ apache-tomcat-9.0.36-src/java/org/apache/coyote/http11/Http11InputBuffer.java
@@ -870,7 +870,7 @@ public class Http11InputBuffer implement
headerData.lastSignificantChar = pos;
((Buffer)byteBuffer).position(byteBuffer.position() - 1);
// skipLine() will handle the error
- return skipLine();
+ return skipLine(false);
}
// chr is next byte of header name. Convert to lowercase.
@@ -881,7 +881,7 @@ public class Http11InputBuffer implement
// Skip the line and ignore the header
if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) {
- return skipLine();
+ return skipLine(false);
}
//
@@ -932,15 +932,11 @@ public class Http11InputBuffer implement
} else if (prevChr == Constants.CR && chr == Constants.LF) {
eol = true;
} else if (prevChr == Constants.CR) {
- // Invalid value
- // Delete the header (it will be the most recent one)
- headers.removeHeader(headers.size() - 1);
- return skipLine();
+ // Invalid value - also need to delete header
+ return skipLine(true);
} else if (chr != Constants.HT && HttpParser.isControl(chr)) {
- // Invalid value
- // Delete the header (it will be the most recent one)
- headers.removeHeader(headers.size() - 1);
- return skipLine();
+ // Invalid value - also need to delete header
+ return skipLine(true);
} else if (chr == Constants.SP || chr == Constants.HT) {
byteBuffer.put(headerData.realPos, chr);
headerData.realPos++;
@@ -988,7 +984,27 @@ public class Http11InputBuffer implement
}
- private HeaderParseStatus skipLine() throws IOException {
+ private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException {
+ boolean rejectThisHeader = rejectIllegalHeader;
+ // Check if rejectIllegalHeader is disabled and needs to be overridden
+ // for this header. The header name is required to determine if this
+ // override is required. The header name is only available once the
+ // header has been created. If the header has been created then
+ // deleteHeader will be true.
+ if (!rejectThisHeader && deleteHeader) {
+ if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) {
+ // Malformed content-length headers must always be rejected
+ // RFC 9112, section 6.3, bullet 5.
+ rejectThisHeader = true;
+ } else {
+ // Only need to delete the header if the request isn't going to
+ // be rejected (it will be the most recent one)
+ headers.removeHeader(headers.size() - 1);
+ }
+ }
+
+ // Parse the rest of the invalid header so we can construct a useful
+ // exception and/or debug message.
headerParsePos = HeaderParsePosition.HEADER_SKIPLINE;
boolean eol = false;
@@ -1013,11 +1029,11 @@ public class Http11InputBuffer implement
headerData.lastSignificantChar = pos;
}
}
- if (rejectIllegalHeader || log.isDebugEnabled()) {
+ if (rejectThisHeader || log.isDebugEnabled()) {
String message = sm.getString("iib.invalidheader",
HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart,
headerData.lastSignificantChar - headerData.lineStart + 1));
- if (rejectIllegalHeader) {
+ if (rejectThisHeader) {
throw new IllegalArgumentException(message);
}
log.debug(message);
Index: apache-tomcat-9.0.36-src/webapps/docs/changelog.xml
===================================================================
--- apache-tomcat-9.0.36-src.orig/webapps/docs/changelog.xml
+++ apache-tomcat-9.0.36-src/webapps/docs/changelog.xml
@@ -134,6 +134,11 @@
Improve the recycling of Processor objects to make it more robust.
(markt)
</fix>
+ <fix>
+ Enforce the requirement of RFC 7230 onwards that a request with a
+ malformed <code>content-length</code> header should always be rejected
+ with a 400 response. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">