Это означает, что JVM никогда не обманывается, думая, что объект является типом, которого нет. Обманывать время выполнения, думая, что часть данных имеет другой тип, представляет собой мощный вектор атаки, особенно если вы можете обмануть время выполнения, позволяя присвоить значение тому, что, по его мнению, long
или int
, но на самом деле является указателем.
Основополагающая модель безопасности JVM опирается на объект, являющийся типом, который считает время выполнения .
Я прочитал увлекательную бумагу, в которой подробно описывается атака на машину, на которой работает Java, в которой используется лампа высокой температуры, чтобы резко увеличить ошибки памяти. Затем они использовали программу с миллиардами объектов, стратегически выровненную в памяти, и ждали, что у нее будет спорадический бит. Это привело к тому, что JVM подумал, что имеет дело с другим типом объекта и в конечном итоге разрешает JVM запускать произвольный код (для полного чтения см. Using Memory Errors to Attack a Virtual Machine).
Тот факт, что они использовали бит флип, не имеет отношения к Generics. Но способность обманывать среду исполнения в мышлении объекта другого типа подробно описана в этой статье. Подводя итог, представьте, что вы есть классы A
и B
:
class A {
public long data = 0;
}
class B {
}
Если вы можете как-то обмануть JVM, чтобы позволить этому:
A aButActuallyB = someMagicAssignment(new B());
Где someMagicAssignment
это метод, который может взять ссылку на B
и как-то вернуть объект референта как A
. Затем подумайте о том, что будет на самом деле произойдет, когда вы тогда сделали:
aButActuallyB.data = 0x05124202;
Вы можете писать в произвольные данные в сыром памяти JVM в! Эти данные могут быть, например, местоположением метода. Изменение его, чтобы указать на содержимое некоторого байтового массива, может позволить вам запустить произвольный код.
Так что, когда Oracle говорит
безопасность типа и целостность виртуальной машины Java никогда не рискует, даже при наличии непроверенных предупреждений.
Что это говорит, что несмотря на то, что вы можете сделать это:
public static <T> T someMagicAssignment(B b){
return (T) b; //unchecked cast warning
}
И затем вызвать его:
A a = MyClass.<A>someMagicAssignment(new B());
Это все еще собирается сделать проверку выполнения на присвоение - a
.
Таким образом, запись этого метода someMagicAssignment
не проще, чем раньше. Дженерики никоим образом не увеличили площадь поверхности этого вектора атаки, поскольку JVM игнорирует дженерики в своей системе внутреннего типа. Никогда JVM не позволит вам дать метод List<String>
, а затем выполнить этот метод String
операций над элементами этого списка, не проверяя при этом, что эти элементы фактически являются String
. Никогда не разрешите вам обрабатывать B
как A
без проверки вручную.
так что значит «под угрозой»? можете ли вы привести пример того, когда JVM «находится под угрозой»? –
Смотрите мое обновленное сообщение. –
Я понимаю ваше объяснение стирания стилей, но, если я пишу Список stringList = Arrays.asList («один», «два», «три»); Целое число = (целое число) stringList.get (0); не является ли JVM под угрозой? –