diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java
index ec9d97256553255d1b10bfef16c312b77d3666c8..a22493feb6f2947f2f605e0d7b94d8616a368ac6 100644
--- a/src/share/classes/java/lang/Class.java
+++ b/src/share/classes/java/lang/Class.java
@@ -60,7 +60,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Proxy;
import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
/**
* Instances of the class {@code Class} represent classes and
@@ -247,11 +249,11 @@ public final
ClassLoader loader)
throws ClassNotFoundException
{
- if (loader == null) {
+ if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null) {
+ if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
@@ -316,7 +318,7 @@ public final
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
}
return newInstance0();
}
@@ -1295,7 +1297,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1370,7 +1372,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1421,7 +1423,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1470,7 +1472,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1529,7 +1531,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1614,7 +1616,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1668,7 +1670,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1710,7 +1712,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0();
}
@@ -1754,7 +1756,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1802,7 +1804,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1847,7 +1849,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -1891,7 +1893,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1946,7 +1948,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1996,7 +1998,7 @@ public final
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2166,18 +2168,26 @@ public final
*
Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl) {
+ private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0();
- if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
+ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
- s.checkPackageAccess(name.substring(0, i));
+ // skip the package access check on a proxy class in default proxy package
+ String pkg = name.substring(0, i);
+ if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
+ s.checkPackageAccess(pkg);
+ }
}
}
+ // check package access on the proxy interfaces
+ if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+ }
}
}
diff --git a/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
index 8e068238b1f2b4c03a54d3ba37e35f21dce9f2e2..e305ced7de44c6ea7327e67ed02b01705dbf0573 100644
--- a/src/share/classes/java/lang/invoke/MethodHandleProxies.java
+++ b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
@@ -26,8 +26,12 @@
package java.lang.invoke;
import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance;
import java.util.ArrayList;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
/**
* This class consists exclusively of static methods that help adapt
@@ -137,6 +141,18 @@ public class MethodHandleProxies {
T asInterfaceInstance(final Class intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
+ SecurityManager smgr = System.getSecurityManager();
+ if (smgr != null) {
+ final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
+ final Class> caller = Reflection.getCallerClass(CALLER_FRAME);
+ final ClassLoader ccl = caller.getClassLoader();
+ ReflectUtil.checkProxyPackageAccess(ccl, intfc);
+ }
+ ClassLoader proxyLoader = intfc.getClassLoader();
+ if (proxyLoader == null) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
+ proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
+ }
final Method[] methods = getSingleNameMethods(intfc);
if (methods == null)
throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
@@ -148,27 +164,44 @@ public class MethodHandleProxies {
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
}
- return intfc.cast(Proxy.newProxyInstance(
- intfc.getClassLoader(),
- new Class>[]{ intfc, WrapperInstance.class },
- new InvocationHandler() {
- private Object getArg(String name) {
- if ((Object)name == "getWrapperInstanceTarget") return target;
- if ((Object)name == "getWrapperInstanceType") return intfc;
- throw new AssertionError();
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- for (int i = 0; i < methods.length; i++) {
- if (method.equals(methods[i]))
- return vaTargets[i].invokeExact(args);
- }
- if (method.getDeclaringClass() == WrapperInstance.class)
- return getArg(method.getName());
- if (isObjectMethod(method))
- return callObjectMethod(proxy, method, args);
- throw new InternalError("bad proxy method: "+method);
+ final InvocationHandler ih = new InvocationHandler() {
+ private Object getArg(String name) {
+ if ((Object)name == "getWrapperInstanceTarget") return target;
+ if ((Object)name == "getWrapperInstanceType") return intfc;
+ throw new AssertionError();
+ }
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ for (int i = 0; i < methods.length; i++) {
+ if (method.equals(methods[i]))
+ return vaTargets[i].invokeExact(args);
}
- }));
+ if (method.getDeclaringClass() == WrapperInstance.class)
+ return getArg(method.getName());
+ if (isObjectMethod(method))
+ return callObjectMethod(proxy, method, args);
+ throw new InternalError("bad proxy method: "+method);
+ }
+ };
+
+ Object proxy;
+ if (smgr != null) {
+ // sun.invoke.WrapperInstance is a restricted interface not accessible
+ // by any non-null class loader.
+ final ClassLoader loader = proxyLoader;
+ proxy = AccessController.doPrivileged(new PrivilegedAction