提交 f8df6562 编写于 作者: M mchung

8011557: Improve reflection utility classes

Reviewed-by: ahgross, alanb
上级 0e4ea563
......@@ -2338,7 +2338,7 @@ public final class Class<T> implements java.io.Serializable,
if (i != -1) {
// 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)) {
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
......
......@@ -734,25 +734,21 @@ public class Proxy implements java.io.Serializable {
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String pcn = proxyClass.getName();
if (pcn.startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
// all proxy interfaces are public
return;
}
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader();
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader();
// do permission check if the caller is in a different runtime package
// of the proxy class
int n = pcn.lastIndexOf('.');
String pkg = (n == -1) ? "" : pcn.substring(0, n);
// do permission check if the caller is in a different runtime package
// of the proxy class
int n = proxyClass.getName().lastIndexOf('.');
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}
......
......@@ -27,6 +27,7 @@
package sun.reflect.misc;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import sun.reflect.Reflection;
public final class ReflectUtil {
......@@ -114,11 +115,26 @@ public final class ReflectUtil {
return false;
}
/**
* Checks package access on the given class.
*
* If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements
* a non-public interface (i.e. may be in a non-restricted package),
* also check the package access on the proxy interfaces.
*/
public static void checkPackageAccess(Class<?> clazz) {
checkPackageAccess(clazz.getName());
if (isNonPublicProxyClass(clazz)) {
checkProxyPackageAccess(clazz);
}
}
/**
* Checks package access on the given classname.
* This method is typically called when the Class instance is not
* available and the caller attempts to load a class on behalf
* the true caller (application).
*/
public static void checkPackageAccess(String name) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
......@@ -179,14 +195,31 @@ public final class ReflectUtil {
return !isAncestor(from, to);
}
/**
* Check package access on the proxy interfaces that the given proxy class
* implements.
*
* @param clazz Proxy class object
*/
public static void checkProxyPackageAccess(Class<?> clazz) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
// check proxy interfaces if the given class is a proxy class
if (Proxy.isProxyClass(clazz)) {
for (Class<?> intf : clazz.getInterfaces()) {
checkPackageAccess(intf);
}
}
}
}
/**
* Access check on the interfaces that a proxy class implements and throw
* {@code SecurityException} if it accesses a restricted package.
* {@code SecurityException} if it accesses a restricted package from
* the caller's class loader.
*
* @param ccl the caller's class loader
* @param interfaces the list of interfaces that a proxy class implements
*
* @see Proxy#checkProxyAccess
*/
public static void checkProxyPackageAccess(ClassLoader ccl,
Class<?>... interfaces)
......@@ -205,4 +238,16 @@ public final class ReflectUtil {
// Note that bytecode instrumentation tools may exclude 'sun.*'
// classes but not generated proxy classes and so keep it in com.sun.*
public static final String PROXY_PACKAGE = "com.sun.proxy";
/**
* Test if the given class is a proxy class that implements
* non-public interface. Such proxy class may be in a non-restricted
* package that bypasses checkPackageAccess.
*/
public static boolean isNonPublicProxyClass(Class<?> cls) {
String name = cls.getName();
int i = name.lastIndexOf('.');
String pkg = (i != -1) ? name.substring(0, i) : "";
return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册