Disallowing the dynamic loading of agents by default
Andrew Dinn
adinn at redhat.com
Mon Apr 3 16:44:43 UTC 2017
On 03/04/17 16:50, Alan Bateman wrote:
>> Also, can you provide a reason why you are so agin agent-hoisting from
>> within a JVM? Is there a reason why it is such a cardinal sin?
> As Mark said, this discussion got off to a bad start. We might have to
> explain the issue again.
Sure, only I don't think I have misunderstood the existing explanations
(that was what I wanted to check). However, I am not clear that I am
getting the same, consistent explanation each time.
> Java SE 9 / JDK 9 brings strong encapsulation. The access control for
> the Java Language and VM has been extended to modules so that modules
> that don't want their internals to be accessed from code outside the
> module can do so. None of the core modules want their internals to be
> accessed so none of the core modules are open or open any packages. A
> consequence of this is that code on the class path or module path
> doesn't get to break in these modules. This is really nice but it
> exposes a lot of technical debt in existing code (as we've seen in mails
> here over the last 18 months).
Yes, it is really nice in many ways. But it is also not necessarily what
everyone wants.
One thing I am not clear on as regards that 'really nice' is whether
anything in the JVM wants -- or even hopes -- to rely on module
encapsulation never being broken in order to provide 'semantic'
guarantees. That's different from relying on it to provide security
guarantees. The sort of thing I am thinking about is, say, a module-wide
global analysis in the JIT guaranteeing that a call argument will only
ever be non-NULL, a positive int, or some such invariant that can fed
into an optimization phase. I can understand how a switch to disable
dynamic agent loading might be needed to underline that sort of guarantee.
> . . .
> Now bring the attach API and late binding agents into the picture. This
> is where things blur and where the problem arises. A library can use the
> attach mechanism to load an agent into the current VM and break into any
> module. It's much easier in JDK 9 compared to previous releases because
> the jdk.attach module is resolved by default. All it takes is someone to
> post a solution on stackoverflow that spins a sneaky agent to leak the
> Instrumentation object to the library. It's just too easy to "migrate"
> existing reflection hacks.
I think this is already very well known technology and the presence of
the jdk.attach module in the runtime was never really much of a bar. The
people who want to do this certainly don't have to look for sneaky
solutions on stackoverflow. However, I still don't really see your point
here. If people want to migrate existing reflection hacks then they can
and will do so by switching off your proposed flag or adding the agent
at startup.
Are you perhaps concerned that users might have their hand forced by
providers of library jars or middleware who hoist an agent into the JVM
behind their backs? I think that would be rather a patronising view to
take of the vast majority of producers and consumers of libraries and/or
middleware. My belief is that anyone who attempted to provide a library
or framework (open source or not) that disabled (some or all) modules by
stealth would very soon be found out. I also believe they would
immediately lose all (or, at least, most) of their prospective business
from serious, paying customers. After all, that sort of behaviour
*would* be a major security issue.
As I mentioned in my reply to Mark it is critical for users to know
exactly how any agent they load into their JVM is going to modify the
access restrictions in place in the JVM so that they can be sue that use
of the agent is safe (just as they need to know that any jars they place
into the classpath are not going to do things like round down their
costs and pocket the spare change in a bank account somwehere). Users
don't just add stuff to their classpath without knowing what it does and
why it is appropriate.
Also, that doesn't mean there will be no market for code which
advertises that it is going to change access controls. If users know
what they are getting and know what the consequences are then I am sure
there are cases where they can safely decide whether or not to use a
library that opens up module access. It's the idea that people are going
to be hoodwinked here -- if indeed that is your idea -- that I find
rather difficult to follow. We seem to have moved from dynamic agent
loading being a security issue that didn't seem to have a real basis to
a 'users cannot be entrusted to look after their own classpath' issue
that I find equally as baseless. Is there more to what you are saying
that I have not grasped?
> The attach mechanism was of course never intended to be used this way.
> It was meant for troubleshooting tools and profilers/similar to load
> agents into running VMs. Back in the JDK 6 then we did consider
> disallowing attaching to the current VM but didn't enforce it - one
> reason is that it's not hard to just fork a VM with tools.jar on the
> class path and connect back to the parent.
Well, I understand that this is not what you intended. However, i) it
turns out to have been very useful that it does work this way and ii)
stopping it doing so has a cost which needs to be taken into account --
at the very least by giving those who have been relying on it for quite
some time to manage their business concerns to adjust to the change.
> So that is the context for the discussion. We need to find a good way to
> put the Genie back in its bottle. It may be that we have to disable
> attaching to the current or ancestor VMs. We may have to prohibit the
> instrumentation of core modules by late binding agents. We may have to
> do some disabling of agent loading. Maybe a combination. Suggestions and
> proposals are of course welcome.
I'm very happy to consider all sorts of half-way houses or even -- in
time -- the full change recommended in the original JIRA. For example,
rejecting instrumentation in some specific set of bootstrap/JDK module
classes (like, say, java.base) from an agent which has been dynamically
loaded might well be a workable compromise -- that at least allows users
to employ an agent to tweak any code that is in the classpath through
their choice.
However, whatever compromise we arrive at I'd certainly like time to
adjust to it and hence prefer to see it happen in JDK10.
regards,
Andrew Dinn
-----------
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander
More information about the jigsaw-dev
mailing list