From e41f6f33d5881c1fb03940ca834e656853b3923e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 12 2015 16:09:19 +0000 Subject: import tomcat-7.0.54-2.el7_1 --- diff --git a/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch b/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch new file mode 100644 index 0000000..3d07cc4 --- /dev/null +++ b/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch @@ -0,0 +1,410 @@ +--- java/org/apache/coyote/http11/filters/ChunkedInputFilter.java.orig 2015-03-24 16:32:02.657913000 -0400 ++++ java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2015-03-24 18:21:47.397617000 -0400 +@@ -14,7 +14,6 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +- + package org.apache.coyote.http11.filters; + + import java.io.EOFException; +@@ -29,6 +28,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,9 +39,11 @@ + */ + public class ChunkedInputFilter implements InputFilter { + ++ private static final StringManager sm = StringManager.getManager( ++ ChunkedInputFilter.class.getPackage().getName()); + +- // -------------------------------------------------------------- Constants + ++ // -------------------------------------------------------------- Constants + + protected static final String ENCODING_NAME = "chunked"; + protected static final ByteChunk ENCODING = new ByteChunk(); +@@ -49,7 +51,6 @@ + + // ----------------------------------------------------- Static Initializer + +- + static { + ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0, + ENCODING_NAME.length()); +@@ -58,7 +59,6 @@ + + // ----------------------------------------------------- Instance Variables + +- + /** + * Next buffer in the pipeline. + */ +@@ -106,6 +106,7 @@ + */ + protected ByteChunk trailingHeaders = new ByteChunk(); + ++ + /** + * Flag set to true if the next call to doRead() must parse a CRLF pair + * before doing anything else. +@@ -130,21 +131,29 @@ + */ + private final int maxTrailerSize; + ++ + /** + * Size of extensions processed for this request. + */ + private long extensionSize; + + ++ /** ++ * Flag that indicates if an error has occurred. ++ */ ++ private boolean error; ++ ++ + // ----------------------------------------------------------- Constructors ++ + public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) { + this.trailingHeaders.setLimit(maxTrailerSize); + this.maxExtensionSize = maxExtensionSize; + this.maxTrailerSize = maxTrailerSize; + } + +- // ---------------------------------------------------- InputBuffer Methods + ++ // ---------------------------------------------------- InputBuffer Methods + + /** + * Read bytes. +@@ -156,11 +165,12 @@ + * control, the returned value should be -1. + */ + @Override +- public int doRead(ByteChunk chunk, Request req) +- throws IOException { +- +- if (endChunk) ++ public int doRead(ByteChunk chunk, Request req) throws IOException { ++ if (endChunk) { + return -1; ++ } ++ ++ checkError(); + + if(needCRLFParse) { + needCRLFParse = false; +@@ -169,7 +179,7 @@ + + if (remaining <= 0) { + if (!parseChunkHeader()) { +- throw new IOException("Invalid chunk header"); ++ throwIOException(sm.getString("chunkedInputFilter.invalidHeader")); + } + if (endChunk) { + parseEndChunk(); +@@ -181,8 +191,7 @@ + + if (pos >= lastValid) { + if (readBytes() < 0) { +- throw new IOException( +- "Unexpected end of stream whilst reading request body"); ++ throwIOException(sm.getString("chunkedInputFilter.eos")); + } + } + +@@ -207,13 +216,11 @@ + } + + return result; +- + } + + + // ---------------------------------------------------- InputFilter Methods + +- + /** + * Read the content length from the request. + */ +@@ -227,17 +234,13 @@ + * End the current request. + */ + @Override +- public long end() +- throws IOException { +- +- // Consume extra bytes : parse the stream until the end chunk is found ++ public long end() throws IOException { + while (doRead(readChunk, null) >= 0) { +- // NOOP: Just consume the input ++ // NOOP: just consume the input + } + + // Return the number of extra bytes which were consumed +- return (lastValid - pos); +- ++ return lastValid - pos; + } + + +@@ -246,7 +249,7 @@ + */ + @Override + public int available() { +- return (lastValid - pos); ++ return lastValid - pos; + } + + +@@ -272,6 +275,7 @@ + trailingHeaders.recycle(); + trailingHeaders.setLimit(maxTrailerSize); + extensionSize = 0; ++ error = false; + } + + +@@ -287,12 +291,10 @@ + + // ------------------------------------------------------ Protected Methods + +- + /** + * Read bytes from the previous buffer. + */ +- protected int readBytes() +- throws IOException { ++ protected int readBytes() throws IOException { + + int nRead = buffer.doRead(readChunk, null); + pos = readChunk.getStart(); +@@ -300,7 +302,6 @@ + buf = readChunk.getBytes(); + + return nRead; +- + } + + +@@ -315,8 +316,7 @@ + * digits. We should not parse F23IAMGONNAMESSTHISUP34CRLF as a valid + * header according to the spec. + */ +- protected boolean parseChunkHeader() +- throws IOException { ++ protected boolean parseChunkHeader() throws IOException { + + int result = 0; + boolean eol = false; +@@ -356,7 +356,7 @@ + // validated. Currently it is simply ignored. + extensionSize++; + if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) { +- throw new IOException("maxExtensionSize exceeded"); ++ throwIOException(sm.getString("chunkedInputFilter.maxExtension")); + } + } + +@@ -364,21 +364,22 @@ + if (!eol) { + pos++; + } +- + } + +- if (readDigit == 0 || result < 0) ++ if (readDigit == 0 || result < 0) { + return false; ++ } + +- if (result == 0) ++ if (result == 0) { + endChunk = true; ++ } + + remaining = result; +- if (remaining < 0) ++ if (remaining < 0) { + return false; ++ } + + return true; +- + } + + +@@ -405,26 +406,27 @@ + boolean crfound = false; + + while (!eol) { +- + if (pos >= lastValid) { +- if (readBytes() <= 0) +- throw new IOException("Invalid CRLF"); ++ if (readBytes() <= 0) { ++ 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++; +- + } + } + +@@ -433,7 +435,6 @@ + * Parse end chunk data. + */ + protected void parseEndChunk() throws IOException { +- + // Handle optional trailer headers + while (parseHeader()) { + // Loop until we run out of headers +@@ -449,8 +450,9 @@ + + // 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"); ++ if (readBytes() <0) { ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); ++ } + } + + chr = buf[pos]; +@@ -474,8 +476,9 @@ + + // 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"); ++ if (readBytes() <0) { ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); ++ } + } + + chr = buf[pos]; +@@ -515,8 +518,9 @@ + + // 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"); ++ if (readBytes() <0) { ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); ++ } + } + + chr = buf[pos]; +@@ -526,7 +530,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 { +@@ -540,8 +544,9 @@ + + // 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"); ++ if (readBytes() <0) { ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); ++ } + } + + chr = buf[pos]; +@@ -565,8 +570,9 @@ + + // 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"); ++ if (readBytes() <0) { ++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); ++ } + } + + chr = buf[pos]; +@@ -587,4 +593,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")); ++ } ++ } + } +--- java/org/apache/coyote/http11/filters/LocalStrings.properties.orig 2015-03-24 16:32:02.662909000 -0400 ++++ java/org/apache/coyote/http11/filters/LocalStrings.properties 2015-03-24 16:39:31.017419000 -0400 +@@ -0,0 +1,27 @@ ++# 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 ++ ++inputFilter.maxSwallow=maxSwallowSize exceeded +\ No newline at end of file diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec index 0d242a1..71eaf13 100644 --- a/SPECS/tomcat.spec +++ b/SPECS/tomcat.spec @@ -54,7 +54,7 @@ Name: tomcat Epoch: 0 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 1%{?dist} +Release: 2%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API Group: System Environment/Daemons @@ -90,6 +90,7 @@ Source24: tomcat-named.service Patch0: %{name}-%{major_version}.%{minor_version}-bootstrap-MANIFEST.MF.patch Patch1: %{name}-%{major_version}.%{minor_version}-tomcat-users-webapp.patch Patch2: tomcat-7.0.54-rebase.patch +Patch3: %{name}-7.0.54-CVE-2014-0227.patch #Patch2: %{name}-%{version}-CVE-2013-4286.patch #Patch3: %{name}-%{version}-CVE-2013-4322.patch #Patch4: %{name}-%{version}-CVE-2014-0050.patch @@ -246,11 +247,7 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch0 -p0 %patch1 -p0 %patch2 -p0 -#%patch3 -p0 -#%patch4 -p0 -#%patch5 -p0 -#%patch6 -p0 -#%patch7 -p0 +%patch3 -p0 %{__ln_s} $(build-classpath jakarta-taglibs-core) webapps/examples/WEB-INF/lib/jstl.jar %{__ln_s} $(build-classpath jakarta-taglibs-standard) webapps/examples/WEB-INF/lib/standard.jar @@ -683,6 +680,9 @@ fi %attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service %changelog +* Tue Mar 24 2015 David Knox - 0:7.0.54-2 +- Resovles: CVE-2014-0227 + * Wed Sep 17 2014 David Knox - 0:7.0.54-1 - Resolves: rhbz#1141372 - Remove systemv artifacts. Add new systemd - artifacts. Rebase on 7.0.54.