diff -Nru tomcat7-7.0.52/debian/changelog tomcat7-7.0.52/debian/changelog --- tomcat7-7.0.52/debian/changelog 2015-06-19 20:14:50.000000000 +0000 +++ tomcat7-7.0.52/debian/changelog 2016-06-29 16:51:02.000000000 +0000 @@ -1,3 +1,73 @@ +tomcat7 (7.0.52-1ubuntu0.6) trusty-security; urgency=medium + + * SECURITY UPDATE: directory traversal vulnerability in RequestUtil.java + - debian/patches/CVE-2015-5174.patch: fix normalization edge cases in + java/org/apache/tomcat/util/http/RequestUtil.java, + test/org/apache/tomcat/util/http/TestRequestUtil.java. + - CVE-2015-5174 + * SECURITY UPDATE: information disclosure via redirects by mapper + - debian/patches/CVE-2015-5345.patch: fix redirect logic in + java/org/apache/catalina/Context.java, + java/org/apache/catalina/authenticator/FormAuthenticator.java, + java/org/apache/catalina/core/StandardContext.java, + java/org/apache/catalina/core/mbeans-descriptors.xml, + java/org/apache/catalina/servlets/DefaultServlet.java, + java/org/apache/catalina/servlets/WebdavServlet.java, + java/org/apache/catalina/startup/FailedContext.java, + java/org/apache/tomcat/util/http/mapper/Mapper.java, + test/org/apache/catalina/startup/TomcatBaseTest.java, + webapps/docs/config/context.xml, + test/org/apache/catalina/core/TesterContext.java. + - CVE-2015-5345 + * SECURITY UPDATE: session fixation vulnerability + - debian/patches/CVE-2015-5346.patch: handle different session settings + in java/org/apache/catalina/connector/CoyoteAdapter.java, + java/org/apache/catalina/connector/Request.java. + - CVE-2015-5346 + * SECURITY UPDATE: CSRF protection mechanism bypass + - debian/patches/CVE-2015-5351.patch: don't create sessions + unnecessarily in webapps/host-manager/WEB-INF/jsp/401.jsp, + webapps/host-manager/WEB-INF/jsp/403.jsp, + webapps/host-manager/WEB-INF/jsp/404.jsp, + webapps/host-manager/index.jsp, + webapps/manager/WEB-INF/web.xml, + webapps/manager/index.jsp. + - CVE-2015-5351 + * SECURITY UPDATE: securityManager restrictions bypass via + StatusManagerServlet + - debian/patches/CVE-2016-0706.patch: place servlet in restricted list + in java/org/apache/catalina/core/RestrictedServlets.properties. + - CVE-2016-0706 + * SECURITY UPDATE: securityManager restrictions bypass via + session-persistence implementation + - debian/patches/CVE-2016-0714.patch: extend the session attribute + filtering options in + java/org/apache/catalina/ha/session/ClusterManagerBase.java + java/org/apache/catalina/ha/session/mbeans-descriptors.xml, + java/org/apache/catalina/session/LocalStrings.properties, + java/org/apache/catalina/session/ManagerBase.java, + java/org/apache/catalina/session/StandardManager.java, + java/org/apache/catalina/session/mbeans-descriptors.xml, + java/org/apache/catalina/util/CustomObjectInputStream.java, + java/org/apache/catalina/util/LocalStrings.properties, + webapps/docs/config/cluster-manager.xml, + webapps/docs/config/manager.xml. + - CVE-2016-0714 + * SECURITY UPDATE: securityManager restrictions bypass via crafted global + context + - debian/patches/CVE-2016-0763.patch: protect initialization in + java/org/apache/naming/factory/ResourceLinkFactory.java. + - CVE-2016-0763 + * SECURITY UPDATE: denial of service in FileUpload + - debian/patches/CVE-2016-3092.patch: properly handle size in + java/org/apache/tomcat/util/http/fileupload/MultipartStream.java. + - CVE-2016-3092 + * debian/patches/fix_cookie_names_in_tests.patch: fix FTBFS by removing + colons in cookie names which is illegal in newer java versions in + test/org/apache/catalina/authenticator/*.java. + + -- Marc Deslauriers Wed, 29 Jun 2016 12:50:02 -0400 + tomcat7 (7.0.52-1ubuntu0.3) trusty-security; urgency=medium * SECURITY UPDATE: arbitrary file disclosure via XML parser diff -Nru tomcat7-7.0.52/debian/patches/CVE-2015-5174.patch tomcat7-7.0.52/debian/patches/CVE-2015-5174.patch --- tomcat7-7.0.52/debian/patches/CVE-2015-5174.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2015-5174.patch 2016-06-21 17:12:14.000000000 +0000 @@ -0,0 +1,212 @@ +Description: fix directory traversal vulnerability in RequestUtil.java +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1696284 +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1700898 + +Index: tomcat7-7.0.52/java/org/apache/tomcat/util/http/RequestUtil.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/tomcat/util/http/RequestUtil.java 2012-02-01 05:52:00.000000000 -0500 ++++ tomcat7-7.0.52/java/org/apache/tomcat/util/http/RequestUtil.java 2016-06-21 13:03:30.575220112 -0400 +@@ -30,6 +30,9 @@ + * try to perform security checks for malicious input. + * + * @param path Relative path to be normalized ++ * ++ * @return The normalized path or null of the path cannot be ++ * normalized + */ + public static String normalize(String path) { + return normalize(path, true); +@@ -44,11 +47,15 @@ + * + * @param path Relative path to be normalized + * @param replaceBackSlash Should '\\' be replaced with '/' ++ * ++ * @return The normalized path or null of the path cannot be ++ * normalized + */ + public static String normalize(String path, boolean replaceBackSlash) { + +- if (path == null) ++ if (path == null) { + return null; ++ } + + // Create a place for the normalized path + String normalized = path; +@@ -56,9 +63,6 @@ + if (replaceBackSlash && normalized.indexOf('\\') >= 0) + normalized = normalized.replace('\\', '/'); + +- if (normalized.equals("/.")) +- return "/"; +- + // Add a leading "/" if necessary + if (!normalized.startsWith("/")) + normalized = "/" + normalized; +@@ -66,34 +70,43 @@ + // Resolve occurrences of "//" in the normalized path + while (true) { + int index = normalized.indexOf("//"); +- if (index < 0) ++ if (index < 0) { + break; +- normalized = normalized.substring(0, index) + +- normalized.substring(index + 1); ++ } ++ normalized = normalized.substring(0, index) + normalized.substring(index + 1); + } + + // Resolve occurrences of "/./" in the normalized path + while (true) { + int index = normalized.indexOf("/./"); +- if (index < 0) ++ if (index < 0) { + break; +- normalized = normalized.substring(0, index) + +- normalized.substring(index + 2); ++ } ++ normalized = normalized.substring(0, index) + normalized.substring(index + 2); + } + + // Resolve occurrences of "/../" in the normalized path + while (true) { + int index = normalized.indexOf("/../"); +- if (index < 0) ++ if (index < 0) { + break; +- if (index == 0) +- return (null); // Trying to go outside our context ++ } ++ if (index == 0) { ++ return null; // Trying to go outside our context ++ } + int index2 = normalized.lastIndexOf('/', index - 1); +- normalized = normalized.substring(0, index2) + +- normalized.substring(index + 3); ++ normalized = normalized.substring(0, index2) + normalized.substring(index + 3); ++ } ++ ++ if (normalized.equals("/.")) { ++ return "/"; ++ } ++ ++ if (normalized.equals("/..")) { ++ return null; // Trying to go outside our context + } + + // Return the normalized path that we have completed +- return (normalized); ++ return normalized; + } + } +Index: tomcat7-7.0.52/test/org/apache/tomcat/util/http/TestRequestUtil.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/tomcat/util/http/TestRequestUtil.java 2012-02-01 05:52:00.000000000 -0500 ++++ tomcat7-7.0.52/test/org/apache/tomcat/util/http/TestRequestUtil.java 2016-06-21 13:03:32.787241711 -0400 +@@ -23,11 +23,101 @@ + public class TestRequestUtil { + + @Test +- public void testNormalizeString() { +- assertEquals("/something",RequestUtil.normalize("//something")); +- assertEquals("/some/thing",RequestUtil.normalize("some//thing")); +- assertEquals("/something/",RequestUtil.normalize("something//")); +- assertEquals("/",RequestUtil.normalize("//")); ++ public void testNormalize01() { ++ doTestNormalize("//something", "/something"); + } + ++ @Test ++ public void testNormalize02() { ++ doTestNormalize("some//thing", "/some/thing"); ++ } ++ ++ @Test ++ public void testNormalize03() { ++ doTestNormalize("something//", "/something/"); ++ } ++ ++ @Test ++ public void testNormalize04() { ++ doTestNormalize("//", "/"); ++ } ++ ++ @Test ++ public void testNormalize05() { ++ doTestNormalize("//", "/"); ++ } ++ ++ @Test ++ public void testNormalize06() { ++ doTestNormalize("///", "/"); ++ } ++ ++ @Test ++ public void testNormalize07() { ++ doTestNormalize("////", "/"); ++ } ++ ++ @Test ++ public void testNormalize08() { ++ doTestNormalize("/.", "/"); ++ } ++ ++ @Test ++ public void testNormalize09() { ++ doTestNormalize("/./", "/"); ++ } ++ ++ @Test ++ public void testNormalize10() { ++ doTestNormalize(".", "/"); ++ } ++ ++ @Test ++ public void testNormalize11() { ++ doTestNormalize("/..", null); ++ } ++ ++ @Test ++ public void testNormalize12() { ++ doTestNormalize("/../", null); ++ } ++ ++ @Test ++ public void testNormalize13() { ++ doTestNormalize("..", null); ++ } ++ ++ @Test ++ public void testNormalize14() { ++ doTestNormalize("//..", null); ++ } ++ ++ @Test ++ public void testNormalize15() { ++ doTestNormalize("//../", null); ++ } ++ ++ @Test ++ public void testNormalize16() { ++ doTestNormalize("/./..", null); ++ } ++ ++ @Test ++ public void testNormalize17() { ++ doTestNormalize("/./../", null); ++ } ++ ++ @Test ++ public void testNormalize18() { ++ doTestNormalize("/a/../..", null); ++ } ++ ++ @Test ++ public void testNormalize19() { ++ doTestNormalize("/a/../../", null); ++ } ++ ++ private void doTestNormalize(String input, String expected) { ++ assertEquals(expected,RequestUtil.normalize(input)); ++ } + } diff -Nru tomcat7-7.0.52/debian/patches/CVE-2015-5345.patch tomcat7-7.0.52/debian/patches/CVE-2015-5345.patch --- tomcat7-7.0.52/debian/patches/CVE-2015-5345.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2015-5345.patch 2016-06-29 16:40:03.000000000 +0000 @@ -0,0 +1,478 @@ +Description: fix information disclosure via redirects by mapper +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1715213 +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1717212 + +Index: tomcat7-7.0.52/java/org/apache/catalina/Context.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/Context.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/Context.java 2016-06-29 12:31:54.800360921 -0400 +@@ -1603,4 +1603,44 @@ + * method names. + */ + public Map findPreDestroyMethods(); ++ ++ /** ++ * If enabled, requests for a web application context root will be ++ * redirected (adding a trailing slash) by the Mapper. This is more ++ * efficient but has the side effect of confirming that the context path is ++ * valid. ++ * ++ * @param mapperContextRootRedirectEnabled Should the redirects be enabled? ++ */ ++ public void setMapperContextRootRedirectEnabled(boolean mapperContextRootRedirectEnabled); ++ ++ /** ++ * Determines if requests for a web application context root will be ++ * redirected (adding a trailing slash) by the Mapper. This is more ++ * efficient but has the side effect of confirming that the context path is ++ * valid. ++ * ++ * @return {@code true} if the Mapper level redirect is enabled for this ++ * Context. ++ */ ++ public boolean getMapperContextRootRedirectEnabled(); ++ ++ /** ++ * If enabled, requests for a directory will be redirected (adding a ++ * trailing slash) by the Mapper. This is more efficient but has the ++ * side effect of confirming that the directory is valid. ++ * ++ * @param mapperDirectoryRedirectEnabled Should the redirects be enabled? ++ */ ++ public void setMapperDirectoryRedirectEnabled(boolean mapperDirectoryRedirectEnabled); ++ ++ /** ++ * Determines if requests for a directory will be redirected (adding a ++ * trailing slash) by the Mapper. This is more efficient but has the ++ * side effect of confirming that the directory is valid. ++ * ++ * @return {@code true} if the Mapper level redirect is enabled for this ++ * Context. ++ */ ++ public boolean getMapperDirectoryRedirectEnabled(); + } +Index: tomcat7-7.0.52/java/org/apache/catalina/authenticator/FormAuthenticator.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/authenticator/FormAuthenticator.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/authenticator/FormAuthenticator.java 2016-06-29 12:31:54.800360921 -0400 +@@ -263,6 +263,20 @@ + + // No -- Save this request and redirect to the form login page + if (!loginAction) { ++ // If this request was to the root of the context without a trailing ++ // '/', need to redirect to add it else the submit of the login form ++ // may not go to the correct web application ++ if (request.getServletPath().length() == 0 && request.getPathInfo() == null) { ++ StringBuilder location = new StringBuilder(requestURI); ++ location.append('/'); ++ if (request.getQueryString() != null) { ++ location.append('?'); ++ location.append(request.getQueryString()); ++ } ++ response.sendRedirect(response.encodeRedirectURL(location.toString())); ++ return false; ++ } ++ + session = request.getSessionInternal(true); + if (log.isDebugEnabled()) { + log.debug("Save request in session '" + session.getIdInternal() + "'"); +Index: tomcat7-7.0.52/java/org/apache/catalina/core/StandardContext.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/core/StandardContext.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/core/StandardContext.java 2016-06-29 12:31:54.804360969 -0400 +@@ -894,8 +894,45 @@ + private String containerSciFilter; + + ++ boolean mapperContextRootRedirectEnabled = false; ++ ++ boolean mapperDirectoryRedirectEnabled = false; ++ + // ----------------------------------------------------- Context Properties +- ++ ++ @Override ++ public void setMapperContextRootRedirectEnabled(boolean mapperContextRootRedirectEnabled) { ++ this.mapperContextRootRedirectEnabled = mapperContextRootRedirectEnabled; ++ } ++ ++ ++ /** ++ * {@inheritDoc} ++ *

++ * The default value for this implementation is {@code false}. ++ */ ++ @Override ++ public boolean getMapperContextRootRedirectEnabled() { ++ return mapperContextRootRedirectEnabled; ++ } ++ ++ ++ @Override ++ public void setMapperDirectoryRedirectEnabled(boolean mapperDirectoryRedirectEnabled) { ++ this.mapperDirectoryRedirectEnabled = mapperDirectoryRedirectEnabled; ++ } ++ ++ ++ /** ++ * {@inheritDoc} ++ *

++ * The default value for this implementation is {@code false}. ++ */ ++ @Override ++ public boolean getMapperDirectoryRedirectEnabled() { ++ return mapperDirectoryRedirectEnabled; ++ } ++ + @Override + public void setContainerSciFilter(String containerSciFilter) { + this.containerSciFilter = containerSciFilter; +@@ -1087,7 +1124,7 @@ + this.instanceManager = instanceManager; + } + +- ++ + @Override + public String getEncodedPath() { + return encodedPath; +Index: tomcat7-7.0.52/java/org/apache/catalina/core/mbeans-descriptors.xml +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/core/mbeans-descriptors.xml 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/core/mbeans-descriptors.xml 2016-06-29 12:31:54.804360969 -0400 +@@ -221,6 +221,14 @@ + description="The object used for mapping" + type="java.lang.Object"/> + ++ ++ ++ ++ + +Index: tomcat7-7.0.52/java/org/apache/catalina/servlets/DefaultServlet.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/servlets/DefaultServlet.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/servlets/DefaultServlet.java 2016-06-29 12:31:54.804360969 -0400 +@@ -364,6 +364,10 @@ + * @param request The servlet request we are processing + */ + protected String getRelativePath(HttpServletRequest request) { ++ return getRelativePath(request, false); ++ } ++ ++ protected String getRelativePath(HttpServletRequest request, boolean allowEmptyPath) { + // IMPORTANT: DefaultServlet can be mapped to '/' or '/path/*' but always + // serves resources from the web app root with context rooted paths. + // i.e. it can not be used to mount the web app root under a sub-path +@@ -395,7 +399,7 @@ + } else { + result = request.getServletPath() + result; + } +- if ((result == null) || (result.equals(""))) { ++ if (((result == null) || (result.equals(""))) && !allowEmptyPath) { + result = "/"; + } + return (result); +@@ -773,7 +777,8 @@ + boolean serveContent = content; + + // Identify the requested resource path +- String path = getRelativePath(request); ++ String path = getRelativePath(request, true); ++ + if (debug > 0) { + if (serveContent) + log("DefaultServlet.serveResource: Serving resource '" + +@@ -783,6 +788,12 @@ + path + "' headers only"); + } + ++ if (path.length() == 0) { ++ // Context root redirect ++ doDirectoryRedirect(request, response); ++ return; ++ } ++ + CacheEntry cacheEntry = resources.lookupCache(path); + + if (!cacheEntry.exists) { +@@ -851,6 +862,11 @@ + + if (cacheEntry.context != null) { + ++ if (!path.endsWith("/")) { ++ doDirectoryRedirect(request, response); ++ return; ++ } ++ + // Skip directory listings if we have been configured to + // suppress them + if (!listings) { +@@ -1058,6 +1074,16 @@ + + } + ++ private void doDirectoryRedirect(HttpServletRequest request, HttpServletResponse response) ++ throws IOException { ++ StringBuilder location = new StringBuilder(request.getRequestURI()); ++ location.append('/'); ++ if (request.getQueryString() != null) { ++ location.append('?'); ++ location.append(request.getQueryString()); ++ } ++ response.sendRedirect(response.encodeRedirectURL(location.toString())); ++ } + + /** + * Parse the content-range header. +Index: tomcat7-7.0.52/java/org/apache/catalina/servlets/WebdavServlet.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/servlets/WebdavServlet.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/servlets/WebdavServlet.java 2016-06-29 12:31:54.804360969 -0400 +@@ -430,6 +430,11 @@ + */ + @Override + protected String getRelativePath(HttpServletRequest request) { ++ return getRelativePath(request, false); ++ } ++ ++ @Override ++ protected String getRelativePath(HttpServletRequest request, boolean allowEmptyPath) { + // Are we being processed by a RequestDispatcher.include()? + if (request.getAttribute( + RequestDispatcher.INCLUDE_REQUEST_URI) != null) { +Index: tomcat7-7.0.52/java/org/apache/catalina/startup/FailedContext.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/startup/FailedContext.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/startup/FailedContext.java 2016-06-29 12:31:54.804360969 -0400 +@@ -703,4 +703,21 @@ + + @Override + public String getContainerSciFilter() { return null; } +-} +\ No newline at end of file ++ ++ @Override ++ public void setMapperContextRootRedirectEnabled(boolean mapperContextRootRedirectEnabled) { ++ // NO-OP ++ } ++ ++ @Override ++ public boolean getMapperContextRootRedirectEnabled() { return false; } ++ ++ @Override ++ public void setMapperDirectoryRedirectEnabled(boolean mapperDirectoryRedirectEnabled) { ++ // NO-OP ++ } ++ ++ @Override ++ public boolean getMapperDirectoryRedirectEnabled() { return false; } ++ ++} +Index: tomcat7-7.0.52/java/org/apache/tomcat/util/http/mapper/Mapper.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/tomcat/util/http/mapper/Mapper.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/java/org/apache/tomcat/util/http/mapper/Mapper.java 2016-06-29 12:39:48.354060095 -0400 +@@ -195,11 +195,36 @@ + * @param context Context object + * @param welcomeResources Welcome files defined for this context + * @param resources Static resources of the context ++ * @deprecated Use {@link #addContextVersion(String, Object, String, String, Object, String[], ++ * javax.naming.Context, boolean, boolean)} + */ ++ @Deprecated + public void addContextVersion(String hostName, Object host, String path, + String version, Object context, String[] welcomeResources, + javax.naming.Context resources) { +- ++ addContextVersion(hostName, host, path, version, context, welcomeResources, resources, ++ false, false); ++ } ++ ++ ++ /** ++ * Add a new Context to an existing Host. ++ * ++ * @param hostName Virtual host name this context belongs to ++ * @param host Host object ++ * @param path Context path ++ * @param version Context version ++ * @param context Context object ++ * @param welcomeResources Welcome files defined for this context ++ * @param resources Static resources of the context ++ * @param mapperContextRootRedirectEnabled Mapper does context root redirects ++ * @param mapperDirectoryRedirectEnabled Mapper does directory redirects ++ */ ++ public void addContextVersion(String hostName, Object host, String path, ++ String version, Object context, String[] welcomeResources, ++ javax.naming.Context resources, ++ boolean mapperContextRootRedirectEnabled, boolean mapperDirectoryRedirectEnabled) { ++ + Host[] hosts = this.hosts; + int pos = find(hosts, hostName); + if( pos <0 ) { +@@ -241,6 +266,9 @@ + newContextVersion.object = context; + newContextVersion.welcomeResources = welcomeResources; + newContextVersion.resources = resources; ++ newContextVersion.mapperContextRootRedirectEnabled = mapperContextRootRedirectEnabled; ++ newContextVersion.mapperDirectoryRedirectEnabled = mapperDirectoryRedirectEnabled; ++ + if (insertMap(contextVersions, newContextVersions, newContextVersion)) { + mappedContext.versions = newContextVersions; + } +@@ -250,6 +278,7 @@ + } + + ++ + /** + * Remove a context from an existing host. + * +@@ -834,20 +863,13 @@ + + int pathOffset = path.getOffset(); + int pathEnd = path.getEnd(); +- int servletPath = pathOffset; + boolean noServletPath = false; + + int length = contextVersion.path.length(); +- if (length != (pathEnd - pathOffset)) { +- servletPath = pathOffset + length; +- } else { ++ if (length == (pathEnd - pathOffset)) { + noServletPath = true; +- path.append('/'); +- pathOffset = path.getOffset(); +- pathEnd = path.getEnd(); +- servletPath = pathOffset+length; + } +- ++ int servletPath = pathOffset + length; + path.setOffset(servletPath); + + // Rule 1 -- Exact Match +@@ -882,10 +904,13 @@ + } + } + +- if(mappingData.wrapper == null && noServletPath) { ++ if(mappingData.wrapper == null && noServletPath && ++ contextVersion.mapperContextRootRedirectEnabled) { + // The path is empty, redirect to "/" ++ path.append('/'); ++ pathEnd = path.getEnd(); + mappingData.redirectPath.setChars +- (path.getBuffer(), pathOffset, pathEnd-pathOffset); ++ (path.getBuffer(), pathOffset, pathEnd - pathOffset); + path.setEnd(pathEnd - 1); + return; + } +@@ -1006,11 +1031,16 @@ + Object file = null; + String pathStr = path.toString(); + try { +- file = contextVersion.resources.lookup(pathStr); ++ if (pathStr.length() == 0) { ++ file = contextVersion.resources.lookup("/"); ++ } else { ++ file = contextVersion.resources.lookup(pathStr); ++ } + } catch(NamingException nex) { + // Swallow, since someone else handles the 404 + } +- if (file != null && file instanceof DirContext) { ++ if (file != null && file instanceof DirContext && ++ contextVersion.mapperDirectoryRedirectEnabled) { + // Note: this mutates the path: do not do any processing + // after this (since we set the redirectPath, there + // shouldn't be any) +@@ -1027,7 +1057,6 @@ + + path.setOffset(pathOffset); + path.setEnd(pathEnd); +- + } + + +@@ -1510,6 +1539,8 @@ + public Wrapper[] wildcardWrappers = new Wrapper[0]; + public Wrapper[] extensionWrappers = new Wrapper[0]; + public int nesting = 0; ++ public boolean mapperContextRootRedirectEnabled = false; ++ public boolean mapperDirectoryRedirectEnabled = false; + + } + +Index: tomcat7-7.0.52/test/org/apache/catalina/startup/TomcatBaseTest.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/catalina/startup/TomcatBaseTest.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/test/org/apache/catalina/startup/TomcatBaseTest.java 2016-06-29 12:31:54.804360969 -0400 +@@ -223,8 +223,7 @@ + String method) throws IOException { + + URL url = new URL(path); +- HttpURLConnection connection = +- (HttpURLConnection) url.openConnection(); ++ HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setUseCaches(false); + connection.setReadTimeout(readTimeout); + connection.setRequestMethod(method); +Index: tomcat7-7.0.52/webapps/docs/config/context.xml +=================================================================== +--- tomcat7-7.0.52.orig/webapps/docs/config/context.xml 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/webapps/docs/config/context.xml 2016-06-29 12:31:54.808361018 -0400 +@@ -352,6 +352,22 @@ + default value of false is used.

+ + ++ ++

If enabled, requests for a web application context root will be ++ redirected (adding a trailing slash) if necessary by the Mapper rather ++ than the default Servlet. This is more efficient but has the side effect ++ of confirming that the context path exists. If not specified, the ++ default value of false is used.

++
++ ++ ++

If enabled, requests for a web application directory will be ++ redirected (adding a trailing slash) if necessary by the Mapper rather ++ than the default Servlet. This is more efficient but has the side effect ++ of confirming that the directory is exists. If not specified, the ++ default value of false is used.

++
++ + +

Set to true to ignore any settings in both the global + or Host default contexts. By default, settings +Index: tomcat7-7.0.52/test/org/apache/catalina/core/TesterContext.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/catalina/core/TesterContext.java 2016-06-29 12:31:54.808361018 -0400 ++++ tomcat7-7.0.52/test/org/apache/catalina/core/TesterContext.java 2016-06-29 12:31:54.808361018 -0400 +@@ -1219,4 +1219,20 @@ + + @Override + public String getContainerSciFilter() { return null; } ++ ++ @Override ++ public void setMapperContextRootRedirectEnabled(boolean mapperContextRootRedirectEnabled) { ++ // NO-OP ++ } ++ ++ @Override ++ public boolean getMapperContextRootRedirectEnabled() { return false; } ++ ++ @Override ++ public void setMapperDirectoryRedirectEnabled(boolean mapperDirectoryRedirectEnabled) { ++ // NO-OP ++ } ++ ++ @Override ++ public boolean getMapperDirectoryRedirectEnabled() { return false; } + } diff -Nru tomcat7-7.0.52/debian/patches/CVE-2015-5346.patch tomcat7-7.0.52/debian/patches/CVE-2015-5346.patch --- tomcat7-7.0.52/debian/patches/CVE-2015-5346.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2015-5346.patch 2016-06-29 16:42:13.000000000 +0000 @@ -0,0 +1,71 @@ +Description: fix session fixation vulnerability +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1713187 + +Index: tomcat7-7.0.52/java/org/apache/catalina/connector/CoyoteAdapter.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/connector/CoyoteAdapter.java 2016-06-29 12:41:19.823161652 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/connector/CoyoteAdapter.java 2016-06-29 12:41:57.651617285 -0400 +@@ -712,6 +712,9 @@ + version = ctxt.getWebappVersion(); + // Reset mapping + request.getMappingData().recycle(); ++ // Recycle session info in case the correct ++ // context is configured with different settings ++ request.recycleSessionInfo(); + break; + } + } +Index: tomcat7-7.0.52/java/org/apache/catalina/connector/Request.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/connector/Request.java 2016-06-29 12:41:19.823161652 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/connector/Request.java 2016-06-29 12:41:19.819161605 -0400 +@@ -494,18 +494,7 @@ + notes.clear(); + cookies = null; + +- if (session != null) { +- try { +- session.endAccess(); +- } catch (Throwable t) { +- ExceptionUtils.handleThrowable(t); +- log.warn(sm.getString("coyoteRequest.sessionEndAccessFail"), t); +- } +- } +- session = null; +- requestedSessionCookie = false; +- requestedSessionId = null; +- requestedSessionURL = false; ++ recycleSessionInfo(); + + if (Globals.IS_SECURITY_ENABLED || Connector.RECYCLE_FACADES) { + parameterMap = new ParameterMap(); +@@ -553,11 +542,24 @@ + } + + +- /** +- * Clear cached encoders (to save memory for Comet requests). +- */ +- public boolean read() +- throws IOException { ++ protected void recycleSessionInfo() { ++ if (session != null) { ++ try { ++ session.endAccess(); ++ } catch (Throwable t) { ++ ExceptionUtils.handleThrowable(t); ++ log.warn(sm.getString("coyoteRequest.sessionEndAccessFail"), t); ++ } ++ } ++ session = null; ++ requestedSessionCookie = false; ++ requestedSessionId = null; ++ requestedSessionURL = false; ++ requestedSessionSSL = false; ++ } ++ ++ ++ public boolean read() throws IOException { + return (inputBuffer.realReadBytes(null, 0, 0) > 0); + } + diff -Nru tomcat7-7.0.52/debian/patches/CVE-2015-5351.patch tomcat7-7.0.52/debian/patches/CVE-2015-5351.patch --- tomcat7-7.0.52/debian/patches/CVE-2015-5351.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2015-5351.patch 2016-06-29 14:18:31.000000000 +0000 @@ -0,0 +1,82 @@ +Description: fix CSRF protection mechanism bypass +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1720661 +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1720663 + +Index: tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/401.jsp +=================================================================== +--- tomcat7-7.0.64.orig/webapps/host-manager/WEB-INF/jsp/401.jsp 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/401.jsp 2016-06-17 12:02:00.276256670 +0300 +@@ -14,6 +14,7 @@ + See the License for the specific language governing permissions and + limitations under the License. + --%> ++<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + +Index: tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/403.jsp +=================================================================== +--- tomcat7-7.0.64.orig/webapps/host-manager/WEB-INF/jsp/403.jsp 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/403.jsp 2016-06-17 12:02:00.276256670 +0300 +@@ -14,6 +14,7 @@ + See the License for the specific language governing permissions and + limitations under the License. + --%> ++<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + +Index: tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/404.jsp +=================================================================== +--- tomcat7-7.0.64.orig/webapps/host-manager/WEB-INF/jsp/404.jsp 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/host-manager/WEB-INF/jsp/404.jsp 2016-06-17 12:02:00.276256670 +0300 +@@ -14,7 +14,8 @@ + See the License for the specific language governing permissions and + limitations under the License. + --%> +-<%@ page import="org.apache.catalina.util.RequestUtil" %> ++<%@ page import="org.apache.catalina.util.RequestUtil" session="false" ++ trimDirectiveWhitespaces="true" %> + + + +Index: tomcat7-7.0.64/webapps/host-manager/index.jsp +=================================================================== +--- tomcat7-7.0.64.orig/webapps/host-manager/index.jsp 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/host-manager/index.jsp 2016-06-17 12:02:00.276256670 +0300 +@@ -14,5 +14,5 @@ + See the License for the specific language governing permissions and + limitations under the License. + --%> +-<% response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + +- "/html")); %> +\ No newline at end of file ++<%@ page session="false" trimDirectiveWhitespaces="true" %> ++<% response.sendRedirect(request.getContextPath() + "/html"); %> +\ No newline at end of file +Index: tomcat7-7.0.64/webapps/manager/WEB-INF/web.xml +=================================================================== +--- tomcat7-7.0.64.orig/webapps/manager/WEB-INF/web.xml 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/manager/WEB-INF/web.xml 2016-06-17 12:02:00.276256670 +0300 +@@ -116,7 +116,6 @@ + + CSRF + HTMLManager +- jsp + + + +Index: tomcat7-7.0.64/webapps/manager/index.jsp +=================================================================== +--- tomcat7-7.0.64.orig/webapps/manager/index.jsp 2016-06-17 12:02:00.280256721 +0300 ++++ tomcat7-7.0.64/webapps/manager/index.jsp 2016-06-17 12:02:00.276256670 +0300 +@@ -14,5 +14,5 @@ + See the License for the specific language governing permissions and + limitations under the License. + --%> +-<% response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + +- "/html")); %> +\ No newline at end of file ++<%@ page session="false" %> ++<% response.sendRedirect(request.getContextPath() + "/html"); %> +\ No newline at end of file diff -Nru tomcat7-7.0.52/debian/patches/CVE-2016-0706.patch tomcat7-7.0.52/debian/patches/CVE-2016-0706.patch --- tomcat7-7.0.52/debian/patches/CVE-2016-0706.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2016-0706.patch 2016-06-29 14:18:43.000000000 +0000 @@ -0,0 +1,12 @@ +Description: fix securityManager restrictions bypass via StatusManagerServlet +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1722801 + +Index: tomcat7-7.0.64/java/org/apache/catalina/core/RestrictedServlets.properties +=================================================================== +--- tomcat7-7.0.64.orig/java/org/apache/catalina/core/RestrictedServlets.properties 2016-06-17 12:02:12.924419556 +0300 ++++ tomcat7-7.0.64/java/org/apache/catalina/core/RestrictedServlets.properties 2016-06-17 12:02:12.920419504 +0300 +@@ -16,3 +16,4 @@ + org.apache.catalina.ssi.SSIServlet=restricted + org.apache.catalina.servlets.CGIServlet=restricted + org.apache.catalina.manager.JMXProxyServlet=restricted ++org.apache.catalina.manager.StatusManagerServlet=restricted diff -Nru tomcat7-7.0.52/debian/patches/CVE-2016-0714.patch tomcat7-7.0.52/debian/patches/CVE-2016-0714.patch --- tomcat7-7.0.52/debian/patches/CVE-2016-0714.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2016-0714.patch 2016-06-29 16:49:44.000000000 +0000 @@ -0,0 +1,640 @@ +Description: fix securityManager restrictions bypass via session-persistence implementation +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1726923 +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1727034 + +Index: tomcat7-7.0.52/java/org/apache/catalina/ha/session/ClusterManagerBase.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/ha/session/ClusterManagerBase.java 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/ha/session/ClusterManagerBase.java 2016-06-29 12:47:39.527736771 -0400 +@@ -187,6 +187,8 @@ + copy.setProcessExpiresFrequency(getProcessExpiresFrequency()); + copy.setNotifyListenersOnReplication(isNotifyListenersOnReplication()); + copy.setSessionAttributeFilter(getSessionAttributeFilter()); ++ copy.setSessionAttributeValueClassNameFilter(getSessionAttributeValueClassNameFilter()); ++ copy.setWarnOnSessionAttributeFilterFailure(getWarnOnSessionAttributeFilterFailure()); + copy.setSecureRandomClass(getSecureRandomClass()); + copy.setSecureRandomProvider(getSecureRandomProvider()); + copy.setSecureRandomAlgorithm(getSecureRandomAlgorithm()); +Index: tomcat7-7.0.52/java/org/apache/catalina/ha/session/mbeans-descriptors.xml +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/ha/session/mbeans-descriptors.xml 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/ha/session/mbeans-descriptors.xml 2016-06-29 12:49:05.924778289 -0400 +@@ -336,6 +336,14 @@ + is="true" + description="All session messages before state transfer message creation are dropped." + type="boolean"/> ++ ++ + ++ ++ + ++ * This implementation excludes session attributes from distribution if the: ++ *

    ++ *
  • attribute name matches {@link #getSessionAttributeNameFilter()}
  • ++ *
++ */ ++ public boolean willAttributeDistribute(String name, Object value) { ++ Pattern sessionAttributeNamePattern = getSessionAttributeNamePattern(); ++ if (sessionAttributeNamePattern != null) { ++ if (!sessionAttributeNamePattern.matcher(name).matches()) { ++ if (getWarnOnSessionAttributeFilterFailure() || log.isDebugEnabled()) { ++ String msg = sm.getString("managerBase.sessionAttributeNameFilter", ++ name, sessionAttributeNamePattern); ++ if (getWarnOnSessionAttributeFilterFailure()) { ++ log.warn(msg); ++ } else { ++ log.debug(msg); ++ } ++ } ++ return false; ++ } ++ } ++ ++ Pattern sessionAttributeValueClassNamePattern = getSessionAttributeValueClassNamePattern(); ++ if (value != null && sessionAttributeValueClassNamePattern != null) { ++ if (!sessionAttributeValueClassNamePattern.matcher( ++ value.getClass().getName()).matches()) { ++ if (getWarnOnSessionAttributeFilterFailure() || log.isDebugEnabled()) { ++ String msg = sm.getString("managerBase.sessionAttributeValueClassNameFilter", ++ name, value.getClass().getName(), sessionAttributeNamePattern); ++ if (getWarnOnSessionAttributeFilterFailure()) { ++ log.warn(msg); ++ } else { ++ log.debug(msg); ++ } ++ } ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ + // ------------------------------------------------------ Protected Methods + + +Index: tomcat7-7.0.52/java/org/apache/catalina/session/StandardManager.java +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/session/StandardManager.java 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/session/StandardManager.java 2016-06-29 12:47:39.527736771 -0400 +@@ -231,17 +231,20 @@ + ObjectInputStream ois = null; + Loader loader = null; + ClassLoader classLoader = null; ++ Log logger = null; + try { + fis = new FileInputStream(file.getAbsolutePath()); + bis = new BufferedInputStream(fis); + if (container != null) +- loader = container.getLoader(); ++ logger = container.getLogger(); + if (loader != null) + classLoader = loader.getClassLoader(); + if (classLoader != null) { + if (log.isDebugEnabled()) + log.debug("Creating custom object input stream for class loader "); +- ois = new CustomObjectInputStream(bis, classLoader); ++ ois = new CustomObjectInputStream(bis, classLoader, logger, ++ getSessionAttributeValueClassNamePattern(), ++ getWarnOnSessionAttributeFilterFailure()); + } else { + if (log.isDebugEnabled()) + log.debug("Creating standard object input stream"); +Index: tomcat7-7.0.52/java/org/apache/catalina/session/mbeans-descriptors.xml +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/session/mbeans-descriptors.xml 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/session/mbeans-descriptors.xml 2016-06-29 12:47:39.527736771 -0400 +@@ -132,6 +132,18 @@ + description="Number of sessions we rejected due to maxActive beeing reached" + type="int" + writeable="false"/> ++ ++ ++ ++ ++ ++ + + + ++ ++ ++ ++ ++ ++ + ObjectInputStream that loads from the +@@ -35,14 +44,26 @@ + extends ObjectInputStream { + + ++ private static final StringManager sm = StringManager.getManager("org.apache.catalina.util"); ++ ++ private static final WeakHashMap> reportedClassCache = ++ new WeakHashMap>(); ++ + /** + * The class loader we will use to resolve classes. + */ + private ClassLoader classLoader = null; ++ private final Set reportedClasses; ++ private final Log log; ++ ++ private final Pattern allowedClassNamePattern; ++ private final String allowedClassNameFilter; ++ private final boolean warnOnFailure; + + + /** +- * Construct a new instance of CustomObjectInputStream ++ * Construct a new instance of CustomObjectInputStream without any filtering ++ * of deserialized classes. + * + * @param stream The input stream we will read from + * @param classLoader The class loader used to instantiate objects +@@ -52,9 +73,53 @@ + public CustomObjectInputStream(InputStream stream, + ClassLoader classLoader) + throws IOException { ++ this(stream, classLoader, null, null, false); ++ } + ++ /** ++ * Construct a new instance of CustomObjectInputStream with filtering of ++ * deserialized classes. ++ * ++ * @param stream The input stream we will read from ++ * @param classLoader The class loader used to instantiate objects ++ * @param log The logger to use to report any issues. It may only be null if ++ * the filterMode does not require logging ++ * @param allowedClassNamePattern The regular expression to use to filter ++ * deserialized classes. The fully qualified ++ * class name must match this pattern for ++ * deserialization to be allowed if filtering ++ * is enabled. ++ * @param warnOnFailure Should any failures be logged? ++ * ++ * @exception IOException if an input/output error occurs ++ */ ++ public CustomObjectInputStream(InputStream stream, ClassLoader classLoader, ++ Log log, Pattern allowedClassNamePattern, boolean warnOnFailure) ++ throws IOException { + super(stream); ++ if (log == null && allowedClassNamePattern != null && warnOnFailure) { ++ throw new IllegalArgumentException( ++ sm.getString("customObjectInputStream.logRequired")); ++ } + this.classLoader = classLoader; ++ this.log = log; ++ this.allowedClassNamePattern = allowedClassNamePattern; ++ if (allowedClassNamePattern == null) { ++ this.allowedClassNameFilter = null; ++ } else { ++ this.allowedClassNameFilter = allowedClassNamePattern.toString(); ++ } ++ this.warnOnFailure = warnOnFailure; ++ ++ Set reportedClasses; ++ synchronized (reportedClassCache) { ++ reportedClasses = reportedClassCache.get(classLoader); ++ if (reportedClasses == null) { ++ reportedClasses = Collections.newSetFromMap(new ConcurrentHashMap()); ++ reportedClassCache.put(classLoader, reportedClasses); ++ } ++ } ++ this.reportedClasses = reportedClasses; + } + + +@@ -70,8 +135,24 @@ + @Override + public Class resolveClass(ObjectStreamClass classDesc) + throws ClassNotFoundException, IOException { ++ ++ String name = classDesc.getName(); ++ if (allowedClassNamePattern != null) { ++ boolean allowed = allowedClassNamePattern.matcher(name).matches(); ++ if (!allowed) { ++ boolean doLog = warnOnFailure && reportedClasses.add(name); ++ String msg = sm.getString("customObjectInputStream.nomatch", name, allowedClassNameFilter); ++ if (doLog) { ++ log.warn(msg); ++ } else if (log.isDebugEnabled()) { ++ log.debug(msg); ++ } ++ throw new InvalidClassException(msg); ++ } ++ } ++ + try { +- return Class.forName(classDesc.getName(), false, classLoader); ++ return Class.forName(name, false, classLoader); + } catch (ClassNotFoundException e) { + try { + // Try also the superclass because of primitive types +Index: tomcat7-7.0.52/java/org/apache/catalina/util/LocalStrings.properties +=================================================================== +--- tomcat7-7.0.52.orig/java/org/apache/catalina/util/LocalStrings.properties 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/java/org/apache/catalina/util/LocalStrings.properties 2016-06-29 12:47:39.531736819 -0400 +@@ -17,6 +17,8 @@ + resourceSet.locked=No modifications are allowed to a locked ResourceSet + hexUtil.bad=Bad hexadecimal digit + hexUtil.odd=Odd number of hexadecimal digits ++customObjectInputStream.logRequired=A valid logger is required for class name filtering with logging ++customObjectInputStream.nomatch=The class [{0}] did not match the regular expression [{1}] for classes allowed to be deserialized + #Default Messages Utilized by the ExtensionValidator + extensionValidator.web-application-manifest=Web Application Manifest + extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]: Required extension [{2}] not found. +Index: tomcat7-7.0.52/webapps/docs/config/cluster-manager.xml +=================================================================== +--- tomcat7-7.0.52.orig/webapps/docs/config/cluster-manager.xml 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/webapps/docs/config/cluster-manager.xml 2016-06-29 12:47:39.531736819 -0400 +@@ -165,6 +165,37 @@ + Set to true if you wish to have container listeners notified + across Tomcat nodes in the cluster. + ++ ++

A regular expression used to filter which session attributes will be ++ replicated. An attribute will only be replicated if its name matches ++ this pattern. If the pattern is zero length or null, all ++ attributes are eligible for replication. The pattern is anchored so the ++ session attribute name must fully match the pattern. As an example, the ++ value (userName|sessionHistory) will only replicate the ++ two session attributes named userName and ++ sessionHistory. If not specified, the default value of ++ null will be used unless a SecurityManager is ++ enabled in which case the default will be ++ java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

++
++ ++

A regular expression used to filter which session attributes will be ++ replicated. An attribute will only be replicated if the implementation ++ class name of the value matches this pattern. If the pattern is zero ++ length or null, all attributes are eligible for ++ replication. The pattern is anchored so the fully qualified class name ++ must fully match the pattern. If not specified, the default value of ++ null will be used.

++
++ ++

If sessionAttributeNameFilter or ++ sessionAttributeValueClassNameFilter blocks an ++ attribute, should this be logged at WARN level? If ++ WARN level logging is disabled then it will be logged at ++ DEBUG. The default value of this attribute is ++ false unless a SecurityManager is enabled in ++ which case the default will be true.

++
+ + The time in seconds to wait for a session state transfer to complete + from another node when a node is starting up. +@@ -220,6 +251,37 @@ + another map. + Default value is 15000 milliseconds. + ++ ++

A regular expression used to filter which session attributes will be ++ replicated. An attribute will only be replicated if its name matches ++ this pattern. If the pattern is zero length or null, all ++ attributes are eligible for replication. The pattern is anchored so the ++ session attribute name must fully match the pattern. As an example, the ++ value (userName|sessionHistory) will only replicate the ++ two session attributes named userName and ++ sessionHistory. If not specified, the default value of ++ null will be used.

++
++ ++

A regular expression used to filter which session attributes will be ++ replicated. An attribute will only be replicated if the implementation ++ class name of the value matches this pattern. If the pattern is zero ++ length or null, all attributes are eligible for ++ replication. The pattern is anchored so the fully qualified class name ++ must fully match the pattern. If not specified, the default value of ++ null will be used unless a SecurityManager is ++ enabled in which case the default will be ++ java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

++
++ ++

If sessionAttributeNameFilter or ++ sessionAttributeValueClassNameFilter blocks an ++ attribute, should this be logged at WARN level? If ++ WARN level logging is disabled then it will be logged at ++ DEBUG. The default value of this attribute is ++ false unless a SecurityManager is enabled in ++ which case the default will be true.

++
+ + Set to true if you wish to terminate replication map when replication + map fails to start. If replication map is terminated, associated context +Index: tomcat7-7.0.52/webapps/docs/config/manager.xml +=================================================================== +--- tomcat7-7.0.52.orig/webapps/docs/config/manager.xml 2016-06-29 12:47:39.531736819 -0400 ++++ tomcat7-7.0.52/webapps/docs/config/manager.xml 2016-06-29 12:47:39.531736819 -0400 +@@ -174,6 +174,39 @@ + string.

+
+ ++ ++

A regular expression used to filter which session attributes will be ++ distributed. An attribute will only be distributed if its name matches ++ this pattern. If the pattern is zero length or null, all ++ attributes are eligible for distribution. The pattern is anchored so the ++ session attribute name must fully match the pattern. As an example, the ++ value (userName|sessionHistory) will only distribute the ++ two session attributes named userName and ++ sessionHistory. If not specified, the default value of ++ null will be used.

++
++ ++ ++

A regular expression used to filter which session attributes will be ++ distributed. An attribute will only be distributed if the implementation ++ class name of the value matches this pattern. If the pattern is zero ++ length or null, all attributes are eligible for ++ distribution. The pattern is anchored so the fully qualified class name ++ must fully match the pattern. If not specified, the default value of ++ null will be used unless a SecurityManager is ++ enabled in which case the default will be ++ java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

++
++ ++ ++

If sessionAttributeNameFilter or ++ sessionAttributeValueClassNameFilter blocks an ++ attribute, should this be logged at WARN level? If ++ WARN level logging is disabled then it will be logged at ++ DEBUG. The default value of this attribute is ++ false unless a SecurityManager is enabled in ++ which case the default will be true.

++
+ + +

Persistent Manager Implementation

+@@ -263,6 +296,40 @@ + org.apache.catalina.session.StandardManager class. +

+
++ ++ ++

A regular expression used to filter which session attributes will be ++ distributed. An attribute will only be distributed if its name matches ++ this pattern. If the pattern is zero length or null, all ++ attributes are eligible for distribution. The pattern is anchored so the ++ session attribute name must fully match the pattern. As an example, the ++ value (userName|sessionHistory) will only distribute the ++ two session attributes named userName and ++ sessionHistory. If not specified, the default value of ++ null will be used.

++
++ ++ ++

A regular expression used to filter which session attributes will be ++ distributed. An attribute will only be distributed if the implementation ++ class name of the value matches this pattern. If the pattern is zero ++ length or null, all attributes are eligible for ++ distribution. The pattern is anchored so the fully qualified class name ++ must fully match the pattern. If not specified, the default value of ++ null will be used unless a SecurityManager is ++ enabled in which case the default will be ++ java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

++
++ ++ ++

If sessionAttributeNameFilter or ++ sessionAttributeValueClassNameFilter blocks an ++ attribute, should this be logged at WARN level? If ++ WARN level logging is disabled then it will be logged at ++ DEBUG. The default value of this attribute is ++ false unless a SecurityManager is enabled in ++ which case the default will be true.

++
+ + +

In order to successfully use a PersistentManager, you must nest inside diff -Nru tomcat7-7.0.52/debian/patches/CVE-2016-0763.patch tomcat7-7.0.52/debian/patches/CVE-2016-0763.patch --- tomcat7-7.0.52/debian/patches/CVE-2016-0763.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2016-0763.patch 2016-06-29 15:33:47.000000000 +0000 @@ -0,0 +1,19 @@ +Description: fix securityManager restrictions bypass via crafted global context +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=1725931 + +Index: tomcat7-7.0.64/java/org/apache/naming/factory/ResourceLinkFactory.java +=================================================================== +--- tomcat7-7.0.64.orig/java/org/apache/naming/factory/ResourceLinkFactory.java 2016-06-17 12:04:45.074390009 +0300 ++++ tomcat7-7.0.64/java/org/apache/naming/factory/ResourceLinkFactory.java 2016-06-17 12:04:45.070389958 +0300 +@@ -60,6 +60,11 @@ + * @param newGlobalContext new global context value + */ + public static void setGlobalContext(Context newGlobalContext) { ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) { ++ sm.checkPermission(new RuntimePermission( ++ ResourceLinkFactory.class.getName() + ".setGlobalContext")); ++ } + globalContext = newGlobalContext; + } + diff -Nru tomcat7-7.0.52/debian/patches/CVE-2016-3092.patch tomcat7-7.0.52/debian/patches/CVE-2016-3092.patch --- tomcat7-7.0.52/debian/patches/CVE-2016-3092.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/CVE-2016-3092.patch 2016-06-27 18:17:55.000000000 +0000 @@ -0,0 +1,50 @@ +From: Markus Koschany +Date: Sun, 26 Jun 2016 19:14:54 +0200 +Subject: CVE-2016-3092 + +A denial of service vulnerability was identified in Commons FileUpload that +occurred when the length of the multipart boundary was just below the size of +the buffer (4096 bytes) used to read the uploaded file. This caused the file +upload process to take several orders of magnitude longer than if the boundary +was the typical tens of bytes long. + +Upstream advisory: +http://markmail.org/message/oyxfv73jb2g7rjg3 + +Origin: https://svn.apache.org/r1743480 +Origin: https://svn.apache.org/viewvc?view=revision&revision=1743742 +--- + .../apache/tomcat/util/http/fileupload/MultipartStream.java | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +Index: tomcat7-7.0.68/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java +=================================================================== +--- tomcat7-7.0.68.orig/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2016-06-27 14:12:36.278176085 -0400 ++++ tomcat7-7.0.68/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2016-06-27 14:12:36.274176038 -0400 +@@ -282,11 +282,10 @@ + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { +- this.input = input; +- this.bufSize = bufSize; +- this.buffer = new byte[bufSize]; +- this.notifier = pNotifier; + ++ if (boundary == null) { ++ throw new IllegalArgumentException("boundary may not be null"); ++ } + // We prepend CR/LF to the boundary to chop trailing CR/LF from + // body-data tokens. + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; +@@ -294,6 +293,11 @@ + throw new IllegalArgumentException( + "The buffer size specified for the MultipartStream is too small"); + } ++ this.input = input; ++ this.bufSize = Math.max(bufSize, boundaryLength*2); ++ this.buffer = new byte[this.bufSize]; ++ this.notifier = pNotifier; ++ + this.boundary = new byte[this.boundaryLength]; + this.keepRegion = this.boundary.length; + diff -Nru tomcat7-7.0.52/debian/patches/fix_cookie_names_in_tests.patch tomcat7-7.0.52/debian/patches/fix_cookie_names_in_tests.patch --- tomcat7-7.0.52/debian/patches/fix_cookie_names_in_tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/fix_cookie_names_in_tests.patch 2016-06-27 15:41:55.000000000 +0000 @@ -0,0 +1,87 @@ +Description: fix FTBFS by removing colons in cookie names which is illegal + in newer java versions +Origin: backport, http://svn.apache.org/viewvc?view=revision&revision=1715547 +Origin: backport, http://svn.apache.org/viewvc?view=revision&revision=1715550 + +Index: tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestNonLoginAndBasicAuthenticator.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/catalina/authenticator/TestNonLoginAndBasicAuthenticator.java 2016-06-27 10:50:06.053815019 -0400 ++++ tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestNonLoginAndBasicAuthenticator.java 2016-06-27 10:50:06.049814992 -0400 +@@ -412,7 +412,7 @@ + new HashMap>(); + + if (useCookie && (cookies != null)) { +- reqHeaders.put(CLIENT_COOKIE_HEADER + ":", cookies); ++ reqHeaders.put(CLIENT_COOKIE_HEADER, cookies); + } + + ByteChunk bc = new ByteChunk(); +@@ -437,7 +437,7 @@ + new HashMap>(); + + if (useCookie && (cookies != null)) { +- reqHeaders.put(CLIENT_COOKIE_HEADER + ":", cookies); ++ reqHeaders.put(CLIENT_COOKIE_HEADER, cookies); + } + else { + if (credentials != null) { +@@ -625,4 +625,4 @@ + return credentials; + } + } +-} +\ No newline at end of file ++} +Index: tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestSSOnonLoginAndBasicAuthenticator.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/catalina/authenticator/TestSSOnonLoginAndBasicAuthenticator.java 2016-06-27 10:50:06.053815019 -0400 ++++ tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestSSOnonLoginAndBasicAuthenticator.java 2016-06-27 10:50:06.053815019 -0400 +@@ -358,7 +358,7 @@ + new HashMap>(); + + if (useCookie && (cookies != null)) { +- reqHeaders.put(CLIENT_COOKIE_HEADER + ":", cookies); ++ reqHeaders.put(CLIENT_COOKIE_HEADER, cookies); + } + + ByteChunk bc = new ByteChunk(); +@@ -382,7 +382,7 @@ + Map> respHeaders = new HashMap>(); + + if (useCookie && (cookies != null)) { +- reqHeaders.put(CLIENT_COOKIE_HEADER + ":", cookies); ++ reqHeaders.put(CLIENT_COOKIE_HEADER, cookies); + } + else { + if (credentials != null) { +@@ -568,7 +568,7 @@ + protected void addCookies(Map> reqHeaders) { + + if ((cookies != null) && (cookies.size() > 0)) { +- reqHeaders.put(CLIENT_COOKIE_HEADER + ":", cookies); ++ reqHeaders.put(CLIENT_COOKIE_HEADER, cookies); + } + } + +@@ -655,4 +655,4 @@ + return credentials; + } + } +-} +\ No newline at end of file ++} +Index: tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestSSOnonLoginAndDigestAuthenticator.java +=================================================================== +--- tomcat7-7.0.52.orig/test/org/apache/catalina/authenticator/TestSSOnonLoginAndDigestAuthenticator.java 2016-06-27 10:50:06.053815019 -0400 ++++ tomcat7-7.0.52/test/org/apache/catalina/authenticator/TestSSOnonLoginAndDigestAuthenticator.java 2016-06-27 10:50:06.053815019 -0400 +@@ -485,7 +485,7 @@ + protected void addCookies(Map> reqHeaders) { + + if ((cookies != null) && (cookies.size() > 0)) { +- reqHeaders.put(BROWSER_COOKIES + ":", cookies); ++ reqHeaders.put(BROWSER_COOKIES, cookies); + } + } +-} +\ No newline at end of file ++} diff -Nru tomcat7-7.0.52/debian/patches/series tomcat7-7.0.52/debian/patches/series --- tomcat7-7.0.52/debian/patches/series 2015-06-19 20:13:36.000000000 +0000 +++ tomcat7-7.0.52/debian/patches/series 2016-06-27 18:17:55.000000000 +0000 @@ -22,3 +22,12 @@ CVE-2014-7810.patch 0022-use-tls-in-ssl-unit-tests.patch 0023-replace-expired-ssl-certificates.patch +CVE-2015-5174.patch +CVE-2015-5345.patch +CVE-2015-5346.patch +CVE-2015-5351.patch +CVE-2016-0706.patch +CVE-2016-0714.patch +CVE-2016-0763.patch +fix_cookie_names_in_tests.patch +CVE-2016-3092.patch