RFE: support safely wrapping restricted FFM calls

Rob Spoor openjdk at icemanx.nl
Sat Nov 18 14:59:37 UTC 2023


On 18/11/2023 06:46, Kasper Nielsen wrote:
> Hi Rob,
> 
> Delegating caller sensitive methods can be tricky.
> 
> Besides the obvious solutions with StackWalker and/or Lookup objects I've
> sometimes used an abstract class that must be extended by users of my library.
> This may be more trouble in your case than the other solutions though.
> 
> In your situation it would be something like this.
> 
> // Defined in your library and extendable by users of your library
> public abstract class NativeLoader {
> 
>      protected abstract MethodHandle downcallHandle(Linker linker, MemorySegment
>           address, FunctionDescriptor function, Linker.Option... options);
> 
>      public final <T> T load(Class<T> interFace) {
>       .. do stuff.
>       call this.downcallHandle
>       .. do more stuff
>      }
> }
> 
> // Usage by other library
> class UsageByOtherLibrary {
>     private static final NativeLoader NL = new NativeLoader() {
>          protected MethodHandle downcallHandle(Linker linker, MemorySegment
>                     address, FunctionDescriptor function, Option... options) {
>              return linker.downcallHandle(address, function, options);
>          }
>      };
> 
>      public void main() {
>          SomeInterface si = NL.load(SomeInterface.class);
>      }
> }
> 
> The actual call to Linker.downcallHandle is now only performed by the user of
> your library. So depending on what you do, you might even be able to avoid
> requiring enabling native access for your library. Only the libraries that use
> your library would need it.
> 
> /Kasper

Hi Kasper,

This would indeed be relatively easiy if Linker.downcallHandle was the 
only native call, but I've already used AddressLayout.withTargetLayout, 
and just had to add a call to MemorySegment.reinterpret for the 
MemorySegment an AddressLayout was referring to (the result of a native 
call like malloc). Such custom implementations would need to be passed 
around several method calls of my module. Still, this is something to 
consider, as it does take away restricted calls away from my module to 
the caller. Thanks for the hint!

Rob


> 
> 
> 
> 
> On Thu, 16 Nov 2023 at 19:21, Rob Spoor <openjdk at icemanx.nl> wrote:
>>
>> On 16/11/2023 18:15, Maurizio Cimadamore wrote:
>>>
>>> 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.



More information about the core-libs-dev mailing list