【问题标题】:java will intermittently not resolve symlinks on Linuxjava 将间歇性地无法解析 Linux 上的符号链接
【发布时间】:2012-05-03 15:40:40
【问题描述】:

我正在尝试解析文件夹树中所有文件的规范路径,但由于某种原因它无法解析它们(并且 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() 的调用来解析,如上所示。

这对任何人都有意义吗?

【问题讨论】:

  • 您可能希望提交错误报告;我无法在我的 Ubuntu 11.04 系统上使用 openjdk 或 sun jdk 重现最初的 getCanonicalPath() 问题。
  • sarnold,您使用的是确切的 OpenJDK 版本吗?想知道这是否是特定版本中的问题。此外,我刚刚发现,如果我设置 -Dsun.io.useCanonCaches=false 或 -Dsun.io.useCanonPrefixCache=false ,我可以获得规范路径来解决 100% 的时间,但这似乎很奇怪。
  • 很抱歉我没有考虑包含版本号; java -version 报告 OpenJDK Runtime Environment (IcedTea6 1.10.6) (6b22-1.10.6-0ubuntu1) OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode).
  • 不确定是否会有所不同,但请尝试以 root 身份运行您的应用程序。
  • 一个不起眼的远景:如果修改符号链接以定位“绝对”路径,这有什么区别吗? (即/usr/share/java/gnome-java-bridge.jar

标签: java linux permissions openjdk


【解决方案1】:

我的一位同事在 OpenJDK 6u23 上确认了该问题,但在任何之前或之后的版本中都没有。话虽这么说,因为这个问题有

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

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

    【讨论】:

    • 文件和符号链接都对“其他”进行了“读取”,因此这似乎不是问题,层次结构中的目录也是如此。
    猜你喜欢
    • 2021-12-22
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多