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: [email protected]
For additional commands, e-mail: [email protected]