Author: markt Date: Fri Jan 17 15:37:20 2014 New Revision: 1559153 URL: http://svn.apache.org/r1559153 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55943 Better implementation of the class loader check that prevents web applications from trying to override J2SE implementation classes. Refactor the way a null parent class loader was handled which enables a number of null checks and object creation calls to be removed
Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1559134 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1559153&r1=1559152&r2=1559153&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Fri Jan 17 15:37:20 2014 @@ -227,14 +227,26 @@ public class WebappClassLoader public WebappClassLoader() { super(new URL[0]); - this.parent = getParent(); - system = getSystemClassLoader(); - securityManager = System.getSecurityManager(); + ClassLoader p = getParent(); + if (p == null) { + p = getSystemClassLoader(); + } + this.parent = p; + + ClassLoader j = String.class.getClassLoader(); + if (j == null) { + j = getSystemClassLoader(); + while (j.getParent() != null) { + j = j.getParent(); + } + } + this.j2seClassLoader = j; + + securityManager = System.getSecurityManager(); if (securityManager != null) { refreshPolicy(); } - } @@ -251,11 +263,22 @@ public class WebappClassLoader super(new URL[0], parent); - this.parent = getParent(); + ClassLoader p = getParent(); + if (p == null) { + p = getSystemClassLoader(); + } + this.parent = p; - system = getSystemClassLoader(); - securityManager = System.getSecurityManager(); + ClassLoader j = String.class.getClassLoader(); + if (j == null) { + j = getSystemClassLoader(); + while (j.getParent() != null) { + j = j.getParent(); + } + } + this.j2seClassLoader = j; + securityManager = System.getSecurityManager(); if (securityManager != null) { refreshPolicy(); } @@ -413,6 +436,15 @@ public class WebappClassLoader /** + * The bootstrap class loader used to load the J2SE classes. In some + * implementations this class loader is always <code>null</null> and in + * those cases {@link ClassLoader#getParent()} will be called recursively on + * the system class loader and the last non-null result used. + */ + protected final ClassLoader j2seClassLoader; + + + /** * Has this component been started? */ protected boolean started = false; @@ -1396,10 +1428,7 @@ public class WebappClassLoader if (delegate) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - url = loader.getResource(name); + url = parent.getResource(name); if (url != null) { if (log.isDebugEnabled()) log.debug(" --> Returning '" + url.toString() + "'"); @@ -1433,10 +1462,7 @@ public class WebappClassLoader // (3) Delegate to parent unconditionally if not already attempted if( !delegate ) { - ClassLoader loader = parent; - if (loader == null) - loader = system; - url = loader.getResource(name); + url = parent.getResource(name); if (url != null) { if (log.isDebugEnabled()) log.debug(" --> Returning '" + url.toString() + "'"); @@ -1480,10 +1506,7 @@ public class WebappClassLoader if (delegate) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - stream = loader.getResourceAsStream(name); + stream = parent.getResourceAsStream(name); if (stream != null) { // FIXME - cache??? if (log.isDebugEnabled()) @@ -1515,10 +1538,7 @@ public class WebappClassLoader if (!delegate) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader unconditionally " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - stream = loader.getResourceAsStream(name); + stream = parent.getResourceAsStream(name); if (stream != null) { // FIXME - cache??? if (log.isDebugEnabled()) @@ -1617,7 +1637,7 @@ public class WebappClassLoader // (0.2) Try loading the class with the system class loader, to prevent // the webapp from overriding J2SE classes try { - clazz = system.loadClass(name); + clazz = j2seClassLoader.loadClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); @@ -1648,11 +1668,8 @@ public class WebappClassLoader if (delegateLoad) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader1 " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; try { - clazz = Class.forName(name, false, loader); + clazz = Class.forName(name, false, parent); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Loading class from parent"); @@ -1685,11 +1702,8 @@ public class WebappClassLoader if (!delegateLoad) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader at end: " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; try { - clazz = Class.forName(name, false, loader); + clazz = Class.forName(name, false, parent); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Loading class from parent"); 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=1559153&r1=1559152&r2=1559153&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jan 17 15:37:20 2014 @@ -71,6 +71,13 @@ <code>/ROOT</code> as equivalent to <code>/</code>. (markt) </fix> <fix> + <bug>55943</bug>: Improve the implementation of the class loader check + that prevents web applications from trying to override J2SE + implementation classes. As part of this fix, refactor the way a null + parent class loader is handled which enables a number of null checks and + object creation calls to be removed. (markt) + </fix> + <fix> <bug>55958</bug>: Differentiate between <code>foo.war</code> the WAR file and <code>foo.war</code> the directory. (markt) </fix> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org