Alternative mechanism for reflective access control (#ReflectiveAccessToNonExportedTypes / #AwkwardStrongEncapsulation)
John Rose
john.r.rose at oracle.com
Tue Oct 11 19:39:47 UTC 2016
On Sep 29, 2016, at 2:29 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>
> This bug only talk about the callee side, i.e. accessing to a non accessible class by a framework.
> The other part, the caller side, is to have a way to emit a call that send the caller lookup to a framework,
> the easy way to do that is to have javac to emit an invokedynamic instead of an invokeinterface/invokevirtual
> after having verified that everything is typechecked.
FTR, I added a comment to the bug that expands on this theme.
https://bugs.openjdk.java.net/browse/JDK-8162494?focusedCommentId=14010672 <https://bugs.openjdk.java.net/browse/JDK-8162494?focusedCommentId=14010672>
— John
P.S. CC-ed here:
Remi Forax notes that this proposal is about gaining access to classes.
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-September/009518.html
Once somebody (the class itself, a neighboring class, a module, a layer, the Unsafe API) grants you a Lookup object, you can call any class feature the lookup can access, by using a method handle.
The most general Lookup object, for a given class, can always be created by a method in the class's bytecodes that looks like this:
class C {
private C() { } protected void m() { } int f; // etc., etc.
public MethodHandles.Lookup grantAccess() { return MethodHandles.lookup(); }
}
In this example, the "grantAccess" method gives the whole world (or at least the module) full access to all class members, up to and including privates.
The essence of the present proposal is to introduce mechanisms for creating Lookup objects which (a ) can be as powerful (on class C) as that returned by the "grantAccess" method above, and (b ) do not require any changes to the bytecodes of the class itself.
The difficult part of the proposal is designing the alternative Lookup factory in such a way that it doesn't just "give away the store" (as presumably the Unsafe version would). The Lookup object should be (c ) handed out by a trusted delegate of C (such as its module layer), and (d ) only handed to callers who have been vetted in some way (such as by a SecurityManager check, as by setAccessible). Finally, the Lookup object must be (e ) right-sized, so that it gives only access (say) to public methods, or package-private methods, according to the needs of the caller and the rules of the factory.
Another possible framework-like operation that Remi brings up is creating simulations of calls from managed framework code to other frameworks. In some cases, this can also be done with the Lookup API. If the callee is caller-sensitive (like Class.forName), the Lookup API handles it specially, embedding the Lookup's target class into the method handle it returns (for that callee) in such a way that when the method handle the caller-sensitive method observes the Lookup's target class, not the current invoker of the method handle. Only the immediate caller is "edited" in this way; a full stack walk will see the specially-embedded caller and all of frames of the current invocation.
Another use case for frameworks is enumerating and examining (e.g., annotations of) reflected class members, instead of just invoking them. The Lookup API is intended to help with this also. The Lookup.revealDirect method can translate a previously accessed method handle into a Core Reflection object that describes the same underlying class member. The Lookup API (as of 9) also has the ability to resolve class names with respect to the Lookup's target class. Finally (as noted above) calls to caller-sensitive Core Reflection API points can be made to appear originating from a target class by looking up those API points via a full-power Lookup on the target class, instead of calling from normal bytecodes.
Personally, I would like to encourage people interested in structured access elevation, by bona fide frameworks, to propose securable mechanisms for handing out Lookup objects, or similar restrictable capability objects.
More information about the jigsaw-dev
mailing list