|
|
f90819 |
--- java/org/apache/catalina/security/SecurityClassLoad.java.orig 2014-07-24 18:29:38.830023000 -0400
|
|
|
f90819 |
+++ java/org/apache/catalina/security/SecurityClassLoad.java 2014-07-24 18:31:18.655356000 -0400
|
|
|
f90819 |
@@ -25,9 +25,7 @@
|
|
|
f90819 |
*
|
|
|
f90819 |
* @author Glenn L. Nielsen
|
|
|
f90819 |
* @author Jean-Francois Arcand
|
|
|
f90819 |
- * @version $Id: SecurityClassLoad.java 1410548 2012-11-16 19:38:51Z markt $
|
|
|
f90819 |
*/
|
|
|
f90819 |
-
|
|
|
f90819 |
public final class SecurityClassLoad {
|
|
|
f90819 |
|
|
|
f90819 |
public static void securityClassLoad(ClassLoader loader)
|
|
|
f90819 |
@@ -41,6 +39,7 @@
|
|
|
f90819 |
loadCoyotePackage(loader);
|
|
|
f90819 |
loadLoaderPackage(loader);
|
|
|
f90819 |
loadRealmPackage(loader);
|
|
|
f90819 |
+ loadServletsPackage(loader);
|
|
|
f90819 |
loadSessionPackage(loader);
|
|
|
f90819 |
loadUtilPackage(loader);
|
|
|
f90819 |
loadValvesPackage(loader);
|
|
|
f90819 |
@@ -76,12 +75,6 @@
|
|
|
f90819 |
"AsyncContextImpl$1");
|
|
|
f90819 |
loader.loadClass
|
|
|
f90819 |
(basePackage +
|
|
|
f90819 |
- "AsyncContextImpl$PrivilegedGetTccl");
|
|
|
f90819 |
- loader.loadClass
|
|
|
f90819 |
- (basePackage +
|
|
|
f90819 |
- "AsyncContextImpl$PrivilegedSetTccl");
|
|
|
f90819 |
- loader.loadClass
|
|
|
f90819 |
- (basePackage +
|
|
|
f90819 |
"AsyncListenerWrapper");
|
|
|
f90819 |
loader.loadClass
|
|
|
f90819 |
(basePackage +
|
|
|
f90819 |
@@ -124,14 +117,24 @@
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
+ private static final void loadServletsPackage(ClassLoader loader)
|
|
|
f90819 |
+ throws Exception {
|
|
|
f90819 |
+ final String basePackage = "org.apache.catalina.servlets.";
|
|
|
f90819 |
+ // Avoid a possible memory leak in the DefaultServlet when running with
|
|
|
f90819 |
+ // a security manager. The DefaultServlet needs to load an XML parser
|
|
|
f90819 |
+ // when running under a security manager. We want this to be loaded by
|
|
|
f90819 |
+ // the container rather than a web application to prevent a memory leak
|
|
|
f90819 |
+ // via web application class loader.
|
|
|
f90819 |
+ loader.loadClass(basePackage + "DefaultServlet");
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
+
|
|
|
f90819 |
private static final void loadSessionPackage(ClassLoader loader)
|
|
|
f90819 |
throws Exception {
|
|
|
f90819 |
final String basePackage = "org.apache.catalina.session.";
|
|
|
f90819 |
loader.loadClass
|
|
|
f90819 |
(basePackage + "StandardSession");
|
|
|
f90819 |
loader.loadClass
|
|
|
f90819 |
- (basePackage + "StandardSession$PrivilegedSetTccl");
|
|
|
f90819 |
- loader.loadClass
|
|
|
f90819 |
(basePackage + "StandardSession$1");
|
|
|
f90819 |
loader.loadClass
|
|
|
f90819 |
(basePackage + "StandardManager$PrivilegedDoUnload");
|
|
|
f90819 |
@@ -280,10 +283,9 @@
|
|
|
f90819 |
loader.loadClass(basePackage +
|
|
|
f90819 |
"util.net.NioBlockingSelector$BlockPoller$3");
|
|
|
f90819 |
loader.loadClass(basePackage + "util.net.SSLSupport$CipherData");
|
|
|
f90819 |
- loader.loadClass
|
|
|
f90819 |
- (basePackage + "util.net.JIoEndpoint$PrivilegedSetTccl");
|
|
|
f90819 |
- loader.loadClass
|
|
|
f90819 |
- (basePackage + "util.net.AprEndpoint$PrivilegedSetTccl");
|
|
|
f90819 |
+ // security
|
|
|
f90819 |
+ loader.loadClass(basePackage + "util.security.PrivilegedGetTccl");
|
|
|
f90819 |
+ loader.loadClass(basePackage + "util.security.PrivilegedSetTccl");
|
|
|
f90819 |
}
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
--- java/org/apache/catalina/servlets/DefaultServlet.java.orig 2014-07-24 18:29:38.875020000 -0400
|
|
|
f90819 |
+++ java/org/apache/catalina/servlets/DefaultServlet.java 2014-07-24 18:31:18.695352000 -0400
|
|
|
f90819 |
@@ -14,8 +14,6 @@
|
|
|
f90819 |
* See the License for the specific language governing permissions and
|
|
|
f90819 |
* limitations under the License.
|
|
|
f90819 |
*/
|
|
|
f90819 |
-
|
|
|
f90819 |
-
|
|
|
f90819 |
package org.apache.catalina.servlets;
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
@@ -34,6 +32,7 @@
|
|
|
f90819 |
import java.io.Reader;
|
|
|
f90819 |
import java.io.StringReader;
|
|
|
f90819 |
import java.io.StringWriter;
|
|
|
f90819 |
+import java.security.AccessController;
|
|
|
f90819 |
import java.util.ArrayList;
|
|
|
f90819 |
import java.util.Iterator;
|
|
|
f90819 |
import java.util.Locale;
|
|
|
f90819 |
@@ -76,11 +75,14 @@
|
|
|
f90819 |
import org.apache.naming.resources.Resource;
|
|
|
f90819 |
import org.apache.naming.resources.ResourceAttributes;
|
|
|
f90819 |
import org.apache.tomcat.util.res.StringManager;
|
|
|
f90819 |
-
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
|
|
|
f90819 |
import org.w3c.dom.Document;
|
|
|
f90819 |
import org.xml.sax.InputSource;
|
|
|
f90819 |
import org.xml.sax.SAXException;
|
|
|
f90819 |
import org.xml.sax.ext.EntityResolver2;
|
|
|
f90819 |
+
|
|
|
f90819 |
+
|
|
|
f90819 |
/**
|
|
|
f90819 |
* The default resource-serving servlet for most web applications,
|
|
|
f90819 |
* used to serve static resources such as HTML pages and images.
|
|
|
f90819 |
@@ -122,9 +124,7 @@
|
|
|
f90819 |
*
|
|
|
f90819 |
* @author Craig R. McClanahan
|
|
|
f90819 |
* @author Remy Maucherat
|
|
|
f90819 |
- * @version $Id: DefaultServlet.java 1301255 2012-03-15 22:47:40Z markt $
|
|
|
f90819 |
*/
|
|
|
f90819 |
-
|
|
|
f90819 |
public class DefaultServlet
|
|
|
f90819 |
extends HttpServlet {
|
|
|
f90819 |
|
|
|
f90819 |
@@ -132,10 +132,10 @@
|
|
|
f90819 |
|
|
|
f90819 |
private static final DocumentBuilderFactory factory;
|
|
|
f90819 |
|
|
|
f90819 |
- private static final SecureEntityResolver secureEntityResolver =
|
|
|
f90819 |
- new SecureEntityResolver();
|
|
|
f90819 |
- // ----------------------------------------------------- Instance Variables
|
|
|
f90819 |
+ private static final SecureEntityResolver secureEntityResolver;
|
|
|
f90819 |
+
|
|
|
f90819 |
|
|
|
f90819 |
+ // ----------------------------------------------------- Instance Variables
|
|
|
f90819 |
|
|
|
f90819 |
/**
|
|
|
f90819 |
* The debugging detail level for this servlet.
|
|
|
f90819 |
@@ -225,6 +225,11 @@
|
|
|
f90819 |
*/
|
|
|
f90819 |
protected static final ArrayList<Range> FULL = new ArrayList<Range>();
|
|
|
f90819 |
|
|
|
f90819 |
+ /**
|
|
|
f90819 |
+ * Flag to determine if server information is presented.
|
|
|
f90819 |
+ */
|
|
|
f90819 |
+ protected boolean showServerInfo = true;
|
|
|
f90819 |
+
|
|
|
f90819 |
|
|
|
f90819 |
// ----------------------------------------------------- Static Initializer
|
|
|
f90819 |
|
|
|
f90819 |
@@ -239,9 +244,16 @@
|
|
|
f90819 |
urlEncoder.addSafeCharacter('.');
|
|
|
f90819 |
urlEncoder.addSafeCharacter('*');
|
|
|
f90819 |
urlEncoder.addSafeCharacter('/');
|
|
|
f90819 |
- factory = DocumentBuilderFactory.newInstance();
|
|
|
f90819 |
- factory.setNamespaceAware(true);
|
|
|
f90819 |
- factory.setValidating(false);
|
|
|
f90819 |
+
|
|
|
f90819 |
+ if (Globals.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ factory = DocumentBuilderFactory.newInstance();
|
|
|
f90819 |
+ factory.setNamespaceAware(true);
|
|
|
f90819 |
+ factory.setValidating(false);
|
|
|
f90819 |
+ secureEntityResolver = new SecureEntityResolver();
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ factory = null;
|
|
|
f90819 |
+ secureEntityResolver = null;
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
@@ -270,6 +282,7 @@
|
|
|
f90819 |
protected static final int BUFFER_SIZE = 4096;
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
+
|
|
|
f90819 |
// --------------------------------------------------------- Public Methods
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
@@ -345,6 +358,9 @@
|
|
|
f90819 |
throw new UnavailableException("No resources");
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
+ if (getServletConfig().getInitParameter("showServerInfo") != null) {
|
|
|
f90819 |
+ showServerInfo = Boolean.parseBoolean(getServletConfig().getInitParameter("showServerInfo"));
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
@@ -1251,7 +1267,6 @@
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
-
|
|
|
f90819 |
/**
|
|
|
f90819 |
* Decide which way to render. HTML or XML.
|
|
|
f90819 |
*/
|
|
|
f90819 |
@@ -1259,13 +1274,15 @@
|
|
|
f90819 |
throws IOException, ServletException {
|
|
|
f90819 |
|
|
|
f90819 |
Source xsltSource = findXsltInputStream(cacheEntry.context);
|
|
|
f90819 |
- if (xsltSource ==null) {
|
|
|
f90819 |
+
|
|
|
f90819 |
+ if (xsltSource == null) {
|
|
|
f90819 |
return renderHtml(contextPath, cacheEntry);
|
|
|
f90819 |
}
|
|
|
f90819 |
return renderXml(contextPath, cacheEntry, xsltSource);
|
|
|
f90819 |
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
+
|
|
|
f90819 |
/**
|
|
|
f90819 |
* Return an InputStream to an HTML representation of the contents
|
|
|
f90819 |
* of this directory.
|
|
|
f90819 |
@@ -1362,11 +1379,27 @@
|
|
|
f90819 |
sb.append("]]></readme>");
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
-
|
|
|
f90819 |
sb.append("</listing>");
|
|
|
f90819 |
|
|
|
f90819 |
-
|
|
|
f90819 |
+ // Prevent possible memory leak. Ensure Transformer and
|
|
|
f90819 |
+ // TransformerFactory are not loaded from the web application.
|
|
|
f90819 |
+ ClassLoader original;
|
|
|
f90819 |
+ if (Globals.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedGetTccl pa = new PrivilegedGetTccl();
|
|
|
f90819 |
+ original = AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ original = Thread.currentThread().getContextClassLoader();
|
|
|
f90819 |
+ }
|
|
|
f90819 |
try {
|
|
|
f90819 |
+ if (Globals.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa =
|
|
|
f90819 |
+ new PrivilegedSetTccl(DefaultServlet.class.getClassLoader());
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(
|
|
|
f90819 |
+ DefaultServlet.class.getClassLoader());
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
TransformerFactory tFactory = TransformerFactory.newInstance();
|
|
|
f90819 |
Source xmlSource = new StreamSource(new StringReader(sb.toString()));
|
|
|
f90819 |
Transformer transformer = tFactory.newTransformer(xsltSource);
|
|
|
f90819 |
@@ -1379,6 +1412,13 @@
|
|
|
f90819 |
return (new ByteArrayInputStream(stream.toByteArray()));
|
|
|
f90819 |
} catch (TransformerException e) {
|
|
|
f90819 |
throw new ServletException("XSL transformer error", e);
|
|
|
f90819 |
+ } finally {
|
|
|
f90819 |
+ if (Globals.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(original);
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
@@ -1530,7 +1570,9 @@
|
|
|
f90819 |
sb.append(" ");
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
- sb.append("").append(ServerInfo.getServerInfo()).append("");
|
|
|
f90819 |
+ if (showServerInfo) {
|
|
|
f90819 |
+ sb.append("").append(ServerInfo.getServerInfo()).append("");
|
|
|
f90819 |
+ }
|
|
|
f90819 |
sb.append("</body>\r\n");
|
|
|
f90819 |
sb.append("</html>\r\n");
|
|
|
f90819 |
|
|
|
f90819 |
@@ -1588,7 +1630,7 @@
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
/**
|
|
|
f90819 |
- * Return the xsl template inputstream (if possible)
|
|
|
f90819 |
+ * Return a Source for the xsl template (if possible)
|
|
|
f90819 |
*/
|
|
|
f90819 |
protected Source findXsltInputStream(DirContext directory)
|
|
|
f90819 |
throws IOException {
|
|
|
f90819 |
@@ -1630,31 +1672,32 @@
|
|
|
f90819 |
/* Open and read in file in one fell swoop to reduce chance
|
|
|
f90819 |
* chance of leaving handle open.
|
|
|
f90819 |
*/
|
|
|
f90819 |
- if (globalXsltFile != null) {
|
|
|
f90819 |
- File f = validateGlobalXsltFile();
|
|
|
f90819 |
- if (f != null ){
|
|
|
f90819 |
- FileInputStream fis = null;
|
|
|
f90819 |
- try {
|
|
|
f90819 |
- fis = new FileInputStream(f);
|
|
|
f90819 |
- byte b[] = new byte[(int)f.length()]; /* danger! */
|
|
|
f90819 |
- fis.read(b);
|
|
|
f90819 |
- return new StreamSource(new ByteArrayInputStream(b));
|
|
|
f90819 |
- } finally {
|
|
|
f90819 |
- if (fis != null) {
|
|
|
f90819 |
- try {
|
|
|
f90819 |
- fis.close();
|
|
|
f90819 |
- } catch(IOException ioe) {
|
|
|
f90819 |
- // ignore
|
|
|
f90819 |
- }
|
|
|
f90819 |
- }
|
|
|
f90819 |
- }
|
|
|
f90819 |
- }
|
|
|
f90819 |
+ if (globalXsltFile != null) {
|
|
|
f90819 |
+ File f = validateGlobalXsltFile();
|
|
|
f90819 |
+ if (f != null){
|
|
|
f90819 |
+ FileInputStream fis = null;
|
|
|
f90819 |
+ try {
|
|
|
f90819 |
+ fis = new FileInputStream(f);
|
|
|
f90819 |
+ byte b[] = new byte[(int)f.length()]; /* danger! */
|
|
|
f90819 |
+ fis.read(b);
|
|
|
f90819 |
+ return new StreamSource(new ByteArrayInputStream(b));
|
|
|
f90819 |
+ } finally {
|
|
|
f90819 |
+ if (fis != null) {
|
|
|
f90819 |
+ try {
|
|
|
f90819 |
+ fis.close();
|
|
|
f90819 |
+ } catch (IOException ioe) {
|
|
|
f90819 |
+ // Ignore
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
return null;
|
|
|
f90819 |
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
+
|
|
|
f90819 |
private File validateGlobalXsltFile() {
|
|
|
f90819 |
|
|
|
f90819 |
File result = null;
|
|
|
f90819 |
@@ -1705,6 +1748,7 @@
|
|
|
f90819 |
return candidate;
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
+
|
|
|
f90819 |
private Source secureXslt(InputStream is) {
|
|
|
f90819 |
// Need to filter out any external entities
|
|
|
f90819 |
Source result = null;
|
|
|
f90819 |
@@ -1740,7 +1784,6 @@
|
|
|
f90819 |
|
|
|
f90819 |
// -------------------------------------------------------- protected Methods
|
|
|
f90819 |
|
|
|
f90819 |
-
|
|
|
f90819 |
/**
|
|
|
f90819 |
* Check if sendfile can be used.
|
|
|
f90819 |
*/
|
|
|
f90819 |
@@ -2240,9 +2283,6 @@
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
|
|
|
f90819 |
- // ------------------------------------------------------ Range Inner Class
|
|
|
f90819 |
-
|
|
|
f90819 |
-
|
|
|
f90819 |
protected static class Range {
|
|
|
f90819 |
|
|
|
f90819 |
public long start;
|
|
|
f90819 |
@@ -2259,6 +2299,7 @@
|
|
|
f90819 |
}
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
+
|
|
|
f90819 |
/**
|
|
|
f90819 |
* This is secure in the sense that any attempt to use an external entity
|
|
|
f90819 |
* will trigger an exception.
|
|
|
f90819 |
@@ -2288,4 +2329,3 @@
|
|
|
f90819 |
}
|
|
|
f90819 |
}
|
|
|
f90819 |
}
|
|
|
f90819 |
-
|
|
|
f90819 |
--- webapps/docs/changelog.xml.orig 2014-07-24 18:29:38.917021000 -0400
|
|
|
f90819 |
+++ webapps/docs/changelog.xml 2014-07-24 18:36:52.526481000 -0400
|
|
|
f90819 |
@@ -158,6 +158,15 @@
|
|
|
f90819 |
<bug>55176</bug>: Correctly handle regular expressions within SSI
|
|
|
f90819 |
expressions that contain an equals character. (markt)
|
|
|
f90819 |
</fix>
|
|
|
f90819 |
+ <fix>
|
|
|
f90819 |
+ Ensure that a TLD parser obtained from the cache has the correct value
|
|
|
f90819 |
+ of blockExternal . (markt)
|
|
|
f90819 |
+ </fix>
|
|
|
f90819 |
+ <add>
|
|
|
f90819 |
+ Extend XML factory, parser etc. memory leak protection to cover some
|
|
|
f90819 |
+ additional locations where, theoretically, a memory leak could occur.
|
|
|
f90819 |
+ (markt)
|
|
|
f90819 |
+ </add>
|
|
|
f90819 |
</changelog>
|
|
|
f90819 |
</subsection>
|
|
|
f90819 |
<subsection name="Coyote">
|
|
|
f90819 |
@@ -352,6 +361,10 @@
|
|
|
f90819 |
request if the CRLF terminating the request line was split across
|
|
|
f90819 |
multiple packets. Patch by Konstantin Preißer. (markt)
|
|
|
f90819 |
</fix>
|
|
|
f90819 |
+ <fix>
|
|
|
f90819 |
+ Only create XML parsing objects if required and fix associated potential
|
|
|
f90819 |
+ memory leak in the default Servlet. (markt)
|
|
|
f90819 |
+ </fix>
|
|
|
f90819 |
</changelog>
|
|
|
f90819 |
</subsection>
|
|
|
f90819 |
<subsection name="Jasper">
|
|
|
f90819 |
--- java/org/apache/jasper/xmlparser/ParserUtils.java.orig 2014-07-24 18:29:38.952016000 -0400
|
|
|
f90819 |
+++ java/org/apache/jasper/xmlparser/ParserUtils.java 2014-07-24 18:31:18.746354000 -0400
|
|
|
f90819 |
@@ -18,6 +18,7 @@
|
|
|
f90819 |
|
|
|
f90819 |
import java.io.IOException;
|
|
|
f90819 |
import java.io.InputStream;
|
|
|
f90819 |
+import java.security.AccessController;
|
|
|
f90819 |
|
|
|
f90819 |
import javax.xml.parsers.DocumentBuilder;
|
|
|
f90819 |
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
f90819 |
@@ -29,6 +30,8 @@
|
|
|
f90819 |
import org.apache.tomcat.util.descriptor.DigesterFactory;
|
|
|
f90819 |
import org.apache.tomcat.util.descriptor.LocalResolver;
|
|
|
f90819 |
import org.apache.tomcat.util.descriptor.XmlErrorHandler;
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
|
|
|
f90819 |
import org.w3c.dom.Comment;
|
|
|
f90819 |
import org.w3c.dom.Document;
|
|
|
f90819 |
import org.w3c.dom.NamedNodeMap;
|
|
|
f90819 |
@@ -36,7 +39,6 @@
|
|
|
f90819 |
import org.w3c.dom.NodeList;
|
|
|
f90819 |
import org.w3c.dom.Text;
|
|
|
f90819 |
import org.xml.sax.EntityResolver;
|
|
|
f90819 |
-import org.xml.sax.ErrorHandler;
|
|
|
f90819 |
import org.xml.sax.InputSource;
|
|
|
f90819 |
import org.xml.sax.SAXException;
|
|
|
f90819 |
import org.xml.sax.SAXParseException;
|
|
|
f90819 |
@@ -48,16 +50,10 @@
|
|
|
f90819 |
* use a separate class loader for the parser to be used.
|
|
|
f90819 |
*
|
|
|
f90819 |
* @author Craig R. McClanahan
|
|
|
f90819 |
- * @version $Id: ParserUtils.java 1549529 2013-12-09 10:05:56Z markt $
|
|
|
f90819 |
*/
|
|
|
f90819 |
public class ParserUtils {
|
|
|
f90819 |
|
|
|
f90819 |
/**
|
|
|
f90819 |
- * An error handler for use when parsing XML documents.
|
|
|
f90819 |
- */
|
|
|
f90819 |
- static ErrorHandler errorHandler = new XmlErrorHandler();
|
|
|
f90819 |
-
|
|
|
f90819 |
- /**
|
|
|
f90819 |
* An entity resolver for use when parsing XML documents.
|
|
|
f90819 |
*/
|
|
|
f90819 |
static EntityResolver entityResolver;
|
|
|
f90819 |
@@ -99,15 +95,46 @@
|
|
|
f90819 |
Document document = null;
|
|
|
f90819 |
|
|
|
f90819 |
// Perform an XML parse of this document, via JAXP
|
|
|
f90819 |
+ ClassLoader original;
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedGetTccl pa = new PrivilegedGetTccl();
|
|
|
f90819 |
+ original = AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ original = Thread.currentThread().getContextClassLoader();
|
|
|
f90819 |
+ }
|
|
|
f90819 |
try {
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa =
|
|
|
f90819 |
+ new PrivilegedSetTccl(ParserUtils.class.getClassLoader());
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(
|
|
|
f90819 |
+ ParserUtils.class.getClassLoader());
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
DocumentBuilderFactory factory =
|
|
|
f90819 |
DocumentBuilderFactory.newInstance();
|
|
|
f90819 |
factory.setNamespaceAware(true);
|
|
|
f90819 |
factory.setValidating(validating);
|
|
|
f90819 |
+ if (validating) {
|
|
|
f90819 |
+ // Enable DTD validation
|
|
|
f90819 |
+ factory.setFeature(
|
|
|
f90819 |
+ "http://xml.org/sax/features/validation",
|
|
|
f90819 |
+ true);
|
|
|
f90819 |
+ // Enable schema validation
|
|
|
f90819 |
+ factory.setFeature(
|
|
|
f90819 |
+ "http://apache.org/xml/features/validation/schema",
|
|
|
f90819 |
+ true);
|
|
|
f90819 |
+ }
|
|
|
f90819 |
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
|
f90819 |
builder.setEntityResolver(entityResolverInstance);
|
|
|
f90819 |
- builder.setErrorHandler(errorHandler);
|
|
|
f90819 |
+ XmlErrorHandler handler = new XmlErrorHandler();
|
|
|
f90819 |
+ builder.setErrorHandler(handler);
|
|
|
f90819 |
document = builder.parse(is);
|
|
|
f90819 |
+ if (!handler.getErrors().isEmpty()) {
|
|
|
f90819 |
+ // throw the first to indicate there was a error during processing
|
|
|
f90819 |
+ throw handler.getErrors().iterator().next();
|
|
|
f90819 |
+ }
|
|
|
f90819 |
} catch (ParserConfigurationException ex) {
|
|
|
f90819 |
throw new JasperException
|
|
|
f90819 |
(Localizer.getMessage("jsp.error.parse.xml", location), ex);
|
|
|
f90819 |
@@ -124,6 +151,13 @@
|
|
|
f90819 |
} catch (IOException io) {
|
|
|
f90819 |
throw new JasperException
|
|
|
f90819 |
(Localizer.getMessage("jsp.error.parse.xml", location), io);
|
|
|
f90819 |
+ } finally {
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(original);
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
// Convert the resulting document to a graph of TreeNodes
|
|
|
f90819 |
--- java/org/apache/jasper/compiler/JspDocumentParser.java.orig 2014-07-24 18:29:38.974016000 -0400
|
|
|
f90819 |
+++ java/org/apache/jasper/compiler/JspDocumentParser.java 2014-07-24 18:31:18.774352000 -0400
|
|
|
f90819 |
@@ -20,6 +20,7 @@
|
|
|
f90819 |
import java.io.FileNotFoundException;
|
|
|
f90819 |
import java.io.IOException;
|
|
|
f90819 |
import java.io.InputStream;
|
|
|
f90819 |
+import java.security.AccessController;
|
|
|
f90819 |
import java.util.Iterator;
|
|
|
f90819 |
import java.util.List;
|
|
|
f90819 |
import java.util.jar.JarFile;
|
|
|
f90819 |
@@ -35,6 +36,8 @@
|
|
|
f90819 |
import org.apache.jasper.JspCompilationContext;
|
|
|
f90819 |
import org.apache.tomcat.util.descriptor.DigesterFactory;
|
|
|
f90819 |
import org.apache.tomcat.util.descriptor.LocalResolver;
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
|
|
|
f90819 |
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
|
|
|
f90819 |
import org.xml.sax.Attributes;
|
|
|
f90819 |
import org.xml.sax.InputSource;
|
|
|
f90819 |
import org.xml.sax.Locator;
|
|
|
f90819 |
@@ -129,7 +132,7 @@
|
|
|
f90819 |
Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
|
|
|
f90819 |
boolean blockExternal;
|
|
|
f90819 |
if (blockExternalString == null) {
|
|
|
f90819 |
- blockExternal = Constants.IS_SECURITY_ENABLED;
|
|
|
f90819 |
+ blockExternal = true;
|
|
|
f90819 |
} else {
|
|
|
f90819 |
blockExternal = Boolean.parseBoolean(blockExternalString);
|
|
|
f90819 |
}
|
|
|
f90819 |
@@ -1464,33 +1467,58 @@
|
|
|
f90819 |
JspDocumentParser jspDocParser)
|
|
|
f90819 |
throws Exception {
|
|
|
f90819 |
|
|
|
f90819 |
- SAXParserFactory factory = SAXParserFactory.newInstance();
|
|
|
f90819 |
-
|
|
|
f90819 |
- factory.setNamespaceAware(true);
|
|
|
f90819 |
- // Preserve xmlns attributes
|
|
|
f90819 |
- factory.setFeature(
|
|
|
f90819 |
- "http://xml.org/sax/features/namespace-prefixes",
|
|
|
f90819 |
- true);
|
|
|
f90819 |
-
|
|
|
f90819 |
- factory.setValidating(validating);
|
|
|
f90819 |
- if (validating) {
|
|
|
f90819 |
- // Enable DTD validation
|
|
|
f90819 |
- factory.setFeature(
|
|
|
f90819 |
- "http://xml.org/sax/features/validation",
|
|
|
f90819 |
- true);
|
|
|
f90819 |
- // Enable schema validation
|
|
|
f90819 |
- factory.setFeature(
|
|
|
f90819 |
- "http://apache.org/xml/features/validation/schema",
|
|
|
f90819 |
- true);
|
|
|
f90819 |
+ ClassLoader original;
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedGetTccl pa = new PrivilegedGetTccl();
|
|
|
f90819 |
+ original = AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ original = Thread.currentThread().getContextClassLoader();
|
|
|
f90819 |
}
|
|
|
f90819 |
+ try {
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa =
|
|
|
f90819 |
+ new PrivilegedSetTccl(JspDocumentParser.class.getClassLoader());
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(
|
|
|
f90819 |
+ JspDocumentParser.class.getClassLoader());
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
+ SAXParserFactory factory = SAXParserFactory.newInstance();
|
|
|
f90819 |
|
|
|
f90819 |
- // Configure the parser
|
|
|
f90819 |
- SAXParser saxParser = factory.newSAXParser();
|
|
|
f90819 |
- XMLReader xmlReader = saxParser.getXMLReader();
|
|
|
f90819 |
- xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser);
|
|
|
f90819 |
- xmlReader.setErrorHandler(jspDocParser);
|
|
|
f90819 |
+ factory.setNamespaceAware(true);
|
|
|
f90819 |
+ // Preserve xmlns attributes
|
|
|
f90819 |
+ factory.setFeature(
|
|
|
f90819 |
+ "http://xml.org/sax/features/namespace-prefixes",
|
|
|
f90819 |
+ true);
|
|
|
f90819 |
|
|
|
f90819 |
- return saxParser;
|
|
|
f90819 |
+ factory.setValidating(validating);
|
|
|
f90819 |
+ if (validating) {
|
|
|
f90819 |
+ // Enable DTD validation
|
|
|
f90819 |
+ factory.setFeature(
|
|
|
f90819 |
+ "http://xml.org/sax/features/validation",
|
|
|
f90819 |
+ true);
|
|
|
f90819 |
+ // Enable schema validation
|
|
|
f90819 |
+ factory.setFeature(
|
|
|
f90819 |
+ "http://apache.org/xml/features/validation/schema",
|
|
|
f90819 |
+ true);
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
+ // Configure the parser
|
|
|
f90819 |
+ SAXParser saxParser = factory.newSAXParser();
|
|
|
f90819 |
+ XMLReader xmlReader = saxParser.getXMLReader();
|
|
|
f90819 |
+ xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser);
|
|
|
f90819 |
+ xmlReader.setErrorHandler(jspDocParser);
|
|
|
f90819 |
+
|
|
|
f90819 |
+ return saxParser;
|
|
|
f90819 |
+ } finally {
|
|
|
f90819 |
+ if (Constants.IS_SECURITY_ENABLED) {
|
|
|
f90819 |
+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
|
|
|
f90819 |
+ AccessController.doPrivileged(pa);
|
|
|
f90819 |
+ } else {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(original);
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+ }
|
|
|
f90819 |
}
|
|
|
f90819 |
|
|
|
f90819 |
/*
|
|
|
f90819 |
--- java/org/apache/tomcat/util/security/PrivilegedGetTccl.java.orig 2014-07-24 18:59:42.923103000 -0400
|
|
|
f90819 |
+++ java/org/apache/tomcat/util/security/PrivilegedGetTccl.java 2014-07-24 18:56:17.729411000 -0400
|
|
|
f90819 |
@@ -0,0 +1,28 @@
|
|
|
f90819 |
+/*
|
|
|
f90819 |
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
f90819 |
+ * contributor license agreements. See the NOTICE file distributed with
|
|
|
f90819 |
+ * this work for additional information regarding copyright ownership.
|
|
|
f90819 |
+ * The ASF licenses this file to You under the Apache License, Version 2.0
|
|
|
f90819 |
+ * (the "License"); you may not use this file except in compliance with
|
|
|
f90819 |
+ * the License. You may obtain a copy of the License at
|
|
|
f90819 |
+ *
|
|
|
f90819 |
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
f90819 |
+ *
|
|
|
f90819 |
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
f90819 |
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
f90819 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
f90819 |
+ * See the License for the specific language governing permissions and
|
|
|
f90819 |
+ * limitations under the License.
|
|
|
f90819 |
+ */
|
|
|
f90819 |
+package org.apache.tomcat.util.security;
|
|
|
f90819 |
+
|
|
|
f90819 |
+import java.security.PrivilegedAction;
|
|
|
f90819 |
+
|
|
|
f90819 |
+public class PrivilegedGetTccl implements PrivilegedAction<ClassLoader> {
|
|
|
f90819 |
+ @Override
|
|
|
f90819 |
+ public ClassLoader run() {
|
|
|
f90819 |
+ return Thread.currentThread().getContextClassLoader();
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+}
|
|
|
f90819 |
+
|
|
|
f90819 |
+
|
|
|
f90819 |
--- java/org/apache/tomcat/util/security/PrivilegedSetTccl.java.orig 2014-07-24 18:59:42.928107000 -0400
|
|
|
f90819 |
+++ java/org/apache/tomcat/util/security/PrivilegedSetTccl.java 2014-07-24 18:56:17.736421000 -0400
|
|
|
f90819 |
@@ -0,0 +1,34 @@
|
|
|
f90819 |
+/*
|
|
|
f90819 |
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
f90819 |
+ * contributor license agreements. See the NOTICE file distributed with
|
|
|
f90819 |
+ * this work for additional information regarding copyright ownership.
|
|
|
f90819 |
+ * The ASF licenses this file to You under the Apache License, Version 2.0
|
|
|
f90819 |
+ * (the "License"); you may not use this file except in compliance with
|
|
|
f90819 |
+ * the License. You may obtain a copy of the License at
|
|
|
f90819 |
+ *
|
|
|
f90819 |
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
f90819 |
+ *
|
|
|
f90819 |
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
f90819 |
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
f90819 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
f90819 |
+ * See the License for the specific language governing permissions and
|
|
|
f90819 |
+ * limitations under the License.
|
|
|
f90819 |
+ */
|
|
|
f90819 |
+package org.apache.tomcat.util.security;
|
|
|
f90819 |
+
|
|
|
f90819 |
+import java.security.PrivilegedAction;
|
|
|
f90819 |
+
|
|
|
f90819 |
+public class PrivilegedSetTccl implements PrivilegedAction<Void> {
|
|
|
f90819 |
+
|
|
|
f90819 |
+ private ClassLoader cl;
|
|
|
f90819 |
+
|
|
|
f90819 |
+ public PrivilegedSetTccl(ClassLoader cl) {
|
|
|
f90819 |
+ this.cl = cl;
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+
|
|
|
f90819 |
+ @Override
|
|
|
f90819 |
+ public Void run() {
|
|
|
f90819 |
+ Thread.currentThread().setContextClassLoader(cl);
|
|
|
f90819 |
+ return null;
|
|
|
f90819 |
+ }
|
|
|
f90819 |
+}
|
|
|
f90819 |
\ No newline at end of file
|