Author: kkolinko
Date: Sun May 11 17:15:52 2014
New Revision: 1593821
URL: http://svn.apache.org/r1593821
Log:
Defensive coding around some XML activities that are triggered by web
applications and are therefore at potential risk of a memory leak.
Patch by markt.
Added:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/
- copied from r1593818,
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/security/
Modified:
tomcat/tc6.0.x/trunk/STATUS.txt
tomcat/tc6.0.x/trunk/java/org/apache/catalina/security/SecurityClassLoad.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELFunctionMapper.java
tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java
tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Sun May 11 17:15:52 2014
@@ -28,12 +28,6 @@ None
PATCHES PROPOSED TO BACKPORT:
[ New proposals should be added at the end of the list ]
-* Defensive coding around some XML activities that are triggered by web
- applications and are therefore at potential risk of a memory leak.
- http://people.apache.org/~markt/patches/2014-04-25-memory-leak-tc6-v1.patch
- +1: markt, kkolinko, fhanik
- -1:
-
* Followup to r1589635
To simplify code and align it with TC7 & 8.
(Discussed in Re:r1589635)
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/security/SecurityClassLoad.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/security/SecurityClassLoad.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/catalina/security/SecurityClassLoad.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/catalina/security/SecurityClassLoad.java
Sun May 11 17:15:52 2014
@@ -96,17 +96,10 @@ public final class SecurityClassLoad {
private final static void loadSessionPackage(ClassLoader loader)
throws Exception {
- String basePackage = "org.apache.catalina.";
- loader.loadClass
- (basePackage + "session.StandardSession");
- loader.loadClass
- (basePackage + "session.StandardSession$PrivilegedSetTccl");
- loader.loadClass
- (basePackage +
- "session.StandardSession$1");
- loader.loadClass
- (basePackage +
- "session.StandardManager$PrivilegedDoUnload");
+ String basePackage = "org.apache.catalina.session.";
+ loader.loadClass(basePackage + "StandardSession");
+ loader.loadClass(basePackage + "StandardSession$1");
+ loader.loadClass(basePackage + "StandardManager$PrivilegedDoUnload");
}
@@ -229,6 +222,10 @@ public final class SecurityClassLoad {
Class<?> clazz = loader.loadClass(
basePackage + "util.http.FastHttpDateFormat");
clazz.newInstance();
+
+ // security
+ loader.loadClass(basePackage + "util.security.PrivilegedGetTccl");
+ loader.loadClass(basePackage + "util.security.PrivilegedSetTccl");
}
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
Sun May 11 17:15:52 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.Iterator;
import java.util.Locale;
@@ -68,6 +69,8 @@ import org.apache.naming.resources.Cache
import org.apache.naming.resources.ProxyDirContext;
import org.apache.naming.resources.Resource;
import org.apache.naming.resources.ResourceAttributes;
+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;
@@ -1326,11 +1329,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);
@@ -1343,6 +1362,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/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
Sun May 11 17:15:52 2014
@@ -60,6 +60,7 @@ import org.apache.catalina.core.Standard
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.security.SecurityUtil;
import org.apache.catalina.session.ManagerBase.SessionTiming;
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
/**
* Standard implementation of the <b>Session</b> interface. This object is
@@ -1744,28 +1745,9 @@ public class StandardSession
(sm.getString("standardSession.attributeEvent"), t);
}
}
-
}
-
-
- private static class PrivilegedSetTccl
- implements PrivilegedAction<Void> {
-
- private ClassLoader cl;
-
- PrivilegedSetTccl(ClassLoader cl) {
- this.cl = cl;
- }
-
- public Void run() {
- Thread.currentThread().setContextClassLoader(cl);
- return null;
- }
- }
-
}
-
// ------------------------------------------------------------ Protected Class
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELFunctionMapper.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELFunctionMapper.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELFunctionMapper.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELFunctionMapper.java
Sun May 11 17:15:52 2014
@@ -24,6 +24,7 @@ import javax.servlet.jsp.tagext.Function
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
/**
* This class generates functions mappers for the EL expressions in the page.
@@ -307,13 +308,5 @@ public class ELFunctionMapper {
return clazz.getCanonicalName();
}
}
-
- private static class PrivilegedGetTccl
- implements PrivilegedAction<ClassLoader> {
-
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- }
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
Sun May 11 17:15:52 2014
@@ -20,7 +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;
@@ -36,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;
@@ -1454,33 +1456,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/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java Sun
May 11 17:15:52 2014
@@ -18,6 +18,7 @@ package org.apache.jasper.xmlparser;
import java.io.IOException;
import java.io.InputStream;
+import java.security.AccessController;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -29,6 +30,8 @@ import org.apache.jasper.compiler.Locali
import org.apache.tomcat.util.descriptor.DigesterFactory;
import org.apache.tomcat.util.descriptor.LocalResolver;
import org.apache.tomcat.util.descriptor.XmlErrorHandler;
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
@@ -105,7 +108,23 @@ public class ParserUtils {
Document document = null;
// Perform an XML parse of this document, via JAXP
+ 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(ParserUtils.class.getClassLoader());
+ AccessController.doPrivileged(pa);
+ } else {
+ Thread.currentThread().setContextClassLoader(
+ ParserUtils.class.getClassLoader());
+ }
+
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
@@ -129,23 +148,30 @@ public class ParserUtils {
// throw the first to indicate there was a error during
processing
throw handler.getErrors().iterator().next();
}
- } catch (ParserConfigurationException ex) {
- throw new JasperException
- (Localizer.getMessage("jsp.error.parse.xml", location), ex);
- } catch (SAXParseException ex) {
- throw new JasperException
- (Localizer.getMessage("jsp.error.parse.xml.line",
- location,
- Integer.toString(ex.getLineNumber()),
- Integer.toString(ex.getColumnNumber())),
- ex);
- } catch (SAXException sx) {
- throw new JasperException
- (Localizer.getMessage("jsp.error.parse.xml", location), sx);
+ } catch (ParserConfigurationException ex) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.parse.xml", location), ex);
+ } catch (SAXParseException ex) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.parse.xml.line",
+ location,
+ Integer.toString(ex.getLineNumber()),
+ Integer.toString(ex.getColumnNumber())),
+ ex);
+ } catch (SAXException sx) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.parse.xml", location), sx);
} catch (IOException io) {
- throw new JasperException
- (Localizer.getMessage("jsp.error.parse.xml", location), io);
- }
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.parse.xml", location), io);
+ } finally {
+ if (Constants.IS_SECURITY_ENABLED) {
+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
+ AccessController.doPrivileged(pa);
+ } else {
+ Thread.currentThread().setContextClassLoader(original);
+ }
+ }
// Convert the resulting document to a graph of TreeNodes
return (convert(null, document.getDocumentElement()));
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java?rev=1593821&r1=1593818&r2=1593821&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java
Sun May 11 17:15:52 2014
@@ -19,7 +19,6 @@ package org.apache.tomcat.util.security;
import java.security.PrivilegedAction;
public class PrivilegedGetTccl implements PrivilegedAction<ClassLoader> {
- @Override
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java?rev=1593821&r1=1593818&r2=1593821&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java
Sun May 11 17:15:52 2014
@@ -26,7 +26,6 @@ public class PrivilegedSetTccl implement
this.cl = cl;
}
- @Override
public Void run() {
Thread.currentThread().setContextClassLoader(cl);
return null;
Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1593821&r1=1593820&r2=1593821&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Sun May 11 17:15:52 2014
@@ -99,6 +99,11 @@
Ensure that a TLD parser obtained from the cache has the correct value
of <code>blockExternal</code>. (markt/kkolinko)
</fix>
+ <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]