--- a/jdk/src/share/classes/java/lang/reflect/Proxy.java Wed Apr 17 10:15:33 2013 +0800
+++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java Tue Apr 16 21:39:52 2013 -0700
@@ -39,6 +39,8 @@
import java.util.List;
import java.util.WeakHashMap;
import sun.misc.ProxyGenerator;
+import sun.misc.VM;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
@@ -408,28 +410,21 @@
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*/
+ @CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
- return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
- }
-
- private static void checkProxyLoader(ClassLoader ccl,
- ClassLoader loader)
- {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- if (loader == null && ccl != null) {
- if (!ProxyAccessHelper.allowNullLoader) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
}
+
+ return getProxyClass0(loader, interfaces);
}
/*
- * Generate a proxy class (caller-sensitive).
+ * Check permissions required to create a Proxy class.
*
* To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
@@ -446,17 +441,28 @@
* will throw IllegalAccessError when the generated proxy class is
* being defined via the defineClass0 method.
*/
- private static Class<?> getProxyClass0(ClassLoader loader,
- Class<?>... interfaces) {
+ private static void checkProxyAccess(Class<?> caller,
+ ClassLoader loader,
+ Class<?>... interfaces)
+ {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
- final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
- final ClassLoader ccl = caller.getClassLoader();
- checkProxyLoader(ccl, loader);
+ ClassLoader ccl = caller.getClassLoader();
+ if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
+ if (!ProxyAccessHelper.allowNullLoader) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
+ }
+ /**
+ * Generate a proxy class. Must call the checkProxyAccess method
+ * to perform permission checks before calling this.
+ */
+ private static Class<?> getProxyClass0(ClassLoader loader,
+ Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
@@ -698,6 +704,7 @@
* if the invocation handler, {@code h}, is
* {@code null}
*/
+ @CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
@@ -707,10 +714,15 @@
throw new NullPointerException();
}
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ }
+
/*
* Look up or generate the designated proxy class.
*/
- Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
+ Class<?> cl = getProxyClass0(loader, interfaces);
/*
* Invoke its constructor with the designated invocation handler.
@@ -718,7 +730,6 @@
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
- SecurityManager sm = System.getSecurityManager();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission