8015256: Better class accessibility

Improve protection domain check in forName()

Reviewed-by: mchung, acorn, jdn
This commit is contained in:
Coleen Phillimore 2014-07-22 16:24:48 +04:00
parent 6037f786bb
commit 3e5a530aff
3 changed files with 29 additions and 12 deletions

View File

@ -262,8 +262,8 @@ public final class Class<T> implements java.io.Serializable,
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
@ -333,22 +333,27 @@ public final class Class<T> implements java.io.Serializable,
ClassLoader loader)
throws ClassNotFoundException
{
if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
Class<?> caller = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager
// is present. Avoid the overhead of making this call otherwise.
caller = Reflection.getCallerClass();
if (sun.misc.VM.isSystemDomainLoader(loader)) {
ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader);
return forName0(name, initialize, loader, caller);
}
/** Called after security checks have been made. */
/** Called after security check for system loader access checks have been made. */
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader)
ClassLoader loader,
Class<?> caller)
throws ClassNotFoundException;
/**

View File

@ -385,6 +385,19 @@ JVM_ResolveClass(JNIEnv *env, jclass cls);
JNIEXPORT jclass JNICALL
JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
/*
* Find a class from a given class loader. Throws ClassNotFoundException.
* name: name of class
* init: whether initialization is done
* loader: class loader to look up the class. This may not be the same as the caller's
* class loader.
* caller: initiating class. The initiating class may be null when a security
* manager is not installed.
*/
JNIEXPORT jclass JNICALL
JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
jobject loader, jclass caller);
/*
* Find a class from a given class loader. Throw ClassNotFoundException
* or NoClassDefFoundError depending on the value of the last

View File

@ -93,7 +93,7 @@ Java_java_lang_Class_registerNatives(JNIEnv *env, jclass cls)
JNIEXPORT jclass JNICALL
Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname,
jboolean initialize, jobject loader)
jboolean initialize, jobject loader, jclass caller)
{
char *clname;
jclass cls = 0;
@ -131,8 +131,7 @@ Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname,
goto done;
}
cls = JVM_FindClassFromClassLoader(env, clname, initialize,
loader, JNI_FALSE);
cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller);
done:
if (clname != buf) {