[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

CVE-2014-0230: non-persistent DoS attack by feeding data aborting an upload



Source: tomcat6
Version: 6.0.41-2+squeeze6
Severity: normal
Tags: security upstream fixed-upstream

Hello,

The following vulnerability affects tomcat6 in squeeze and wheezy.

CVE-2014-0230 [cve]: Tomcat permits a limited Denial of Service.

I have prepared the attached patch for the 6.0.41-2+squeeze6 version,
based on [fix].

If you fix the vulnerability please also make sure to include the
CVE (Common Vulnerabilities & Exposures) id in your changelog entry.

[cve] https://security-tracker.debian.org/tracker/CVE-2014-0230
[fix] https://svn.apache.org/viewvc?view=revision&revision=1659537

Please adjust the affected versions in the BTS as needed.

Regards,

Santiago
Description: Add support for maxSwallowSize
 Fixes CVE-2014-0230
Origin: https://svn.apache.org/viewvc?view=revision&revision=1659537

Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
===================================================================
--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
+++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
@@ -20,7 +20,7 @@ package org.apache.coyote.http11.filters
 import java.io.IOException;
 
 import org.apache.tomcat.util.buf.ByteChunk;
-
+import org.apache.tomcat.util.res.StringManager;
 import org.apache.coyote.InputBuffer;
 import org.apache.coyote.Request;
 import org.apache.coyote.http11.InputFilter;
@@ -32,9 +32,11 @@ import org.apache.coyote.http11.InputFil
  */
 public class IdentityInputFilter implements InputFilter {
 
+    private static final StringManager sm = StringManager.getManager(
+            IdentityInputFilter.class.getPackage().getName());
 
-    // -------------------------------------------------------------- Constants
 
+    // -------------------------------------------------------------- Constants
 
     protected static final String ENCODING_NAME = "identity";
     protected static final ByteChunk ENCODING = new ByteChunk();
@@ -150,17 +152,25 @@ public class IdentityInputFilter impleme
     }
 
 
-    /**
-     * End the current request.
-     */
-    public long end()
-        throws IOException {
+    public long end() throws IOException {
+
+        final int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE;
+        final boolean maxSwallowSizeExceeded = (maxSwallowSize > -1 && remaining > maxSwallowSize);
+        long swallowed = 0;
 
         // Consume extra bytes.
         while (remaining > 0) {
+
             int nread = buffer.doRead(endChunk, null);
             if (nread > 0 ) {
+                swallowed += nread;
                 remaining = remaining - nread;
+                if (maxSwallowSizeExceeded && swallowed > maxSwallowSize) {
+                    // Note: We do not fail early so the client has a chance to
+                    // read the response before the connection is closed. See:
+                    // http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix
+                    throw new IOException(sm.getString("inputFilter.maxSwallow"));
+                }
             } else { // errors are handled higher up.
                 remaining = 0;
             }
Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
===================================================================
--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/LocalStrings.properties
+++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
@@ -22,4 +22,6 @@ chunkedInputFilter.invalidCrlfNoCR=Inval
 chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
 chunkedInputFilter.invalidHeader=Invalid chunk header
 chunkedInputFilter.maxExtension=maxExtensionSize exceeded
-chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
\ No newline at end of file
+chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
+
+inputFilter.maxSwallow=maxSwallowSize exceeded
Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
===================================================================
--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
@@ -216,8 +216,15 @@ public class ChunkedInputFilter implemen
      * End the current request.
      */
     public long end() throws IOException {
+        int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE;
+        long swallowed = 0;
+        int read = 0;
         // Consume extra bytes : parse the stream until the end chunk is found
-        while (doRead(readChunk, null) >= 0) {
+        while ((read = doRead(readChunk, null)) >= 0) {
+            swallowed += read;
+            if (maxSwallowSize > -1 && swallowed > maxSwallowSize) {
+                throwIOException(sm.getString("inputFilter.maxSwallow"));
+            }
         }
 
         // Return the number of extra bytes which were consumed
Index: tomcat6-6.0.41/java/org/apache/coyote/Constants.java
===================================================================
--- tomcat6-6.0.41.orig/java/org/apache/coyote/Constants.java
+++ tomcat6-6.0.41/java/org/apache/coyote/Constants.java
@@ -85,4 +85,13 @@ public final class Constants {
         Integer.parseInt(System.getProperty(
                 "org.apache.coyote.MAX_EXTENSION_SIZE",
                 "8192"));
+
+    /**
+     * Limit on the length of request body Tomcat will swallow if it is not
+     * read during normal request processing. Defaults to 2MB.
+     */
+    public static final int MAX_SWALLOW_SIZE =
+        Integer.parseInt(System.getProperty(
+                "org.apache.coyote.MAX_SWALLOW_SIZE",
+                "2097152"));
 }
Index: tomcat6-6.0.41/webapps/docs/changelog.xml
===================================================================
--- tomcat6-6.0.41.orig/webapps/docs/changelog.xml
+++ tomcat6-6.0.41/webapps/docs/changelog.xml
@@ -51,6 +51,11 @@
         attributes with empty string value in custom tags. Based on a patch
         provided by Hariprasad Manchi. (violetagg/kkolinko)
       </fix>
+      <fix>
+        When applying the <code>maxSwallowSize</code> limit to a connection read
+        that many bytes first before closing the connection to give the client a
+        chance to read the reponse. (markt)
+      </fix>
     </changelog>
   </subsection>
 </section>
Index: tomcat6-6.0.41/webapps/docs/config/systemprops.xml
===================================================================
--- tomcat6-6.0.41.orig/webapps/docs/config/systemprops.xml
+++ tomcat6-6.0.41/webapps/docs/config/systemprops.xml
@@ -440,6 +440,14 @@
       <p>If not specified, the default value of <code>8192</code> will be used.</p>
     </property>
 
+    <property name="org.apache.coyote.MAX_SWALLOW_SIZE">
+      <p>Limits the length of a request body Tomcat will swallow if it is not
+      read during normal request processing. If the value is <code>-1</code>, no
+      limit will be imposed.</p>
+      <p>If not specified, the default value of <code>2097152</code> (2MB) will
+      be used.</p>
+    </property>
+
     <property name="catalina.useNaming">
       <p>If this is <code>false</code> it will override the
       <code>useNaming</code> attribute for all <a href="context.html">

Attachment: signature.asc
Description: Digital signature


Reply to: