Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
[dep, 13Jul2011] We recently had a problem where the Solaris-packaged java help (delivered as an extension) didn't work when used with a strict security policy... but only on some machines. On machines that worked, java would load the java help jar from /usr/jdk/instances/jdk1.6.0/jre/lib/ext/jhall.jar On machines that did not, it would load the jar from /usr/jdk/packages/javax.help-2.0/lib/jhall.jar The former is a symlink to the latter. For correct application of the security policy, it is necessary for the extension to load from the extension directory, not from /usr/jdk/packages. A similar problem is discussed in (4141872). The problem here is slightly different. On these two machines, we are getting different results when Java canonicalizes the symlink. On one machine, we get the symlink, on the other, we get the target. The problem boils down to the implementation of the canonicalization cache, as illustrated by a test case that does nothing but call getCanonicalFile() on the above symlink: # On the functioning machine: $ java -Dsun.io.useCanonPrefixCache=true Test /usr/jdk/instances/jdk1.6.0/jre/lib/ext/jhall.jar $ java -Dsun.io.useCanonPrefixCache=false Test /usr/jdk/packages/javax.help-2.0/lib/jhall.jar # On the malfunctioning machine: $ java -Dsun.io.useCanonPrefixCache=true Test /usr/jdk/packages/javax.help-2.0/lib/jhall.jar $ java -Dsun.io.useCanonPrefixCache=false Test /usr/jdk/packages/javax.help-2.0/lib/jhall.jar It turns out that the two machines -- despite having identical java installations -- had one subtle difference in the installed bits: the raw contents of the /usr/jdk/instances/jdk1.6.0/jre/lib/ext directory are ordered differently (observable using "ls -1U"). This is important because when constructing the URLClassLoader for java.ext.dirs, sun.misc.Launcher just calls list() on each directory to enumerate the jars within. The canonicalization cache, meanwhile, will cache path prefixes found under ${java.home}, passing through all subsequent files found under a previously canonicalized directory. This means that the results from the canonicalization algorithm differ depending on the order lookups are performed. If the first file canonicalized in a directory is a real file, subsequently canonicalized symlinks will be returned unmodified -- i.e. as if they are real files. On the other hand, if the first file canonicalized in a directory is a symlink (or more precisely, all symlinks in a directory canonicalized before a regular file is canonicalized), it will be resolved to its target prior to canonicalization. To put all the pieces together, we were seeing failures on those machines where chance resulted in the jhall.jar symlink being the first .jar file in the extension directory. This resulted in an attempt to load the extension from outside the extension directory, which in turn was considered a violation of the security policy that was in place. It is unfortunate that we must rely on the canonicalization cache in the first place -- as discussed in 4141872, manually resolving symlinks before determining if something falls in your sandbox defeats one of the primary uses of symlinks in Unix. That said, if we must rely on the canonicalization cache, it needs to at least behave in a consistent fashion.
|