java периодически не разрешает символьные ссылки в Linux


Я пытаюсь разрешить канонические пути для всех файлов в дереве папок, но по какой-то причине он не разрешает их (и периодически код безопасности JVM будет правильно разрешать символьную ссылку в FilePermission и вызывать ошибку безопасности).

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)

Известная символьная ссылка в системе - это /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, но никогда моими собственными вызовами файла.getCanonicalPath (), как показано выше.

Имеет ли это смысл для кого-нибудь?

2 12

2 ответа:

Мой коллега подтвердил эту проблему на OpenJDK 6u23, но не на каких-либо предыдущих или последующих версиях. Тем не менее, поскольку вопрос имеет

А) обходной путь в виде системного свойства

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

B), по-видимому, решается в более поздней сборке (u24)

, как представляется, мало мотивации, чтобы копать еще глубже.

В Unix символьная ссылка - это "специальный" файл со своими собственными разрешениями.

Тот факт, что у вас есть разрешение на чтение по символической ссылке, не означает, что вы будете иметь его для связанного файла.

Я предполагаю, что вы запускаете свою программу как пользователь, который может прочитать символическую ссылку, но не сам файл.

При входе в режим отладки вы запускаете вызов некоторого метода, который изменяет внутреннее состояние объекта FilePermission, делая его разрешимым в фактический файл и таким образом возвращая вам "ложь".

Когда вы получаете "true", это просто говорит вам, что вы можете прочитать символическую ссылку.

Вместо тебя я проверю разрешение на этот файл.: - /usr / share / java / gnome-java-bridge.jar

И к двум каталогам: - /usr / share - /usr / share / java