[tomcat7] 01/01: Prepare next security release for Wheezy.

Markus Koschany apo at moszumanska.debian.org
Fri Nov 4 14:34:53 UTC 2016


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch wheezy
in repository tomcat7.

commit b0a66d829f152186b8e260dfcffa919b0b694cf4
Author: Markus Koschany <apo at debian.org>
Date:   Fri Nov 4 15:04:31 2016 +0100

    Prepare next security release for Wheezy.
---
 debian/changelog                                   |  32 +++
 ...-java.security.policy-file-in-catalina.sh.patch |  20 +-
 debian/patches/CVE-2016-0762.patch                 |  25 ++
 debian/patches/CVE-2016-5018.patch                 | 107 +++++++++
 debian/patches/CVE-2016-6794.patch                 | 145 ++++++++++++
 debian/patches/CVE-2016-6796.patch                 | 111 +++++++++
 debian/patches/CVE-2016-6797.patch                 | 258 +++++++++++++++++++++
 debian/patches/series                              |   5 +
 debian/tomcat7.init                                |  11 +-
 debian/tomcat7.postrm.in                           |   1 +
 10 files changed, 702 insertions(+), 13 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 4f8b5df..10eaff7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+tomcat7 (7.0.28-4+deb7u7) UNRELEASED; urgency=high
+
+  * Fixed CVE-2016-0762: The Realm implementations did not process the supplied
+    password if the supplied user name did not exist. This made a timing attack
+    possible to determine valid user names.
+  * Fixed CVE-2016-5018: A malicious web application was able to bypass
+    a configured SecurityManager via a Tomcat utility method that was
+    accessible to web applications.
+  * Fixed CVE-2016-6794: When a SecurityManager is configured, a web
+    application's ability to read system properties should be controlled by
+    the SecurityManager. Tomcat's system property replacement feature for
+    configuration files could be used by a malicious web application to bypass
+    the SecurityManager and read system properties that should not be visible.
+  * Fixed CVE-2016-6796: A malicious web application was able to bypass
+    a configured SecurityManager via manipulation of the configuration
+    parameters for the JSP Servlet.
+  * Fixed CVE-2016-6797: The ResourceLinkFactory did not limit web application
+    access to global JNDI resources to those resources explicitly linked to the
+    web application. Therefore, it was possible for a web application to access
+    any global JNDI resource whether an explicit ResourceLink had been
+    configured or not.
+  * CVE-2016-1240 follow-up:
+    - The previous init.d fix was vulnerable to a race condition that could
+      be exploited to make any existing file writable by the tomcat user.
+      Thanks to Paul Szabo for the report and the fix.
+    - The catalina.policy file generated on startup was affected by a similar
+      vulnerability that could be exploited to overwrite any file on the system.
+      Thanks to Paul Szabo for the report.
+  * Hardened the init.d script, thanks to Paul Szabo
+
+ -- Markus Koschany <apo at debian.org>  Thu, 03 Nov 2016 17:15:18 +0100
+
 tomcat7 (7.0.28-4+deb7u6) wheezy-security; urgency=high
 
   * Team upload.
diff --git a/debian/patches/0009-Use-java.security.policy-file-in-catalina.sh.patch b/debian/patches/0009-Use-java.security.policy-file-in-catalina.sh.patch
index a516ce9..1ebaefc 100644
--- a/debian/patches/0009-Use-java.security.policy-file-in-catalina.sh.patch
+++ b/debian/patches/0009-Use-java.security.policy-file-in-catalina.sh.patch
@@ -1,6 +1,6 @@
 From: Adam Guthrie <asguthrie at gmail.com>
 Date: Mon, 28 Jun 2010 21:53:50 +0200
-Subject: [PATCH] Use java.security.policy file in catalina.sh
+Subject: Use java.security.policy file in catalina.sh
 
 Make sure catalina.sh uses the Debian/Ubuntu java.security.policy
 file location when Tomcat is started with a security manager.
@@ -9,35 +9,37 @@ Bug-Ubuntu: https://bugs.launchpad.net/bugs/591802
 Bug-Debian: http://bugs.debian.org/585379
 Forwarded: not-needed
 ---
- bin/catalina.sh |    6 +++---
- 1 files changed, 3 insertions(+), 3 deletions(-)
+ bin/catalina.sh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
 
+diff --git a/bin/catalina.sh b/bin/catalina.sh
+index 1690c14..a0e0aed 100755
 --- a/bin/catalina.sh
 +++ b/bin/catalina.sh
-@@ -287,7 +287,7 @@
+@@ -287,7 +287,7 @@ if [ "$1" = "debug" ] ; then
          -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
          -sourcepath "$CATALINA_HOME"/../../java \
          -Djava.security.manager \
 -        -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-+        -Djava.security.policy=="$CATALINA_BASE"/work/catalina.policy \
++        -Djava.security.policy=="$CATALINA_BASE"/policy/catalina.policy \
          -Dcatalina.base="$CATALINA_BASE" \
          -Dcatalina.home="$CATALINA_HOME" \
          -Djava.io.tmpdir="$CATALINA_TMPDIR" \
-@@ -314,7 +314,7 @@
+@@ -314,7 +314,7 @@ elif [ "$1" = "run" ]; then
      eval exec \"$_RUNJAVA\" \"$LOGGING_CONFIG\" $JAVA_OPTS $CATALINA_OPTS \
        -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \
        -Djava.security.manager \
 -      -Djava.security.policy==\"$CATALINA_BASE/conf/catalina.policy\" \
-+      -Djava.security.policy==\"$CATALINA_BASE/work/catalina.policy\" \
++      -Djava.security.policy==\"$CATALINA_BASE/policy/catalina.policy\" \
        -Dcatalina.base=\"$CATALINA_BASE\" \
        -Dcatalina.home=\"$CATALINA_HOME\" \
        -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \
-@@ -378,7 +378,7 @@
+@@ -378,7 +378,7 @@ elif [ "$1" = "start" ] ; then
      eval \"$_RUNJAVA\" \"$LOGGING_CONFIG\" $JAVA_OPTS $CATALINA_OPTS \
        -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \
        -Djava.security.manager \
 -      -Djava.security.policy==\"$CATALINA_BASE/conf/catalina.policy\" \
-+      -Djava.security.policy==\"$CATALINA_BASE/work/catalina.policy\" \
++      -Djava.security.policy==\"$CATALINA_BASE/policy/catalina.policy\" \
        -Dcatalina.base=\"$CATALINA_BASE\" \
        -Dcatalina.home=\"$CATALINA_HOME\" \
        -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \
diff --git a/debian/patches/CVE-2016-0762.patch b/debian/patches/CVE-2016-0762.patch
new file mode 100644
index 0000000..308b7c7
--- /dev/null
+++ b/debian/patches/CVE-2016-0762.patch
@@ -0,0 +1,25 @@
+From: Markus Koschany <apo at debian.org>
+Date: Fri, 4 Nov 2016 00:05:38 +0100
+Subject: CVE-2016-0762
+
+Only JNDIRealm class is affected in Wheezy.
+
+Origin: https://svn.apache.org/r1758502
+---
+ java/org/apache/catalina/realm/JNDIRealm.java | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/java/org/apache/catalina/realm/JNDIRealm.java b/java/org/apache/catalina/realm/JNDIRealm.java
+index 541063f..8554bf4 100644
+--- a/java/org/apache/catalina/realm/JNDIRealm.java
++++ b/java/org/apache/catalina/realm/JNDIRealm.java
+@@ -1488,6 +1488,9 @@ public class JNDIRealm extends RealmBase {
+                  containerLog.trace(sm.getString("jndiRealm.authenticateSuccess",
+                                   user.getUserName()));
+              } else {
++                 // User was not found in the database.
++                 // Waste a bit of time as not to reveal that the user does not exist.
++                 compareCredentials(context, user, credentials);
+                  containerLog.trace(sm.getString("jndiRealm.authenticateFailure",
+                                   user.getUserName()));
+              }
diff --git a/debian/patches/CVE-2016-5018.patch b/debian/patches/CVE-2016-5018.patch
new file mode 100644
index 0000000..343238d
--- /dev/null
+++ b/debian/patches/CVE-2016-5018.patch
@@ -0,0 +1,107 @@
+From: Markus Koschany <apo at debian.org>
+Date: Thu, 3 Nov 2016 16:37:46 +0100
+Subject: CVE-2016-5018
+
+Origin: http://svn.apache.org/r1754902
+---
+ .../apache/jasper/runtime/JspRuntimeLibrary.java   | 59 +---------------------
+ 1 file changed, 1 insertion(+), 58 deletions(-)
+
+diff --git a/java/org/apache/jasper/runtime/JspRuntimeLibrary.java b/java/org/apache/jasper/runtime/JspRuntimeLibrary.java
+index 9fb6e55..73ea608 100644
+--- a/java/org/apache/jasper/runtime/JspRuntimeLibrary.java
++++ b/java/org/apache/jasper/runtime/JspRuntimeLibrary.java
+@@ -14,7 +14,6 @@
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+-
+ package org.apache.jasper.runtime;
+ 
+ import java.beans.PropertyEditor;
+@@ -23,9 +22,6 @@ import java.io.ByteArrayOutputStream;
+ import java.io.IOException;
+ import java.io.OutputStreamWriter;
+ import java.lang.reflect.Method;
+-import java.security.AccessController;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+ import java.util.Enumeration;
+ 
+ import javax.servlet.RequestDispatcher;
+@@ -37,7 +33,6 @@ import javax.servlet.jsp.JspWriter;
+ import javax.servlet.jsp.PageContext;
+ import javax.servlet.jsp.tagext.BodyContent;
+ 
+-import org.apache.jasper.Constants;
+ import org.apache.jasper.JasperException;
+ import org.apache.jasper.compiler.Localizer;
+ import org.apache.jasper.util.ExceptionUtils;
+@@ -56,36 +51,6 @@ import org.apache.jasper.util.ExceptionUtils;
+  */
+ public class JspRuntimeLibrary {
+     
+-    protected static class PrivilegedIntrospectHelper
+-        implements PrivilegedExceptionAction<Void> {
+-
+-        private Object bean;
+-        private String prop;
+-        private String value;
+-        private ServletRequest request;
+-        private String param;
+-        private boolean ignoreMethodNF;
+-
+-        PrivilegedIntrospectHelper(Object bean, String prop,
+-                                   String value, ServletRequest request,
+-                                   String param, boolean ignoreMethodNF)
+-        {
+-            this.bean = bean;
+-            this.prop = prop;
+-            this.value = value;
+-            this.request = request;
+-            this.param = param;
+-            this.ignoreMethodNF = ignoreMethodNF;
+-        }
+-         
+-        @Override
+-        public Void run() throws JasperException {
+-            internalIntrospecthelper(
+-                bean,prop,value,request,param,ignoreMethodNF);
+-            return null;
+-        }
+-    }
+-
+     /**
+      * Returns the value of the javax.servlet.error.exception request
+      * attribute value, if present, otherwise the value of the
+@@ -290,29 +255,7 @@ public class JspRuntimeLibrary {
+     public static void introspecthelper(Object bean, String prop,
+                                         String value, ServletRequest request,
+                                         String param, boolean ignoreMethodNF)
+-                                        throws JasperException
+-    {
+-        if( Constants.IS_SECURITY_ENABLED ) {
+-            try {
+-                PrivilegedIntrospectHelper dp =
+-                    new PrivilegedIntrospectHelper(
+-                        bean,prop,value,request,param,ignoreMethodNF);
+-                AccessController.doPrivileged(dp);
+-            } catch( PrivilegedActionException pe) {
+-                Exception e = pe.getException();
+-                throw (JasperException)e;
+-            }
+-        } else {
+-            internalIntrospecthelper(
+-                bean,prop,value,request,param,ignoreMethodNF);
+-        }
+-    }
+-
+-    private static void internalIntrospecthelper(Object bean, String prop,
+-                                        String value, ServletRequest request,
+-                                        String param, boolean ignoreMethodNF) 
+-                                        throws JasperException
+-    {
++                                        throws JasperException {
+         Method method = null;
+         Class<?> type = null;
+         Class<?> propertyEditorClass = null;
diff --git a/debian/patches/CVE-2016-6794.patch b/debian/patches/CVE-2016-6794.patch
new file mode 100644
index 0000000..53d60d5
--- /dev/null
+++ b/debian/patches/CVE-2016-6794.patch
@@ -0,0 +1,145 @@
+From: Markus Koschany <apo at debian.org>
+Date: Thu, 3 Nov 2016 16:36:01 +0100
+Subject: CVE-2016-6794
+
+Origin: http://svn.apache.org/r1754728
+---
+ .../apache/catalina/loader/WebappClassLoader.java  | 24 +++++++++++-
+ java/org/apache/tomcat/util/digester/Digester.java | 10 +++++
+ .../tomcat/util/security/PermissionCheck.java      | 43 ++++++++++++++++++++++
+ 3 files changed, 76 insertions(+), 1 deletion(-)
+ create mode 100644 java/org/apache/tomcat/util/security/PermissionCheck.java
+
+diff --git a/java/org/apache/catalina/loader/WebappClassLoader.java b/java/org/apache/catalina/loader/WebappClassLoader.java
+index b182ce3..dfb3ee7 100644
+--- a/java/org/apache/catalina/loader/WebappClassLoader.java
++++ b/java/org/apache/catalina/loader/WebappClassLoader.java
+@@ -78,6 +78,7 @@ import org.apache.naming.resources.ResourceAttributes;
+ import org.apache.tomcat.util.ExceptionUtils;
+ import org.apache.tomcat.util.IntrospectionUtils;
+ import org.apache.tomcat.util.res.StringManager;
++import org.apache.tomcat.util.security.PermissionCheck;
+ 
+ /**
+  * Specialized web application class loader.
+@@ -123,7 +124,7 @@ import org.apache.tomcat.util.res.StringManager;
+  */
+ public class WebappClassLoader
+     extends URLClassLoader
+-    implements Lifecycle
++    implements Lifecycle, PermissionCheck
+  {
+ 
+     private static final org.apache.juli.logging.Log log=
+@@ -1744,6 +1745,27 @@ public class WebappClassLoader
+     }
+ 
+ 
++    @Override
++    public boolean check(Permission permission) {
++        if (!Globals.IS_SECURITY_ENABLED) {
++            return true;
++        }
++        Policy currentPolicy = Policy.getPolicy();
++        if (currentPolicy != null) {
++            ResourceEntry entry = findResourceInternal("/", "/");
++            if (entry != null) {
++                CodeSource cs = new CodeSource(
++                        entry.codeBase, (java.security.cert.Certificate[]) null);
++                PermissionCollection pc = currentPolicy.getPermissions(cs);
++                if (pc.implies(permission)) {
++                    return true;
++                }
++            }
++        }
++        return false;
++    }
++
++
+     /**
+      * Returns the search path of URLs for loading classes and resources.
+      * This includes the original list of URLs specified to the constructor,
+diff --git a/java/org/apache/tomcat/util/digester/Digester.java b/java/org/apache/tomcat/util/digester/Digester.java
+index 84cbeb3..d631528 100644
+--- a/java/org/apache/tomcat/util/digester/Digester.java
++++ b/java/org/apache/tomcat/util/digester/Digester.java
+@@ -29,6 +29,8 @@ import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
++import java.util.PropertyPermission;
++import java.security.Permission;
+ 
+ import javax.xml.parsers.ParserConfigurationException;
+ import javax.xml.parsers.SAXParser;
+@@ -38,6 +40,7 @@ import org.apache.juli.logging.Log;
+ import org.apache.juli.logging.LogFactory;
+ import org.apache.tomcat.util.ExceptionUtils;
+ import org.apache.tomcat.util.IntrospectionUtils;
++import org.apache.tomcat.util.security.PermissionCheck;
+ import org.xml.sax.Attributes;
+ import org.xml.sax.EntityResolver;
+ import org.xml.sax.ErrorHandler;
+@@ -80,6 +83,13 @@ public class Digester extends DefaultHandler {
+         implements IntrospectionUtils.PropertySource {
+         @Override
+         public String getProperty( String key ) {
++            ClassLoader cl = Thread.currentThread().getContextClassLoader();
++            if (cl instanceof PermissionCheck) {
++                Permission p = new PropertyPermission(key, "read");
++                if (!((PermissionCheck) cl).check(p)) {
++                    return null;
++                }
++            }
+             return System.getProperty(key);
+         }
+     }
+diff --git a/java/org/apache/tomcat/util/security/PermissionCheck.java b/java/org/apache/tomcat/util/security/PermissionCheck.java
+new file mode 100644
+index 0000000..ba2bdd3
+--- /dev/null
++++ b/java/org/apache/tomcat/util/security/PermissionCheck.java
+@@ -0,0 +1,43 @@
++/*
++ * 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.tomcat.util.security;
++
++import java.security.Permission;
++
++/**
++ * This interface is implemented by components to enable privileged code to
++ * check whether the component has a given permission.
++ * This is typically used when a privileged component (e.g. the container) is
++ * performing an action on behalf of an untrusted component (e.g. a web
++ * application) without the current thread having passed through a code source
++ * provided by the untrusted component. Because the current thread has not
++ * passed through a code source provided by the untrusted component the
++ * SecurityManager assumes the code is trusted so the standard checking
++ * mechanisms can't be used.
++ */
++public interface PermissionCheck {
++
++    /**
++     * Does this component have the given permission?
++     *
++     * @param permission The permission to test
++     *
++     * @return {@code false} if a SecurityManager is enabled and the component
++     *         does not have the given permission, otherwise {@code false}
++     */
++    boolean check(Permission permission);
++}
diff --git a/debian/patches/CVE-2016-6796.patch b/debian/patches/CVE-2016-6796.patch
new file mode 100644
index 0000000..7ee2ae3
--- /dev/null
+++ b/debian/patches/CVE-2016-6796.patch
@@ -0,0 +1,111 @@
+From: Markus Koschany <apo at debian.org>
+Date: Thu, 3 Nov 2016 16:27:56 +0100
+Subject: CVE-2016-6796
+
+Origin: http://svn.apache.org/r1758495
+---
+ conf/web.xml                                             | 4 ++++
+ java/org/apache/jasper/EmbeddedServletOptions.java       | 4 ++++
+ java/org/apache/jasper/resources/LocalStrings.properties | 1 +
+ java/org/apache/jasper/servlet/JspServlet.java           | 9 +++++++--
+ webapps/docs/jasper-howto.xml                            | 4 ++--
+ 5 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/conf/web.xml b/conf/web.xml
+index 2482d93..9126d54 100644
+--- a/conf/web.xml
++++ b/conf/web.xml
+@@ -158,6 +158,8 @@
+   <!--   engineOptionsClass  Allows specifying the Options class used to    -->
+   <!--                       configure Jasper. If not present, the default  -->
+   <!--                       EmbeddedServletOptions will be used.           -->
++  <!--                       This option is ignored when running under a    -->
++  <!--                       SecurityManager.                               -->
+   <!--                                                                      -->
+   <!--   errorOnUseBeanInvalidClassAttribute                                -->
+   <!--                       Should Jasper issue an error when the value of -->
+@@ -219,6 +221,8 @@
+   <!--   scratchdir          What scratch directory should we use when      -->
+   <!--                       compiling JSP pages?  [default work directory  -->
+   <!--                       for the current web application]               -->
++  <!--                       This option is ignored when running under a    -->
++  <!--                       SecurityManager.                               -->
+   <!--                                                                      -->
+   <!--   suppressSmap        Should the generation of SMAP info for JSR45   -->
+   <!--                       debugging be suppressed?  [false]              -->
+diff --git a/java/org/apache/jasper/EmbeddedServletOptions.java b/java/org/apache/jasper/EmbeddedServletOptions.java
+index 6c5ddbd..05c6fe6 100644
+--- a/java/org/apache/jasper/EmbeddedServletOptions.java
++++ b/java/org/apache/jasper/EmbeddedServletOptions.java
+@@ -640,6 +640,10 @@ public final class EmbeddedServletOptions implements Options {
+          * scratchdir
+          */
+         String dir = config.getInitParameter("scratchdir"); 
++        if (dir != null && Constants.IS_SECURITY_ENABLED) {
++            log.info(Localizer.getMessage("jsp.info.ignoreSetting", "scratchdir", dir));
++            dir = null;
++        }
+         if (dir != null) {
+             scratchDir = new File(dir);
+         } else {
+diff --git a/java/org/apache/jasper/resources/LocalStrings.properties b/java/org/apache/jasper/resources/LocalStrings.properties
+index 4b67a9c..5cd0657 100644
+--- a/java/org/apache/jasper/resources/LocalStrings.properties
++++ b/java/org/apache/jasper/resources/LocalStrings.properties
+@@ -455,6 +455,7 @@ jsp.error.unbalanced.endtag=The end tag \"</{0}\" is unbalanced
+ jsp.error.invalid.bean=The value for the useBean class attribute {0} is invalid.
+ jsp.error.prefix.use_before_dcl=The prefix {0} specified in this tag directive has been previously used by an action in file {1} line {2}.
+ jsp.error.lastModified=Unable to determine last modified date for file [{0}]
++jsp.info.ignoreSetting=Ignored setting for [{0}] of [{1}] because a SecurityManager was enabled
+ 
+ jsp.exception=An exception occurred processing JSP page {0} at line {1}
+ 
+diff --git a/java/org/apache/jasper/servlet/JspServlet.java b/java/org/apache/jasper/servlet/JspServlet.java
+index 289b9e9..4e253e3 100644
+--- a/java/org/apache/jasper/servlet/JspServlet.java
++++ b/java/org/apache/jasper/servlet/JspServlet.java
+@@ -71,8 +71,8 @@ public class JspServlet extends HttpServlet implements PeriodicEventListener {
+     private ServletConfig config;
+     private transient Options options;
+     private transient JspRuntimeContext rctxt;
+-    //jspFile for a jsp configured explicitly as a servlet, in environments where this configuration is
+-    //translated into an init-param for this servlet.
++    // jspFile for a jsp configured explicitly as a servlet, in environments where this
++    // configuration is translated into an init-param for this servlet.
+     private String jspFile;
+ 
+ 
+@@ -90,6 +90,11 @@ public class JspServlet extends HttpServlet implements PeriodicEventListener {
+         // Check for a custom Options implementation
+         String engineOptionsName = 
+             config.getInitParameter("engineOptionsClass");
++        if (Constants.IS_SECURITY_ENABLED && engineOptionsName != null) {
++            log.info(Localizer.getMessage(
++                    "jsp.info.ignoreSetting", "engineOptionsClass", engineOptionsName));
++            engineOptionsName = null;
++        }
+         if (engineOptionsName != null) {
+             // Instantiate the indicated Options implementation
+             try {
+diff --git a/webapps/docs/jasper-howto.xml b/webapps/docs/jasper-howto.xml
+index 826c051..fb9b28e 100644
+--- a/webapps/docs/jasper-howto.xml
++++ b/webapps/docs/jasper-howto.xml
+@@ -127,7 +127,7 @@ default <code>true</code>.
+ 
+ <li><strong>engineOptionsClass</strong> - Allows specifying the Options class
+ used to configure Jasper. If not present, the default EmbeddedServletOptions
+-will be used.
++will be used. This option is ignored if running under a SecurityManager.
+ </li>
+ 
+ <li><strong>errorOnUseBeanInvalidClassAttribute</strong> - Should Jasper issue
+@@ -180,7 +180,7 @@ may be expensive and could lead to excessive resource usage.</li>
+ 
+ <li><strong>scratchdir</strong> - What scratch directory should we use when
+ compiling JSP pages? Default is the work directory for the current web
+-application.</li>
++application. This option is ignored if running under a SecurityManager.</li>
+ 
+ <li><strong>suppressSmap</strong> - Should the generation of SMAP info for JSR45
+ debugging be suppressed? <code>true</code> or <code>false</code>, default
diff --git a/debian/patches/CVE-2016-6797.patch b/debian/patches/CVE-2016-6797.patch
new file mode 100644
index 0000000..cf71759
--- /dev/null
+++ b/debian/patches/CVE-2016-6797.patch
@@ -0,0 +1,258 @@
+From: Markus Koschany <apo at debian.org>
+Date: Thu, 3 Nov 2016 16:26:45 +0100
+Subject: CVE-2016-6797
+
+Origin: http://svn.apache.org/r1757275
+---
+ .../catalina/core/NamingContextListener.java       | 20 +++++
+ .../apache/naming/factory/ResourceLinkFactory.java | 61 +++++++++++++++
+ test/org/apache/naming/TestNamingContext.java      | 87 ++++++++++++++++++++++
+ 3 files changed, 168 insertions(+)
+ create mode 100644 test/org/apache/naming/TestNamingContext.java
+
+diff --git a/java/org/apache/catalina/core/NamingContextListener.java b/java/org/apache/catalina/core/NamingContextListener.java
+index 527ad6f..f95416b 100644
+--- a/java/org/apache/catalina/core/NamingContextListener.java
++++ b/java/org/apache/catalina/core/NamingContextListener.java
+@@ -40,6 +40,7 @@ import org.apache.catalina.Container;
+ import org.apache.catalina.ContainerEvent;
+ import org.apache.catalina.ContainerListener;
+ import org.apache.catalina.Context;
++import org.apache.catalina.Engine;
+ import org.apache.catalina.Host;
+ import org.apache.catalina.Lifecycle;
+ import org.apache.catalina.LifecycleEvent;
+@@ -67,6 +68,7 @@ import org.apache.naming.ResourceLinkRef;
+ import org.apache.naming.ResourceRef;
+ import org.apache.naming.ServiceRef;
+ import org.apache.naming.TransactionRef;
++import org.apache.naming.factory.ResourceLinkFactory;
+ import org.apache.tomcat.util.modeler.Registry;
+ import org.apache.tomcat.util.res.StringManager;
+ 
+@@ -335,6 +337,12 @@ public class NamingContextListener
+             for (ObjectName objectName : names) {
+                 Registry.getRegistry(null, null).unregisterComponent(objectName);
+             }
++
++            javax.naming.Context global = getGlobalNamingContext();
++            if (global != null) {
++                ResourceLinkFactory.deregisterGlobalResourceAccess(global);
++            }
++
+             objectNames.clear();
+ 
+             namingContext = null;
+@@ -1125,6 +1133,17 @@ public class NamingContextListener
+             logger.error(sm.getString("naming.bindFailed", e));
+         }
+ 
++        ResourceLinkFactory.registerGlobalResourceAccess(
++                getGlobalNamingContext(), resourceLink.getName(), resourceLink.getGlobal());
++    }
++
++
++    private javax.naming.Context getGlobalNamingContext() {
++        if (container instanceof Context) {
++            Engine e = (Engine) ((Context) container).getParent().getParent();
++            return e.getService().getServer().getGlobalNamingContext();
++        }
++        return null;
+     }
+ 
+ 
+@@ -1228,6 +1247,7 @@ public class NamingContextListener
+             logger.error(sm.getString("naming.unbindFailed", e));
+         }
+ 
++        ResourceLinkFactory.deregisterGlobalResourceAccess(getGlobalNamingContext(), name);
+     }
+ 
+ 
+diff --git a/java/org/apache/naming/factory/ResourceLinkFactory.java b/java/org/apache/naming/factory/ResourceLinkFactory.java
+index 03188da..157adfb 100644
+--- a/java/org/apache/naming/factory/ResourceLinkFactory.java
++++ b/java/org/apache/naming/factory/ResourceLinkFactory.java
+@@ -18,7 +18,10 @@
+ 
+ package org.apache.naming.factory;
+ 
++import java.util.HashMap;
+ import java.util.Hashtable;
++import java.util.Map;
++import java.util.concurrent.ConcurrentHashMap;
+ 
+ import javax.naming.Context;
+ import javax.naming.Name;
+@@ -52,6 +55,8 @@ public class ResourceLinkFactory
+      */
+     private static Context globalContext = null;
+ 
++    private static Map<ClassLoader,Map<String,String>> globalResourceRegistrations =
++            new ConcurrentHashMap<ClassLoader,Map<String,String>>();
+ 
+     // --------------------------------------------------------- Public Methods
+ 
+@@ -71,6 +76,56 @@ public class ResourceLinkFactory
+     }
+ 
+ 
++    public static void registerGlobalResourceAccess(Context globalContext, String localName,
++            String globalName) {
++        validateGlobalContext(globalContext);
++        ClassLoader cl = Thread.currentThread().getContextClassLoader();
++        Map<String,String> registrations = globalResourceRegistrations.get(cl);
++        if (registrations == null) {
++            // Web application initialization is single threaded so this is
++            // safe.
++            registrations = new HashMap<String,String>();
++            globalResourceRegistrations.put(cl, registrations);
++        }
++        registrations.put(localName, globalName);
++    }
++
++
++    public static void deregisterGlobalResourceAccess(Context globalContext, String localName) {
++        validateGlobalContext(globalContext);
++        ClassLoader cl = Thread.currentThread().getContextClassLoader();
++        Map<String,String> registrations = globalResourceRegistrations.get(cl);
++        if (registrations != null) {
++            registrations.remove(localName);
++        }
++    }
++
++
++    public static void deregisterGlobalResourceAccess(Context globalContext) {
++        validateGlobalContext(globalContext);
++        ClassLoader cl = Thread.currentThread().getContextClassLoader();
++        globalResourceRegistrations.remove(cl);
++    }
++
++
++    private static void validateGlobalContext(Context globalContext) {
++        if (ResourceLinkFactory.globalContext != null &&
++                ResourceLinkFactory.globalContext != globalContext) {
++            throw new SecurityException("Caller provided invalid global context");
++        }
++    }
++
++
++    private static boolean validateGlobalResourceAccess(String globalName) {
++        ClassLoader cl = Thread.currentThread().getContextClassLoader();
++        Map<String,String> registrations = globalResourceRegistrations.get(cl);
++        if (registrations != null && registrations.containsValue(globalName)) {
++            return true;
++        }
++        return false;
++    }
++
++
+     // -------------------------------------------------- ObjectFactory Methods
+ 
+ 
+@@ -95,6 +150,12 @@ public class ResourceLinkFactory
+         RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME);
+         if (refAddr != null) {
+             globalName = refAddr.getContent().toString();
++            // When running under a security manager confirm that the current
++            // web application has really been configured to access the specified
++            // global resource
++            if (!validateGlobalResourceAccess(globalName)) {
++                return null;
++            }
+             Object result = null;
+             result = globalContext.lookup(globalName);
+             // FIXME: Check type
+diff --git a/test/org/apache/naming/TestNamingContext.java b/test/org/apache/naming/TestNamingContext.java
+new file mode 100644
+index 0000000..f108893
+--- /dev/null
++++ b/test/org/apache/naming/TestNamingContext.java
+@@ -0,0 +1,87 @@
++package org.apache.naming;
++
++import javax.naming.Context;
++import javax.naming.NamingException;
++
++import org.apache.catalina.deploy.ContextEnvironment;
++import org.apache.catalina.deploy.ContextResourceLink;
++import org.apache.catalina.startup.Tomcat;
++import org.apache.catalina.startup.TomcatBaseTest;
++import org.apache.naming.factory.ResourceLinkFactory;
++import org.junit.Assert;
++import org.junit.Test;
++
++public class TestNamingContext extends TomcatBaseTest {
++
++    private static final String COMP_ENV = "comp/env";
++    private static final String GLOBAL_NAME = "global";
++    private static final String LOCAL_NAME = "local";
++    private static final String DATA = "Cabbage";
++
++
++    @Test
++    public void testGlobalNaming() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++        tomcat.enableNaming();
++
++        org.apache.catalina.Context ctx = tomcat.addContext("", null);
++
++        tomcat.start();
++
++        Context webappInitial = ContextBindings.getContext(ctx);
++
++        // Nothing added at the moment so should be null
++        Object obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME);
++        Assert.assertNull(obj);
++
++        ContextEnvironment ce = new ContextEnvironment();
++        ce.setName(GLOBAL_NAME);
++        ce.setValue(DATA);
++        ce.setType(DATA.getClass().getName());
++
++        tomcat.getServer().getGlobalNamingResources().addEnvironment(ce);
++
++        // No link so still should be null
++        obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME);
++        Assert.assertNull(obj);
++
++        // Now add a resource link to the context
++        ContextResourceLink crl = new ContextResourceLink();
++        crl.setGlobal(GLOBAL_NAME);
++        crl.setName(LOCAL_NAME);
++        crl.setType(DATA.getClass().getName());
++        ctx.getNamingResources().addResourceLink(crl);
++
++        // Link exists so should be OK now
++        obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME);
++        Assert.assertEquals(DATA, obj);
++
++        // Try shortcut
++        ResourceLinkFactory factory = new ResourceLinkFactory();
++        ResourceLinkRef rlr = new ResourceLinkRef(DATA.getClass().getName(), GLOBAL_NAME, null, null);
++        obj = factory.getObjectInstance(rlr, null, null, null);
++        Assert.assertEquals(DATA, obj);
++
++        // Remove the link
++        ctx.getNamingResources().removeResourceLink(LOCAL_NAME);
++
++        // No link so should be null
++        obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME);
++        Assert.assertNull(obj);
++
++        // Shortcut should fail too
++        obj = factory.getObjectInstance(rlr, null, null, null);
++        Assert.assertNull(obj);
++    }
++
++
++    private Object doLookup(Context context, String name) {
++        Object result = null;
++        try {
++            result = context.lookup(name);
++        } catch (NamingException nnfe) {
++            // Ignore
++        }
++        return result;
++    }
++}
diff --git a/debian/patches/series b/debian/patches/series
index e12269f..72b5561 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -37,3 +37,8 @@ CVE-2016-0706.patch
 CVE-2016-0714.patch
 CVE-2016-0763.patch
 CVE-2016-3092.patch
+CVE-2016-5018.patch
+CVE-2016-6794.patch
+CVE-2016-6796.patch
+CVE-2016-6797.patch
+CVE-2016-0762.patch
diff --git a/debian/tomcat7.init b/debian/tomcat7.init
index 2821a3d..35e3bb3 100644
--- a/debian/tomcat7.init
+++ b/debian/tomcat7.init
@@ -118,7 +118,7 @@ if [ ! -f "$CATALINA_HOME/bin/bootstrap.jar" ]; then
 	exit 1
 fi
 
-POLICY_CACHE="$CATALINA_BASE/work/catalina.policy"
+POLICY_CACHE="$CATALINA_BASE/policy/catalina.policy"
 
 if [ -z "$CATALINA_TMPDIR" ]; then
 	CATALINA_TMPDIR="$JVM_TMP"
@@ -172,7 +172,8 @@ catalina_sh() {
 	# Run the catalina.sh script as a daemon
 	set +e
 	if [ ! -f "$CATALINA_BASE"/logs/catalina.out ]; then
-		install -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_BASE"/logs/catalina.out
+		# run install as tomcat7 to work around #841371
+		su $TOMCAT7_USER -s /bin/bash -c "install -m 644 /dev/null $CATALINA_BASE/logs/catalina.out"
 	fi
 	install -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_PID"
 	start-stop-daemon --start -b -u "$TOMCAT7_USER" -g "$TOMCAT7_GROUP" \
@@ -202,6 +203,8 @@ case "$1" in
 
 		# Regenerate POLICY_CACHE file
 		umask 022
+		rm -rf "$CATALINA_BASE/policy"
+		mkdir "$CATALINA_BASE/policy"
 		echo "// AUTO-GENERATED FILE from /etc/tomcat7/policy.d/" \
 			> "$POLICY_CACHE"
 		echo ""  >> "$POLICY_CACHE"
@@ -210,11 +213,11 @@ case "$1" in
 
 		# Remove / recreate JVM_TMP directory
 		rm -rf "$JVM_TMP"
-		mkdir -p "$JVM_TMP" || {
+		mkdir "$JVM_TMP" || {
 			log_failure_msg "could not create JVM temporary directory"
 			exit 1
 		}
-		chown $TOMCAT7_USER "$JVM_TMP"
+		chown -h $TOMCAT7_USER "$JVM_TMP"
 
 		catalina_sh start $SECURITY
 		sleep 5
diff --git a/debian/tomcat7.postrm.in b/debian/tomcat7.postrm.in
index de35c3a..293ffde 100644
--- a/debian/tomcat7.postrm.in
+++ b/debian/tomcat7.postrm.in
@@ -8,6 +8,7 @@ LR_CONFFILE=/etc/logrotate.d/tomcat7
 
 # Remove cached files and auto-generated catalina.policy
 rm -rf /var/cache/tomcat7/*
+rm -rf /var/lib/tomcat7/policy
 
 case "$1" in
     remove)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/tomcat7.git



More information about the pkg-java-commits mailing list