Уязвимости в подсистеме eBPF, позволяющие обойти защиту от атак класса Spectre

В ядре Linux выявлена уязвимость (CVE-2021-33624), позволяющая использовать подсистему еBPF для обхода защиты от уязвимостей класса Spectre, дающих возможность определить содержимое памяти в результате создания условий для спекулятивного выполнения определённых операций. Для атаки Spectre требуется наличие в привилегированном коде определённой последовательности команд, приводящих к спекулятивному выполнению инструкций. Через манипуляцию с передаваемыми для выполнения BPF-программами можно добиться генерации подобных инструкций в еBPF и добиться утечки по сторонним каналам содержимого памяти ядра и произвольных областей физической памяти.

Уязвимость вызвана недоработками в верификаторе, который применяется для выявления ошибок и недопустимой активности в BPF-программах. Верификатор перебирает возможные пути выполнения кода, но пропускает варианты ветвления, недопустимые с точки зрения семантики архитектуры набора команд. При выполнении же BPF программы подобные варианты ветвления, не учтённые верификатором, могут быть неверно предсказаны процессором и выполнены в спекулятивном режиме. Например, при анализе операции “load” верификатор рассчитывает, что в инструкции используется регистр с адресом, значение которого всегда находится в заданных границах, но атакующий может создать условия, при которых процессор попытается спекулятивно выполнить операцию с адресом, не соответствующим условиям проверки.

Проблема проявляется начиная с выпуска ядра 4.15 и устранена в форме патчей (1, 2, 3, 4). В дистрибутивах уязвимость пока остаётся неисправленной (Debian, RHEL, Ubuntu, Fedora, SUSE, Arch).

Дополнительно можно отметить заметку о влиянии на производительность средств для защиты от уязвимостей класса Spectre.
В заметке обобщены результаты оптимизации отладчика rr (Record and Replay), в своё время созданного в Mozilla для отладки сложно повторяемых ошибок в Firefox. Кэширование системных вызовов, используемых для проверки существования каталогов, позволило сократить выполнение операции “rr sources” для тестового проекта с 3 минут 19 секунд до 36 секунд.

Автор оптимизации решил проверить, насколько изменится производительность после отключения защиты от Spectre. После загрузки системы с параметром “mitigations=off” время выполнения “rr sources” без оптимизации составило 2 минуты 5 секунд (в 1.6 раза быстрее), а с оптимизацией – 33 секунды (на 9% быстрее). Интересно, что отключение защиты от Spectre не только в 1.4 раза сократило время выполнения кода на уровне ядра (c 2m9s до 1m32s), но и в два раза уменьшило время выполнения в пространстве пользователя (c 1m9s до 0m33s), предположительно из-за снижения эффективности работы кэша CPU и сбросов TLB при включённой защите от Spectre.

Release. Ссылка here.