Пошумели — разошлись: Meltdown/Spectre спустя месяц

Краткая версия доклада

С января по май 2017 года четыре научных центра в ходе исследований свойств предсказания ветвлений в современных процессорах обнаружили в них ряд уязвимостей. После того, как о потенциальных проблемах были оповещены как вендоры, так и разработчики (Intel, ARM, Linux, Microsoft, Apple), было решено в срок до 9 января 2018 года найти патчи, не ставя в известность широкую публику. Однако уже в декабре 2017 года появилась первая неофициальная информация о наличии проблем, названных Spectre и Meltdown, а 3 января, раньше запланированного срока, о них узнали все. После непродолжительного периода ажиотажа по поводу уязвимостей, когда журналисты и блогеры выступали с зачастую далекими от реальности заявлениями, наступил резкий спад интереса к теме. Спустя месяц после сенсации можно подвести некоторые ее итоги.

Современный процессор может предсказывать ветвления с использованием механизма branch target prediction, что позволяет ему заранее начать вычисления, пока, например, выполняются условия процесса, с задействованием определенного сектора оперативной памяти. В случае с Meltdown выяснилось, что предсказатель перехода, считая возможные решения и отбрасывая ненужные, не проверяет права доступа к памяти. Однако при этом "ненужное" значение попадает в кэш процессора, где его можно так или иначе использовать. Уязвимость Meltdown, благодаря предсказателю перехода, позволяет обойти получение разрешения (permission) на использование регионов оперативной памяти в ядре. Решение проблемы, предложенное многими разработчиками, заключается в том, чтобы не отображать адресное пространство в недоверенный процесс. В целом можно сказать, что среднее кумулятивное падение оперативной памяти при таком решении оказалось не слишком большим, особенно если речь идет о вычислениях, а не множестве операций ввода-вывода.

В ситуации со Spectre потенциальная уязвимость может проявиться при условии, что используется недоверенный код с правами на вывод данных вовне, при этом код имеет доступ к высокоточным таймерам (т.е. имеет возможность измерять скорость выполнения инструкций с высокой точностью), и, кроме того, код исполняется в оптимизированном режиме. В дополнение к этому, уязвимость проявится при наличии хотя бы одного из трех условий: отсутствии обновлений ОС для Meltdown; хранении сенситивной информации в процессе виртуальной машины, к которой недоверенный код потенциально не имеет доступа; доступе атакующего к вводу или выводу данных других процессов, содержащих сенситивную информацию. В совокупности эти условия ведут к тому, что недоверенный код может прочитать сенситивные данные за счет увеличения пространства для возможных атак (attack surface).

Для решения проблемы Google предложил патч Retpoline, решающий проблему в 99% случаях, другие команды разработчиков - набор патчей IBRS/IBPB для оставшегося 1%, однако при этом ведущий к серьезной деградации производительности.

Параллельно разработчики браузеров также включились в разработку исправлений. В основном их идеи свелись к снижению точности (загрублению) высокопрецизных таймеров до 1 мс, а также к отключению возможности доступа к таймерам в ходе циклов, выполняющихся в параллельных тредах. Дополнительно в браузере Chrome была предусмотрена опция полной изоляции сайта (full site isolation), которая предусматривает, что все вспомогательные процессы рендера будут иметь доступ только к одному сайту. Таким образом, если где-то выполняется недоверенный скрипт-код, потенциально эксплуатирующий уязвимость, то, по крайней мере, он не сможет прочесть данные других сайтов.

Разработчики Webkit, в свою очередь, предложили методику "отравления указателей" (pointer poisoning) при которой содержимое отдельного класса данных помещается в отдельную структуру, с созданием указателя, который затем отправляет значения в общий раздел памяти. Кроме того, в Webkit разработали еще одну методику - index masking, предполагающую создание маски к массиву данных, что обеспечивает защиту от атак, содержащих вложения с большим значением в индексе, направляя их в область памяти. Для больших массивов эту методику можно развивать, в частности, использовать кастомный аллокатор.

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