RFE: support safely wrapping restricted FFM calls

Rob Spoor openjdk at icemanx.nl
Wed Nov 15 17:13:14 UTC 2023


Hello all,

I'm working on a module that makes working with FFM easier; think of 
something like JNA. For instance, it allows creating structures without 
having to manually manage var handles etc.

My module uses restricted mehods like AddressLayout.withTargetLayout to 
support pointers. Those correctly give warnings if I don't use 
--enable-native-access. This is where I've identified a potential 
security risk. Native access would need to be enabled for *my* module, 
which would allow modules that use my module to call these restricted 
methods indirectly and without needing native access enabled themselves. 
This means that any malicious module could piggy-back on the native 
access that would be enabled for my module.

I can implement my own access checks using the following:

     StackWalker.getInstance(Set.of(Option.RETAIN_CLASS_REFERENCE))
             .getCallerClass()
             .getModule()
             .isNativeAccessEnabled()

However, that would mean users of my module would need to provide access 
using two different mechanisms. I think that making some existing code 
public could help situations like mine:

* Changing the visibility of java.lang.Module.ensureNativeAccess from 
package-private to public would allow me to check access using the JVM's 
own mechanism, in combination with the StackWalker class to get the 
caller (current) class and its module. Alternatively, new instance 
method Class.ensureNativeAccess(owner, methodName) could delegate to 
Reflection.ensureNativeAccess(this, owner, methodName) to make sure that 
a different module couldn't be used instead, or static method 
Class.ensureNativeAccess(currentClass, owner, methodName) could delegate 
to Reflection.ensureNativeAccess to support null classes.

* Moving jdk.internal.javac.Restricted to java.lang.foreign would allow 
me to easily document that methods are restricted.

There is an alternative in using --add-exports to access 
jdk.internal.reflect (for Reflection.ensureNativeAccess that indirectly 
calls Module.ensureNativeAccess) and jdk.internal.javac (for 
Restricted), but that adds another burden on callers. In this case, a 
burden that cannot be easily remedied using a manifest entry 
(Enable-Native-Access).


Kind regards,

Rob


More information about the core-libs-dev mailing list