提交 1f092314 编写于 作者: M mchung

8017196: Ensure Proxies are handled appropriately

Reviewed-by: dfuchs, jrose, jdn, ahgross, chegar
上级 bf47e2a1
......@@ -433,7 +433,7 @@ public class MethodHandles {
Lookup(Class<?> lookupClass) {
this(lookupClass, ALL_MODES);
// make sure we haven't accidentally picked up a privileged class:
checkUnprivilegedlookupClass(lookupClass);
checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
}
private Lookup(Class<?> lookupClass, int allowedModes) {
......@@ -487,7 +487,7 @@ public class MethodHandles {
// No permissions.
newModes = 0;
}
checkUnprivilegedlookupClass(requestedLookupClass);
checkUnprivilegedlookupClass(requestedLookupClass, newModes);
return new Lookup(requestedLookupClass, newModes);
}
......@@ -503,10 +503,19 @@ public class MethodHandles {
/** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
String name = lookupClass.getName();
if (name.startsWith("java.lang.invoke."))
throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
// For caller-sensitive MethodHandles.lookup()
// disallow lookup more restricted packages
if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
if (name.startsWith("java.") ||
(name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
}
}
}
/**
......
......@@ -347,11 +347,11 @@ public class Proxy implements java.io.Serializable {
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access.</li>
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to any one of the
* given proxy interfaces.</li>
* s.checkPackageAccess()} denies access to {@code intf}.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
......@@ -680,11 +680,11 @@ public class Proxy implements java.io.Serializable {
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access;</li>
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to any one of the
* given proxy interfaces.</li>
* s.checkPackageAccess()} denies access to {@code intf};</li>
* <li> any of the given proxy interfaces is non-public and the
* caller class is not in the same {@linkplain Package runtime package}
* as the non-public interface and the invocation of
......@@ -795,7 +795,14 @@ public class Proxy implements java.io.Serializable {
* @return the invocation handler for the proxy instance
* @throws IllegalArgumentException if the argument is not a
* proxy instance
* @throws SecurityException if a security manager, <em>s</em>, is present
* and the caller's class loader is not the same as or an
* ancestor of the class loader for the invocation handler
* and invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the invocation
* handler's class.
*/
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
......@@ -806,8 +813,19 @@ public class Proxy implements java.io.Serializable {
throw new IllegalArgumentException("not a proxy instance");
}
Proxy p = (Proxy) proxy;
return p.h;
final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih;
}
private static native Class<?> defineClass0(ClassLoader loader, String name,
......
......@@ -26,8 +26,10 @@
package sun.reflect.misc;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import sun.reflect.Reflection;
public final class ReflectUtil {
......@@ -250,4 +252,50 @@ public final class ReflectUtil {
String pkg = (i != -1) ? name.substring(0, i) : "";
return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE);
}
/**
* Check if the given method is a method declared in the proxy interface
* implemented by the given proxy instance.
*
* @param proxy a proxy instance
* @param method an interface method dispatched to a InvocationHandler
*
* @throws IllegalArgumentException if the given proxy or method is invalid.
*/
public static void checkProxyMethod(Object proxy, Method method) {
// check if it is a valid proxy instance
if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("Not a Proxy instance");
}
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalArgumentException("Can't handle static method");
}
Class<?> c = method.getDeclaringClass();
if (c == Object.class) {
String name = method.getName();
if (name.equals("hashCode") || name.equals("equals") || name.equals("toString")) {
return;
}
}
if (isSuperInterface(proxy.getClass(), c)) {
return;
}
// disallow any method not declared in one of the proxy intefaces
throw new IllegalArgumentException("Can't handle: " + method);
}
private static boolean isSuperInterface(Class<?> c, Class<?> intf) {
for (Class<?> i : c.getInterfaces()) {
if (i == intf) {
return true;
}
if (isSuperInterface(i, intf)) {
return true;
}
}
return false;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册