DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=28256>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=28256 WebappClassLoader.findClassInternal() permission problems Summary: WebappClassLoader.findClassInternal() permission problems Product: Tomcat 5 Version: 5.0.19 Platform: Sun OS/Version: Solaris Status: NEW Severity: Blocker Priority: Other Component: Catalina AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] CC: [EMAIL PROTECTED] In summary, because WebappClassLoader extends the behavior of URLClassLoader's findClass method, it needs to insulate its extended behavior in a doPrivileged block (with a stored AccessControlContext) just like URLClassLoader.findClass does. The findClassInternal method of WebappClassLoader does not execute as a privileged operation, but a brief glance the source to its superclass, URLClassLoader, shows that it needs to. A class loader needs to insulate itself from the arbitrary security context in which it might be invoked (such as during lazy class loading). The specific problem we are encountering is a bit complex, but in brief, the bug occurs when attempting to load a class using a class loader whose parent is a servlet's WebappClassLoader-- the loading fails with a security exception. (This situation can come about when, for example, a servlet attempts to download the proxy for a Jini service, for which the service proxy's class gets loaded using the RMIClassLoader.loadClass API.) When the child class loader, which is also a URLClassLoader, defines a class that it has loaded itself, that operation executes as a privileged operation restricted by the protection domains in the access control context stored in that URLClassLoader instance (this access control context was snapshotted by URLClassLoader's constructor). This access control context's domain's may not include permissions to read from where the parent WebappClassLoader looks for classes and resources-- in the case of an RMI class loader, for example, it typically does not include such permissions, because it will only include permissions to read from the loader's own URLs. When this defineClass operation causes a recursive loading operation (such as to load a supertype of the class being defined), delegation to the parent WebappClassLoader results in its findClassInternal method being invoked. Because that method does not execute as a privileged operation itself, its attempt to read the class definition from some location (such as the .../WEB-INF/classes/ tree) fails with a security exception, because the child loader's privileged operation is still in force. [Because the access control context used by RMI class loaders uses a domain with a set of permissions that were assembled synthetically, it is impossible to grant the necessary permissions through the security policy (as a workaround), except by granting them to all code, which is clearly undesirable.] The fix is a relatively simple one. First we need to add a private class variable to hold the loaders context: private AccessControlContext acc; next we need to retrieve and store this context in the Class's two constructors: public WebappClassLoader() { ... if (securityManager != null) { refreshPolicy(); } acc = AccessController.getContext(); // see URLClassLoader >>>----^ add this line above }^M Finally we need to wrap the logic of the findClassInternal() method in a doPriveleged operation: protected Class findClassInternal(final String name) throws ClassNotFoundException { try { return (Class) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException { if (!validate(name)) throw new ClassNotFoundException(name); Etc... }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } } We have developed a simple servlet that employs the RMIClassloader to demonstrate the problem. We've tested the fixes supplied above and they do correct the problem. We would be happy to furnish the test to you, if you like. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]