Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java will intermittently not resolve symlinks on Linux

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?

like image 859
Ray Avatar asked Apr 23 '12 00:04

Ray


People also ask

How do I fix a broken symbolic link in Linux?

The only way to fix these broken symlinks is by deleting them. Your system contains hundreds of dangling links and no one has the time to check for these links manually. In such cases, Linux tools and commands prove to be really helpful.

How do I fix too many levels of symbolic links in Linux?

There are two ways to solve the “Too many levels of symbolic links” error. We can pass the source parameter as either an absolute or relative path.

How does symlinks work in Linux?

A symlink is a symbolic Linux/ UNIX link that points to another file or folder on your computer, or a connected file system. This is similar to a Windows shortcut. Symlinks can take two forms: Soft links are similar to shortcuts, and can point to another file or directory in any file system.

How do you check if a file is a symlink Java?

Detecting a Symbolic Link To determine whether a Path instance is a symbolic link, you can use the isSymbolicLink(Path) method. The following code snippet shows how: Path file = ...; boolean isSymbolicLink = Files. isSymbolicLink(file);


1 Answers

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

-Dsun.io.useCanonCaches=false 
OR
-Dsun.io.useCanonPrefixCache=false

B) appears to be resolved in the later build (u24)

there appears to be little motivation to dig any deeper.

like image 84
Ray Avatar answered Sep 21 '22 15:09

Ray