提交 6a4b3466 编写于 作者: J jrose

8025112: JSR 292 spec updates for security manager and caller sensitivity

Summary: align CONSTANT_MethodHandle and Lookup.find* API calls, clarify security manager & @CallerSensitive interactions
Reviewed-by: mchung, twisti
上级 31532c96
......@@ -1330,6 +1330,11 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
return null; // DMH returns DMH.member
}
/*non-public*/
Class<?> internalCallerClass() {
return null; // caller-bound MH for @CallerSensitive method returns caller
}
/*non-public*/
MethodHandle withInternalMemberName(MemberName member) {
if (member != null) {
......
......@@ -381,6 +381,10 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MemberName internalMemberName() {
return asFixedArity().internalMemberName();
}
@Override
Class<?> internalCallerClass() {
return asFixedArity().internalCallerClass();
}
/*non-public*/
@Override
......@@ -831,7 +835,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle vamh = prepareForInvoker(mh);
// Cache the result of makeInjectedInvoker once per argument class.
MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName());
return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass);
}
private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
......@@ -886,10 +890,12 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
// Undo the adapter effect of prepareForInvoker:
private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) {
private static MethodHandle restoreToType(MethodHandle vamh, MethodType type,
MemberName member,
Class<?> hostClass) {
MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
mh = mh.asType(type);
mh = mh.withInternalMemberName(member);
mh = new WrappedMember(mh, type, member, hostClass);
return mh;
}
......@@ -958,11 +964,13 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static class WrappedMember extends MethodHandle {
private final MethodHandle target;
private final MemberName member;
private final Class<?> callerClass;
private WrappedMember(MethodHandle target, MethodType type, MemberName member) {
private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) {
super(type, reinvokerForm(target));
this.target = target;
this.member = member;
this.callerClass = callerClass;
}
@Override
......@@ -980,19 +988,23 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return member;
}
@Override
Class<?> internalCallerClass() {
return callerClass;
}
@Override
boolean isInvokeSpecial() {
return target.isInvokeSpecial();
}
@Override
MethodHandle viewAsType(MethodType newType) {
return new WrappedMember(target, newType, member);
return new WrappedMember(target, newType, member, callerClass);
}
}
static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
if (member.equals(target.internalMemberName()))
return target;
return new WrappedMember(target, target.type(), member);
return new WrappedMember(target, target.type(), member, null);
}
}
......@@ -61,6 +61,18 @@ import static java.lang.invoke.MethodHandleStatics.*;
* Cracking must be done via a {@code Lookup} object equivalent to that which created
* the target method handle, or which has enough access permissions to recreate
* an equivalent method handle.
* <p>
* If the underlying method is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>,
* the direct method handle will have been "bound" to a particular caller class, the
* {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}
* of the lookup object used to create it.
* Cracking this method handle with a different lookup class will fail
* even if the underlying method is public (like {@code Class.forName}).
* <p>
* The requirement of lookup object matching provides a "fast fail" behavior
* for programs which may otherwise trust erroneous revelation of a method
* handle with symbolic information (or caller binding) from an unexpected scope.
* Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation.
*
* <h1><a name="refkinds"></a>Reference kinds</h1>
* The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
......
......@@ -107,6 +107,11 @@ public class MethodHandleProxies {
* such as abstract classes with single abstract methods.
* Future versions of this API may also equip wrapper instances
* with one or more additional public "marker" interfaces.
* <p>
* If a security manager is installed, this method is caller sensitive.
* During any invocation of the target method handle via the returned wrapper,
* the original creator of the wrapper (the caller) will be visible
* to context checks requested by the security manager.
*
* @param <T> the desired type of the wrapper, a single-method interface
* @param intfc a class object representing {@code T}
......
......@@ -47,7 +47,10 @@ public class TestPrivateMember {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(void.class);
try {
MethodHandle mh = lookup.findStatic(Class.class, "checkInitted", mt);
Class<?> checkInittedHolder = TestPrivateMemberPackageSibling.class;
// Original model: checkInittedHolder = Class.class;
// Not using Class.checkInitted because it could change without notice.
MethodHandle mh = lookup.findStatic(checkInittedHolder, "checkInitted", mt);
throw new RuntimeException("IllegalAccessException not thrown");
} catch (IllegalAccessException e) {
// okay
......@@ -55,3 +58,7 @@ public class TestPrivateMember {
}
}
}
class TestPrivateMemberPackageSibling {
private static void checkInitted() { }
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册