Подтвердить что ты не робот

Java будет периодически прерывать symlinks в 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, но никогда не вызывает мои собственные вызовы file.getCanonicalPath(), как показано выше.

Это имеет смысл для всех?

4b9b3361

Ответ 1

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

A) работа в виде системного свойства

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

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

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

Ответ 2

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

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

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

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

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

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

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