JEP draft: Disallow the Dynamic Loading of Agents by Default

Volker Simonis volker.simonis at gmail.com
Fri Apr 28 15:38:12 UTC 2023


On Wed, Apr 19, 2023 at 12:29 AM Ron Pressler <ron.pressler at oracle.com> wrote:
>
> Hi.
>
> Following last month’s email about changing the default of
> EnableDynamicAgentLoading [1], we’ve now published two JEP drafts.
>
> The first is an informational JEP describing what integrity is and why we need it,
> and motivates what changes are required to get it (which include the
> restriction of dynamically loaded agents among others):
>
> https://openjdk.org/jeps/8305968 Integrity and Strong Encapsulation
>

>    - Use sun.misc.Unsafe to access and modify private fields.
>
>    - Load a native library that employs JNI to call private methods and
>      set private fields. (The JNI API is not subject to access checks.)
>
>    - Load an agent that changes code in a running application,
>      using an API intended for tools only.
>
>   To attain our goal of integrity by default, we will gradually restrict
>   these APIs and close all loopholes in a series of upcoming JEPs, ensuring
>   that no library can assume superpowers without the application's consent.
>   Libraries that rely on these APIs should spend the time remaining until
>   they are restricted to prepare their users for any necessary changes.

I think it is a little unfortunate to put the usage of s.m.Unsafe and
JNI/Instrumentation/JVMTI into the same category, especially when it
comes to blaming developers for their usage. While s.m.Unsafe has
always been an internal, undocumented and unsupported API, the latter
three are part of the Java Platform (e.g. "native" is a Java keyword
and Runtime.loadLibrary() is part of the Java API).

Do you really plan to make JNI an optional feature which will have to
be manually enabled at startup? What will be the benefit? I understand
that in an ideal world where you had no user-supplied JNI libraries at
all, you might be able to perform more/better optimizations. But as
you'd have to support JNI anyway, wouldn't the maintenance of the
resulting code become a nightmare. How many "if (JNI) {..} else {..}"
would we get? And what would be the benefit of disabling it by default
for the user except increased "integrity"? I.e. do you have some
concrete examples of planned features X, Y, Z which will only work
with disabled JNI? Will these features be Java SE features or
implementation specific OpenJDK-only features?

> The second touches on the specifics of dynamically loaded agents and the
> proposed change:
>
> https://openjdk.org/jeps/8306275 Disallow the Dynamic Loading of Agents by Default
>

>    Agents are used by profiling tools to instrument Java applications,
>    but agents can also be misused to undermine the integrity of the
>    Java Platform.

I don't think it is fair to assume that profilers are the only "valid"
use case for agents and imply that all other use cases are a mis-use
of the API.

>    - It is not a goal to change the Attach API that allows a tool to
>      connect to a running JVM for monitoring and management purposes.

I don't understand this "Non-Goal"? The Attach API [1] allows to
dynamically attach to a running JVM and "Once a reference to a virtual
machine is obtained, the loadAgent, loadAgentLibrary, and
loadAgentPath methods are used to load agents into target virtual
machine". So how can you achieve this JEP's goals without
changing/restricting the Attach API? I therefore think this "Non-Goal"
should be rephrased to explain which parts of the Attach API will be
changed and moved to the "Goal" section instead.

General comments:

- You go into great detail to explain why a human-operated tool is
"superior" (in the sense of trust and security) to a library and
"would ideally not be subject to the integrity constraints imposed on
the application". I can't follow this argument, because both, the
decision to use a specific tool as well as the decision to rely on a
library is taken by a human. I'd even argue that the decision to
depend on a specific library which requires the dynmaic attach
mechanism is taken by a more knowledgeable user (i.e. the developer
himself). Of course both, a tool as well as a library can contain
malicious code, but I don't see a fundamental difference between the
two.

- You may argue that users have to be protected from malicious
libraries which gain their superpowers by secretly loading agents at
runtime. But users who don't know and don't care about their library
dependencies will just as easy and without reflection (pun intended :)
add the -XX:+EnableDynamicAgentLoading to their command line arguments
(making this the new, most often used command line option even
surpassing the usage of --add-opens :)

- I still can't understand the benefit of "only" changing the default
behavior for dynamic agent loading. I could understand this if you'd
do it with a plan to deprecate and completely remove the dynamic agent
loading capability. But what are the benefits of changing the default
if you'll have to support the functionality anyway? As mentioned in
earlier discussions, my main concern with the proposed change is the
impact it will have on the evolution of Java. Java's dynamic features
are one of its biggest strength and a major reason for its success.
Sacrificing some of them or making their usage increasingly expensive
requires a broader discussion in the community and shouldn't happen
"under the hood" of a discussion about the default setting of a
command line flag.

- I don't understand why this JEP has scope "SE". As you rightly
mentioned, the Attach API is a "non-standard" API which can be changed
at any time and without affecting the Java SE specification, so this
JEP should rather have scope "JDK" instead. On the other hand, the
fact that this functionality is not governed by the SE specification
will allow different OpenJDK distributors to use a different default
setting for -XX:EnableDynamicAgentLoading which has the potential to
cause a lot of confusion if we can't sattle on a common strategy.

- If doing this change at all, I think it would be better to do it in
a non-LTS release first.

Best regards,
Volker

[1] https://docs.oracle.com/en/java/javase/20/docs/api/jdk.attach/com/sun/tools/attach/VirtualMachine.html


> [1]: https://mail.openjdk.org/pipermail/jigsaw-dev/2023-March/014816.html
>
> — Ron


More information about the jigsaw-dev mailing list