diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch new file mode 100644 index 0000000..0b682d5 --- /dev/null +++ b/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch @@ -0,0 +1,284 @@ +--- java/org/apache/coyote/http11/filters/ChunkedInputFilter.java.orig 2014-06-16 18:41:33.642851000 -0400 ++++ java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2014-06-16 19:36:36.796994000 -0400 +@@ -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,9 @@ + */ + public class ChunkedInputFilter implements InputFilter { + ++ private static final StringManager sm = StringManager.getManager( ++ ChunkedInputFilter.class.getPackage().getName()); ++ + private static final org.apache.juli.logging.Log log + = org.apache.juli.logging.LogFactory.getLog(ChunkedInputFilter.class); + +@@ -138,6 +142,11 @@ + */ + private long extensionSize; + ++ /** ++ * Flat that indicates an error has occured ++ */ ++ private boolean error; ++ + // ----------------------------------------------------------- Constructors + public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) { + this.trailingHeaders.setLimit(maxTrailerSize); +@@ -161,6 +170,8 @@ + public int doRead(ByteChunk chunk, Request req) + throws IOException { + ++ checkError(); ++ + if (endChunk) + return -1; + +@@ -171,7 +182,8 @@ + + if (remaining <= 0) { + if (!parseChunkHeader()) { +- throw new IOException("Invalid chunk header"); ++ throwIOException(sm.getString( ++ "chunkedInputFilter.invalidHeader")); + } + if (endChunk) { + parseEndChunk(); +@@ -183,9 +195,9 @@ + + if (pos >= lastValid) { + if (readBytes() < 0) { +- throw new IOException( +- "Unexpected end of stream whilst reading request body"); ++ throwIOException(sm.getString("chunkedInputFilter.eos")); + } ++ + } + + if (remaining > (lastValid - pos)) { +@@ -232,6 +244,8 @@ + public long end() + throws IOException { + ++ checkError(); ++ + // Consume extra bytes : parse the stream until the end chunk is found + while (doRead(readChunk, null) >= 0) { + // NOOP: Just consume the input +@@ -274,6 +288,7 @@ + trailingHeaders.recycle(); + trailingHeaders.setLimit(maxTrailerSize); + extensionSize = 0; ++ error = false; + } + + +@@ -286,6 +301,22 @@ + return ENCODING; + } + ++ private void throwIOException(String msg) throws IOException { ++ error = true; ++ throw new IOException(msg); ++ } ++ ++ private void throwEOFException(String msg) throws IOException { ++ error = true; ++ throw new IOException(msg); ++ } ++ ++ private void checkError() throws IOException { ++ if (error) { ++ throw new IOException( ++ sm.getString("chunkedInputFilter.error")); ++ } ++ } + + // ------------------------------------------------------ Protected Methods + +@@ -322,7 +353,7 @@ + + int result = 0; + boolean eol = false; +- boolean readDigit = false; ++ int readDigit = 0; + boolean extension = false; + + while (!eol) { +@@ -346,10 +377,9 @@ + } else if (!extension) { + //don't read data after the trailer + int charValue = HexUtils.getDec(buf[pos]); +- if (charValue != -1) { +- readDigit = true; +- result *= 16; +- result += charValue; ++ if (charValue != -1 && readDigit < 8) { ++ readDigit++; ++ result = (result << 4) | charValue; + } else { + //we shouldn't allow invalid, non hex characters + //in the chunked header +@@ -362,7 +392,8 @@ + // validated. Currently it is simply ignored. + extensionSize++; + if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) { +- throw new IOException("maxExtensionSize exceeded"); ++ throwIOException(sm.getString( ++ "chunkedInputFilter.maxExtension")); + } + } + // Parsing the CRLF increments pos +@@ -371,7 +402,7 @@ + } + } + +- if (!readDigit) ++ if (readDigit == 0 || result < 0) + return false; + + if (result == 0) +@@ -411,20 +442,27 @@ + while (!eol) { + + if (pos >= lastValid) { +- if (readBytes() <= 0) +- throw new IOException("Invalid CRLF"); ++ if (readBytes() <= 0) { ++ throwIOException(sm.getString( ++ "chunkedInputFilter.invaldCrlfNoData")); ++ } + } + + if (buf[pos] == Constants.CR) { +- if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered."); ++ if (crfound) { ++ throwIOException(sm.getString( ++ "chunkedInputFilter.invaldCrlfCRCR")); ++ } + 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++; +@@ -453,8 +491,10 @@ + + // 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]; +@@ -478,8 +518,10 @@ + + // 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]; +@@ -530,7 +572,8 @@ + // limit placed on trailing header size + int newlimit = trailingHeaders.getLimit() -1; + if (trailingHeaders.getEnd() > newlimit) { +- throw new IOException("Exceeded maxTrailerSize"); ++ throw new IOException( ++ sm.getString("chunkedInputFilter.maxTrailer")); + } + trailingHeaders.setLimit(newlimit); + } else { +@@ -542,8 +585,11 @@ + + // 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]; +@@ -567,8 +613,10 @@ + + // 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]; +--- java/org/apache/coyote/http11/filters/LocalStrings.properties.orig 2014-06-16 18:41:33.647850000 -0400 ++++ java/org/apache/coyote/http11/filters/LocalStrings.properties 2014-06-16 19:22:22.740111000 -0400 +@@ -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 +--- webapps/docs/changelog.xml.orig 2014-06-16 18:41:33.658857000 -0400 ++++ webapps/docs/changelog.xml 2014-06-16 19:37:59.354278000 -0400 +@@ -336,6 +336,12 @@ + + + ++ Resolves: CVE-2014-0075. Improve processing of chunk size from ++ chunked headers. Avoid overflow and use a bit of shift instead ++ of multiplication as it is marginally faster. (mark/kkolinko) ++ Patch applied by Red Hat Jun 16 2014 ++ ++ + 54947: Fix the HTTP NIO connector that incorrectly rejected a + request if the CRLF terminating the request line was split across + multiple packets. Patch by Konstantin Preißer. (markt) diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch new file mode 100644 index 0000000..4137056 --- /dev/null +++ b/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch @@ -0,0 +1,380 @@ +--- conf/web.xml.orig 2014-06-16 14:44:40.800412000 -0400 ++++ conf/web.xml 2014-06-16 15:16:19.075817000 -0400 +@@ -88,10 +88,10 @@ + + + +- +- +- +- ++ ++ ++ ++ + + + default +--- java/org/apache/catalina/servlets/DefaultServlet.java.orig 2014-06-16 14:44:40.820409000 -0400 ++++ java/org/apache/catalina/servlets/DefaultServlet.java 2014-06-16 17:31:56.392767000 -0400 +@@ -36,6 +36,7 @@ + import java.io.StringWriter; + import java.util.ArrayList; + import java.util.Iterator; ++import java.util.Locale; + import java.util.StringTokenizer; + + import javax.naming.InitialContext; +@@ -53,10 +54,14 @@ + import javax.servlet.http.HttpServlet; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; ++import javax.xml.parsers.DocumentBuilder; ++import javax.xml.parsers.DocumentBuilderFactory; ++import javax.xml.parsers.ParserConfigurationException; + import javax.xml.transform.Source; + import javax.xml.transform.Transformer; + import javax.xml.transform.TransformerException; + import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.dom.DOMSource; + import javax.xml.transform.stream.StreamResult; + import javax.xml.transform.stream.StreamSource; + +@@ -72,7 +77,10 @@ + import org.apache.naming.resources.ResourceAttributes; + import org.apache.tomcat.util.res.StringManager; + +- ++import org.w3c.dom.Document; ++import org.xml.sax.InputSource; ++import org.xml.sax.SAXException; ++import org.xml.sax.ext.EntityResolver2; + /** + *

The default resource-serving servlet for most web applications, + * used to serve static resources such as HTML pages and images. +@@ -122,6 +130,10 @@ + + private static final long serialVersionUID = 1L; + ++ private static final DocumentBuilderFactory factory; ++ ++ private static final SecureEntityResolver secureEntityResolver = ++ new SecureEntityResolver(); + // ----------------------------------------------------- Instance Variables + + +@@ -227,6 +239,9 @@ + urlEncoder.addSafeCharacter('.'); + urlEncoder.addSafeCharacter('*'); + urlEncoder.addSafeCharacter('/'); ++ factory = DocumentBuilderFactory.newInstance(); ++ factory.setNamespaceAware(true); ++ factory.setValidating(false); + } + + +@@ -1243,13 +1258,11 @@ + protected InputStream render(String contextPath, CacheEntry cacheEntry) + throws IOException, ServletException { + +- InputStream xsltInputStream = +- findXsltInputStream(cacheEntry.context); +- +- if (xsltInputStream==null) { ++ Source xsltSource = findXsltInputStream(cacheEntry.context); ++ if (xsltSource ==null) { + return renderHtml(contextPath, cacheEntry); + } +- return renderXml(contextPath, cacheEntry, xsltInputStream); ++ return renderXml(contextPath, cacheEntry, xsltSource); + + } + +@@ -1262,7 +1275,7 @@ + */ + protected InputStream renderXml(String contextPath, + CacheEntry cacheEntry, +- InputStream xsltInputStream) ++ Source xsltSource) + throws IOException, ServletException { + + StringBuilder sb = new StringBuilder(); +@@ -1356,8 +1369,7 @@ + try { + TransformerFactory tFactory = TransformerFactory.newInstance(); + Source xmlSource = new StreamSource(new StringReader(sb.toString())); +- Source xslSource = new StreamSource(xsltInputStream); +- Transformer transformer = tFactory.newTransformer(xslSource); ++ Transformer transformer = tFactory.newTransformer(xsltSource); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); +@@ -1578,7 +1590,7 @@ + /** + * Return the xsl template inputstream (if possible) + */ +- protected InputStream findXsltInputStream(DirContext directory) ++ protected Source findXsltInputStream(DirContext directory) + throws IOException { + + if (localXsltFile != null) { +@@ -1586,8 +1598,13 @@ + Object obj = directory.lookup(localXsltFile); + if ((obj != null) && (obj instanceof Resource)) { + InputStream is = ((Resource) obj).streamContent(); +- if (is != null) +- return is; ++ if (is != null) { ++ if (Globals.IS_SECURITY_ENABLED) { ++ return secureXslt(is); ++ } else { ++ return new StreamSource(is); ++ } ++ } + } + } catch (NamingException e) { + if (debug > 10) +@@ -1598,8 +1615,13 @@ + if (contextXsltFile != null) { + InputStream is = + getServletContext().getResourceAsStream(contextXsltFile); +- if (is != null) +- return is; ++ if (is != null) { ++ if (Globals.IS_SECURITY_ENABLED) { ++ return secureXslt(is); ++ } else { ++ return new StreamSource(is); ++ } ++ } + + if (debug > 10) + log("contextXsltFile '" + contextXsltFile + "' not found"); +@@ -1608,25 +1630,111 @@ + /* Open and read in file in one fell swoop to reduce chance + * chance of leaving handle open. + */ +- if (globalXsltFile!=null) { +- FileInputStream fis = null; ++ if (globalXsltFile != null) { ++ File f = validateGlobalXsltFile(); ++ if (f != null ){ ++ FileInputStream fis = null; ++ try { ++ fis = new FileInputStream(f); ++ byte b[] = new byte[(int)f.length()]; /* danger! */ ++ fis.read(b); ++ return new StreamSource(new ByteArrayInputStream(b)); ++ } finally { ++ if (fis != null) { ++ try { ++ fis.close(); ++ } catch(IOException ioe) { ++ // ignore ++ } ++ } ++ } ++ } ++ } + +- try { +- File f = new File(globalXsltFile); +- if (f.exists()){ +- fis =new FileInputStream(f); +- byte b[] = new byte[(int)f.length()]; /* danger! */ +- fis.read(b); +- return new ByteArrayInputStream(b); +- } +- } finally { +- if (fis!=null) +- fis.close(); ++ return null; ++ ++ } ++ ++ private File validateGlobalXsltFile() { ++ ++ File result = null; ++ String base = System.getProperty(Globals.CATALINA_BASE_PROP); ++ ++ if (base != null) { ++ File baseConf = new File(base, "conf"); ++ result = validateGlobalXsltFile(baseConf); ++ } ++ ++ if (result == null) { ++ String home = System.getProperty(Globals.CATALINA_HOME_PROP); ++ if (home != null && !home.equals(base)) { ++ File homeConf = new File(home, "conf"); ++ result = validateGlobalXsltFile(homeConf); + } + } + +- return null; ++ return result; ++ } ++ + ++ private File validateGlobalXsltFile(File base) { ++ File candidate = new File(globalXsltFile); ++ if (!candidate.isAbsolute()) { ++ candidate = new File(base, globalXsltFile); ++ } ++ ++ if (!candidate.isFile()) { ++ return null; ++ } ++ ++ // First check that the resulting path is under the provided base ++ try { ++ if (!candidate.getCanonicalPath().startsWith(base.getCanonicalPath())) { ++ return null; ++ } ++ } catch (IOException ioe) { ++ return null; ++ } ++ ++ // Next check that an .xsl or .xslt file has been specified ++ String nameLower = candidate.getName().toLowerCase(Locale.ENGLISH); ++ if (!nameLower.endsWith(".xslt") && !nameLower.endsWith(".xsl")) { ++ return null; ++ } ++ ++ return candidate; ++ } ++ ++ private Source secureXslt(InputStream is) { ++ // Need to filter out any external entities ++ Source result = null; ++ try { ++ DocumentBuilder builder = factory.newDocumentBuilder(); ++ builder.setEntityResolver(secureEntityResolver); ++ Document document = builder.parse(is); ++ result = new DOMSource(document); ++ } catch (ParserConfigurationException e) { ++ if (debug > 0) { ++ log(e.getMessage(), e); ++ } ++ } catch (SAXException e) { ++ if (debug > 0) { ++ log(e.getMessage(), e); ++ } ++ } catch (IOException e) { ++ if (debug > 0) { ++ log(e.getMessage(), e); ++ } ++ } finally { ++ if (is != null) { ++ try { ++ is.close(); ++ } catch (IOException e) { ++ // Ignore ++ } ++ } ++ } ++ return result; + } + + +@@ -2150,4 +2258,34 @@ + return (start >= 0) && (end >= 0) && (start <= end) && (length > 0); + } + } ++ ++ /** ++ * This is secure in the sense that any attempt to use an external entity ++ * will trigger an exception. ++ */ ++ private static class SecureEntityResolver implements EntityResolver2 { ++ ++ @Override ++ public InputSource resolveEntity(String publicId, String systemId) ++ throws SAXException, IOException { ++ throw new SAXException(sm.getString("defaultServlet.blockExternalEntity", ++ publicId, systemId)); ++ } ++ ++ @Override ++ public InputSource getExternalSubset(String name, String baseURI) ++ throws SAXException, IOException { ++ throw new SAXException(sm.getString("defaultServlet.blockExternalSubset", ++ name, baseURI)); ++ } ++ ++ @Override ++ public InputSource resolveEntity(String name, String publicId, ++ String baseURI, String systemId) throws SAXException, ++ IOException { ++ throw new SAXException(sm.getString("defaultServlet.blockExternalEntity2", ++ name, publicId, baseURI, systemId)); ++ } ++ } + } ++ +--- java/org/apache/catalina/servlets/LocalStrings.properties.orig 2014-06-16 14:44:40.830411000 -0400 ++++ java/org/apache/catalina/servlets/LocalStrings.properties 2014-06-16 16:15:08.577726000 -0400 +@@ -13,6 +13,10 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + ++ ++defaultServlet.blockExternalEntity=Blocked access to external entity with publicId [{0}] and systemId [{0}] ++defaultServlet.blockExternalEntity2=Blocked access to external entity with name [{0}], publicId [{1}], baseURI [{2}] and systemId [{3}] ++defaultServlet.blockExternalSubset=Blocked access to external subset with name [{0}] and baseURI [{1}] + defaultServlet.missingResource=The requested resource ({0}) is not available + defaultservlet.directorylistingfor=Directory Listing for: + defaultservlet.upto=Up to: +--- webapps/docs/default-servlet.xml.orig 2014-06-16 14:44:40.836413000 -0400 ++++ webapps/docs/default-servlet.xml 2014-06-16 16:17:41.419241000 -0400 +@@ -110,22 +110,24 @@ + globalXsltFile + + If you wish to customize your directory listing, you +- can use an XSL transformation. This value is an absolute +- file name which be used for all directory listings. +- This can be overridden per context and/or per directory. See +- contextXsltFile and localXsltFile +- below. The format of the xml is shown below. ++ can use an XSL transformation. This value is a relative file name (to ++ either $CATALINA_BASE/conf/ or $CATALINA_HOME/conf/) which will be used ++ for all directory listings. This can be overridden per context and/or ++ per directory. See contextXsltFile and ++ localXsltFile below. The format of the xml is shown ++ below. + + + + contextXsltFile + + You may also customize your directory listing by context by +- configuring contextXsltFile. This should be a context +- relative path (e.g.: /path/to/context.xslt). This +- overrides globalXsltFile. If this value is present but a +- file does not exist, then globalXsltFile will be used. If + globalXsltFile does not exist, then the default ++ configuring contextXsltFile. This must be a context ++ relative path (e.g.: /path/to/context.xslt) to a file with ++ a .xsl or .xslt extension. This overrides ++ globalXsltFile. If this value is present but a file does ++ not exist, then globalXsltFile will be used. If + directory listing will be shown. + + +@@ -133,11 +135,12 @@ + localXsltFile + + You may also customize your directory listing by directory by +- configuring localXsltFile. This should be a relative +- file name in the directory where the listing will take place. +- This overrides globalXsltFile and +- contextXsltFile. If this value is present but a file +- does not exist, then contextXsltFile will be used. If ++ configuring localXsltFile. This must be a file in the ++ directory where the listing will take place to with a ++ .xsl or .xslt extension. This overrides ++ globalXsltFile and contextXsltFile. If this ++ value is present but a file does not exist, then ++ contextXsltFile will be used. If + contextXsltFile does not exist, then + globalXsltFile will be used. If + globalXsltFile does not exist, then the default diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch new file mode 100644 index 0000000..ac72ae3 --- /dev/null +++ b/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch @@ -0,0 +1,49 @@ +--- java/org/apache/tomcat/util/buf/Ascii.java.orig 2014-06-16 13:31:00.031497000 -0400 ++++ java/org/apache/tomcat/util/buf/Ascii.java 2014-06-16 13:40:15.667390000 -0400 +@@ -40,6 +40,7 @@ + private static final boolean[] isWhite = new boolean[256]; + private static final boolean[] isDigit = new boolean[256]; + ++ private static final long OVERFLOW_LIMIT = Long.MAX_VALUE / 10; + /* + * Initialize character translation and type tables. + */ +@@ -206,20 +207,16 @@ + } + + long n = c - '0'; +- long m; + + while (--len > 0) { +- if (!isDigit(c = b[off++])) { ++ if (isDigit(c = b[off++]) && ++ (n < OVERFLOW_LIMIT || ++ ( n == OVERFLOW_LIMIT && (c - '0') < 8))) { ++ n = n * 10 + c - '0'; ++ } else { + throw new NumberFormatException(); + } +- m = n * 10 + c - '0'; + +- if (m < n) { +- // Overflow +- throw new NumberFormatException(); +- } else { +- n = m; +- } + } + + return n; +--- webapps/docs/changelog.xml.orig 2014-06-16 13:31:00.067494000 -0400 ++++ webapps/docs/changelog.xml 2014-06-16 13:42:21.284821000 -0400 +@@ -59,6 +59,10 @@ + + + ++ CVE-2014-0099, Fix overflow when parsing long values from ++ byte array. (markt) Patch applied by Red Hat Jun 16 2014 ++ ++ + Fix CVE-2014-0050, a denial of service with a malicious, malformed + Content-Type header and multipart request processing. Fixed by merging + latest code (r1565163) from Commons FileUpload. (markt) diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec index e20b68b..798d69a 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: 5%{?dist} +Release: 6%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API Group: System Environment/Daemons @@ -88,6 +88,13 @@ Patch1: %{name}-%{major_version}.%{minor_version}-tomcat-users-webapp.patch Patch2: %{name}-%{version}-CVE-2013-4286.patch Patch3: %{name}-%{version}-CVE-2013-4322.patch Patch4: %{name}-%{version}-CVE-2014-0050.patch +Patch5: %{name}-%{version}-CVE-2014-0099.patch +Patch6: %{name}-%{version}-CVE-2014-0096.patch +Patch7: %{name}-%{version}-CVE-2014-0075.patch +# postponed. apply with 4590 +# Deferred +#Patch5: %{name}-%{version}-CVE-2013-4590.patch +#Patch8: %{name}-%{version}-CVE-2014-0119.patch BuildArch: noarch @@ -248,6 +255,12 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch2 -p0 %patch3 -p0 %patch4 -p0 +%patch5 -p0 +%patch6 -p0 +%patch7 -p0 +# postponed. apply with 4590 +#%patch8 -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 @@ -686,8 +699,15 @@ fi %{_sbindir}/%{name}-jsvc-sysd %attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service - %changelog +* Wed Jun 11 2014 David Knox - 0:7.0.42-6 +- Resolves: CVE-2014-0099 Fix possible overflow when parsing +- long values from byte array +- Resolves: CVE-2014-0096 Information discloser process XSLT +- files not subject to same constraint running under +- java security manager +- Resolves: CVE-2014-0075 Avoid overflow in ChunkedInputFilter. + * Wed Apr 16 2014 David Knox - 0:7.0.42-5 - Related: CVE-2013-4286 - Related: CVE-2013-4322