12

我正在尝试解析文件夹树中所有文件的规范路径,但由于某种原因它无法解析它们(并且间歇性地,JVM 安全代码将在 FilePermission 中正确解析符号链接并导致安全错误)。

环境:

$ 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)

系统中一个已知的符号链接是 /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

以下代码应解析此已知符号链接:

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());

但产生:

/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

进一步的测试,使用以下代码,有时会返回 true 进行权限检查,但有时会返回 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));

典型的结果是:

(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

但是在调试时,如果我逐步在目标文件上创建 FilePermission,则在内部将路径解析为符号链接,并且输出结果为:

(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

问题是,在实际发生权限检查的应用程序上下文中,符号链接始终由 FilePermission 对象解析,但从来没有通过我自己对 file.getCanonicalPath() 的调用来解析,如上所示。

这对任何人都有意义吗?

4

2 回答 2

4

我的一位同事在 OpenJDK 6u23 上确认了这个问题,但在任何之前或之后的版本上都没有。话虽如此,既然问题已经

A)以系统属性的形式解决

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

B)似乎在以后的构建中得到解决(u24)

似乎没有什么动力去深入挖掘。

于 2012-05-18T13:30:23.680 回答
0

在 Unix 中,符号链接是一个“特殊”文件,具有自己的权限。

您对符号链接具有读取权限这一事实并不意味着您将拥有链接文件的权限。

我的猜测是您正在以可以读取符号链接但不能读取实际文件的用户身份运行程序。

进入调试模式时,您会触发对某些方法的调用,这些方法会更改 FilePermission 对象的内部状态,使其解析为实际文件,从而返回“false”。

当您获得“真实”时,它只是告诉您可以阅读符号链接。

在您的位置,我将检查此文件的权限: - /usr/share/java/gnome-java-bridge.jar

和两个目录: - /usr/share - /usr/share/java

于 2012-05-16T07:30:07.343 回答