Author: markt
Date: Fri Apr 25 13:49:02 2014
New Revision: 1590028
URL: http://svn.apache.org/r1590028
Log:
Defensive coding around some XML activities that are triggered by web
applications and are therefore at potential risk of a memory leak.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1589837,1589980
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1590028&r1=1590027&r2=1590028&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
Fri Apr 25 13:49:02 2014
@@ -32,6 +32,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.Iterator;
import java.util.Locale;
@@ -74,6 +75,8 @@ import org.apache.naming.resources.Proxy
import org.apache.naming.resources.Resource;
import org.apache.naming.resources.ResourceAttributes;
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;
@@ -1367,11 +1370,27 @@ public class DefaultServlet
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);
@@ -1384,6 +1403,13 @@ public class DefaultServlet
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/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1590028&r1=1590027&r2=1590028&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
Fri Apr 25 13:49:02 2014
@@ -20,6 +20,7 @@ import java.io.CharArrayWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.security.AccessController;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;
@@ -35,6 +36,8 @@ import org.apache.jasper.JasperException
import org.apache.jasper.JspCompilationContext;
import org.apache.tomcat.util.descriptor.DigesterFactory;
import org.apache.tomcat.util.descriptor.LocalResolver;
+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;
@@ -1464,33 +1467,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/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1590028&r1=1590027&r2=1590028&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Apr 25 13:49:02 2014
@@ -116,6 +116,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]