Hi,
We use Hotspot's dynamic attach mechanism in our Thermostat monitoring
tool [1], however we have discovered a bit of a problem with access
control. One of our typical use-cases is to have our agent running as
root, which will monitor all JVMs on the machine. We have noticed that
our agent with root privileges cannot attach to other unprivileged users
VMs, which seems to go against the principle of the root user.
I have attached a Hotspot patch and JDK patch targeting 7u-dev to allow
root to attach to any user's VMs. I'd appreciate it if someone could
take a look.
Thanks,
Elliott
[1] http://icedtea.classpath.org/thermostat/
diff --git a/src/os/linux/vm/attachListener_linux.cpp b/src/os/linux/vm/attachListener_linux.cpp
--- a/src/os/linux/vm/attachListener_linux.cpp
+++ b/src/os/linux/vm/attachListener_linux.cpp
@@ -53,7 +53,7 @@
// 1. The well known file that the socket is bound to has permission 400
// 2. When a client connect, the SO_PEERCRED socket option is used to
// obtain the credentials of client. We check that the effective uid
-// of the client matches this process.
+// of the client matches this process or is root.
// forward reference
class LinuxAttachOperation;
@@ -347,7 +347,9 @@
uid_t euid = geteuid();
gid_t egid = getegid();
- if (cred_info.uid != euid || cred_info.gid != egid) {
+ // root is always allowed
+ if (cred_info.uid != euid && cred_info.uid != 0 || cred_info.gid != egid &&
+ cred_info.gid != 0) {
int res;
RESTARTABLE(::close(s), res);
continue;
@@ -480,7 +482,7 @@
if (ret == 0) {
// simple check to avoid starting the attach mechanism when
// a bogus user creates the file
- if (st.st_uid == geteuid()) {
+ if (st.st_uid == geteuid() || st.st_uid == 0) {
init();
return true;
}
diff --git a/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c b/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c
--- a/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c
+++ b/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c
@@ -356,7 +356,8 @@
/*
* Check that the path is owned by the effective uid/gid of this
- * process. Also check that group/other access is not allowed.
+ * process, unless the effective uid/gid of this process is root.
+ * Also check that group/other access is not allowed.
*/
uid = geteuid();
gid = getegid();
@@ -373,7 +374,8 @@
}
if (res == 0) {
- if ( (sb.st_uid != uid) || (sb.st_gid != gid) ||
+ if ( (sb.st_uid != uid) && (uid != 0) ||
+ (sb.st_gid != gid) && (gid != 0) ||
((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) ) {
JNU_ThrowIOException(env, "well-known file is not secure");
}