# HG changeset patch # User xuelei # Date 1381972751 25200 # Node ID 76262685781c3f6a835fd5d0e27b0723d268d01a # Parent 48dc2eacb0e58342144922264118c1cf29fbb546 8025758: Enhance Naming management Summary: Enforce package access control with current context. Also reviewed by Alexander Fomin Reviewed-by: weijun, ahgross diff -r 48dc2eacb0e5 -r 76262685781c src/share/classes/com/sun/naming/internal/FactoryEnumeration.java --- a/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Wed Oct 16 13:26:05 2013 +0400 +++ b/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Wed Oct 16 18:19:11 2013 -0700 @@ -56,9 +56,12 @@ * references so as not to prevent GC of the class loader. Each * weak reference is tagged with the factory's class name so the * class can be reloaded if the reference is cleared. - + * * @param factories A non-null list * @param loader The class loader of the list's contents + * + * This internal method is used with Thread Context Class Loader (TCCL), + * please don't expose this method as public. */ FactoryEnumeration(List> factories, ClassLoader loader) { @@ -79,7 +82,9 @@ try { if (answer == null) { // reload class if weak ref cleared - answer = Class.forName(className, true, loader); + Class cls = Class.forName(className, true, loader); + VersionHelper12.checkPackageAccess(cls); + answer = cls; } // Instantiate Class to get factory answer = ((Class) answer).newInstance(); diff -r 48dc2eacb0e5 -r 76262685781c src/share/classes/com/sun/naming/internal/VersionHelper12.java --- a/src/share/classes/com/sun/naming/internal/VersionHelper12.java Wed Oct 16 13:26:05 2013 +0400 +++ b/src/share/classes/com/sun/naming/internal/VersionHelper12.java Wed Oct 16 18:19:11 2013 -0700 @@ -39,6 +39,7 @@ import java.util.Properties; import javax.naming.*; +import sun.reflect.misc.ReflectUtil; /** * VersionHelper was used by JNDI to accommodate differences between @@ -53,21 +54,39 @@ final class VersionHelper12 extends VersionHelper { - private boolean getSystemPropsFailed = false; + // workaround to disable additional package access control with + // Thread Context Class Loader (TCCL). + private final static boolean noPackageAccessWithTCCL = "true".equals( + AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return System.getProperty( + "com.sun.naming.untieAccessContextWithTCCL"); + } + } + )); - VersionHelper12() {} // Disallow external from creating one of these. + // Disallow external from creating one of these. + VersionHelper12() { + } public Class loadClass(String className) throws ClassNotFoundException { - ClassLoader cl = getContextClassLoader(); - return Class.forName(className, true, cl); + return loadClass(className, getContextClassLoader()); } /** - * Package private. - */ + * Package private. + * + * This internal method is used with Thread Context Class Loader (TCCL), + * please don't expose this method as public. + */ Class loadClass(String className, ClassLoader cl) throws ClassNotFoundException { - return Class.forName(className, true, cl); + Class cls = Class.forName(className, true, cl); + if (!noPackageAccessWithTCCL) { + checkPackageAccess(cls); + } + return cls; } /** @@ -75,13 +94,42 @@ * @param codebase A non-null, space-separated list of URL strings. */ public Class loadClass(String className, String codebase) - throws ClassNotFoundException, MalformedURLException { - ClassLoader cl; + throws ClassNotFoundException, MalformedURLException { ClassLoader parent = getContextClassLoader(); - cl = URLClassLoader.newInstance(getUrlArray(codebase), parent); + ClassLoader cl = + URLClassLoader.newInstance(getUrlArray(codebase), parent); + + return loadClass(className, cl); + } - return Class.forName(className, true, cl); + /** + * check package access of a class that is loaded with Thread Context + * Class Loader (TCCL). + * + * Similar to java.lang.ClassLoader.checkPackageAccess() + */ + static void checkPackageAccess(Class cls) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (ReflectUtil.isNonPublicProxyClass(cls)) { + for (Class intf: cls.getInterfaces()) { + checkPackageAccess(intf); + } + return; + } + + final String name = cls.getName(); + final int i = name.lastIndexOf('.'); + if (i != -1) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + sm.checkPackageAccess(name.substring(0, i)); + return null; + } + }, AccessController.getContext()); + } + } } String getJndiProperty(final int i) { @@ -99,16 +147,12 @@ } String[] getJndiProperties() { - if (getSystemPropsFailed) { - return null; // after one failure, don't bother trying again - } Properties sysProps = AccessController.doPrivileged( new PrivilegedAction() { public Properties run() { try { return System.getProperties(); } catch (SecurityException e) { - getSystemPropsFailed = true; return null; } } @@ -173,7 +217,17 @@ return new InputStreamEnumeration(urls); } + /** + * Package private. + * + * This internal method makes use of Thread Context Class Loader (TCCL), + * please don't expose this method as public. + * + * Please take care of package access control on the current context + * whenever using TCCL. + */ ClassLoader getContextClassLoader() { + return AccessController.doPrivileged( new PrivilegedAction() { public ClassLoader run() { @@ -183,7 +237,6 @@ ); } - /** * Given an enumeration of URLs, an instance of this class represents * an enumeration of their InputStreams. Each operation on the URL