RFR: 8200559: Java agents doing instrumentation need a means to define auxiliary classes [v2]

Alan Bateman Alan.Bateman at oracle.com
Mon Apr 19 15:18:15 UTC 2021

On 19/04/2021 15:10, Peter Levart wrote:
> :
> I hear Rafael that dynamic attach is important to support monitoring and instrumenting large numbers of JVMs with no preparations (i.e. without issueing special command-line options to enable it). As I understand, current attach mechanism is designed to allow a process running under the same UID as the JVM or under root to attach to the JVM.
> What if this dynamic attach mechanism was modified so that only a process running under root could dynamically attach to the JVM? Old behavior would be enabled by special command line option, so by default, dynamic attach would be limited to tools running under root. Rafael mentions discovery, monitoring and instrumenting large number of JVMs running on hosts, so if one such tool has to attach to different JVMs running under different UIDs, it has to run as root now anyway.
> With such default "secure" dynamic attach and when the JVM is not running as root (which is a recommended security practice anyway), a library in such JVM could not attach back to the same JVM even through spawning sub-processes.
> How to achieve such "secure" dynamic attach? One way that comes to mind 
is a modified handshake. Currently, I think at least on Linux, the tool that wishes to attach to the JVM searches for a special UNIX socket (`$PWD/.java_pid<vmid>`, `/tmp/.java_pid<vmid>`) and if not found, creates a special attach file (`$PWD/.attach_pid<vmid>`, `/tmp/.attach_pid<vmid>`) to 
signal the JVM to create a listening UNIX socket under mentioned special path, then it connects to the socket. The UNIX socket file has UID:GID set to effective UID:GID of the JVM process and permissions to 0600, so only a tool running under same UID or root can connect to such socket.
> In modified handshake, JVM not running as root could not create a UNIX socket file with permissions to allow only root user to connect to it, but a tool running under root could create a listening UNIX socket with permission to allow JVM to connect to it in a way that the JVM connecting to 
such socket would know that the listening process is running as root. Simply by checking the owner of the listening UNIX socket file. Such socket file would have to have permission 0666 in order to allow JVMs running under any UID to connect to it, but otherwise be "hidden". This can be achieved by the tool creating a special directory and a UNIX socket in this directory, say: `/tmp/.attach_dir<tool pid>/<random string>`, The directory UID:GID would be 0:0 and have permission 0711. This means, any user could connect to the socket as long as it knows the `<random string>`, but no user but root can list the content of the directory to discover the name of the socket file. The last piece of the puzzle
>    is how to signal to the JVM about the name of the socket file. Well, 
creating a file with the content holding the name of the socket file would be OK, as long as only target JVM could read it. File permissions could 
be set such that any process running under the same UID as the JVM could read the file. This would give a rouge library a chance to connect to the 
tool and pretend to be the monitoring JVM, but it could not connect to back to the JVM though...

One initial comment is that the attach mechanism is also used for the 
troubleshooting tools (jcmd, jstack, jmap, ...). This is how tools start 
the JMX agent in the target VM, or request a stack trace or heap dump, 
to name a few. It's just the loading of JVMTI agents that would need to 
be restricted (Java agents use the JPLIS JVMTI agent).

A second comment is that the attach mechanism on Linux and macOS is 
based on Unix domain sockets and the effective uid/gid of the peer is 
available. So if you are exploring here then you should be able to just 
use that rather than changing the handshake. The Windows implementation 
injects a stub into the target VM to queue the command so there isn't 
the equivalent.


More information about the core-libs-dev mailing list