Restricted Methods

Some methods in the Foreign Function and Memory (FFM) API are unsafe and therefore restricted. If used incorrectly, restricted methods can crash the JVM and may silently result in memory corruption.

If you run an application that invokes one of the following restricted methods, the Java runtime will print a warning message. To enable code in a module M to use these restricted methods or any unsafe methods without warnings, specify the --enable-native-access=M command-line option. Specify multiple modules with a comma-separated list. To enable warning-free use for all code on the class path, specify the --enable-native-access=ALL-UNNAMED option. Alternatively, you can specify the JAR-file manifest attribute Enable-Native-Access: ALL-UNNAMED in an executable JAR to enable warning-free use by all code on the class path. Note that you cannot specify a module name as the value of this attribute.

Table 12-1 Restricted Methods from the FFM API

Methods Reasoning Behind Restricting the Methods

java.lang.ModuleLayer.Controller.enableNativeAccess(Module)

The method enables native access for the specified module if the caller's module has native acces. This method is restricted because it propagates privileges to call restricted methods.

AddressLayout.withTargetLayout(MemoryLayout)

Once you have an address layout with a given target layout, you can use it in a dereference operation (for example, MemorySegment.get(AddressLayout, long) to resize the segment being read, which is unsafe.

Linker.downcallhandle(FunctionDescriptor, Linker.Option...)

Linker.downcallhandle(MemorySegment, FunctionDescriptor, Linker.Option...)

Creating a downcall method handle is intrinsically unsafe. A linker has no way to verify that the provided function descriptor is compatible with the function being called.

A symbol in a foreign library does not typically contain enough signature information, such as arity and the types of foreign function parameters, to enable the linker at runtime to validate linkage requests. When a client interacts with a downcall method handle obtained through an invalid linkage request, for example, by specifying a function descriptor featuring too many argument layouts, the result of such an interaction is unspecified and can lead to JVM crashes.

Linker.upcallStub(MethodHandle, FunctionDescriptor, Arena, Linker.Option...)

As with creating downcall handles, the linker can't check whether the function pointer you are creating (like the qsort comparator in the example in Upcalls: Passing Java Code as a Function Pointer to a Foreign Function) is the correct one for the for the downcall you are passing it to (like the qsort method handle in the same example).

MemorySegment.reinterpret(long)

MemorySegment.reinterpret(long, Arena, Consumer)

MemorySegment.reinterpret(Arena, Consumer)

These methods allows you to change the size and lifetime of an existing segment by creating a new alias to the same region of memory. See Foreign Functions That Return Pointers for more information.

The spatial or temporal bounds associated with the memory segment alias returned by these methods might be incorrect. For example, consider a region of memory that's 10 bytes long that's backing a zero-length memory segment. An application might overestimate the size of the region and use MemorySegment::reinterpret to obtain a segment that's 100 bytes long. Later, this might result in attempts to dereference memory outside the bounds of the region, which might cause a JVM crash or, even worse, result in silent memory corruption.

SymbolLookup.libraryLookup(String, Arena)

SymbolLookup.libraryLookup(Path, Arena)

Loading a library can always cause execution of native code. For example, on Linux, they can be executed through dlopen hooks.