Re: Bug#1034392: Acknowledgement (tomcat9: jstack/jcmd broken for non-root users with tomcat9+jdk11 or greater)
Hi,
A short update on this. This is a known regression in more recent
versions of Java: https://bugs.openjdk.org/browse/JDK-8226919
One of my colleagues (thanks, Sebastian!) managed to workaround this by
patching the JDK 17 sources to make it use plain /tmp in this case (when
ns_pid == pid), and also added some better error handling in case this
fails.
We are currently working on getting this submitted upstream to OpenJDK,
but I wanted to share it with you as well. One option would be to
include this in Debian's set of local JDK patches
(https://salsa.debian.org/openjdk-team/openjdk/-/tree/master/debian/patches),
but I don't know how conservative the project is re. fixes like this?
I'll leave this up to the debian-java maintainers to decide.
Best regards,
Per
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java
+++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java
@@ -209,11 +209,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
}
// Return the socket file for the given process.
- private File findSocketFile(int pid, int ns_pid) {
- // A process may not exist in the same mount namespace as the caller.
- // Instead, attach relative to the target root filesystem as exposed by
- // procfs regardless of namespaces.
- String root = "/proc/" + pid + "/root/" + tmpdir;
+ private File findSocketFile(int pid, int ns_pid) throws IOException {
+ String root = findTargetProcessTmpDirectory(pid, ns_pid);
return new File(root, ".java_pid" + ns_pid);
}
@@ -229,21 +226,33 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
// Do not canonicalize the file path, or we will fail to attach to a VM in a container.
f.createNewFile();
} catch (IOException x) {
- String root;
- if (pid != ns_pid) {
- // A process may not exist in the same mount namespace as the caller.
- // Instead, attach relative to the target root filesystem as exposed by
- // procfs regardless of namespaces.
- root = "/proc/" + pid + "/root/" + tmpdir;
- } else {
- root = tmpdir;
- }
+ String root = findTargetProcessTmpDirectory(pid, ns_pid);
f = new File(root, fn);
f.createNewFile();
}
return f;
}
+ private String findTargetProcessTmpDirectory(int pid, int ns_pid) throws IOException {
+ String root;
+ if (pid != ns_pid) {
+ // A process may not exist in the same mount namespace as the caller.
+ // Instead, attach relative to the target root filesystem as exposed by
+ // procfs regardless of namespaces.
+ String procRootDirectory = "/proc/" + pid + "/root";
+ if (!Files.isReadable(Path.of(procRootDirectory))) {
+ throw new IOException(
+ String.format("Unable to access root directory %s " +
+ "of target process %d", procRootDirectory, pid));
+ }
+
+ root = procRootDirectory + "/" + tmpdir;
+ } else {
+ root = tmpdir;
+ }
+ return root;
+ }
+
/*
* Write/sends the given to the target VM. String is transmitted in
* UTF-8 encoding.
Reply to: