Disallowing the dynamic loading of agents by default

mark.reinhold at oracle.com mark.reinhold at oracle.com
Thu Mar 30 15:38:45 UTC 2017

// Moving the general discussion to jigsaw-dev for the record;
// bcc'ing {hotspot-runtime,serviceability}-dev for reference.


Thanks for your feedback on this topic [1][2][3].

First, we apologize for the way in which this topic was raised.  Our
intent was to post a proposal for discussion prior to code review, but
unfortunately that review was posted prematurely (as is evident by its
inclusion of Oracle-internal e-mail addresses and URLs).

Second, I agree with your earlier analysis as to the security impact of
this change.  If an attack is possible via this vector then closing the
vector would only slow the attack, not prevent it.

The motivation for this change is, however, not merely to improve the
security of the platform but to improve its integrity, which is one of
the principal goals of the entire modularity effort.  Integrity has
benefits for security and also for maintainability, of both the JDK
itself and of code that runs upon it, since it makes it clear exactly
which APIs are intended for external use, and which are not.

To improve platform integrity we've strongly encapsulated (most) of the
internal APIs of the JDK.  That can be, as we all know, a source of pain
for developers trying to get existing applications to run on JDK 9, so
we've provided workarounds via the encapsulation-busting `--add-opens`
and `--add-exports` command-line options and, recently, the temporary
but more powerful (and verbose) `--permit-illegal-access` option.

There are no API equivalents to these command-line options [4].  That's
intentional: We want developers and deployers using Java out-of-the-box
to be assured that their code is only using APIs actually intended for
external use.  They can choose explicitly to expose internal APIs, via
the command line, but then that's a deliberate choice that they make, and
they own the consequences.  It's reasonable to allow this via the command
line since we assume that anyone with access to the command line already
has the power to corrupt the JDK in any way they please.

The proposal to disable the loading of dynamic agents by default is one
more part of the overall integrity story.  As things stand today, code in
any JAR file can use the `VirtualMachine.loadAgent` API to load an agent
into the JVM in which it's running and, via that agent, break into any
module it likes.  Changing the default and providing a new command-line
option, in this case `-XX:+EnableDyanmicAgentLoading`, is consistent with
the other encapsulation-busting options we've introduced.  It allows a
developer or deployer to choose to bend, if not violate, the integrity
of the platform, yet also to know that by default the platform is whole.
(Changing this default is also consistent, as Alan has noted, with the
original intent of the `VirtualMachine.loadAgent` API.)

I understand your points about the practical difficulties of having to
educate users about this new option and enhance startup scripts to use
the option only when invoking JDK 9.  Isn't it already the case, however,
that migrating existing applications to JDK 9 is often going to require
the use of a few new options anyway, in order to expose internal APIs?
If so then would it really be that much more burdensome for users also
to think explicitly, at the same time, about whether they want to enable
dynamic agent loading?

This change would be disruptive to some but it's the best way we've
found, so far, to preserve platform integrity in the face of dynamic
agent loading.  If there's a better way to do that, we'd like to know.

- Mark

[1] http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2017-March/022948.html
[2] http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2017-March/022951.html
[3] https://bugs.openjdk.java.net/browse/JDK-8177154
[4] There are limited reflective APIs via which code in a module can
    apply some of these operations to just that module, and via which
    code that creates a module layer can do so for modules in that
    layer, but none of these APIs can break into arbitrary modules.

More information about the jigsaw-dev mailing list