This is an automated email from the git hooks/post-receive script. ebourg-guest pushed a commit to branch wheezy in repository tomcat7.
commit 9907927b53a48a68cc6f04b76097650e0ad1ba4f Author: Emmanuel Bourg <[email protected]> Date: Fri Jan 8 11:58:02 2016 +0100 Fixed CVE-2014-0227: Add an error flag in ChunkedInputFilter to allow subsequent attempts at reading after an error to fail fast --- debian/changelog | 4 + debian/patches/CVE-2014-0227.patch | 213 +++++++++++++++++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 218 insertions(+) diff --git a/debian/changelog b/debian/changelog index 769891d..061daa3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,10 @@ tomcat7 (7.0.28-4+deb7u3) wheezy-security; urgency=high could enable the streaming of an unlimited amount of data to the server, bypassing the various size limits enforced on a request. This enabled a denial of service attack. + * Fixed CVE-2014-0227: Add an error flag in ChunkedInputFilter to allow + subsequent attempts at reading after an error to fail fast. This prevents + remote attackers from conducting HTTP request smuggling attacks or causing + a denial of service by streaming data with malformed chunked requests. -- Emmanuel Bourg <[email protected]> Mon, 04 Jan 2016 12:03:34 +0100 diff --git a/debian/patches/CVE-2014-0227.patch b/debian/patches/CVE-2014-0227.patch new file mode 100644 index 0000000..66e72b3 --- /dev/null +++ b/debian/patches/CVE-2014-0227.patch @@ -0,0 +1,213 @@ +Description: CVE-2014-0227: Add an error flag in ChunkedInputFilter to allow subsequent + attempts at reading after an error to fail fast. This prevents remote attackers from + conducting HTTP request smuggling attacks or causing a denial of service by streaming + data with malformed chunked requests. +Origin: backport, https://svn.apache.org/r1601333 +--- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java ++++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +@@ -29,6 +29,7 @@ + import org.apache.tomcat.util.buf.HexUtils; + import org.apache.tomcat.util.buf.MessageBytes; + import org.apache.tomcat.util.http.MimeHeaders; ++import org.apache.tomcat.util.res.StringManager; + + /** + * Chunked input filter. Parses chunked data according to +@@ -39,6 +40,8 @@ + */ + public class ChunkedInputFilter implements InputFilter { + ++ private static final StringManager sm = StringManager.getManager( ++ ChunkedInputFilter.class.getPackage().getName()); + + // -------------------------------------------------------------- Constants + +@@ -135,6 +138,11 @@ + */ + private long extensionSize; + ++ /** ++ * Flag that indicates if an error has occurred. ++ */ ++ private boolean error; ++ + + // ----------------------------------------------------------- Constructors + public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) { +@@ -162,6 +170,8 @@ + if (endChunk) + return -1; + ++ checkError(); ++ + if(needCRLFParse) { + needCRLFParse = false; + parseCRLF(false); +@@ -169,7 +179,7 @@ + + if (remaining <= 0) { + if (!parseChunkHeader()) { +- throw new IOException("Invalid chunk header"); ++ throwIOException(sm.getString("chunkedInputFilter.invalidHeader")); + } + if (endChunk) { + parseEndChunk(); +@@ -180,7 +190,9 @@ + int result = 0; + + if (pos >= lastValid) { +- readBytes(); ++ if (readBytes() < 0) { ++ throwIOException(sm.getString("chunkedInputFilter.eos")); ++ } + } + + if (remaining > (lastValid - pos)) { +@@ -269,6 +281,7 @@ + trailingHeaders.recycle(); + trailingHeaders.setLimit(maxTrailerSize); + extensionSize = 0; ++ error = false; + } + + +@@ -351,7 +364,7 @@ + // validated. Currently it is simply ignored. + extensionSize++; + if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) { +- throw new IOException("maxExtensionSize exceeded"); ++ throwIOException(sm.getString("chunkedInputFilter.maxExtension")); + } + } + +@@ -403,19 +416,19 @@ + + if (pos >= lastValid) { + if (readBytes() <= 0) +- throw new IOException("Invalid CRLF"); ++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoData")); + } + + if (buf[pos] == Constants.CR) { +- if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered."); ++ if (crfound) throwIOException(sm.getString("chunkedInputFilter.invalidCrlfCRCR")); + crfound = true; + } else if (buf[pos] == Constants.LF) { + if (!tolerant && !crfound) { +- throw new IOException("Invalid CRLF, no CR character encountered."); ++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoCR")); + } + eol = true; + } else { +- throw new IOException("Invalid CRLF"); ++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlf")); + } + + pos++; +@@ -445,7 +458,7 @@ + // Read new bytes if needed + if (pos >= lastValid) { + if (readBytes() <0) +- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } + + chr = buf[pos]; +@@ -470,7 +483,7 @@ + // Read new bytes if needed + if (pos >= lastValid) { + if (readBytes() <0) +- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } + + chr = buf[pos]; +@@ -511,7 +524,7 @@ + // Read new bytes if needed + if (pos >= lastValid) { + if (readBytes() <0) +- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } + + chr = buf[pos]; +@@ -521,7 +534,7 @@ + // limit placed on trailing header size + int newlimit = trailingHeaders.getLimit() -1; + if (trailingHeaders.getEnd() > newlimit) { +- throw new IOException("Exceeded maxTrailerSize"); ++ throwIOException(sm.getString("chunkedInputFilter.maxTrailer")); + } + trailingHeaders.setLimit(newlimit); + } else { +@@ -536,7 +549,7 @@ + // Read new bytes if needed + if (pos >= lastValid) { + if (readBytes() <0) +- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } + + chr = buf[pos]; +@@ -561,7 +574,7 @@ + // Read new bytes if needed + if (pos >= lastValid) { + if (readBytes() <0) +- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } + + chr = buf[pos]; +@@ -582,4 +595,23 @@ + + return true; + } ++ ++ ++ private void throwIOException(String msg) throws IOException { ++ error = true; ++ throw new IOException(msg); ++ } ++ ++ ++ private void throwEOFException(String msg) throws IOException { ++ error = true; ++ throw new EOFException(msg); ++ } ++ ++ ++ private void checkError() throws IOException { ++ if (error) { ++ throw new IOException(sm.getString("chunkedInputFilter.error")); ++ } ++ } + } +--- /dev/null ++++ b/java/org/apache/coyote/http11/filters/LocalStrings.properties +@@ -0,0 +1,25 @@ ++# Licensed to the Apache Software Foundation (ASF) under one or more ++# contributor license agreements. See the NOTICE file distributed with ++# this work for additional information regarding copyright ownership. ++# The ASF licenses this file to You under the Apache License, Version 2.0 ++# (the "License"); you may not use this file except in compliance with ++# the License. You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under the License is distributed on an "AS IS" BASIS, ++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++# See the License for the specific language governing permissions and ++# limitations under the License. ++ ++chunkedInputFilter.error=No data available due to previous error ++chunkedInputFilter.eos=Unexpected end of stream while reading request body ++chunkedInputFilter.eosTrailer=Unexpected end of stream while reading trailer headers ++chunkedInputFilter.invalidCrlf=Invalid end of line sequence (character other than CR or LF found) ++chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR) ++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.maxExtension=maxExtensionSize exceeded ++chunkedInputFilter.maxTrailer=maxTrailerSize exceeded +\ No newline at end of file diff --git a/debian/patches/series b/debian/patches/series index b0add1f..9a2673f 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -25,3 +25,4 @@ CVE-2014-7810.patch CVE-2014-0099.patch CVE-2013-4444.patch CVE-2014-0075.patch +CVE-2014-0227.patch -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/tomcat7.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

