diff --git a/SOURCES/tomcat-7.0.76-CVE-2017-12617.patch b/SOURCES/tomcat-7.0.76-CVE-2017-12617.patch
new file mode 100644
index 0000000..7cc2048
--- /dev/null
+++ b/SOURCES/tomcat-7.0.76-CVE-2017-12617.patch
@@ -0,0 +1,715 @@
+--- java/org/apache/catalina/servlets/DefaultServlet.java.orig 2017-10-13 09:41:05.734302404 -0400
++++ java/org/apache/catalina/servlets/DefaultServlet.java 2017-10-13 09:42:53.515701311 -0400
+@@ -855,23 +855,6 @@
+ return;
+ }
+
+- // If the resource is not a collection, and the resource path
+- // ends with "/" or "\", return NOT FOUND
+- if (cacheEntry.context == null) {
+- if (path.endsWith("/") || (path.endsWith("\\"))) {
+- // Check if we're included so we can return the appropriate
+- // missing resource name in the error
+- String requestUri = (String) request.getAttribute(
+- RequestDispatcher.INCLUDE_REQUEST_URI);
+- if (requestUri == null) {
+- requestUri = request.getRequestURI();
+- }
+- response.sendError(HttpServletResponse.SC_NOT_FOUND,
+- requestUri);
+- return;
+- }
+- }
+-
+ boolean isError = DispatcherType.ERROR == request.getDispatcherType();
+
+ // Check if the conditions specified in the optional If headers are
+--- java/org/apache/naming/resources/FileDirContext.java.orig 2017-10-13 09:41:05.737302387 -0400
++++ java/org/apache/naming/resources/FileDirContext.java 2017-10-13 09:42:53.516701306 -0400
+@@ -14,8 +14,6 @@
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-
+-
+ package org.apache.naming.resources;
+
+ import java.io.File;
+@@ -75,6 +73,8 @@
+
+ /**
+ * Builds a file directory context using the given environment.
++ *
++ * @param env The environment with which to build the context
+ */
+ public FileDirContext(Hashtable env) {
+ super(env);
+@@ -95,6 +95,8 @@
+ */
+ protected String absoluteBase = null;
+
++ private String canonicalBase = null;
++
+
+ /**
+ * Allow linking.
+@@ -104,7 +106,6 @@
+
+ // ------------------------------------------------------------- Properties
+
+-
+ /**
+ * Set the document root.
+ *
+@@ -117,32 +118,41 @@
+ */
+ @Override
+ public void setDocBase(String docBase) {
++ // Validate the format of the proposed document root
++ if (docBase == null) {
++ throw new IllegalArgumentException(sm.getString("resources.null"));
++ }
+
+- // Validate the format of the proposed document root
+- if (docBase == null)
+- throw new IllegalArgumentException
+- (sm.getString("resources.null"));
+-
+- // Calculate a File object referencing this document base directory
+- base = new File(docBase);
++ // Calculate a File object referencing this document base directory
++ base = new File(docBase);
+ try {
+ base = base.getCanonicalFile();
+ } catch (IOException e) {
+ // Ignore
+ }
+
+- // Validate that the document base is an existing directory
+- if (!base.exists() || !base.isDirectory() || !base.canRead())
+- throw new IllegalArgumentException
+- (sm.getString("fileResources.base", docBase));
+- this.absoluteBase = base.getAbsolutePath();
+- super.setDocBase(docBase);
++ // Validate that the document base is an existing directory
++ if (!base.exists() || !base.isDirectory() || !base.canRead()) {
++ throw new IllegalArgumentException(sm.getString("fileResources.base", docBase));
++ }
+
++ this.absoluteBase = normalize(base.getAbsolutePath());
++
++ // absoluteBase also needs to be normalized. Using the canonical path is
++ // the simplest way of doing this.
++ try {
++ this.canonicalBase = base.getCanonicalPath();
++ } catch (IOException e) {
++ throw new IllegalArgumentException(e);
++ }
++ super.setDocBase(docBase);
+ }
+
+
+ /**
+ * Set allow linking.
++ *
++ * @param allowLinking The new value for the attribute
+ */
+ public void setAllowLinking(boolean allowLinking) {
+ this.allowLinking = allowLinking;
+@@ -151,6 +161,8 @@
+
+ /**
+ * Is linking allowed.
++ *
++ * @return {@code true} is linking is allowed, otherwise {@false}
+ */
+ public boolean getAllowLinking() {
+ return allowLinking;
+@@ -193,7 +205,7 @@
+ @Override
+ protected Object doLookup(String name) {
+ Object result = null;
+- File file = file(name);
++ File file = file(name, true);
+
+ if (file == null)
+ return null;
+@@ -230,7 +242,7 @@
+ public void unbind(String name)
+ throws NamingException {
+
+- File file = file(name);
++ File file = file(name, true);
+
+ if (file == null)
+ throw new NameNotFoundException(
+@@ -255,22 +267,22 @@
+ * @exception NamingException if a naming exception is encountered
+ */
+ @Override
+- public void rename(String oldName, String newName)
+- throws NamingException {
++ public void rename(String oldName, String newName) throws NamingException {
+
+- File file = file(oldName);
++ File file = file(oldName, true);
+
+- if (file == null)
+- throw new NameNotFoundException
+- (sm.getString("resources.notFound", oldName));
++ if (file == null) {
++ throw new NameNotFoundException(sm.getString("resources.notFound", oldName));
++ }
+
+- File newFile = new File(base, newName);
++ File newFile = file(newName, false);
++ if (newFile == null) {
++ throw new NamingException(sm.getString("resources.renameFail", oldName, newName));
++ }
+
+ if (!file.renameTo(newFile)) {
+- throw new NamingException(sm.getString("resources.renameFail",
+- oldName, newName));
++ throw new NamingException(sm.getString("resources.renameFail", oldName, newName));
+ }
+-
+ }
+
+
+@@ -291,11 +303,11 @@
+ protected List doListBindings(String name)
+ throws NamingException {
+
+- File file = file(name);
++ File file = file(name, true);
+
+ if (file == null)
+ return null;
+-
++
+ return list(file);
+
+ }
+@@ -395,7 +407,7 @@
+ throws NamingException {
+
+ // Building attribute list
+- File file = file(name);
++ File file = file(name, true);
+
+ if (file == null)
+ return null;
+@@ -463,12 +475,20 @@
+ * @exception NamingException if a naming exception is encountered
+ */
+ @Override
+- public void bind(String name, Object obj, Attributes attrs)
+- throws NamingException {
++ public void bind(String name, Object obj, Attributes attrs) throws NamingException {
+
+ // Note: No custom attributes allowed
+
+- File file = new File(base, name);
++ // bind() is meant to create a file so ensure that the path doesn't end
++ // in '/'
++ if (name.endsWith("/")) {
++ throw new NamingException(sm.getString("resources.bindFailed", name));
++ }
++
++ File file = file(name, false);
++ if (file == null) {
++ throw new NamingException(sm.getString("resources.bindFailed", name));
++ }
+ if (file.exists())
+ throw new NameAlreadyBoundException
+ (sm.getString("resources.alreadyBound", name));
+@@ -503,7 +523,10 @@
+ // Note: No custom attributes allowed
+ // Check obj type
+
+- File file = new File(base, name);
++ File file = file(name, false);
++ if (file == null) {
++ throw new NamingException(sm.getString("resources.bindFailed", name));
++ }
+
+ InputStream is = null;
+ if (obj instanceof Resource) {
+@@ -583,13 +606,14 @@
+ public DirContext createSubcontext(String name, Attributes attrs)
+ throws NamingException {
+
+- File file = new File(base, name);
++ File file = file(name, false);
++ if (file == null) {
++ throw new NamingException(sm.getString("resources.bindFailed", name));
++ }
+ if (file.exists())
+- throw new NameAlreadyBoundException
+- (sm.getString("resources.alreadyBound", name));
++ throw new NameAlreadyBoundException(sm.getString("resources.alreadyBound", name));
+ if (!file.mkdir())
+- throw new NamingException
+- (sm.getString("resources.bindFailed", name));
++ throw new NamingException(sm.getString("resources.bindFailed", name));
+ return (DirContext) lookup(name);
+
+ }
+@@ -758,6 +782,7 @@
+
+ }
+
++
+ /**
+ * Return a File object representing the specified normalized
+ * context-relative path if it exists and is readable. Otherwise,
+@@ -766,51 +791,133 @@
+ * @param name Normalized context-relative path (with leading '/')
+ */
+ protected File file(String name) {
++ return file(name, true);
++ }
++
++
++ /**
++ * Return a File object representing the specified normalized
++ * context-relative path if it exists and is readable. Otherwise,
++ * return null
.
++ *
++ * @param name Normalized context-relative path (with leading '/')
++ * @param mustExist Must the specified resource exist?
++ */
++ protected File file(String name, boolean mustExist) {
++ if (name.equals("/")) {
++ name = "";
++ }
+
+ File file = new File(base, name);
+- if (file.exists() && file.canRead()) {
++ return validate(file, name, mustExist, absoluteBase, canonicalBase);
++ }
+
+- if (allowLinking)
+- return file;
+-
+- // Check that this file belongs to our root path
+- String canPath = null;
+- try {
+- canPath = file.getCanonicalPath();
+- } catch (IOException e) {
+- // Ignore
+- }
+- if (canPath == null)
+- return null;
+
+- // Check to see if going outside of the web application root
+- if (!canPath.startsWith(absoluteBase)) {
+- return null;
+- }
++ protected File validate(File file, String name, boolean mustExist, String absoluteBase,
++ String canonicalBase) {
+
+- // Case sensitivity check - this is now always done
+- String fileAbsPath = file.getAbsolutePath();
+- if (fileAbsPath.endsWith("."))
+- fileAbsPath = fileAbsPath + "/";
+- String absPath = normalize(fileAbsPath);
+- canPath = normalize(canPath);
+- if ((absoluteBase.length() < absPath.length())
+- && (absoluteBase.length() < canPath.length())) {
+- absPath = absPath.substring(absoluteBase.length() + 1);
+- if (absPath.equals(""))
+- absPath = "/";
+- canPath = canPath.substring(absoluteBase.length() + 1);
+- if (canPath.equals(""))
+- canPath = "/";
+- if (!canPath.equals(absPath))
+- return null;
+- }
++ // If the requested names ends in '/', the Java File API will return a
++ // matching file if one exists. This isn't what we want as it is not
++ // consistent with the Servlet spec rules for request mapping.
++ if (name.endsWith("/") && file.isFile()) {
++ return null;
++ }
+
+- } else {
++ // If the file/dir must exist but the identified file/dir can't be read
++ // then signal that the resource was not found
++ if (mustExist && !file.canRead()) {
++ return null;
++ }
++
++ // If allow linking is enabled, files are not limited to being located
++ // under the fileBase so all further checks are disabled.
++ if (allowLinking) {
++ return file;
++ }
++
++ // Additional Windows specific checks to handle known problems with
++ // File.getCanonicalPath()
++ if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) {
++ return null;
++ }
++
++ // Check that this file is located under the web application root
++ String canPath = null;
++ try {
++ canPath = file.getCanonicalPath();
++ } catch (IOException e) {
++ // Ignore
++ }
++ if (canPath == null || !canPath.startsWith(canonicalBase)) {
++ return null;
++ }
++
++ // Ensure that the file is not outside the fileBase. This should not be
++ // possible for standard requests (the request is normalized early in
++ // the request processing) but might be possible for some access via the
++ // Servlet API (RequestDispatcher etc.) therefore these checks are
++ // retained as an additional safety measure. absoluteBase has been
++ // normalized so absPath needs to be normalized as well.
++ String absPath = normalize(file.getAbsolutePath());
++ if ((absoluteBase.length() > absPath.length())) {
+ return null;
+ }
++
++ // Remove the fileBase location from the start of the paths since that
++ // was not part of the requested path and the remaining check only
++ // applies to the request path
++ absPath = absPath.substring(absoluteBase.length());
++ canPath = canPath.substring(canonicalBase.length());
++
++ // Case sensitivity check
++ // The normalized requested path should be an exact match the equivalent
++ // canonical path. If it is not, possible reasons include:
++ // - case differences on case insensitive file systems
++ // - Windows removing a trailing ' ' or '.' from the file name
++ //
++ // In all cases, a mis-match here results in the resource not being
++ // found
++ //
++ // absPath is normalized so canPath needs to be normalized as well
++ // Can't normalize canPath earlier as canonicalBase is not normalized
++ if (canPath.length() > 0) {
++ canPath = normalize(canPath);
++ }
++ if (!canPath.equals(absPath)) {
++ return null;
++ }
++
+ return file;
++ }
++
+
++ private boolean isInvalidWindowsFilename(String name) {
++ final int len = name.length();
++ if (len == 0) {
++ return false;
++ }
++ // This consistently ~10 times faster than the equivalent regular
++ // expression irrespective of input length.
++ for (int i = 0; i < len; i++) {
++ char c = name.charAt(i);
++ if (c == '\"' || c == '<' || c == '>') {
++ // These characters are disallowed in Windows file names and
++ // there are known problems for file names with these characters
++ // when using File#getCanonicalPath().
++ // Note: There are additional characters that are disallowed in
++ // Windows file names but these are not known to cause
++ // problems when using File#getCanonicalPath().
++ return true;
++ }
++ }
++ // Windows does not allow file names to end in ' ' unless specific low
++ // level APIs are used to create the files that bypass various checks.
++ // File names that end in ' ' are known to cause problems when using
++ // File#getCanonicalPath().
++ if (name.charAt(len -1) == ' ') {
++ return true;
++ }
++ return false;
+ }
+
+
+@@ -1054,10 +1161,10 @@
+ return super.getResourceType();
+ }
+
+-
++
+ /**
+ * Get canonical path.
+- *
++ *
+ * @return String the file's canonical path
+ */
+ @Override
+@@ -1071,10 +1178,6 @@
+ }
+ return canonicalPath;
+ }
+-
+-
+ }
+-
+-
+ }
+
+--- java/org/apache/naming/resources/VirtualDirContext.java.orig 2017-10-13 09:41:05.740302370 -0400
++++ java/org/apache/naming/resources/VirtualDirContext.java 2017-10-13 09:42:53.517701300 -0400
+@@ -76,7 +76,8 @@
+ * be listed twice.
+ *
+ *
+- * @param path
++ * @param path The set of file system paths and virtual paths to map them to
++ * in the required format
+ */
+ public void setExtraResourcePaths(String path) {
+ extraResourcePaths = path;
+@@ -106,13 +107,13 @@
+ }
+ path = resSpec.substring(0, idx);
+ }
+- String dir = resSpec.substring(idx + 1);
++ File dir = new File(resSpec.substring(idx + 1));
+ List resourcePaths = mappedResourcePaths.get(path);
+ if (resourcePaths == null) {
+ resourcePaths = new ArrayList();
+ mappedResourcePaths.put(path, resourcePaths);
+ }
+- resourcePaths.add(dir);
++ resourcePaths.add(dir.getAbsolutePath());
+ }
+ }
+ if (mappedResourcePaths.isEmpty()) {
+@@ -151,15 +152,17 @@
+ String resourcesDir = dirList.get(0);
+ if (name.equals(path)) {
+ File f = new File(resourcesDir);
+- if (f.exists() && f.canRead()) {
++ f = validate(f, name, true, resourcesDir);
++ if (f != null) {
+ return new FileResourceAttributes(f);
+ }
+ }
+ path += "/";
+ if (name.startsWith(path)) {
+ String res = name.substring(path.length());
+- File f = new File(resourcesDir + "/" + res);
+- if (f.exists() && f.canRead()) {
++ File f = new File(resourcesDir, res);
++ f = validate(f, res, true, resourcesDir);
++ if (f != null) {
+ return new FileResourceAttributes(f);
+ }
+ }
+@@ -168,9 +171,16 @@
+ throw initialException;
+ }
+
++
+ @Override
+ protected File file(String name) {
+- File file = super.file(name);
++ return file(name, true);
++ }
++
++
++ @Override
++ protected File file(String name, boolean mustExist) {
++ File file = super.file(name, true);
+ if (file != null || mappedResourcePaths == null) {
+ return file;
+ }
+@@ -185,7 +195,8 @@
+ if (name.equals(path)) {
+ for (String resourcesDir : dirList) {
+ file = new File(resourcesDir);
+- if (file.exists() && file.canRead()) {
++ file = validate(file, name, true, resourcesDir);
++ if (file != null) {
+ return file;
+ }
+ }
+@@ -194,7 +205,8 @@
+ String res = name.substring(path.length());
+ for (String resourcesDir : dirList) {
+ file = new File(resourcesDir, res);
+- if (file.exists() && file.canRead()) {
++ file = validate(file, res, true, resourcesDir);
++ if (file != null) {
+ return file;
+ }
+ }
+@@ -229,7 +241,8 @@
+ if (res != null) {
+ for (String resourcesDir : dirList) {
+ File f = new File(resourcesDir, res);
+- if (f.exists() && f.canRead() && f.isDirectory()) {
++ f = validate(f, res, true, resourcesDir);
++ if (f != null && f.isDirectory()) {
+ List virtEntries = super.list(f);
+ for (NamingEntry entry : virtEntries) {
+ // filter duplicate
+@@ -264,7 +277,8 @@
+ if (name.equals(path)) {
+ for (String resourcesDir : dirList) {
+ File f = new File(resourcesDir);
+- if (f.exists() && f.canRead()) {
++ f = validate(f, name, true, resourcesDir);
++ if (f != null) {
+ if (f.isFile()) {
+ return new FileResource(f);
+ }
+@@ -279,8 +293,9 @@
+ if (name.startsWith(path)) {
+ String res = name.substring(path.length());
+ for (String resourcesDir : dirList) {
+- File f = new File(resourcesDir + "/" + res);
+- if (f.exists() && f.canRead()) {
++ File f = new File(resourcesDir, res);
++ f = validate(f, res, true, resourcesDir);
++ if (f != null) {
+ if (f.isFile()) {
+ return new FileResource(f);
+ }
+@@ -304,4 +319,9 @@
+ return null;
+ }
+ }
++
++
++ protected File validate(File file, String name, boolean mustExist, String absoluteBase) {
++ return validate(file, name, mustExist, normalize(absoluteBase), absoluteBase);
++ }
+ }
+--- webapps/docs/changelog.xml.orig 2017-10-13 09:15:35.996884086 -0400
++++ webapps/docs/changelog.xml 2017-10-13 09:44:50.895046977 -0400
+@@ -64,6 +64,14 @@
+ 61101: CORS filter should set Vary header in response.
+ Submitted by Rick Riemer. (remm)
+
++
++ Correct regression in 7.0.80 that broke WebDAV. (markt)
++
++
++ 61542: Fix CVE-2017-12617 and prevent JSPs from being
++ uploaded via a specially crafted request when HTTP PUT was enabled.
++ (markt)
++
+
+
+
+--- java/org/apache/naming/resources/JrePlatform.java.orig 2017-10-13 09:41:05.745302342 -0400
++++ java/org/apache/naming/resources/JrePlatform.java 2017-10-13 09:42:53.516701306 -0400
+@@ -0,0 +1,59 @@
++/*
++ * 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.
++ */
++package org.apache.naming.resources;
++
++import java.security.AccessController;
++import java.security.PrivilegedAction;
++
++public class JrePlatform {
++
++ private static final String OS_NAME_PROPERTY = "os.name";
++ private static final String OS_NAME_WINDOWS_PREFIX = "Windows";
++
++ static {
++ /*
++ * There are a few places where a) the behaviour of the Java API depends
++ * on the underlying platform and b) those behavioural differences have
++ * an impact on Tomcat.
++ *
++ * Tomcat therefore needs to be able to determine the platform it is
++ * running on to account for those differences.
++ *
++ * In an ideal world this code would not exist.
++ */
++
++ // This check is derived from the check in Apache Commons Lang
++ String osName;
++ if (System.getSecurityManager() == null) {
++ osName = System.getProperty(OS_NAME_PROPERTY);
++ } else {
++ osName = AccessController.doPrivileged(
++ new PrivilegedAction() {
++
++ @Override
++ public String run() {
++ return System.getProperty(OS_NAME_PROPERTY);
++ }
++ });
++ }
++
++ IS_WINDOWS = osName.startsWith(OS_NAME_WINDOWS_PREFIX);
++ }
++
++
++ public static final boolean IS_WINDOWS;
++}
+--- test/org/apache/naming/resources/TestFileDirContext.java.orig 2017-10-13 09:45:35.991795584 -0400
++++ test/org/apache/naming/resources/TestFileDirContext.java 2017-10-13 09:42:53.517701300 -0400
+@@ -0,0 +1,46 @@
++/*
++ * 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.
++ */
++package org.apache.naming.resources;
++
++import java.io.File;
++
++import javax.servlet.http.HttpServletResponse;
++
++import org.junit.Assert;
++import org.junit.Test;
++
++import org.apache.catalina.startup.Tomcat;
++import org.apache.catalina.startup.TomcatBaseTest;
++import org.apache.tomcat.util.buf.ByteChunk;
++
++public class TestFileDirContext extends TomcatBaseTest {
++
++ @Test
++ public void testLookupResourceWithTrailingSlash() throws Exception {
++ Tomcat tomcat = getTomcatInstance();
++
++ File appDir = new File("test/webapp-3.0");
++ // app dir is relative to server home
++ tomcat.addWebapp(null, "/test", appDir.getAbsolutePath());
++
++ tomcat.start();
++
++ int sc = getUrl("http://localhost:" + getPort() +
++ "/test/index.html/", new ByteChunk(), null);
++ Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, sc);
++ }
++}
diff --git a/SOURCES/tomcat-7.0.76-CVE-2017-5647.patch b/SOURCES/tomcat-7.0.76-CVE-2017-5647.patch
index 6789452..baa284d 100644
--- a/SOURCES/tomcat-7.0.76-CVE-2017-5647.patch
+++ b/SOURCES/tomcat-7.0.76-CVE-2017-5647.patch
@@ -1,6 +1,6 @@
---- java/org/apache/coyote/AbstractProtocol.java.orig 2017-06-08 16:23:31.981000734 -0400
-+++ java/org/apache/coyote/AbstractProtocol.java 2017-06-08 16:23:32.002000817 -0400
-@@ -693,10 +693,9 @@
+--- java/org/apache/coyote/AbstractProtocol.java.orig 2017-08-18 09:12:05.149568367 -0400
++++ java/org/apache/coyote/AbstractProtocol.java 2017-08-18 09:12:55.998699189 -0400
+@@ -693,10 +693,10 @@
release(wrapper, processor, false, true);
} else if (state == SocketState.SENDFILE) {
// Sendfile in progress. If it fails, the socket will be
@@ -11,6 +11,7 @@
+ // closed. If it works, the socket either be added to the
+ // poller (or equivalent) to await more data or processed
+ // if there are any pipe-lined requests remaining.
++ connections.put(socket, processor);
} else if (state == SocketState.UPGRADED) {
// Need to keep the connection associated with the processor
connections.put(socket, processor);
diff --git a/SOURCES/tomcat-7.0.76-CVE-2017-7674.patch b/SOURCES/tomcat-7.0.76-CVE-2017-7674.patch
new file mode 100644
index 0000000..efb3cf9
--- /dev/null
+++ b/SOURCES/tomcat-7.0.76-CVE-2017-7674.patch
@@ -0,0 +1,46 @@
+--- java/org/apache/catalina/filters/CorsFilter.java.orig 2017-10-12 16:48:47.426952298 -0400
++++ java/org/apache/catalina/filters/CorsFilter.java 2017-10-12 16:48:47.431952269 -0400
+@@ -297,6 +297,10 @@
+ exposedHeadersString);
+ }
+
++ // Indicate the response depends on the origin
++ response.addHeader(CorsFilter.REQUEST_HEADER_VARY,
++ CorsFilter.REQUEST_HEADER_ORIGIN);
++
+ // Forward the request down the filter chain.
+ filterChain.doFilter(request, response);
+ }
+@@ -998,6 +1002,13 @@
+ "Access-Control-Allow-Headers";
+
+ // -------------------------------------------------- CORS Request Headers
++
++ /**
++ * The Vary header indicates allows disabling proxy caching by indicating
++ * the the response depends on the origin.
++ */
++ public static final String REQUEST_HEADER_VARY = "Vary";
++
+ /**
+ * The Origin header indicates where the cross-origin request or preflight
+ * request originates from.
+--- webapps/docs/changelog.xml.orig 2017-10-12 16:48:47.428952287 -0400
++++ webapps/docs/changelog.xml 2017-10-12 16:50:08.718477877 -0400
+@@ -57,6 +57,16 @@
+ They eventually become mixed with the numbered issues. (I.e., numbered
+ issues do not "pop up" wrt. others).
+ -->
++
++
++
++
++ 61101: CORS filter should set Vary header in response.
++ Submitted by Rick Riemer. (remm)
++
++
++
++
+
+
+
diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec
index 4619b86..493f3b3 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: 2%{?dist}
+Release: 3%{?dist}
Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API
Group: System Environment/Daemons
@@ -90,6 +90,8 @@ Patch2: %{name}-7.0.54-rebase.patch
Patch3: %{name}-7.0-catalina-policy.patch
Patch4: %{name}-7.0.76-CVE-2017-5664.patch
Patch5: %{name}-7.0.76-CVE-2017-5647.patch
+Patch6: %{name}-7.0.76-CVE-2017-7674.patch
+Patch7: %{name}-7.0.76-CVE-2017-12617.patch
BuildArch: noarch
@@ -240,6 +242,8 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name "
%patch3 -p0
%patch4 -p0
%patch5 -p0
+%patch6 -p0
+%patch7 -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
@@ -679,6 +683,11 @@ fi
%attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service
%changelog
+* Thu Oct 12 2017 Coty Sutherland 0:7.0.76-3
+- Resolves: rhbz#1498344 CVE-2017-12615 CVE-2017-12617 tomcat: various flaws
+- Resolves: rhbz#1495654 CVE-2017-7674 tomcat: Vary header not added by CORS filter leading to cache poisoning
+- Resolves: rhbz#1470596 CVE-2017-5647 Add follow up revision
+
* Thu Jun 08 2017 Coty Sutherland 0:7.0.76-2
- Resolves: rhbz#1459747 CVE-2017-5664 tomcat: Security constrained bypass in error page mechanism
- Resolves: rhbz#1441481 CVE-2017-5647 tomcat: Incorrect handling of pipelined requests when send file was used