Как стать автором
Обновить

Комментарии 8

Интересная мысль, но в Java перестали пытаться сделать "безопасность" внутри процесса JVM, ибо всё равно получается дыряво. В Java 17 уже сделали то же самое с SecurityManager, а до этого - с апплетами, JWS и прочим подобным.

Не очень понятно, от кого защищается такая "безопасная библиотека".

Можно ведь сделать и без финализатора, если установить ref.set(this); прямо в конструкторе, который потом упадет.

Не выйдет. Если вы роняете конструктор суперкласса, то до конструктора подкласса исполнение не дойдёт. Если же вы роняете конструктор подкласса, то суперкласс будет полностью инициализирован.

Я имею ввиду вот это:

class Main {
    
    private static Main Value = null;
    
    Main (){
        Main.Value = this;
        throw new RuntimeException("OK");
    }
    
    public static void main(String[] args) {
        try{
            Main val = new Main();
        } catch (Throwable e)
        {
            System.out.println(Main.Value.toString()); 
        }
    }
}

Объект в поле Value есть, но он в неизвестном состоянии.

В данном коде вы полностью контролируете класс и можете что угодно написать в конструкторе. В моём примере вы не контролируете класс и можете модифицировать только подкласс.

Я думаю принципиальной разницы нет. Есть немало кода который куда-то передает this из конструктора до его завершения, что может привести ровно к такой же проблеме. И это не последний вариант, если унаследовать, то можно объявить сериализуемым и обойтись без вызова конструктора, можно использовать unsafe, можно Object.clone, все эти методы дают возможность обойти вызов конструктора.

Это не вся правда. Можно конструировать объекты вообще не вызывая конструктор, если вы инстанцируете объект из класса, унаследованного от этой магии:

https://github.com/openjdk/jdk/blob/3789983e89c9de252ef546a1b98a732a7d066650/src/java.base/share/classes/jdk/internal/reflect/MagicAccessorImpl.java

И схожие методы, вероятно, будут всегда, ну или как минимум ещё достаточно долго (есть и более простые, вроде clone или ObjectInputStream).

Найти способ сломать инварианты в подконтрольном вам (даже не полностью)
коде можно условно всегда.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации