Есть ли способ выполнить небезопасный код (отключить менеджер безопасности) в Java?

Пожалуйста, не публикуйте ответ, говорящий "ты не должен этого делать". Я не планирую использовать это в производственном коде, но только для развлечения.

Отвечая на этот вопрос, я хотел запустить произвольный небезопасный код Java для развлечения. Рассматриваемый код включает в себя поиск только конечных узлов Java TreeMap,

Запуск приведенного ниже кода приводит к

Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util

По этому вопросу я могу использовать System.setSecurityManager(null) чтобы обойти большинство из этих ограничений. Но я не могу этого сделать, потому что ошибка появляется, когда загружается мой класс.

Я уже знаю, что могу сделать все, что захочу, используя отражение после отключения диспетчера безопасности. Но это сделало бы код намного ужаснее. Как разработчики ядра Java пишут свои модульные тесты, например, если они не могут упаковать вещи в java.util ?

Я тоже пробовал -Djava.security.manager=... но это вызывает ошибку инициализации JVM, когда я устанавливаю его null, и я не уверен, что еще я могу установить это. Есть идеи?

package java.util;

import java.util.TreeMap.Entry;

public class TreeMapHax {

    static <K,V> List<Entry<K, V>> getLeafEntries(TreeMap<K, V> map) {      
        Entry<K, V> root = map.getFirstEntry();
        while( root.parent != null ) root = root.parent;

        List<Entry<K,V>> l = new LinkedList<Entry<K,V>>();
        visitInOrderLeaves(root, l);
        return l;
    }

    static <K,V> void visitInOrderLeaves(Entry<K, V> node, List<Entry<K, V>> accum) {       
        if( node.left != null ) visitInOrderLeaves(node.left, accum);       
        if( node.left == null && node.right == null ) accum.add(node);      
        if( node.right != null ) visitInOrderLeaves(node.right, accum);
    }

    public static void main(String[] args) {
        TreeMap<String, Integer> map = new TreeMap<String, Integer>();

        for( int i = 0; i < 10; i++ )
            map.put(Integer.toString(i), i);

        System.out.println(getLeafEntries(map));
    }

}

3 ответа

Просто ответить на ваш вопрос, нет обычного способа

классы в java.* ограничены не менеджером безопасности, они ограничены загрузчиком классов.

Что бы вы ни хотели, вам нужно как-то найти способ взломать JVM. или просто делай, как ты упомянул, делай это с отражением. или просто создайте копию (исходный клон) treemap в вашем собственном пакете.

Я думаю, что вы можете попробовать создать jar для своего пользовательского пакета Java и поместить его в $JRE_HOME/lib/ext и увидеть магию!!

Если вы создадите пользовательский java.lang.SecurityManager со всей заглушенной логикой безопасности и скомпилируете его в пользовательскую JVM, вы сможете ссылаться на него впоследствии, установив свойство "java.security.manager" в свой собственный менеджер.

Поскольку свойство читается программой запуска перед запуском вашей программы, вы должны иметь свой собственный SecurityManager в одобренном пути к классам JVM, а не свою собственную программу (например, включенную в основной файл rt.jar).

Чтобы ответить на ваш вопрос о том, как с этим справляются разработчики ядра: такие тесты, скорее всего, будут выполняться на пользовательской JVM, поскольку они не придерживаются традиционной безопасности производственной JVM. Один пример такой заглушки можно найти здесь.

Другие вопросы по тегам