Hi Remi,

On 11/01/2016 11:59 PM, Remi Forax wrote:
Iteration 3,
https://gist.github.com/forax/c08ce0a8dc88705bce97b17b63e7e2d5

GrantAccess can now be put on a class, on a package or on a module, and give 
access to several frameworks by their names. Getting access to the lookup of a 
class is now a 2 steps process, first claim a framework name to get an 
AccessFacade and then through the AccessFacade, a framework have access to all 
classes annotated (directly or indirectly) by GrantAccess and allowing the 
framework. The facade corresponding to a framework name can only be requested 
once so how to store the FacadeAccess is let to the framework implementation 
and if a code try to sneak in and use a framework name it will be detected.

Rémi

Hm, this variant requires the real framework code to race against its impostor(s) for the access facade granted to a particular name. What if an impostor gets it first?

In addition, I see a similarity of this approach to simply "opening" the required packages of the "granting" module to a chosen "granted" module (i.e. the "hibernate") in the granting module declaration. At least the module name is harder to "spoof" as it is embedded in the module search path layout. But I get the point. Instead of "hibernate", the granting module could declare that it gives access to a "jpa" framework, which is a more general name that several implementations could claim. But I think that they should not simply claim the name and get it on a first-comes basis. What about introducing a general registry of: (module name -> access name) mappings controlled by privileged code or some policy? The problem I see is a problem of choosing the names in general as they get to be hard-coded in the code or declaration of the granting module. Who chooses that "jpa" is the name of the JPA framework? Module names are chosen by their authors. There has to be a module 1st and then one can "require" it. OTOH there has to be a general agreement on the "access name" among several authors of the modules that claim that name. And this requires a central name registry like IANA. And that's not something jigsaw is going to dive into.

I tried to tackle the issue from another perspective. If you ask yourself what is common to all JPA framework implementations, for example, then the answer is: they all implement the same API (in the form of interface(s) or abstract classes). This API will usually be a module by itself. 1st there has to be an API module with the agreed-upon API and then the authors can produce implementation modules (hibernate, eclipse-link, ...). So I thought that the name of the API module could be used as the "access name" of the grant and every implementation module that could prove it contains the implementation of this API would inherit the grant.

Ideally, but not necessarily, services and providers could be leveraged in the implementation. The mechanism could be "secured" on a service-by-service basis using SecurityManager permission(s) like it is done today (the security check is put into the constructor(s) of the abstract service class) so that impostor(s) are kept back.

Regards, Peter

----- Mail original -----
De: "David M. Lloyd" <david.ll...@redhat.com>
À: "Andrew Dinn" <ad...@redhat.com>, jigsaw-dev@openjdk.java.net
Envoyé: Mardi 1 Novembre 2016 21:00:35
Objet: Re: New proposal for #ReflectiveAccessToNonExportedTypes: Open   modules 
& open packages
On 11/01/2016 11:02 AM, Andrew Dinn wrote:
On 01/11/16 15:35, David M. Lloyd wrote:
On 11/01/2016 10:09 AM, Andrew Dinn wrote:
There is a very easy way to provide tightly controlled access to a
framework. Export access to e.g. jdk.internal.misc.Unsafe or e.g.
java.lang.[invoke].MethodHandles to a nominated module provided by your
framework then arrange for that module to hand out Lookups (or better
MethodHandles) to framework code as and when they are needed via a
private channel. You can do arrange that with a single addExports option
on the command line and a very small amount of setup code to establish
the private channel
I don't see how this is safer though.  You're proposing to hand all the
keys (or none) to modules which don't need all the keys, whereas I
propose that a module should only gain incremental additional access on
a grant basis.
No, I'm suggesting handing the keys to a single module provided by your
framework -- which module will then use a key to open a room on demand
for your code and your code only. That means the privilege can be
granted using one command line switch with use of that privilege
controlled by a runtime mechanism of your choosing.
Yes, however that means that I'm on the hook to make sure that the keys
aren't mislaid.  And given the fact of open modules - which already
semantically grants me privileges - requiring a special command line
switch (which is itself undesirable) and custom code to enable those
privileges in the *preferred* manner (i.e. MethodHandles) seems
backwards when open modules would already grant me the ability to
utilize a much finer instrument albeit with the legacy approach (i.e.
reflection).  It seems quite logical to extend this mechanism to the
preferred MethodHandle approach instead, and forget about Unsafe and
anything like it, which I think is in everyone's best interests in the
long term.

At least Rémi's approach requires a specific grant and non-Unsafe
vector, though as I said the weaknesses (of his first approach) are that
the grant must come from the target class (programmatically) instead of
being a static declaration ("opens" is a natural fit for this if I
understand the proposal correctly).  The other weakness is that it
requires class init, but that's purely a consequence of requiring a
programmatic grant as far as I understand.
I did actually suggest a way of avoiding the use of Unsafe. You give
your nominated module full reflective access to java.lang.invoke
allowing it to create Lookup instances (it can actually just create a
single all privileges lookup and use this to clone others). You don't
need to insert a class into java.lang.invoke to do this. You simply add
one exports directive on the command line.
That is marginally better, of course, but I think the rest of my
objections still stand against this argument.

Rémi's newest Gist uses an annotation, which is closer but not quite on
the target IMO.  An annotation cannot be module-deployment-agnostic in
the way that I outlined previously (hence
#IndirectQualifiedReflectiveAccess); ultimately accessibility
information ought to come from the module configuration itself.
If you implement a module with the ability to hand out Lookup instances
you can use whatever control model you like. For example, you might park
an instance which hands out Lookups in a location only available to your
framework or ensure that any caller asking for a Lookup belongs in a
package implemented by your framework or whatever you want. the point is
that once you have granted a class in our code the ability to create
Lookups you can implement whatever runtime access control you want.
Clearly,as John said, you need to do that responsibly.

regards,


Andrew Dinn
-----------
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander

--
- DML

Reply via email to