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

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

Глобальная ошибка, присутствующая примерно во всех существующих процессорах. Была бы полной жопой, если бы не высокая сложность практической реализации, из-за которой хакеры на неё забьют.
То есть в дальнейшем стоит ждать у журналистов нечто типа «данный зловред не мог быть продуктом вирусописателя-одиночки и значит написан спецслужбой xx»
А это вообще не по сложности зловреда определяется в первую очередь, а по тому, центрифуги какой страны он сломал, ггг.
Журналистами??
Это определяется журналисты какой страны определяют что центрифуги взломали, а не забыли смазать…

Ну и как бы практика показывает, что всегда может появиться какой-нибудь Перельман, который из вредности проработает «сложную в практической реализации» задачу, просто «потому что может».
AMD, похоже, наполовину безопаснее прочих, хотя и непонятно, почему.
вангую, что у них какая-нибудь случайно оказавшаяся ошибка с отбросом «не пригодившихся данных» (например — порча какого-нить бита), поэтому он не дает признака нахождения в кеше. И если раньше они грустили (типа «а могли бы работать на полтора процента быстрее»), то теперь радуются по этому поводу.
У AMD предсказатель ветвлений совсем иначе сделан. AFAIK они строят его на перцептронах, в то время как Intel использует какую-то модификацию TAGE. Считается (были где-то измерения), что TAGE существенно быстрее, однако возможно при этом, что перцептрон сложнее натренировать.

Буду рад, если автор статьи меня поправит.
Вот это исследование: hal.inria.fr/hal-01100647/document. Поведение предсказателя ветвлений в Haswell больше всего похоже на ITTAGE. Использование перцептронов в продукции AMD заявлялось ранее самим производителем (они, правда, как-то более пафосно это называли).
Здесь вопрос, скорее всего, не в верхнем уровне предсказателя, а в нижнем. Как минимум, предсказатель работает с упрощённой схемой адресации, а как максимум, его ещё и кормят только виртуальными адресами, не различая, от какого они процесса.
Меня смущает необходимость передавать параметр в атакуемый процесс. Это сильно усложняет такую хрупкую атаку. А так очень интересно написано.
Там всё очень хрупко, что и позволяет, приняв рюмку коньяка, забить.
Как ни крути АМД получается в выигрыше. Первая атака намного опасней и ее решение съедает производительность. Описанная в этой статье какая-то через чур теоретическая. В живую бы эту атаку пощупать. Подождем, выкатят ли нам патчи.
Kind of. Ну то есть оно какого-то чужого кода не читает, но чтение через следы в кэше демонстрирует.

Оно же с комментарием: github.com/Eugnis/spectre-attack
Понятно, что в стерильных условиях (с целиком собственным кодом, исполняемым в нужные моменты времени) оно работает неплохо. А вот существует ли реально работающий пример, который может сколько-нибудь надежно атаковать код в независимом процессе?
хотя если есть возможность читать из расшаренной памяти, это может помочь. Верней это уберет пункт с необходимостью читать через атакуемый процесс, а можно будет читать в своем процессе. Правда это требует еще более конкретного кода для проведения атаки.
Спасибо за 2 часть.
если бы не высокая сложность практической реализации,

Думаю для направленных атак банков, крупных компаний и прочее могут и сделать троян или еще что.
Главное чтобы на основании этих уязвимостей не нашли чего похлеще…
Там такая сложность, что это реально может только сильный ИИ, похоже, сделать. Вам же надо 100500 проходов и еще запуск приложения на каждый бит информации сделать.
на всякий случай. Правильно понимаю, что и к заявлениям RedHat о том, что уже исправили Spectre (2 случая из трех) access.redhat.com/articles/3311301 стоит относится с настороженностью?
То чувство, когда даже компьютер может изменить тебе.
Получается Итаниумы и Эльбрусы опять, похоже, не подвержены багу.
… как и старые атомы; сугубо в силу своей аппаратной примитивности…
не, бранчпредикшен в атомах есть, они к meltdown нечувствительны.
а, ну тогда понятно, что тоже не влияет.

У кого горит CVE-2017-5715, aka #Spectre branch target injection.


Есть unstable microcode от Intel, можно пробовать лечиться и баловаться.


Changelog:
2018-01-04 — Henrique de Moraes Holschuh hmh@debian.org
intel-microcode (3.20171215.1) unstable; urgency=high


  • Add supplementary-ucode-CVE-2017-5715.d/: (closes: #886367)
    New upstream microcodes to partially address CVE-2017-5715
  • Updated Microcodes:
    sig 0x000306c3, pf_mask 0x32, 2017-11-20, rev 0x0023, size 23552
    sig 0x000306d4, pf_mask 0xc0, 2017-11-17, rev 0x0028, size 18432
    sig 0x000306f2, pf_mask 0x6f, 2017-11-17, rev 0x003b, size 33792
    sig 0x00040651, pf_mask 0x72, 2017-11-20, rev 0x0021, size 22528
    sig 0x000406e3, pf_mask 0xc0, 2017-11-16, rev 0x00c2, size 99328
    sig 0x000406f1, pf_mask 0xef, 2017-11-18, rev 0xb000025, size 27648
    sig 0x00050654, pf_mask 0xb7, 2017-11-21, rev 0x200003a, size 27648
    sig 0x000506c9, pf_mask 0x03, 2017-11-22, rev 0x002e, size 16384
    sig 0x000806e9, pf_mask 0xc0, 2017-12-03, rev 0x007c, size 98304
    sig 0x000906e9, pf_mask 0x2a, 2017-12-03, rev 0x007c, size 98304
  • Implements IBRS and IBPB support via new MSR (Spectre variant 2
    mitigation, indirect branches). Support is exposed through cpuid(7).EDX.
  • LFENCE terminates all previous instructions (Spectre variant 2
    mitigation, conditional branches).

https://debian.pkgs.org/sid/debian-nonfree-amd64/intel-microcode_3.20171215.1_amd64.deb.html

https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf
3.2 Branch Target Injection Mitigation


This mitigation strategy requires both updated system software as well as a microcode update to be loaded to support the new interface for many existing processors.
In particular, the capabilities are:
 Indirect Branch Restricted Speculation (IBRS): Restricts speculation of indirect branches.
 Single Thread Indirect Branch Predictors (STIBP): Prevents indirect branch predictions from
being controlled by the sibling Hyperthread.
 Indirect Branch Predictor Barrier (IBPB): Ensures that earlier code’s behavior does not control
later indirect branch predictions.

(в статье не упоминали, что lfence требует каких-либо обновлений микрокода, называя метод "mitigation strategy is focused on software modifications.")
https://access.redhat.com/articles/3311301 — правки ядра (еще не принято в github.com/torvalds/linux), после которых появляются /sys/kernel/debug/x86/pti_enabled, /sys/kernel/debug/x86/ibpb_enabled, /sys/kernel/debug/x86/ibrs_enabled

Упоминания о LFENCE в Changelog не моего авторства, поэтому пока могу только предполагать.


Тем не менее, стоит обратить внимание, что LFENCE в Changelog упоминается в контексте "Spectre variant #2". Тогда как в публикации Intel в контексте "Bounds Check Bypass Mitigation", т.е. "Spectre variant #1".


Поэтому напрашивается предположения:


  • либо в Changelog очепятка (2 вместо 1) и на разных моделях было отличие в поведении LFENCE, которое исправлено в этом микрокоде;
  • либо поведение LFENCE всё-таки имеет какой-то эффект на "Spectre variant #2", но в публикации Intel это упустили в спешке.
А вот, кстати способ, как можно поменять микрокоды в Windows c помощью драйвера от VMware: How to update microcode from Windows..

P.S. А как микрокоды из deb-файла извлечь?
А как микрокоды из deb-файла извлечь?


DEB — это обычный tar-архив. 7-Zip тот же под виндой спокойно открывает.
Спасибо, сам не догадался попробовать. Распаковал, но вот беда, утилита от VMware использует ASCI вариант, а тут только binary. Ищем/ждем дальше.
теперь без вариантов прийдется весной апгрейдиться на Ryzen 2000, intel давай досвидос
Переделать что-то в Ryzen 2000 без откладывания выпуска этак на год (полгода, если очень оптимистично) никто не успеет.
Ну Meltdown он не подвержен, Spectre v2 вроде тоже (и точно без экспериментального микрокода и падения производительности), а Spectre v1 по-любому подвержены все.
А, ну вообще да, zx80 скорее всего не имел в виду, что там будет что-то поправлено.
Так-то и я укрепился в симпатии к райзенам)
Только под линукс?
Только под всё.
Ну вот, сначала пропали видеокарты, теперь процессоры пропадут…
Зато стоит ожидать увеличения числа старых моделей интелов на вторичном рынке.
Я, конечно, понимаю, что это почти неактуально для рынка, но как дела с этими дырками у NV Denver? Судя по вайтпаперам об архитектуре ядра, он не подвержен Meltdown, а что со Spectre?
Spectre скорее всего оба есть.
Напомню, что ещё одним условием было отсутствие других участвующих в процессе переменных в кэше

Вот этот момент не совсем понятен. Речь о переменных, которые проверяются в условии if (как array_size), или о чем-то еще?

Там и array1_size, и array2 должны быть вне кэша. Первый — чтобы спекулятивное выполнение запустилось, второй — чтобы потом можно было понять, какой индекс мы дёрнули.
мне кажется, что в этом и есть секрет амд… что они предиктивно подтягивают в кеш весь массив.
ну так, диванная теория, основанная на комментариях к toy example с gist'a
ps скорее всего — это глупость
Я немного распишу, чтобы совсем не заминусовали. И мне интересно, возможно ли такое с точки зрения, тех, кто разбирается в работе процессоров.
Это такой себе side-channel инжениринг.
У AMD уже давно кеши больше чем Intel, при этом в производительности на ватт они проигрывают, это показывает серверный сегмент, где считается каждая копейка. Первым делом напрашивается ответ, что это из-за маркетинга «игра в бизнес сегменте проиграна, а пользователям — главное цифры в даташите». Но производство процессоров — вещь недешевая, и если уже, даже ради маркетинга, в процессоре добавлен лишний кеш, — его грех не задействовать. Массив — это указатель на указатели, и в принципе, вытягивание значения из кеша, это операция, которую тоже можно распараллелить, И коль у нас много кеша, то мы можем без потери ресурсов грузить избыточную информацию в кеш, не обязательно первого уровня. Предсказатель встречая выгрузку из массива может жестко загружать весь массив в кеш верхнего уровня, с доставкой нужного значения в кеш первого уровня — это может съекономить такты в будущем, поскольку работа с массивами в большинстве случаев производится в цикле с одним массивом, а лишнего кеша у нас дофига.
Ну и еще пару моментов есть, которые меня подталкивают к этой теории, но как я уже объяснил, все это на грани интуиции и информации из тестов toy example.
Для проверки, я бы попробовал все ри уязвимости, но с более структурами данных чем массивы, мне знаний C и ассемблера на хватит, а более высокоуровневые языки могут все поломать.

Довод против: CPU не знает размер массива.

Не обязательно грузить весь массив, достаточно заполнять 16 линий и атакующий сможет узнать из байта только ниббл.

  1. Фактически вы просто предлагаете увеличить линию кэша в 16 раз.
    1.1. Чего это будет стОить? (Увеличится требуемый объём кэша — точно проц станет допоже; увеличится поток данных из DRAM — возможно, проц станет медленней).
  2. Увеличиваем в 16 раз размер элемента массива — и по прежнему узнаём весь байт.
  3. Допустим, мы можем за раз узнать только нибл. Вот проблема-то — атака замедлилась в два раза.

Но вот если добавить поддержку в компилятор (дать CPU hint — размер массива) — загрузка в кэш всего массива может оказаться выгодной...

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

В статье подробно описано: неуязвимых моделей Intel не будет ещё год или два, а с Intel на AMD это (во всех смыслах, кроме безопасности) так себе апгрейд.
чем плох райзен то?
Тогда уж EPYC(но зачем?)
Гасите его переживания умными словами типа «информационная безопасность» и «IT-шники лучше знают». Ну и похвалите, что он такой умный, взял на работу нормальных специалистов.
Строго говоря, для эксплуатации уязвимости на целевой системе нужно что-то запустить. Яваскрипт в браузере или php на сайт подсунуть — не столь важно — но всё же подсунуть надо. Так что если сценарий открытого подсовывания кода невозможен (например, компания не предоставляет хостинговые услуги), то и риски непонятно откуда возьмутся. Разве что найдутся какие-то другие уязвимости, позволяющие запускать код — но с такими уязвимостями и без процессорных багов можно огрести спам-бота или майнера.
AMD вроде говорили, что у них какой-то особенный branch predictor, основанный на нейросетях. Возможно в этом и кроется причина их неуязвимости к некоторым типам атак.
Нет, скорее эти предсказатели просто кормят разными данными. Если интел в него передаёт виртуальные адреса, не заморачиваясь с их преобразованием в реальные, то предсказатель и не будет два разных процесса друг от друга отличать, нейросети там или нет.
а разве в строке таблиц TLB не указывается адрес инструкции где находится «if()» про который строится предсказание? тогда повлиять на соседний процесс было бы сложнее…
Видимо, не TLB, а предсказателя? TLB тут особо ни при чём.

Указывается. Вопрос только в том, какой это адрес. Как минимум, от него для упрощения жизни могут остаться только сколько-то младших бит, как максимум — он вообще может быть виртуальным, а не физическим.
Не смог распарсить вот этот кусочек:
Как мы помним, Meltdown не работает на процессорах, вовремя — до окончания выполнения — проверяющих условия доступа процесса к чужой памяти даже в случае спекулятивного выполнения.
Там где-то опечатка или ошибка в тексте, но не соображу, где именно.

Нет там ошибки.
Если процессор в режиме спекулятивного выполнения сразу проверяет флаги доступа к страницам памяти, то он не подвержен meltdown.

Свежеиспечённые апдэйты kb4056894 KB4056898 и KB4056897(которые вроде как должны фиксить ситуацию) на многих процессорах AMD вызывают синий экран скоро после перезагрузки или сразу.

www.reddit.com/r/windows/comments/7oap39/patch_windows_7_kb4056894
answers.microsoft.com/en-us/windows/forum/windows_7-update/stop-0x000000c4-after-installing-kb4056894-2018-01/f09a8be3-5313-40bb-9cef-727fcdd4cd56?auth=1

Видимо чтобы подгорало не только у обладателей процессоров intel.
Именно так. Вчера принесли ноутбук, довольно старый, на AMD Turion 64 X2 TL-56. При попытке загрузки, Windows 7 падает в синий экран, который не содержит почти никакой дополнительной информации:
image
Автоматически система не смогла восстановить свою загрузку. Вручную удалось откатить на точку восстановления, которая создалась перед установкой обновления. Потом запретил установку обновления KB4056894.
Важным моментом в атаке, кстати, является пункт «медленно и печально» — если array1_size лежит готовый где-то в кэше, процессор может не заморачиваться со спекулятивным вычислением, а просто быстро посчитать условие. Поэтому array1_size должен быть в ОЗУ, откуда его придётся долго доставать.

Только что проверял у себя на AMD. Видел инвалидацию кеша в примере из статьи — не понимал зачем она там нужна. Сам запускал не пример, а свою реализацию, там размер массива был вообще не в переменной а захардкожен. Аналог переменной x гарантировано был в кеше т.к. её только недавно записали. Всё работало.
На другом проце (тоже AMD) — не работало. Сейчас прочёл эту статью, дописал переменную с размером массива и её инвалидацию — заработало. Так что это не жёсткое требование, где-то работает, где-то нет.


Что особенно цинично, базовую возможность проведения атаки нам обеспечила проверка индекса массива, необходимая для обеспечения безопасности кода.

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

На Linux с включённым BPF

Про FreeBSD тоже было.
А как насчет других BSD?
Проблема не в BPF как таковом, просто именно на BPF продемонстрирована успешная атака.
Для понимания почему на AMD «все так плохо» надо читать спеки NUMA, MOESI, MOESI.
«Еденичные уязвимые приложения» и прочите «гаджеты» — это, прежде всего, браузеры. Spectre позволяет читать память браузера из Javascript. Авторы атаки предоставили POC для Chrome. И именно из-за этого вся движуха со срочными фиксами для браузеров, включением Site Isolation и отключением SharedArrayBuffer — для использования атаки достаточно просто заманить пользователя на сайт. Т.е. это не какая-то теоретическая атака, в которой
всё очень хрупко, что и позволяет, приняв рюмку коньяка, забить.

… а вполне конкретная дырка, как минимум в Chrome.
Эта дырка существует в любой программе, где присутствует выполнение произвольного пользовательского кода в «песочнице», обеспечивающей изоляцию кода от внешнего мира одновременно с выполнением его с правами доступа родительской программы, но не контролирующей возможность создания при компиляции кода последовательностей команд, пригодных для атаки.

Говоря русским языком, позволяет все нужные нам структуры создать своими руками и при этом сразу внутри атакуемого процесса.

Другое дело, что таких мало, я в пользовательском окружении сходу кроме браузера с JS ничего и не назову. В серверном — вон, ядро линукса или BSD с BPF. То есть в общем величина дырки имеет более-менее разумный размер, позволяющий её закрыть.
Другое дело, что таких мало, я в пользовательском окружении сходу кроме браузера с JS ничего и не назову.
А приложение на смартфоне с уязвимым arm может заглянуть дальше песочницы?
Надо специалистов по потрохам Dalvik и ART спрашивать, как там изоляция приложений реализована.

В ART (Android 5.0 и новее) — почти наверняка не может, там приложение при установке компилируется в нативный код, а не в байткод для выполнения в виртуалке, соответственно, методы изоляции должны быть такие же, как для обычного приложения. А через них Spectre ходить не умеет, если заранее не найдёт снаружи готовый подходящий код, на выполнение которого сможет повлиять.
То есть, нужна функция процесса, который работает, с привилегиями выше песочницы, при это произведет чтение нужных данных и еще и положит в доступную нам из песочницы память?
Не обязательно выше, но если мы хотим атаковать не сами себя, а сторонний процесс, то нам нужна определённая последовательность команд, находящаяся либо непосредственно в атакуемом процессе, либо в процессе, который имеет свободный доступ к атакуемому (в ядре, например).
Насколько я помню, во всех андроидах (что до ART, что после) каждое приложение это отдельный пользователь. Т.е. каждое приложение запускается под своим «пользователем», что и обеспечивает песочницу.
Но тут может быть интересный вопрос по поводу того какая часть ядра и/или критичных андроидных сервисов действительно находится за пределами маппинга памяти, а какая просто защищена доступом (а значит потенциально уязвима для Meltdown). Потому что все процессы являются форками «зиготы», которая много фреймворков содержит. Это неплохо для производительности, но сколько интересного в действительности попадает в адресное пространство процесса… Тут сложно сказать
Т.е. каждое приложение запускается под своим «пользователем», что и обеспечивает песочницу


Нет, если у нас есть какая-то виртуальная машина, в которой крутится нескомпилированный код, то этот код будет работать в адресном пространстве и с привилегиями виртуальной машины, как JS в браузерах или BPF в ядрах, а значит, может использовать Spectre напрямую. От того, чтобы он куда не положено не лазил, его сама VM и ограничивает. И «пользователи» — это высокоуровневая сущность VM, к разделению на уровне процессов она не имеет отношения; с точки зрения CPU тут процесс один — сама VM.

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

а значит потенциально уязвима для Meltdown


Meltdown на ARM есть только на самых свежих ядрах.

Основная масса неподдерживаемого барахла на рынке — либо на ядрах, умеющих только Spectre, либо не умеющих вообще ничего.
Нет, если у нас есть какая-то виртуальная машина, в которой крутится нескомпилированный код, то этот код будет работать в адресном пространстве и с привилегиями виртуальной машины, как JS в браузерах ...


Я как раз говорю о том, что каждое приложение в Андроиде (даже до ART) это отдельный процесс под отдельным пользователем (UID связан с приложением) с точки зрения Линукса, который его крутит. Именно так гарантируется песочница (в другой каталог файл не запишешь/не прочитаешь, потому что у процесса, который твою VM крутит нет правов кроме как на запись в свои каталоги, ядро ограничивает ресурсы «на пользователя» и прочее).
Естественно, если не рутить телефон, но это отдельная тема.

Но в каждой этой копии VM есть куча шареной памяти от изначальной зиготы (которая содержит кучу фреймворков). И в каждом телефоне ХЗ чего интересного в этой памяти можно найти, если суметь до нее добраться.
И тут уже интереснее можно ли использовать Spectre и/или Meltdown.

Хотя, очевидно, это все пока что из области ковыряния в носу — реальный хак на этом сделать навряд ли выйдет в обозримое будущее…
Нет, если там целиком форкается VM, и в этом форке крутится ровно одно приложение, со Spectre никаким простым способом оно ничего не добьётся.

Расшаренная память (библиотеки, сам форк и т.п.) никак не поможет, на Spectre нельзя через общую библиотеку перебраться из одного процесса в другой. Любое изменение в этой памяти со стороны процесса вызовет copy-on-write и будет видно только самому процессу.

Meltdown при этом будет работать совершенно спокойно, но Meltdown подвержены только три ядра — A15, A57, A72. На этих ядрах массовость имели самсунговские Galaxy Note и Galaxy S (Exynos), потом MTK Helio X20, потом Snapdragon 650/652/653.

Самсунг с большой вероятностью выпустит патчи, если ещё нет. На Снапдрагоне смартфонов не так много, на MTK на глазок побольше, но это всё уже тонет в массе бюджетных моделей, которые выгоднее делать на сборках дешёвых ядер, без всякого этого вашего big.LITTLE. Так что, если Самсунг из списка вычеркнуть, для атакующих становится уже не особо интересно.
Впрочем, я посмотрел ARM'овскую white paper — зря они ошибку в своих ядрах отнесли к Meltdown, надо было ей отдельный номер давать.

Причина там та же, но их «Variant 3a» позволяет читать не память, а лишь отдельные системные регистры, de jure недоступные непривилегированному процессу.

Тоже неприятно, но не смертельно.
Вы немного не правильно восприняли мой комментарий. Я знаю как работает Spectre и знаю ограничения на его применимость. Я скорее о том, что «забить» не получится — всем придется как минимум пообновлять браузеры. Т.е. почти у всех сейчас установлен дырявый хром, в котором эта уязвимость есть в эксплуатируемом виде. А фикс, по планам, выйдет 23-го января. Вопрос не в величине дырки, вопрос в распространенности. Т.е. да, куча народу прочитала статью. Сколько из них пошло и отключило у себя SharedArrayBuffer?
Т.е. да, куча народу прочитала статью. Сколько из них пошло и отключило у себя SharedArrayBuffer?


Примерно ни один.

Но это локальная проблема, она будет устранена до конца января — как раз с обновлением браузеров проблем никаких нет, они это сами делают.
Все, кроме IE. И кроме энтерпрайзных LTSB, где обновлениями заправляет админ. И кроме тех, кто сидит на хроме под Vista / XP. И кроме браузеров, вшитых в необновляемые бюджетные андроиды.

Да и лично мне от ощущения, что у меня в браузере есть дырка, которая будет там еще пару недель, как-то не по себе.
У меня для вас плохие новости: в вашем браузере (если это конечно не lynx или что-то подобное) этих дырок десятки, и будут они там не несколько недель, а годы. Хуже того, они будут и новые добавляться с новыми версиями.

Под "этих дырок" вы подразумеваете "легко эксплуатируемых дырок известных широкой общественности и разработчикам браузера, которые не торопятся чинить"? — выше же именно это обсуждается. А не просто наличие "каких то дырок". Известных дыр точно десятки? Назовите хотя бы три.

В качестве подтверджения, что размер дырки не имеет никакого отношения к вероятности быстрого ее закрытия — bugs.chromium.org/p/chromium/issues/detail?id=508166
Security: Chrome provides high-res timers which allow cache side channel attacks
Reported by mseaborn@chromium.org, Jul 8 2015

и там же
Jul 15 2015, I have a PoC of the «Spy in the Sandbox» attack that works based on Shared Array Buffers instead of via high-resolution timing.


Конкретную проблему в конретном Chrome зарепортили два года назад. Но PoC на то время позволял всего лишь следить за движениями мышки вне браузера и обнаруживать сетевую активность. Сейчас появился PoC который позволяет через нее читать память процесса, и только после этого производители бразуеров зашевелились и выпустили «патч». Точнее, выпустят через две недели. В виде отключения Shared Array Buffers. В остальных приложениях никто ничего проверять и закрывать не собирается.

А позволяет ли какая-либо из дырок пробить виртуализацию облачных хостингов, например Amazon AWS? Я так понимаю, Meltdown, но не Spectre?
Кстати про предсказание. На Stackoverflow САМЫЙ популярный вопрос за всю историю сайта как раз про это (про предсказание ветвлений). Довольно интересно почитать, рекомендую.

stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array
Интересно, придумали ли уже процессоростроители какую-нибудь команду, чтобы программно пометить предпочтительную ветку исполнения? Чтобы процессор не использовал разные методы предсказания, а точно знал, что если это цикл — то скорее всего исполнение пойдёт на второй круг. а не на выход.

Я не совсем понял, проясните пожалуйста. В статье написано, что при замере времени доступа к каждому элементу массива можно понять, получен ли элемент из кэша, либо вытянут из RAM. Узнать, это одно, а получить данные из кэша от другого процесса — не одно и то же. Правильно ли я понимаю, что при доступе к элементу массива в атакующем процессе он будет в итоге содержать данные из кэша от другого процесса?

Данные из кэша напрямую получить нельзя в принципе.

Однако можно понять, закэшировано ли значение, хранящееся в памяти по определённому адресу, или нет.

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

Meltdown работает именно так. В Spectre есть сложности, связанные с тем, что всю эту схему надо организовать внутри атакуемого процесса, поэтому там могут и более сложные схемы косвенного анализа кэша применяться.

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

Совсем не разбираюсь в процессорных архитектурах (так что ниже может быть написана глупость), но сразу по прочтении появилась следующая идея: подмешивать (путём сдвига адресации) в каждом цикле записи в кэш величину, связанную с идентификатором соответствующей операции MMU. При соответствующем извлечении данных из кэша, выполнять обратную операцию. Таким образом, значения в кэше, соответствующие одному процессу, будут распределены с большей энтропией. Мне кажется, здесь будет минимальная потеря операций за такт. Среди минусов — уменьшение эффективного размера кэша.

Я не знаю, реализуемо ли это путём нового микрокода, или необходимы аппаратные модификации.
Энтропия тут вообще ни при чём. Кэш не знает, от имени какого процесса в него свалились данные, и при этом и сейчас раскидывает их по своему объёму непоследовательно — у него есть алгоритмы, определяющие, какие старые данные уже можно перезаписать новыми, а какие лучше пока придержать. Так что новые данные будут каким-то странным образом по кэшу раскиданы по определению, и этот образ может зависеть от совокупной активности всех работающих в системе процессов, т.е. снаружи он труднопредсказуем.

Если сделать так, что закэшированные одним процессом данные не смогут быть доступны другому (ввести в кэш аналог PCID), то это очень сильно ударит по производительности.
Надо просто вовремя проверять права доступа на запрошенный участок памяти, как это делает AMD. То есть изменить архитектуру процессора таким образом, чтобы эта проверка была не дороже получения самого запрошенного значения из памяти.
Не видно причин, препятствующих безусловному сбросу кеша при переключении процессов. Даже если это происходит аппаратно, например, при входе/возвращении из системного вызова или прерывания, можно устроить так, что в этот момент будет генерироваться исключение, обработчик которого сбросит кеш. Собственно, на производительность это никак не повлияет, поскольку переключение между режимами происходят не слишком часто, а время преключения настолько мало, что даже если его и увеличить в десять раз, то системное время не вырастет даже на сотую процента. В таких приложениях, где тысячи процессов постоянно дергают ввод/вывод, можно все порешать поместив все, что выше аппаратного драйвера, которому действительно требуется режим ядра, в пространство пользователя статической линковкой с библиотеками ввода вывода.
Собственно, на производительность это никак не повлияет, поскольку переключение между режимами происходят не слишком часто


Да, примерно каждые две-три миллисекунды на средне нагруженной системе.

На сколько у вас там предполагается обрушить производительность обнулением кэша каждые 2 мс, процентов на сорок?
можно все порешать поместив все

В смысле, исправить приложение? Каждое? Классное решение, ага.

Если говорить о будущих процессорах, надо дорабатывать логику работы кэша, а не ухудшать его характеристики (внедряя рандомные задержки, внезапные сбросы и т.п.).
Я не совсем понимаю отличие Meltdown и Spectre… То есть, я не понимаю, почему одна из них не является уязвимостью, а вторая (и всё производное) — лишь способом эксплуатации…

Если коротко, то — начнем с этого — само по себе оседание значения в кеше и неочистка его после «отката» — само по себе это не уязвимость?..
Само по себе это незначительная уязвимость.

А вот возможность целенаправленно осадить в кэше значение из закрытой для данного процесса памяти — значительная. Не должно быть у процесса доступа к чужой памяти, ни в каком виде, ни в явном, ни в неявном.
Спасибо!

Просто есть ощущение, что Meltdown — это «Spectre, который проявляется не только в данном процессе, но и в памяти ядра». Я не прав?

Ну правда, у меня ощущение, что есть «основная уязвимость», которая позволяет проанализировать память. Происходит это благодаря механизмам: спекулятивного выполнения, косвенной адресации и измерения таймингов. Для атаки необходимо вынудить нужный процесс сделать нужные действия. Это «как бы Spectre».

А есть вторая уязвимость («как бы Meltdown»), которая позволяет применить этот процесс прямо, из атакующего процесса, т.к. вторая уязвимость — это первая, но косвенная адресация может произойти и в память другого процесса.

Где я не прав? Это не копательство в терминологии, я пытаюсь понять, где я не прав. Спасибо!
Нет, механика у Meltdown и Spectre совершенно разная.

Meltdown достаточно легко устраняется в железе, как устранить первый вариант Spectre, не обрушая производительность процессора, вообще не очень понятно.
Так я наоборот говорю, что Meltdown — «дополнение» к Spectre.

Ну если бы все, что обнаружилось в Spectre, было бы строго неверно (т.е. НЕ работало), то Meltdown был бы возможен?
Да, был бы. Meltdown можно реализовать без тренировки предсказателя ветвлений, чисто на одном только спекулятивном выполнении. Атакуемый процесс никаких вообще действий при эксплуатации Meltdown не выполняет.

Единственное критичное для него условие, помимо наличия спекулятивного выполнения — это запоздалая генерация процессором исключения, в результате чего при спекулятивном выполении не ограничиваются права доступа к памяти.

Прочие меры относятся к «а давайте уберём из процессора кэш» или «а давайте выключим спекулятивное выполнение», это из того же разряда, что и «а давайте лечить головную боль гильотиной».
Прочие меры относятся к «а давайте уберём из процессора кэш» или «а давайте выключим спекулятивное выполнение», это из того же разряда, что и «а давайте лечить головную боль гильотиной».

Да, именно такое ощущение у меня и сложилось. Что основное даже не в спекулятивном выполнении, а в связке
  1. оседание в кеше (не важно, из-за чего),
  2. косвенная адресация (!),
  3. возможность (прямого или косвенного) измерения таймингов косвенной адресации

Но, видимо, этих трех вещей недостаточно, и тут я, наверное, и не понимаю…
Не пытайтесь найти общую причину Meltdown и двух версий Spectre, её нет, это три разные уязвимости. Оседание в кэше — не причина, а следствие их.

1) Meltdown: проверка прав доступа после выполнения спекулятивной инструкции. Достаточно легко устраняется в железе процессора.

2) Spectre №1: тренировка предсказателя ветвлений, позволяющая одному процессу влиять на другой. Устранить без потери эффективности очень сложно.

3) Spectre №2: тренировка предсказателя переходов, позволяющая одному процессу влиять на другой. Устранить с несущественной потерей эффективности можно.
Не верно. Общая причина есть — отпечатки в кеше от спекулятивного исполнения. kuraga333 всё верно пишет — суть тут одна и та же, просто разные методы эксплуатации. В том, что называется spectre, спекулятивное исполнение происходит в нереализуемой ветке if, а в том, что называется meltdown — в нереализуемой ветке «после исключения» (по сути тоже if, но не в коде программы, а в микрокоде/схеме проца, который проверяет права доступа). Первое обходит проверку уровня приложения, второе — проверку уровня архитектуры проца. Сам по себе «обход проверок» (и тренировка предсказателя ветвлений — тоже) — не уязвимость, а суть спекулятивного исполнения. Уязвимость в том что от этого исполнения остаются следы.
А причина головной боли — наличие головы.

Вы не можете отключить спекулятивное выполнение от кэша, оно в этом случае просто потеряет смысл. Разве что сделать для него свой кэш, который будет синхронизироваться с основным.
Я, кажется, понял. Я почему-то думал, что получить осажденным в кеше значение по нужному адресу в предсказуемый момент времени (и на достаточно долго) — легко. Вот если бы это было бы так, то, судя по всему, в сочетании с косвенной адресацией и таймингами, нам бы больше ничего и не нужно было.

Но
Оседание в кэше — не причина, а следствие их [уязвимостей].
, и без Spectre/Meltdown вышеуказанное не легко/невозможно.
А причина головной боли — наличие головы.

Не надо ложных аналогий.


Вы не можете отключить спекулятивное выполнение от кэша, оно в этом случае просто потеряет смысл.

И? это как-то опровергает то что я написал выше? Да, нельзя отключить, а это значит что базовая суть уязвимости принципиально неисправима в данной архитектуре. Можно только затыкать её частные дыро-проявления.


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

Интересная идея, но не поможет. Во-первых, у меня есть подозрение что заметная часть кеша заполняется именно спекулятивными операциями (и без этого эффективность кеша резко упадёт), а, во-вторых, читать задержки можно тоже спекулятивно, хоть и чуть сложнее, таким образом получив доступ и к спекулятивному кешу.

НЛО прилетело и опубликовало эту надпись здесь
Если код, проверяющий наличие данных в кеше, выполнится спекулятивно (а он так скорее всего и выполнится даже если не прикладывать к этому специальных усилий, ну а если не выполнится — поставить перед ним что-то долгое и не нужное, чтобы задержать основной поток выполнения), а потом проц дойдёт до этой инструкции по-честному — он естественно не станет заново выбирать данные, так что затраты времени на выборку будут убраны во время спекулятивного исполнения.
Суть всех этих технологий в том что бы максимально ускорить выполнение операций. А ускорение всегда может быть измерено, как бы вы ни старались этого избежать. Нельзя убрать измеряемый эффект ускорения, не убрав само ускорение (то есть не обесценив то, ради чего изначально затевался и кеш и спекулятивные исполнения).

А насколько сложно было бы просто чистить кэш от следов "несыгравшего" спекулятивного выполнения?

Несложно, но бессмысленно. Не поможет от данного типа аттак после минимального изменения их логики.
НЛО прилетело и опубликовало эту надпись здесь
2) Spectre №1: тренировка предсказателя ветвлений

3) Spectre №2: тренировка предсказателя переходов

Непонятно. Я думал, «предсказатель ветвлений» и «предсказатель переходов» — одно и то же. А здесь подразумевается, что это разные механизмы?

Cкорее всего первое — предсказатель вероятности условных переходов, а второе — предсказатель точки назначения переходов по адресу из переменной. Но разницы по сути всё равно нет — всё это всего лишь разные аспекты забегания вперёд.
>если array2 имеет достаточно валидных индексов (не менее k штук), а мы можем снаружи >более-менее прямым способом побудить атакуемую программу его почитать, то на индексе >k операция чтения выполнится быстрее, чем на других индексах, так как он уже закэширован.

Вот это непонятно, ну да в другой программе что-то закэшировано и будет выполняется быстрее.
А как мы измерим время работы другой программы с точностью необходимой для отличия незакэшированных данных от кэешированный?
Нам нужен любой способ более-менее прямого доступа к интересующему нас массиву, без излишней обёртки с непрогнозируемым временем выполнения (т.е. если там ещё по пути будет сотня-другая инструкций, из которых ни одна не лезет в память — это плохо, но не смертельно).
То есть нам нужен способ вызывать функции другой «программы» почти напрямую, кроме syscall'ов кто-нибудь подпадает под требуемые критерии?

Ведь явно даже программа предоставляющая COM/dbus интерфейс не подходит так как там «оверхед» в виде инструкций работающих с памятью там присутсвует.
Сходу подходит любая программа, исполняющая чужой код в песочнице, не выделяя его в отдельный процесс — тогда мы просто сами сформируем код, который сделает что надо уже в её адресном пространстве. JS в браузерах и BPF в ядрах как пример.

В остальных случаях могут подойти более изощрённые способы атаки, их есть ещё несколько, помимо попыток найти читающийся напрямую массив.
А как узнать что на индексе >k операция чтения выполнится быстрее? Эту же операцию проделывает атакуемая программа. Как мы из вне увидим какой элемент читается быстрее?
Если в программе есть доступная снаружи функция, про которую мы знаем, что она более-менее напрямую запрашивает значения из искомого массива и отдаёт их нам с минимальной, предсказуемой по времени обработкой, то мы просто её запросим.

Спасибо большое за подробное объяснение. Как заставиить атакуемое приложение положить нужные данные в кэш — совсем все понятно. Но хуже всего у атакующего, как я понял с чтением из кэша. Все сводится к угадыванию значения, причем маркером того что угадал правильно является время отклика. Поправьте меня пожалуйста если я не прав.
Собственно вопроса 2:


  1. каким образом злоумышленник анализирует время с нужной точностью и не влияя на исследуемый процесс.
  2. Как убедиться что в кэше есть только нужное значение и ничего больше (про очищение кэша понятно, но ведь в это время в него пишут сотни запущенных и продолжающих работать процессов, + само атакуемое приложение может писать много чего)
1. У x86 попросту есть доступный из кода таймер, считающий такты процессора, доступный по единственной ассемблерной команде. Точнее и быстрее измерять время особо уже некуда.

2. Маловероятно, что кто-то будет случайно в то же время — а оно очень небольшое, это доли микросекунды — читать тот же или близкий участок памяти. На практике error rate получается 0,02-0,03 % на сканировании десятков мегабайт памяти на живой системе.
Спасибо
Если я правильно понял то если, к примеру, я буду сам собирать программы из исходников, и мой компилятор будет немного необычен (возможно будет добавлять немного «магии» к конкретным используемым адресам памяти) то вся эти история с Meltdown, Spectre и т.д. для меня будет выглядеть давольно прохладно (код с конкретными адресами есть только у меня, а без конкретных адресов атака неосуществима).

Т.е. open-source получает преимущество)
Meltdown'у ваши программы вообще не нужны для работы. Адрес процесса он достанет из ядра, адрес паролей внутри процесса — уж найдёт как-нибудь.
А в ядро он как залезет?
Я не очень хорошо понимаю как выделяется память под ядро, там какие-то предопределенные адреса? А если я сам своим компилятором ядро собрал?
Да чем бы ни собирали, у вас есть системные вызовы функций из ядра, программа как-то по ним попасть должна — значит, адреса знает.
т.е. преимущество у open-source, собранного самостоятельно из исходников «персонофицированным» компилятором и работающем на AMD (или еще чем-то не подверженном Meltdown)
Судя по описанию уязвимости все тесты синтетические. Для каждого отдельного атакуемого куска кода нужно писать отдельную реализацию. И реализация может занять много времени, так как чтобы довести вероятность перехвата до 100%, нужно тестировать на конкретном процессоре и конкретном ПО. Т.е. на другом процессоре все может пойти не так, верно?
В общем эта атака видиться на вполне конкретные важные цели, а не на обычного массового пользователя и ее нельзя использовать в ботнетах.
правильно ли я понимаю, что предиктор переходов для каждого ядра свой? и атакующий процесс должен работать на том же ядре, что и атакуемый?
Да.
А подскажите пожалуйста, данная уязвимость может украсть данные из, скажем, Java-программы?

Вопрос вот о чем, поидее java-байткод компилируется каждый раз при запуске кода (да, есть возможности оптимизации, но по-умолчанию машиннозависимый код не храниться между запусками программы), и вроде как предсказать адреса памяти невозможно (в том смысле что непонятно как)
Компилируется-то он каждый раз, но при известной версии явы результат этой компиляции так же каждый раз немного предсказуем.
А можете в двух словах пояснить или ткнуть где почитать, не понимаю вот какой момент:

Я запустил Java-машину, ей ОС для работы выделила кусок свободной памяти.
Поидее предсказать заранее какой диапазон адресов достанется программе как минимум трудно.
Далее Java-машина забрала байткод и стала генерировать платформозависимые инструкции, которые уже привязываются к реальным адресам памяти.

Да, если считать адреса переменных в памяти относительно начала выделенной Java-машине области то вероятно получится +- одни и те же адреса, но ведь для того чтобы украсть из них данные с помощью Spectre нужно знать абсолютный адрес. Или нет?

Не понимаю как решается вопрос вычисления в такой ситуации точного адреса переменной при неизвестном адресе начала выделенной Java-машине памяти.
Гипотетически может, но не будет. Не интересно. Гораздо выгоднее писать эксплойт для повышения привилегий в системе, а уже потом, имея высший уровень вытаскивать данные более простыми способами.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации