Author: markt
Date: Thu Apr 24 19:16:21 2014
New Revision: 1589837

URL: http://svn.apache.org/r1589837
Log:
Add some defensive coding around some XML activities that are triggered by web 
applications and are therefore at potential risk of a memory leak.

Modified:
    tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
    tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
    tomcat/trunk/res/checkstyle/org-import-control.xml
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1589837&r1=1589836&r2=1589837&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Thu Apr 
24 19:16:21 2014
@@ -31,6 +31,7 @@ import java.io.RandomAccessFile;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -68,6 +69,8 @@ import org.apache.catalina.util.RequestU
 import org.apache.catalina.util.ServerInfo;
 import org.apache.catalina.util.URLEncoder;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
 import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -1309,11 +1312,27 @@ public class DefaultServlet extends Http
             sb.append("]]></readme>");
         }
 
-
         sb.append("</listing>");
 
-
+        // Prevent possible memory leak. Ensure Transformer and
+        // TransformerFactory are not loaded from the web application.
+        ClassLoader original;
+        if (Globals.IS_SECURITY_ENABLED) {
+            PrivilegedGetTccl pa = new PrivilegedGetTccl();
+            original = AccessController.doPrivileged(pa);
+        } else {
+            original = Thread.currentThread().getContextClassLoader();
+        }
         try {
+            if (Globals.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa =
+                        new 
PrivilegedSetTccl(DefaultServlet.class.getClassLoader());
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(
+                        DefaultServlet.class.getClassLoader());
+            }
+
             TransformerFactory tFactory = TransformerFactory.newInstance();
             Source xmlSource = new StreamSource(new 
StringReader(sb.toString()));
             Transformer transformer = tFactory.newTransformer(xsltSource);
@@ -1326,6 +1345,13 @@ public class DefaultServlet extends Http
             return (new ByteArrayInputStream(stream.toByteArray()));
         } catch (TransformerException e) {
             throw new ServletException("XSL transformer error", e);
+        } finally {
+            if (Globals.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(original);
+            }
         }
     }
 

Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1589837&r1=1589836&r2=1589837&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java Thu Apr 
24 19:16:21 2014
@@ -19,6 +19,7 @@ package org.apache.jasper.compiler;
 import java.io.CharArrayWriter;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.security.AccessController;
 import java.util.Collection;
 import java.util.Iterator;
 
@@ -35,6 +36,8 @@ import org.apache.tomcat.util.descriptor
 import org.apache.tomcat.util.descriptor.LocalResolver;
 import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
 import org.apache.tomcat.util.scan.Jar;
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.Locator;
@@ -1452,33 +1455,58 @@ class JspDocumentParser
         JspDocumentParser jspDocParser)
         throws Exception {
 
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-
-        factory.setNamespaceAware(true);
-        // Preserve xmlns attributes
-        factory.setFeature(
-            "http://xml.org/sax/features/namespace-prefixes";,
-            true);
-
-        factory.setValidating(validating);
-        if (validating) {
-            // Enable DTD validation
-            factory.setFeature(
-                    "http://xml.org/sax/features/validation";,
-                    true);
-            // Enable schema validation
-            factory.setFeature(
-                    "http://apache.org/xml/features/validation/schema";,
-                    true);
+        ClassLoader original;
+        if (Constants.IS_SECURITY_ENABLED) {
+            PrivilegedGetTccl pa = new PrivilegedGetTccl();
+            original = AccessController.doPrivileged(pa);
+        } else {
+            original = Thread.currentThread().getContextClassLoader();
         }
+        try {
+            if (Constants.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa =
+                        new 
PrivilegedSetTccl(JspDocumentParser.class.getClassLoader());
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(
+                        JspDocumentParser.class.getClassLoader());
+            }
+
+            SAXParserFactory factory = SAXParserFactory.newInstance();
 
-        // Configure the parser
-        SAXParser saxParser = factory.newSAXParser();
-        XMLReader xmlReader = saxParser.getXMLReader();
-        xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser);
-        xmlReader.setErrorHandler(jspDocParser);
+            factory.setNamespaceAware(true);
+            // Preserve xmlns attributes
+            factory.setFeature(
+                "http://xml.org/sax/features/namespace-prefixes";,
+                true);
 
-        return saxParser;
+            factory.setValidating(validating);
+            if (validating) {
+                // Enable DTD validation
+                factory.setFeature(
+                        "http://xml.org/sax/features/validation";,
+                        true);
+                // Enable schema validation
+                factory.setFeature(
+                        "http://apache.org/xml/features/validation/schema";,
+                        true);
+            }
+
+            // Configure the parser
+            SAXParser saxParser = factory.newSAXParser();
+            XMLReader xmlReader = saxParser.getXMLReader();
+            xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser);
+            xmlReader.setErrorHandler(jspDocParser);
+
+            return saxParser;
+        } finally {
+            if (Constants.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(original);
+            }
+        }
     }
 
     /*

Modified: tomcat/trunk/res/checkstyle/org-import-control.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/res/checkstyle/org-import-control.xml?rev=1589837&r1=1589836&r2=1589837&view=diff
==============================================================================
--- tomcat/trunk/res/checkstyle/org-import-control.xml (original)
+++ tomcat/trunk/res/checkstyle/org-import-control.xml Thu Apr 24 19:16:21 2014
@@ -102,6 +102,7 @@
     <allow pkg="org.apache.tomcat" exact-match="true"/>
     <allow pkg="org.apache.tomcat.util.descriptor"/>
     <allow pkg="org.apache.tomcat.util.scan"/>
+    <allow pkg="org.apache.tomcat.util.security"/>
     <allow pkg="org.apache.tools.ant"/>
     <allow pkg="org.eclipse.jdt"/>
   </subpackage>

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1589837&r1=1589836&r2=1589837&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Apr 24 19:16:21 2014
@@ -131,6 +131,11 @@
         patterns of the form <code>*.a.b</code> which are not valid patterns 
for
         extension mappings. (markt)
       </add>
+      <add>
+        Extend XML factory, parser etc. memory leak protection to cover some
+        additional locations where, theoretically, a memory leak could occur.
+        (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to