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

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

Это уже не безопасность, а попросту работоспособность. В таких условиях никто уже не может гарантировать, что нормально функционирующая пользовательская программа не произведет подобного же разрушения содержимого памяти.
А вот и нет. Почитайте исходную статью от гугла. Там применяются очень красивые приемы, чтобы случайные изменения битов сначала использовать для выхода из песочница native client, а затем чтобы повысить себе привелегии и писать и читать произвольные места в памяти.
Если кратко, то аллоцируем кучу страниц памяти. RAM забивается вашими страницами и страницами ОС с TLB. В TLB хранятся записи о том, какие страницы памяти вы можете читать и писать. Дальше молотим память. Какие-то биты меняются. Это с большой вероятностью биты либо в ваших страницах, либо в TLB (потому что это большая часть страниц в системе). Если в ваших страницах, то они ничего не рушат. Если в TLB, то с большой вероятностью это биты в адресах страниц, к которым у вас есть доступ (потому что все TLB забиты записями о ваших страницах, которых наплодили на первом этапе). Теперь смотрим, что хранится в наших страницах. В результате того, что мы молотили по памяти и адрес в TLB поменялся ваш процесс мог получить доступ к какой-нибудь другой странице памяти. С большой вероятностью к своей собственной или (с меньшей вероятностью) к TLB (так как TLB страниц тоже много). Во втором случае у нас появиласьвозможность писать в TLB. Но это значит, что мы можем разрешить себе читать и писать в любую угодную нам страницу памяти.
TLB ( translation lookaside buffer) или всё же таблицы страниц? Первое — часть процессора и к ошибкам в модулях памяти отношения не имеет.
Таблицы страниц, я неправильно употребил термин.
что нормально функционирующая пользовательская программа не произведет подобного же разрушения содержимого памяти.

Это тоже не совсем так. Чтобы воспроизвести ошибку надо максимально часто писать в одни и те же ячейки памяти. В обычной программе в такой ситуации работет кеш процессора, поэтому реальная запись в оперативную память происходит редко. Для того, чтобы rowhammer проявился после каждой операции записи производится принудительный сброс данных из кеша CPU в оперативную память. Нормальные программы так не делают.
В докладе про rowhammer написано, что впервые они столкнулись с этой проблемой на серверах при большом количестве DMA запросов, вызванных их Fibre Channel хранилищем. Так что не только сброс кеша может вызвать сбои.
На такой "уязвимой" памяти что выдаёт мемтест86?
Он эту ошибку не находит. memtest пишет большие блоки памяти и сканирует её всю. А для этой ошибки удары должны быть более точечными и надо очень много раз писать строго в одни и те же ячейки памяти.
Окей, но мне кажется, исходя из того, что это просто "битая память" (ну допустим большАя часть памяти таки "битая"), это прямая функция мемтеста, и его недоработка.
В нормальных условиях это будет воплне нормальная память, а не битая.

Для исправления "недоработки" мемтеста придется заставить его работать в экстремальном режиме как и Rowhammer. Это замедлит время работы меместа грубо говоря в миллион раз. Вам действительно нужен мемтест, который работает пару лет?
Почему в миллион раз? Зачем всю память так тестировать? В описании сказано что взломали довольно много систем (применительно к DDR3), значит у многих систем уязвима вся память (или больше половины, ну в общем большой процент)
Rowhammer долбит небольшой сегмент и следит за появлением изменений во всей зарезервированной памяти.

А вы говорите про "исправление" местеста. Если уже делать "полный" тест памяти, то нужно тестировать всю память, не так ли? сраказм

Для всех практических задач предложенное вами "исправление" мемтеста просто не имеет смысла.
Ну уязвимость эксплуатируется не за миллион лет. Почему бы мемтесту не попытаться проэксплуатировать её. Удалось — ошибка. Не удалось — ОК.
Вопрос: что именно вы хотите протестировать мемтестом?

То, что первый попавшийся набор сегментов узязвим (как Rowhammer) или что вся память (все возможные сегменты и их разные комбинации) не имеют узявимости (миллионы лет)?
Первый попавшийся.
Окей. Пусть memtest протестирвовал первый попавшийся сегмент (по методу RowHammer). Тест показал, что проблема не воспроизвелась (на данном сегменте). Какие выводы может сделать memtest? Что память не подвержена проблеме? Но это ведь будет неправда.
Кто сказал что парадигма такая? Может парадигма — либо вся память подвержена, либо нет (на это намекает что уязвимость эксплуатируют, значит часто натыкаются на память где найти проблемное место не составляет труда). К тому же выясняется что в memtest это таки есть: https://habrahabr.ru/company/pt/blog/279749/#comment_8813831
А есть реальные примеры реализации подобной атаки?

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

Как узнать что область памяти, в которую необходимо внести изменения, физически находится рядом с той, которую мы «простукиваем»? Как узнать какие биты поменяются, а какие нет? Смена пары битов приведёт к повышению привелегий? Ну и т.д…

Я может не очень хорошо понял механизм уязвимости, но если проблема в физической близости (одна «строка» памяти) уязвимых блоков к простукиваемым блокам, то почему бы просто не организовывать некую «буферную зону» вокруг важных ячеек, дабы их нельзя было подобным образом менять?
А какие ячейки назвать важными? Программа может получить от чипов памяти достаточную информацию чтобы выяснить её организацию и применить нужный алгоритм. Это конечно будет довольно сложно, но моделей чипов памяти ограниченное количество.
Самая простая защита от этой фигни — на материнке по разному разводить шины адреса и данных. А сами чипы производить со случайным распределением шин данных в каждой странице памяти. Это сильно снизит результативность атаки, и скорей будет приводить к повреждению соседних областей памяти что может приводить к многочисленным аппаратным ошибкам и не может остаться незамеченным.
Кстати дополнительным противодействующим фактором может выступить неизвестное программе распределение ячеек по каналам контроллера памяти когда модуля памяти может быть не один а два или три работающих в многоканальном режиме.
а сами чипы производить со случайным распределением шин данных в каждой странице памяти
Ого! А не разумней ли усилия направить на устранение бага в чипах, могущего доставлять неприятности помимо безопасности.
Судя по тому что баг не исправили — это чрезвычайно трудно и граничит с фундаментальной проблемой. Например, проблема обусловлена плотностью ячеек… и единственный способ её решить это снизить плотность ячеек, т.е. откатится в ёмкости чипа назад…
Конечно, подробностей мало озвучивают почему это происходит… было бы интересно узнать а пока остаётся только строить догадки.
Исправлять баг можно по разному.
У нанд флеша, например, тоже есть фундаментальные проблемы, однако контроллеры с ними успешно борются (хотя на низком уровне проблемы никуда не исчезают).
Чипы со случайным распределением шин на кристалле это security through obscurity, сама проблема при этом остается на месте. При этом производить фактически 100500 разных (пусть и в мелочах) кристаллов может оказаться удовольствием более дорогим, чем даже просто тупо зафигачивать больше битов под ECC.
Однако, это позволит снизить процент успешности атаки и повысить её стоимость. Что вобщем-то тоже было бы неплохо, как дополнительный эшелон в рамках общей системы защиты.
может не очень хорошо понял механизм уязвимости

Это разновидность глич-атаки (Differential Fault Analysis, DFA), первыми заявили в BellCore, затем Ади Шамир и Эли Бихам развили. если мне не изменяет память, Шамир нагреванием вскрывал то ли симки то ли чипы кредиток — при желании можно нагуглить.
Тесты завершались успехом также в случае DDR3-чипов с защитой от Rowhammer под названием ECC (error-correction code).

чего-чего?
В принципе так и есть, если мы меняем посторонние биты в обход ECC то рано или поздно при считывании модифицированной ячейки с высокой вероятностью обнаружим ошибку чётности...
Зарегистрируйтесь на Хабре, чтобы оставить комментарий