--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Oct 11 09:47:26 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 15 09:27:32 2013 +0100
@@ -597,7 +597,7 @@
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) {
@@ -651,7 +651,7 @@
// No permissions.
newModes = 0;
}
- checkUnprivilegedlookupClass(requestedLookupClass);
+ checkUnprivilegedlookupClass(requestedLookupClass, newModes);
return new Lookup(requestedLookupClass, newModes);
}
@@ -667,10 +667,19 @@
/** 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);
+ }
+ }
}
/**
@@ -1759,6 +1768,12 @@
if (MethodHandleNatives.refKindIsField(refKind)) {
return getDirectFieldNoSecurityManager(refKind, defc, member);
} else if (MethodHandleNatives.refKindIsMethod(refKind)) {
+ if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+ MethodHandle mh = findVirtualForMH(member.getName(), member.getMethodType());
+ if (mh != null) {
+ return mh;
+ }
+ }
return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
} else if (refKind == REF_newInvokeSpecial) {
return getDirectConstructorNoSecurityManager(defc, member);