JDK-8307479 : Implementation of Prepare to Restrict The Dynamic Loading of Agents
  • Type: CSR
  • Component: core-svc
  • Sub-Component: tools
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 21
  • Submitted: 2023-05-04
  • Updated: 2023-06-04
  • Resolved: 2023-05-31
Related Reports
CSR :  
Relates :  
Relates :  
Description
Summary
-------

Print warnings to standard error when agents are loaded dynamically into a running JVM. The warnings aim to prepare users for a future release which disallows the dynamic loading of agents by default.

Problem
-------

Libraries that dynamically load agents that grant them "superpowers" are one of the current "loopholes" in strong integrity (see https://openjdk.org/jeps/8305968)

Solution
--------

Print a warning to standard error when an agent is loaded into a running VM.  Add a statement to the JVM TI specification, and the `java.lang.instrument` package description, to mandate that a warning be printed.

For JVM TI agents, the warning is:

```
WARNING: A JVM TI agent has been loaded dynamically (file:/u/bob/libagent.so)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: Dynamic loading of agents will be disallowed by default in a future release
```

and for Java agents the warning is:

```
WARNING: A  Java agent has been loaded dynamically (file:/u/bob/agent.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
```

The warning is printed when an agent is loaded into a running VM. The trigger to load an agent into a running VM is a program using the Attach API or the `jcmd JVMTI.agent_load` command. 

The warning may be suppressed by running with `-XX:+EnableDynamicAgentLoading`. This XX option exists since JDK 9 and is an explicit opt-in to allow agents be dynamically loaded. The default for this option is "true" and is not changed by this CSR.

As detailed in the JEP, this warning will prepare users for a future where the dynamic loading of agents will be disabled by default.

There is already a Java Flight Recorder (JFR) event when agents are loaded (https://bugs.openjdk.org/browse/JDK-8257967). No changes to this event are proposed by this CSR.

Additionally, the system property `jdk.instrument.traceUsage` will enable tracing of calls to the `java.lang.instrument.Instrumentation` API to help identify cases where libraries using the `Instrumentation` API.  If the system property is set on the command line (`-Djdk.instrument.traceUsage`) or set to the value "true" ( `-Djdk.instrument.traceUsage=true`) then a trace message and stack trace is printed to the standard output when the API is used.

JVM TI already has extensive tracing options since JDK 5, no changes are proposed to this tracing. 


Specification
-------------

A zip file with the specdiffs is attached.  

For JVM TI, "Agent Start-Up (Live phase)" section is updated to mandate that a warning be printed when an agent is started in the live phase. 

The `java.lang.instrument` package description has been restructured so the diffs may be difficult to read. The significant changes are:

- The "Starting an agent in a running JVM" section has a statement to mandate that a warning be printed when a Java agent is loaded into a running JVM.

- The description Launcher-Agent-Class, Premain-Class, and Agent-Class JAR file attributes are changed to use "binary name" rather than "class name".

There are no specification changes to go with the JDK-specific system property to enable tracing.

Comments
Okay, we can add implNote/equivalent to both the JVM TI spec and j.l.instrument package description to document the EnableDynamicAgentLoading option. It is also documented in the warning message that is printed, and if is disabled in some future release, then the error message that is returned when attempting to load an agent will also include the option to re-enable.
31-05-2023

Moving to Approved. As a code review comment, as a kindness to readers, putting an implNote tag in the java.lang.instrument changes "the HotSpot flag for this is $FLAG_NAME" could be helpful.
31-05-2023

I've attached jep451-specdiffs-20230529.zip with the latest proposed updates to the JVM TI spec and the j.l.instrument package description. The only change from before is an adjustment to the wording to allow for the warning to be skipped when there is an attempt to load an agent that is already loaded.
29-05-2023

Moving to Provisional, not Approved. Before the request is Finalized, it should get one or more reviewers and the Specification section should be updated to mention the any proposed API changes, as Alan has attached. Is there any JFR involvement of this feature? Not necessarily for the CSR but in a release note or other documentation it would be informative for users to have distilled and written up succinctly: * Options to enable the future checks today (especially if today includes JDK releases before JDK 21) * Options to run with the pre-JDK 21 defaults on JDK 21 and later In other words, summarize and call-out the actions users can take today to identify and audit their existing usage and/or explicitly enable their current usage.
23-05-2023

I've attached jep451-specdiffs-20230519.zip with a draft update to the JVM TI spec and the j.l.instrument package description. For JVM TI spec, the "Agent Start-Up (Live phase)" section is updated to specify a warning be printed when an agent is started in the live phase. The j.l.instrument package description has more extensive changes due to restructuring. The only new testable assertion is in the section "Starting an Agent in a running JVM" section where it specifies that a warning be printed when an agent is started in a running JVM.
19-05-2023