diff -r 0419f45c7761 -r 44dfee24cb71 jdk/src/share/classes/java/lang/reflect/Proxy.java --- 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