New candidate JEP: 472: Prepare to Restrict the Use of JNI

Alan Bateman Alan.Bateman at oracle.com
Mon Jun 3 14:56:00 UTC 2024


On 03/06/2024 12:14, Jonas Kunz wrote:
>
> I have some concerns regarding JEP 472 for javaagents. Many javaagents 
> (such as the elastic APM agent) use functionality which is only 
> available in JNI/JVMTI.
> To do so, they typically ship native binaries embedded in the JAR for 
> all platforms and load the matching one at runtime. This is done so 
> that users can use a single javaagent JAR instead of having to select 
> the correct native agent for their platform.
> Typical use cases are for example loading a profiler (e.g. 
> async-profiler <https://github.com/async-profiler/async-profiler>) or 
> enabling the JVMTI-only allocation profiling 
> <https://openjdk.org/jeps/331>.
>
> IIUC, such agents would now require kind of a "double opt-in":
>  * the user already added either the -javaagent:.. or 
> -XX:+EnableDynamicAgentLoading command line flags, giving the opt-in 
> for the agent to break integrity
>  * the user now needs to additionally add 
> --enable-native-access=some-vendor-module because the agent loads JNI 
> libraries
>
> I feel like this makes things unnecessarily complex for users, because 
> with the explicit loading of the agent they already gave that agent 
> the permission to break JVM integrity.
>
> In my opinion, for that reason there should be an escape hatch for 
> javaagents, just like Instrumentation.redefineModule 
> <https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/java/lang/instrument/Instrumentation.html#redefineModule-java.lang.Module-java.util.Set-java.util.Map-java.util.Map-java.util.Set-java.util.Map-> 
> which was added for Jigsaw.
> I'd propose to add a method 
> Instrumentation.enableNativeAccess(java.lang.Module), which is a copy 
> of ModuleLayer.Controller.enableNativeAccess(java.lang.Module) 
> <https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/ModuleLayer.Controller.html#enableNativeAccess(java.lang.Module)> but 
> without requiring the caller module to be enabled for native access. 
> The caller having access to an java.lang.instrument.Instrumentation 
> instance should be sufficient.


Instrumentation.redefineModule is not really an escape hatch. It was 
introduced primarily to allow an agent augment readability for scenarios 
where an agent instruments code in one module to call into something in 
another module, usually a supporting library that is part of the agent.  
An Instrumentation.enableNativeAccess (and JVMTI equivalent) would allow 
an agent to instrument code to make use of restricted methods, or invoke 
native methods, but it doesn't need that when it's done in the target 
method (it's the module containing the target class/method that would 
require native access).

At things stands, there isn't any support for deploying Java agents as 
named modules so there isn't a value for "some-vendor-module", only 
ALL-UNNAMED will work. The issue with the equivalent of 
Enable-Native-Access in agent's JAR manifest is that it would be the 
equivalent of running with --enable-native-access=ALL-UNNAMED, a 
surprising side effect of running with -javaagent. I haven't personally 
come across Java agents that bring along a JNI library but it seems 
plausible, as is Java agents making use of restricted methods. So this 
does seems like something to be explored further but may in the context 
of agents deployed in named modules. JVM TI agents use JVM TI in 
conjunction with JNI but doing upcalls to invoke System.loadLibrary or 
bind native methods may be less likely there.

-Alan.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20240603/45c50253/attachment-0001.htm>


More information about the jdk-dev mailing list