8011557: Improve reflection utility classes
Reviewed-by: ahgross, alanb
This commit is contained in:
parent
8ab5854ca2
commit
3a6de961eb
@ -2338,7 +2338,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
// skip the package access check on a proxy class in default proxy package
|
// skip the package access check on a proxy class in default proxy package
|
||||||
String pkg = name.substring(0, i);
|
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);
|
s.checkPackageAccess(pkg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -734,25 +734,21 @@ public class Proxy implements java.io.Serializable {
|
|||||||
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
|
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
String pcn = proxyClass.getName();
|
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
|
||||||
if (pcn.startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
|
ClassLoader ccl = caller.getClassLoader();
|
||||||
// all proxy interfaces are public
|
ClassLoader pcl = proxyClass.getClassLoader();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassLoader ccl = caller.getClassLoader();
|
// do permission check if the caller is in a different runtime package
|
||||||
ClassLoader pcl = proxyClass.getClassLoader();
|
// of the proxy class
|
||||||
|
int n = proxyClass.getName().lastIndexOf('.');
|
||||||
|
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
|
||||||
|
|
||||||
// do permission check if the caller is in a different runtime package
|
n = caller.getName().lastIndexOf('.');
|
||||||
// of the proxy class
|
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
|
||||||
int n = pcn.lastIndexOf('.');
|
|
||||||
String pkg = (n == -1) ? "" : pcn.substring(0, n);
|
|
||||||
|
|
||||||
n = caller.getName().lastIndexOf('.');
|
if (pcl != ccl || !pkg.equals(callerPkg)) {
|
||||||
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
|
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;
|
package sun.reflect.misc;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import sun.reflect.Reflection;
|
import sun.reflect.Reflection;
|
||||||
|
|
||||||
public final class ReflectUtil {
|
public final class ReflectUtil {
|
||||||
@ -114,11 +115,26 @@ public final class ReflectUtil {
|
|||||||
return false;
|
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) {
|
public static void checkPackageAccess(Class<?> clazz) {
|
||||||
checkPackageAccess(clazz.getName());
|
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) {
|
public static void checkPackageAccess(String name) {
|
||||||
SecurityManager s = System.getSecurityManager();
|
SecurityManager s = System.getSecurityManager();
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
@ -179,14 +195,31 @@ public final class ReflectUtil {
|
|||||||
return !isAncestor(from, to);
|
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
|
* 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 ccl the caller's class loader
|
||||||
* @param interfaces the list of interfaces that a proxy class implements
|
* @param interfaces the list of interfaces that a proxy class implements
|
||||||
*
|
|
||||||
* @see Proxy#checkProxyAccess
|
|
||||||
*/
|
*/
|
||||||
public static void checkProxyPackageAccess(ClassLoader ccl,
|
public static void checkProxyPackageAccess(ClassLoader ccl,
|
||||||
Class<?>... interfaces)
|
Class<?>... interfaces)
|
||||||
@ -205,4 +238,16 @@ public final class ReflectUtil {
|
|||||||
// Note that bytecode instrumentation tools may exclude 'sun.*'
|
// Note that bytecode instrumentation tools may exclude 'sun.*'
|
||||||
// classes but not generated proxy classes and so keep it in com.sun.*
|
// classes but not generated proxy classes and so keep it in com.sun.*
|
||||||
public static final String PROXY_PACKAGE = "com.sun.proxy";
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user