--- old/src/share/classes/com/sun/jmx/mbeanserver/MXBeanMapping.java Wed Aug 22 13:19:21 2012 +++ new/src/share/classes/com/sun/jmx/mbeanserver/MXBeanMapping.java Wed Aug 22 13:19:20 2012 @@ -169,7 +169,7 @@ return (Class) javaType; try { String className = openType.getClassName(); - return Class.forName(className, false, null); + return Class.forName(className, false, MXBeanMapping.class.getClassLoader()); } catch (ClassNotFoundException e) { throw new RuntimeException(e); // should not happen } --- old/src/share/classes/com/sun/jmx/remote/internal/IIOPHelper.java Wed Aug 22 13:19:22 2012 +++ new/src/share/classes/com/sun/jmx/remote/internal/IIOPHelper.java Wed Aug 22 13:19:22 2012 @@ -52,7 +52,7 @@ AccessController.doPrivileged(new PrivilegedAction() { public IIOPProxy run() { try { - Class c = Class.forName(IMPL_CLASS, true, null); + Class c = Class.forName(IMPL_CLASS); return (IIOPProxy)c.newInstance(); } catch (ClassNotFoundException cnf) { return null; --- old/src/share/classes/java/lang/Class.java Wed Aug 22 13:19:23 2012 +++ new/src/share/classes/java/lang/Class.java Wed Aug 22 13:19:23 2012 @@ -605,7 +605,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) { + if (ClassLoader.needsClassLoaderPermissionCheck(ccl, cl)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } } @@ -2170,8 +2170,7 @@ if (s != null) { s.checkMemberAccess(this, which); ClassLoader cl = getClassLoader0(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !cl.isAncestor(ccl))) { + if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) { String name = this.getName(); int i = name.lastIndexOf('.'); if (i != -1) { --- old/src/share/classes/java/lang/ClassLoader.java Wed Aug 22 13:19:25 2012 +++ new/src/share/classes/java/lang/ClassLoader.java Wed Aug 22 13:19:24 2012 @@ -1403,7 +1403,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && !isAncestor(ccl)) { + if (ClassLoader.needsClassLoaderPermissionCheck(ccl, this)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } } @@ -1473,7 +1473,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { + if (ClassLoader.needsClassLoaderPermissionCheck(ccl, scl)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } } @@ -1523,6 +1523,23 @@ return false; } + // Tests if class loader access requires "getClassLoader" permission + // check. A class loader 'from' can access class loader 'to' if + // class loader 'from' is same as class loader 'to' or an ancestor + // of 'to'. The class loader in a system domain can access + // any class loader. + static boolean needsClassLoaderPermissionCheck(ClassLoader from, + ClassLoader to) + { + if (from == to) + return false; + + if (from == null) + return false; + + return !to.isAncestor(from); + } + // Returns the invoker's class loader, or null if none. // NOTE: This must always be invoked when there is exactly one intervening // frame from the core libraries on the stack between this method's --- old/src/share/classes/java/lang/Thread.java Wed Aug 22 13:19:26 2012 +++ new/src/share/classes/java/lang/Thread.java Wed Aug 22 13:19:25 2012 @@ -1449,8 +1449,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != contextClassLoader && - !contextClassLoader.isAncestor(ccl)) { + if (ClassLoader.needsClassLoaderPermissionCheck(ccl, contextClassLoader)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } } --- old/src/share/classes/java/lang/management/ManagementFactory.java Wed Aug 22 13:19:27 2012 +++ new/src/share/classes/java/lang/management/ManagementFactory.java Wed Aug 22 13:19:27 2012 @@ -576,16 +576,16 @@ Class mxbeanInterface) throws java.io.IOException { - final Class interfaceClass = mxbeanInterface; // Only allow MXBean interfaces from rt.jar loaded by the // bootstrap class loader - final ClassLoader loader = + final Class cls = mxbeanInterface; + ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction() { public ClassLoader run() { - return interfaceClass.getClassLoader(); + return cls.getClassLoader(); } }); - if (loader != null) { + if (!sun.misc.VM.isSystemDomainLoader(loader)) { throw new IllegalArgumentException(mxbeanName + " is not a platform MXBean"); } @@ -593,10 +593,10 @@ try { final ObjectName objName = new ObjectName(mxbeanName); // skip the isInstanceOf check for LoggingMXBean - String intfName = interfaceClass.getName(); + String intfName = mxbeanInterface.getName(); if (!connection.isInstanceOf(objName, intfName)) { throw new IllegalArgumentException(mxbeanName + - " is not an instance of " + interfaceClass); + " is not an instance of " + mxbeanInterface); } final Class[] interfaces; --- old/src/share/classes/java/lang/management/PlatformComponent.java Wed Aug 22 13:19:28 2012 +++ new/src/share/classes/java/lang/management/PlatformComponent.java Wed Aug 22 13:19:28 2012 @@ -363,7 +363,8 @@ try { // Lazy loading the MXBean interface only when it is needed return (Class) - Class.forName(mxbeanInterfaceName, false, null); + Class.forName(mxbeanInterfaceName, false, + PlatformManagedObject.class.getClassLoader()); } catch (ClassNotFoundException x) { throw new AssertionError(x); } --- old/src/share/classes/java/util/prefs/Preferences.java Wed Aug 22 13:19:30 2012 +++ new/src/share/classes/java/util/prefs/Preferences.java Wed Aug 22 13:19:29 2012 @@ -300,7 +300,8 @@ } try { return (PreferencesFactory) - Class.forName(platformFactory, false, null).newInstance(); + Class.forName(platformFactory, false, + Preferences.class.getClassLoader()).newInstance(); } catch (Exception e) { throw new InternalError( "Can't instantiate platform default Preferences factory " --- old/src/share/classes/javax/script/ScriptEngineManager.java Wed Aug 22 13:19:31 2012 +++ new/src/share/classes/javax/script/ScriptEngineManager.java Wed Aug 22 13:19:30 2012 @@ -423,7 +423,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader callerLoader = getCallerClassLoader(); - if (callerLoader != null) { + if (!sun.misc.VM.isSystemDomainLoader(callerLoader)) { if (loader != callerLoader || !isAncestor(loader, callerLoader)) { try { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); --- old/src/share/classes/sun/management/MappedMXBeanType.java Wed Aug 22 13:19:32 2012 +++ new/src/share/classes/sun/management/MappedMXBeanType.java Wed Aug 22 13:19:32 2012 @@ -803,7 +803,7 @@ Class c; try { c = Class.forName(t.getClassName(), false, - String.class.getClassLoader()); + MappedMXBeanType.class.getClassLoader()); MappedMXBeanType.newBasicType(c, t); } catch (ClassNotFoundException e) { // the classes that these predefined types declare --- old/src/share/classes/sun/misc/Unsafe.java Wed Aug 22 13:19:33 2012 +++ new/src/share/classes/sun/misc/Unsafe.java Wed Aug 22 13:19:33 2012 @@ -82,7 +82,7 @@ */ public static Unsafe getUnsafe() { Class cc = sun.reflect.Reflection.getCallerClass(2); - if (cc.getClassLoader() != null) + if (!VM.isSystemDomainLoader(cc.getClassLoader())) throw new SecurityException("Unsafe"); return theUnsafe; } --- old/src/share/classes/sun/misc/VM.java Wed Aug 22 13:19:34 2012 +++ new/src/share/classes/sun/misc/VM.java Wed Aug 22 13:19:34 2012 @@ -218,6 +218,14 @@ } /** + * Returns true if the given class loader is in the system domain + * in which all permissions are granted. + */ + public static boolean isSystemDomainLoader(ClassLoader loader) { + return loader == null; + } + + /** * Returns the system property of the specified key saved at * system initialization time. This method should only be used * for the system properties that are not changed during runtime. --- old/src/share/classes/sun/reflect/misc/ReflectUtil.java Wed Aug 22 13:19:36 2012 +++ new/src/share/classes/sun/reflect/misc/ReflectUtil.java Wed Aug 22 13:19:35 2012 @@ -144,4 +144,34 @@ } return true; } + + /** + * Returns true if package access check is needed for reflective + * access from a class loader 'from' to classes or members in + * a class defined by class loader 'to'. This method returns true + * if 'from' is not the same as or an ancestor of 'to'. All code + * in a system domain are granted with all permission and so this + * method returns false if 'from' class loader is a class loader + * loading system classes. On the other hand, if a class loader + * attempts to access system domain classes, it requires package + * access check and this method will return true. + */ + public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) { + if (from == null || from == to) + return false; + + if (to == null) + return true; + + // If from class loader is in the to's class loader's delegation chain. + // no need for package access check. + ClassLoader acl = to; + do { + acl = acl.getParent(); + if (from == acl) { + return false; + } + } while (acl != null); + return true; + } }