<html><body><div dir="ltr"><div style="">
</div><div style=""><div>
<div dir="ltr">If you keep instrumentation (and i don’t think you want to remove it), don’t make it harder to use programmatically… that really does not make much sense. And please don’t add captcha-like mechanism that’s ridiculous. </div><div dir="ltr"><br></div><div dir="ltr">Backport the fix to turn it off, I will be the first to actually use it. But everything else…</div><div dir="ltr"><br></div><div dir="ltr">Gruss</div><div dir="ltr">Bernd</div><div id="ms-outlook-mobile-signature"><div style="direction:ltr">-- </div><div style="direction:ltr">http://bernd.eckenfels.net</div></div>
</div>
<div> </div><hr style="display:inline-block;width:98%" tabindex="-1"><div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif"><b>Von:</b> serviceability-dev <serviceability-dev-retn@openjdk.org> im Auftrag von Ron Pressler <ron.pressler@oracle.com><br><b>Gesendet:</b> Montag, Mai 1, 2023 12:24 AM<br><b>An:</b> Mike Hearn <mike@plan99net><br><b>Cc:</b> Dan Heidinga <heidinga@redhat.com>; jigsaw-dev@openjdk.org <jigsaw-dev@openjdk.org>; serviceability-dev@openjdk.org <serviceability-dev@openjdk.org><br><b>Betreff:</b> Re: [External] : Re: JEP draft: Disallow the Dynamic Loading of Agents by Default<div> </div></font></div>
<div dir="auto" class="" style="word-wrap:break-word; -webkit-nbsp-mode:space; line-break:after-white-space">
Hi Mike!<br class="">
<div><br class="">
<blockquote type="cite" class="">
<div class="">On 30 Apr 2023, at 19:59, Mike Hearn <<a href="mailto:mike@plan99.net" class="" style="">mike@plan99.net</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class="">
<blockquote type="cite" class="">we’ve begun to explore means other than the flag to allow a tool to load an agent at runtime<br class="">
</blockquote>
<br class="">
How about restricting access to the jcmd socket. For in-VM code it can<br class="">
be blocked at the filesystem implementation level, and for<br class="">
sub-processes by using the operating system APIs to determine if the<br class="">
other side of the socket is part of the same process tree at connect<br class="">
time. This would avoid the need for new UI to re-enable existing jcmd<br class="">
functionality, whilst preventing code loaded into the VM from<br class="">
connecting back to that same VM. Only truly external tools could<br class="">
trigger agent loading, or modules that had been given permission to do<br class="">
that.<br class="">
<br class="">
</div>
</div>
</blockquote>
<div><br class="">
</div>
<div>Determining the process on the other side and/or maintaining the integrity of the process tree is not easy on all OSes.</div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div class="">That is assuming native code is restricted of course but that's a<br class="">
whole other kettle of fish. I don't quite understand how the plan is<br class="">
meant to work when it reaches that stage. JNI is so widely used and so<br class="">
many libraries would break that you'd either just immediately see<br class="">
workarounds appear, like build systems concatenating lists of flags<br class="">
from META-INF files, or it'd just cause a lot of chaos and upgrade<br class="">
rejection. It'd also have to be dynamically controllable for plugins,<br class="">
so then you'd also get people running their apps inside classloaders<br class="">
that auto-grant any request to load native code.<br class="">
</div>
</div>
</blockquote>
<div><br class="">
</div>
<div>No libraries will break and no workarounds would be possible once all loopholes are closed. All you’d need to do is grant the module permission to load/use native libraries, be it through JNI or FFM.</div>
<div><br class="">
</div>
<div>Build tools may do whatever they want, but it’s important to remember that the low-integrity free-for-all worked more-or-less only while Java was relatively stagnant. Once the platform started evolving more rapidly we saw many applications break in the
Java 8 -> 9 upgrade due to deep dependencies that relied on JDK internals in the days before strong encapsulation. </div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div class=""><br class="">
There must be a better way?<br class="">
</div>
</div>
</blockquote>
<div><br class="">
</div>
<div>Before thinking about other ways, I think it’s best to first acknowledge the problem, and that is that we wish for two fundamentally contradictory things: On the one hand, we want it to be easy to break other people’s code’s encapsulation when we need
to, and on the other we want features that fundamentally depend on encapsulation not being broken, such as smooth upgrades, robust security mechanisms, and future Leyden features. Both may be good, but they are in conflict. Because we can't to have our invariants
and break them too, someone must choose between one and the other.</div>
<div><br class="">
</div>
<div>But I also don’t think it’s a very complicated choice. The view of the Java ecosystem as a hotbed of encapsulation-breaking is gradually becoming outdated. Much of the necessity to break encapsulation came about due to the platform’s stagnation in the
JDK 6-8 timeframe. While the ability to break encapsulation is being restricted, the problems that required it in the first place are also being addressed. The number of uses that require breaking strong encapsulation is shrinking.</div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div class=""><br class="">
Maybe the problem can be recast as one of build-time observability?<br class="">
One concept I experimented with for my own build system is the notion<br class="">
of "control reports", a generalization of lockfiles. The build<br class="">
generates text files describing things you care about, and these are<br class="">
then checked in to vcs. There is a build mode that doesn't write the<br class="">
generated reports on disk, instead it verifies there's no difference<br class="">
and exits if there are. By checking the reports into version control<br class="">
and using OWNERS files + code reviews various policies can be<br class="">
enforced.<br class="">
<br class="">
In this context it'd work like so: the JVM would be changed to look<br class="">
for a flags file in the JAR containing the main class/main module as<br class="">
part of its startup. JVM flags can thus be shipped as part of the app,<br class="">
formalizing an already existing convention that's today implemented<br class="">
with shell scripts. Build systems can generate this flag file from<br class="">
their existing lists of JVM flags, and/or compute it automatically by<br class="">
merging flag files found in any library JARs. For people who don't<br class="">
care about deprivileging libs (prototyping, learners, people who only<br class="">
use in-house code etc) this will keep things working as it does today.<br class="">
</div>
</div>
</blockquote>
<div><br class="">
</div>
<div>A main JAR, when used, is already given control over some command-line flags via its manifest, including strong encapsulation controls. That’s fine, because it’s controlled by the application, not libraries.</div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div class="">For people who wish to use this new security feature</div>
</div>
</blockquote>
<div><br class="">
</div>
<div>It’s not a security feature. It’s an integrity feature</div>
<br class="">
<blockquote type="cite" class="">
<div class="">
<div class="">they can review<br class="">
the generated flag file and check it in. Now if they add a dependency<br class="">
on a library that needs to use panama, jni, an agent, opened packages<br class="">
etc, this will become visible as added lines in the flag file, can be<br class="">
pushed back on when the commit is reviewed, and by placing an OWNERS<br class="">
file in the directory containing the report tech leads can allow<br class="">
delegates to add dependencies without being able to change JVM flags.<br class="">
</div>
</div>
</blockquote>
<br class="">
</div>
<div>I think what you’re describing is an automated generation of what the informational JEP calls the codebase map (i.e. the command-line) based on what libraries want. Such automated permission-management could perhaps be appropriate for a security mechanism
for mobile phone apps — requesting access to files, for example, is quite common — but not so much for integrity, as the need to break encapsulation is supposed to be abnormal and rare; it is certainly discouraged, and we believe that it will become less and
less necessary (currently, serialization is probably the biggest issue, but we’re getting closer to a point where it won’t be:
<a href="https://openjdk.org/projects/amber/design-notes/towards-better-serialization" class="" style="">
https://openjdk.org/projects/amber/design-notes/towards-better-serialization</a>).</div>
<div><br class="">
</div>
<div>Of course, tools outside the JDK can offer such a mechanism, but if the number of libraries requiring bypassing of encapsulation continues to decline that may be a rather elaborate solution to a rather small problem. Personally, I think it might be best
to see where the ecosystem is in a few years.</div>
<div><br class="">
</div>
<div>— Ron</div>
<br class="">
</div>
</div></div></body></html>