Author: remy.maucherat(a)jboss.com
Date: 2014-03-20 06:02:47 -0400 (Thu, 20 Mar 2014)
New Revision: 2394
Modified:
branches/2.1.x/java/org/apache/coyote/ajp/AjpAprProcessor.java
branches/2.1.x/java/org/apache/coyote/ajp/AjpProcessor.java
branches/2.1.x/java/org/apache/coyote/http11/Http11AprProcessor.java
branches/2.1.x/java/org/apache/coyote/http11/Http11Processor.java
Log:
Port fix for CVE-2013-4286 (BZ 1074417).
Modified: branches/2.1.x/java/org/apache/coyote/ajp/AjpAprProcessor.java
===================================================================
--- branches/2.1.x/java/org/apache/coyote/ajp/AjpAprProcessor.java 2014-03-18 10:29:10 UTC
(rev 2393)
+++ branches/2.1.x/java/org/apache/coyote/ajp/AjpAprProcessor.java 2014-03-20 10:02:47 UTC
(rev 2394)
@@ -25,6 +25,8 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.coyote.ActionCode;
import org.apache.coyote.ActionHook;
import org.apache.coyote.Adapter;
@@ -655,6 +657,7 @@
// Decode headers
MimeHeaders headers = request.getMimeHeaders();
+ boolean contentLengthSet = false;
int hCount = requestHeaderMessage.getInt();
for(int i = 0 ; i < hCount ; i++) {
String hName = null;
@@ -690,7 +693,16 @@
if (hId == Constants.SC_REQ_CONTENT_LENGTH ||
(hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Length"))) {
// just read the content-length header, so set it
- request.setContentLength( vMB.getInt() );
+ long cl = vMB.getLong();
+ if (contentLengthSet) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ error = true;
+ } else {
+ contentLengthSet = true;
+ // Set the content-length header for the request
+ if(cl < Integer.MAX_VALUE)
+ request.setContentLength( (int)cl );
+ }
} else if (hId == Constants.SC_REQ_CONTENT_TYPE ||
(hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Type"))) {
// just read the content-type header, so set it
Modified: branches/2.1.x/java/org/apache/coyote/ajp/AjpProcessor.java
===================================================================
--- branches/2.1.x/java/org/apache/coyote/ajp/AjpProcessor.java 2014-03-18 10:29:10 UTC
(rev 2393)
+++ branches/2.1.x/java/org/apache/coyote/ajp/AjpProcessor.java 2014-03-20 10:02:47 UTC
(rev 2394)
@@ -27,6 +27,8 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.coyote.ActionCode;
import org.apache.coyote.ActionHook;
import org.apache.coyote.Adapter;
@@ -660,6 +662,7 @@
// Decode headers
MimeHeaders headers = request.getMimeHeaders();
+ boolean contentLengthSet = false;
int hCount = requestHeaderMessage.getInt();
for(int i = 0 ; i < hCount ; i++) {
String hName = null;
@@ -695,7 +698,16 @@
if (hId == Constants.SC_REQ_CONTENT_LENGTH ||
(hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Length"))) {
// just read the content-length header, so set it
- request.setContentLength( vMB.getInt() );
+ long cl = vMB.getLong();
+ if (contentLengthSet) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ error = true;
+ } else {
+ contentLengthSet = true;
+ // Set the content-length header for the request
+ if(cl < Integer.MAX_VALUE)
+ request.setContentLength( (int)cl );
+ }
} else if (hId == Constants.SC_REQ_CONTENT_TYPE ||
(hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Type"))) {
// just read the content-type header, so set it
Modified: branches/2.1.x/java/org/apache/coyote/http11/Http11AprProcessor.java
===================================================================
--- branches/2.1.x/java/org/apache/coyote/http11/Http11AprProcessor.java 2014-03-18
10:29:10 UTC (rev 2393)
+++ branches/2.1.x/java/org/apache/coyote/http11/Http11AprProcessor.java 2014-03-20
10:02:47 UTC (rev 2394)
@@ -1469,10 +1469,20 @@
// Parse content-length header
long contentLength = request.getContentLengthLong();
- if (contentLength >= 0 && !contentDelimitation) {
- inputBuffer.addActiveFilter
+ if (contentLength >= 0) {
+ if (contentDelimitation) {
+ // contentDelimitation being true at this point indicates that
+ // chunked encoding is being used but chunked encoding should
+ // not be used with a content length. RFC 2616, section 4.4,
+ // bullet 3 states Content-Length must be ignored in this case -
+ // so remove it.
+ headers.removeHeader("content-length");
+ request.setContentLength(-1);
+ } else {
+ inputBuffer.addActiveFilter
(inputFilters[Constants.IDENTITY_FILTER]);
- contentDelimitation = true;
+ contentDelimitation = true;
+ }
}
MessageBytes valueMB = headers.getValue("host");
Modified: branches/2.1.x/java/org/apache/coyote/http11/Http11Processor.java
===================================================================
--- branches/2.1.x/java/org/apache/coyote/http11/Http11Processor.java 2014-03-18 10:29:10
UTC (rev 2393)
+++ branches/2.1.x/java/org/apache/coyote/http11/Http11Processor.java 2014-03-20 10:02:47
UTC (rev 2394)
@@ -1273,10 +1273,20 @@
// Parse content-length header
long contentLength = request.getContentLengthLong();
- if (contentLength >= 0 && !contentDelimitation) {
- inputBuffer.addActiveFilter
+ if (contentLength >= 0) {
+ if (contentDelimitation) {
+ // contentDelimitation being true at this point indicates that
+ // chunked encoding is being used but chunked encoding should
+ // not be used with a content length. RFC 2616, section 4.4,
+ // bullet 3 states Content-Length must be ignored in this case -
+ // so remove it.
+ headers.removeHeader("content-length");
+ request.setContentLength(-1);
+ } else {
+ inputBuffer.addActiveFilter
(inputFilters[Constants.IDENTITY_FILTER]);
- contentDelimitation = true;
+ contentDelimitation = true;
+ }
}
MessageBytes valueMB = headers.getValue("host");
Show replies by date