RFE: support safely wrapping restricted FFM calls

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Nov 16 17:15:27 UTC 2023


On 16/11/2023 16:54, Rob Spoor wrote:
> Hi Maurizio,
>
> I don't think you understand what my module is doing. For instance, 
> it's not specifying the downcall method handles themselves, it's just 
> making it easy to define them. Maybe a small example would show what 
> I'm doing.
>
> Consider the following partial interface from JNA:
>
>     public interface Kernel32 extends StdCallLibrary, WinNT, Wincon {
>
>         /** The instance. */
>         Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, 
> W32APIOptions.DEFAULT_OPTIONS);
>
>         int GetLastError();
>     }
>
> What JNA is doing is creating an implementation based on this 
> interface that delegates to the native kernel32 library. This is all 
> done through the Native.load method.

>
> What I'm building is not an FFM-backed version of Kernel32 interface, 
> but something like Native.load. In other words, my module will call 
> the restricted Linker.downcallHandle method. Somebody that then wants 
> to build a Kernel32 interface would not directly call any restricted 
> methods. As a result, their code would not need to have native access 
> enabled because they would get it through my module. That's something 
> I want to protect against, because it's definitely not safe to just 
> grant any access. (In fact, some incorrectly written test code has 
> already crashed my JVM.) While my module will definitely need to have 
> native access enabled, I'd like to require that the module with such a 
> Kernel32 interface needs to have native access enabled as well.

I believe I understood what you were attempting to do :-)

And I still stand by what I said yesterday - a client will need to trust 
your library (and a flag is required there) to generate the correct 
stuff when it gives you an interface (which your framework will generate 
an implementation of using some black magic). Whether the client itself 
is enabled to do native access or not is irrelevant, because unsafe 
operation will not occur on the client module, they will occur on the 
module of your framework. The crucial part here is that for an 
application to be able to use your framework _some_ form of 
`--enable-native-access` will be required (so, the command line will 
give away the fact that the application will require some form of unsafe 
access somewhere).

>
> The idea of using a MethodHandles.Lookup instance looks interesting, 
> but it would only replace the use of the StackWalker. I still would 
> need to print a message or throw an exception from my module instead 
> of reusing the code from Module.ensureNativeAccess, which makes my 
> module either stricter than the FFM API right now, or less strict in 
> the future when the FFM API starts throwing exceptions. 

What you are asking boils down to: how can I define _custom_ restricted 
methods?

The answer is you can't. Restricted methods are a feature of the Java SE 
API (pretty much like preview methods). And I believe this is likely to 
remain that way: as you noticed, emulating a restricted method from 
custom code requires a stackwalk, which we avoid using caller sensitive 
methods (which are also not available outside the JDK).

Maurizio




More information about the core-libs-dev mailing list