<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
On 03/06/2024 12:14, Jonas Kunz wrote:<br>
<blockquote type="cite" cite="mid:CAC3isYfkbLdqF4j9ikLP-DUgzH=3KjjmsBJPmPv26eGuRD+L2g@mail.gmail.com">
<div dir="ltr"><br>
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.<br>
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.
<div>Typical use cases are for example loading a profiler (e.g.
<a href="https://github.com/async-profiler/async-profiler" moz-do-not-send="true">async-profiler</a>) or enabling the
JVMTI-only <a href="https://openjdk.org/jeps/331" moz-do-not-send="true">allocation profiling</a>.</div>
<div><br>
</div>
<div>IIUC, such agents would now require kind of a "double
opt-in":<br>
* the user already added either the <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">-javaagent:..</span> or <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">-XX:+EnableDynamicAgentLoading</span> command
line flags, giving the opt-in for the agent to break integrity</div>
<div> * the user now needs to additionally add <span style="font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;color:rgb(0,0,0);font-size:13.3333px">--enable-native-access=some-vendor-module </span>because
the agent loads JNI libraries</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>In my opinion, for that reason there should be an escape
hatch for javaagents, just like <a href="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-" moz-do-not-send="true">Instrumentation.redefineModule</a>
which was added for Jigsaw.</div>
<div>I'd propose to add a method <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">Instrumentation.enableNativeAccess(java.lang.Module)</span>,
which is a copy of <a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/ModuleLayer.Controller.html#enableNativeAccess(java.lang.Module)" moz-do-not-send="true">ModuleLayer.Controller.enableNativeAccess(java.lang.Module)</a> 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.<br>
</div>
</div>
</blockquote>
<br>
<br>
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).<br>
<br>
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.<br>
<br>
-Alan.<br>
<br>
</body>
</html>