В этой публикации представлен перевод вступительной части документа (whitepaper) о новом расширении Armv8.5-A: Memory Tagging Extension (MTE) от компании ARM. MTE стремится повысить безопасность кода, написанного на небезопасных языках, не требуя изменения исходного кода, а в некоторых случаях, не и требуя перекомпиляции. Простое развертывание механизмов обнаружения и предотвращения последствий нарушений безопасности памяти могут предотвратить эксплуатацию большого класса уязвимостей.
Введение
Интернет-червь в 1988 году вывел из строя десятую часть еще зарождающейся в то время сети, а оставшуюся часть сильно замедлил (The Morris Worm). Боле тридцати лет спустя для кода, написанного на Си-подобном языке программирования, остаются актуальными и важными два класса уязвимости памяти. Согласно BlueHat-презентации 2019 года, 70% всех проблем безопасности, решаемых в продуктах Microsoft, вызваны нарушениями безопасности памяти. Аналогичные данные были получены компанией Google для Android: более 75% уязвимостей являются нарушениями безопасности памяти. Хотя многие из этих нарушений были бы невозможны на более современных безопасных языках, база кода, написанного на C и C++, очень обширна. Один только Debian Linux содержит более полумиллиарда строк.
Нарушения безопасности памяти делятся на две основные категории: пространственная безопасность и временна́я безопасность. Эксплуатация нарушений первого типа обычно предназначены для:
- доставки вредоносной полезной нагрузки;
- получение контроля над системой (в цепочке с другими типами уязвимостей);
- организации утечки привилегированной информации.
Нарушение пространственной безопасности происходит, когда обращение к объекту выходит за пределы его истинных границ. Например: переполнение буфера на стеке, что может позволять перезаписывать адрес возврата из функции, что в свою очередь может лечь в основу нескольких типов атак.
Временна́я безопасность нарушается, когда ссылка на объект используется после окончания времени жизни объекта, как правило, после того, как память объекта была перевыделена менеджером памяти. Например, когда тип содержит указатель на функцию, но память контролируемо перезаписывается вредоносными данными, что так же может лечь в основу нескольких типов атак.
MTE предоставляет механизм обнаружения обеих основных категорий нарушений безопасности памяти. С одной стороны MTE может быть использован до боевого развертывания, за счет повышения эффективности тестирования и фаззинга. Обнаружение и устранение уязвимостей до развертывания снижает поверхность атаки развернутого кода. А так же MTE позволяет обнаруживать уязвимости и после развертывания, в реальной работе. Такое обнаружение (после развертывания) поддерживает реактивное исправление уязвимостей до их широкого использования.
Модель угроз
Механизм MTE разработан для обеспечения устойчивости к атакам, пытающимся подорвать исполнение доверенного кода вредоносными данными, предоставленными злоумышленниками. Он не противодействует алгоритмическим уязвимостям или вредоносному программному обеспечению.
MTE разработан для обнаружения нарушений безопасности памяти и повышения устойчивости к атакам, которые возможны в результате таких нарушений. В динамически связанных системах даже старый (legacy) не перекомпилированный код получает преимущества MTE для динамически выделяемых участков памяти.
Применение MTE к памяти стека требует перекомпиляции. Архитектура MTE разработана с предположением, что указатель стека является доверенным. Поэтому при применении MTE к выделениям на стеке важно сочетать использование MTE с другими функциями, такими как Branch Target Identification (BTI) и Pointer Authentication Code (PAC), чтобы уменьшить вероятность того, что существует гаджет, который позволит злоумышленнику получить контроль над указателем стека.
Безопасность памяти с MTE
Memory Tagging Extension реализует доступ к памяти по принципу «ключ-замок» (lock & key). Замок (lock) может быть установлен на память и доступ к такой памяти потребует ключа. Если ключ подходит к замку (совпадает с замком), то доступ разрешается. В противном случае (несовпадение замка и ключа) сообщается об ошибке.
Области памяти помечаются путем добавления четырех битов метаданных для каждых 16 байтов физической памяти. Эти четыре бита и есть тег (Tag Granule). Присвоение тэгов памяти и есть реализация замка (lock).
Указатели (а, следовательно, и виртуальные адреса) модифицируются таким образом, чтобы в них содержался ключ.
Чтобы реализовать биты ключа, не требуя бо́льших указателей, MTE использует функцию игнорирования верхнего байта Top Byte Ignore (TBI) архитектуры Armv8-A. Когда TBI включен, верхний байт виртуального адреса игнорируется при трансляции адреса. Это позволяет хранить метаданные в этом верхнем байте. MTE использует четыре бита верхнего байта для хранения ключа.
На следующем рисунке представлены примеры принципа «ключ-замок» при доступе к памяти:
MTE полагается на то, что замок и ключ отличаются друг от друга при возникновении нарушений безопасности памяти. Поскольку количество бит в теге сильно ограничено (всего 4), невозможно в общем случае гарантировать, что два выделения памяти будут иметь разные теги. Однако, аллокатор памяти может гарантировать, что теги последовательных выделений памяти всегда будут отличаться, и, таким образом, гарантировать, что наиболее распространенные типы нарушений безопасности будут обнаружены.
В более общем случае MTE поддерживает генерацию псевдо-случайных тегов. При достаточно большом количестве запусков программы вероятность того, что хотя бы один из прогонов обнаружит нарушение, стремится к 100%.
От переводчика
На мой взгляд приведенной выше информации достаточно, что бы составить общее впечатление о Memory Tagging Extension в Armv8-A. Для получения более детальной информации об этой технологии стоит прочесть оригинальный документ, в текущей версии которого не переведенными остались следующие разделы:
- Architectural Details
- Deploying MTE at Scale
- Deploying MTE in Hardware
- Deploying MTE in Software
- Optimizing for MTE
Так же нужно отметить, что Google уже анонсировал внедрение MTE в Android (Arm). Причем речь идет не только об отдельной фазе тестирования/фаззинга, но и о повседневном использовании.
Отдельная благодарность пользователю a13xp0p0v и его отличной публикации «CVE-2019-18683: Эксплуатация уязвимости в подсистеме V4L2 ядра Linux», которая зародила интерес к механизму MTE.