提交 fb96db84 编写于 作者: M mchung

7193339: Prepare system classes be defined by a non-null module loader

Reviewed-by: alanb, dholmes, dsamersoff, sspitsyn, psandoz
上级 b1da5910
......@@ -169,7 +169,7 @@ public abstract class MXBeanMapping {
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
}
......
......@@ -52,7 +52,8 @@ public final class IIOPHelper {
AccessController.doPrivileged(new PrivilegedAction<IIOPProxy>() {
public IIOPProxy run() {
try {
Class<?> c = Class.forName(IMPL_CLASS, true, null);
Class<?> c = Class.forName(IMPL_CLASS, true,
IIOPHelper.class.getClassLoader());
return (IIOPProxy)c.newInstance();
} catch (ClassNotFoundException cnf) {
return null;
......
......@@ -228,7 +228,8 @@ public final
* ensure it's ok to access the bootstrap class loader.
*
* @param name fully qualified name of the desired class
* @param initialize whether the class must be initialized
* @param initialize if {@code true} the class will be initialized.
* See Section 12.4 of <em>The Java Language Specification</em>.
* @param loader class loader from which the class must be loaded
* @return class object representing the desired class
*
......@@ -605,7 +606,7 @@ public final
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 +2171,7 @@ public final
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) {
......
......@@ -1403,7 +1403,7 @@ public abstract class ClassLoader {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = getCallerClassLoader();
if (ccl != null && !isAncestor(ccl)) {
if (needsClassLoaderPermissionCheck(ccl, this)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
......@@ -1473,7 +1473,7 @@ public abstract class ClassLoader {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = getCallerClassLoader();
if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
if (needsClassLoaderPermissionCheck(ccl, scl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
......@@ -1523,6 +1523,23 @@ public abstract class ClassLoader {
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
......
......@@ -1449,8 +1449,7 @@ class Thread implements Runnable {
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);
}
}
......
......@@ -576,16 +576,16 @@ public class ManagementFactory {
Class<T> 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<ClassLoader>() {
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 @@ public class ManagementFactory {
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;
......
......@@ -363,7 +363,8 @@ enum PlatformComponent {
try {
// Lazy loading the MXBean interface only when it is needed
return (Class<? extends PlatformManagedObject>)
Class.forName(mxbeanInterfaceName, false, null);
Class.forName(mxbeanInterfaceName, false,
PlatformManagedObject.class.getClassLoader());
} catch (ClassNotFoundException x) {
throw new AssertionError(x);
}
......
......@@ -300,7 +300,8 @@ public abstract class Preferences {
}
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 "
......
......@@ -423,7 +423,7 @@ public class ScriptEngineManager {
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);
......
......@@ -803,7 +803,7 @@ public abstract class MappedMXBeanType {
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
......
......@@ -82,7 +82,7 @@ public final class Unsafe {
*/
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;
}
......
......@@ -217,6 +217,14 @@ public class VM {
return allowArraySyntax;
}
/**
* 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
......
......@@ -144,4 +144,38 @@ public final class ReflectUtil {
}
return true;
}
// Returns true if p is an ancestor of cl i.e. class loader 'p' can
// be found in the cl's delegation chain
private static boolean isAncestor(ClassLoader p, ClassLoader cl) {
ClassLoader acl = cl;
do {
acl = acl.getParent();
if (p == acl) {
return true;
}
} while (acl != null);
return false;
}
/**
* 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;
return !isAncestor(from, to);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册