I’m trying to resolve canonical paths for all the files in a folder tree, but for some reason it will not resolve them (and intermittently the JVM security code will resolve the symlink properly within the FilePermission and cause a security error).
Env:
$ java -version
java version "1.6.0_23"
OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.2)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
A known symlink in the system is /usr/share/java/gnome-java-bridge.jar:
$ ls -l /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
lrwxrwxrwx 1 root root 50 2012-02-24 13:39 /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar -> ../../../../../../share/java/gnome-java-bridge.jar
The following code should resolve this known symlink:
String symlinkedFilePath =
"/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar";
File symlinkedFile = new File(symlinkedFilePath);
System.out.println(symlinkedFile.getAbsolutePath());
System.out.println(symlinkedFile.getCanonicalPath());
but produces:
/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
A further test, using the following code, will sometimes return true for the permission check, but sometimes will return false:
String symlinkedFilePath =
"/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar";
File symlinkedFile = new File(symlinkedFilePath);
FilePermission recursivePermission = new FilePermission(
symlinkedFile.getParentFile().getParent() + "/-", "read");
FilePermission filePermission = new FilePermission(
symlinkedFile.getAbsolutePath(), "read");
System.out.println(recursivePermission);
System.out.println(filePermission);
System.out.println(
"Can read symlink: " + recursivePermission.implies(filePermission));
The typical result is:
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/- read)
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar read)
Can read symlink: true
but when debugging, if I step through the creation of the FilePermission on the target file, internally the path is resolved to the symlink, and the output results in:
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/- read)
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar read)
Can read symlink: false
The problem is that within the context of the app in which the permission checking actually takes place, the symlink is always resolved by the FilePermission object, but never by my own calls to file.getCanonicalPath() as demonstrated above.
Does this make sense to anyone?
A colleague of mine confirmed the issue on OpenJDK 6u23, but not on any prior or following versions. That being said, since the issue has
A) a work around in the form of the system property
B) appears to be resolved in the later build (u24)
there appears to be little motivation to dig any deeper.