Помеченные указатели

Начиная с Android 11, для 64-битных процессов все выделения кучи имеют тег, определенный реализацией, установленный в верхнем байте указателя на устройствах с поддержкой ядра для игнорирования верхнего байта ARM (TBI). Любое приложение, изменяющее этот тег, закрывается, когда тег проверяется во время освобождения. Это необходимо для будущего аппаратных средств с ARM Memory мечения Extension (МГЭ) поддержки.

Старший байт игнорировать

Функция игнорирования верхнего байта в ARM доступна для 64-битного кода на всем оборудовании Armv8 AArch64. Эта функция означает, что оборудование игнорирует верхний байт указателя при доступе к памяти.

TBI требуетсовместимого ядра , что корректно обрабатывает помечены указатели передаются от пользовательского пространства. Android Общие Ядра от 4,14 (Pixel 4) и выше , функция необходимые патчи TBI .

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

Готовность расширения памяти

Расширение тегов памяти (MTE) ARM помогает решать проблемы безопасности памяти. MTE работает помечая на 56 - й-пятьдесят девятой бит адреса каждого выделение памяти в стеке, куче, и глобал. Аппаратное обеспечение и набор инструкций автоматически проверяют использование правильного тега при каждом обращении к памяти.

Android приложения , которые неправильно хранят информацию в верхнем байте указателя гарантированно перерыв на устройстве MTE включена. Тегированные указатели упрощают обнаружение и отклонение неправильного использования верхнего байта указателя до того, как станут доступны устройства MTE.

Поддержка разработчиков

Если в вашем приложении произошел сбой, и вам была предложена эта ссылка, это может означать одно из следующих:

  1. Приложение попыталось освободить указатель, который не был выделен системным распределителем кучи.
  2. Что-то в вашем приложении изменило верхний байт указателя. Верхний байт указателя не может быть изменен, и для устранения этой проблемы необходимо изменить код.

Примеры неправильного использования или модификации указателя верхнего байта.

  • Указатели на конкретный тип имеют специфические для приложения метаданные, хранящиеся в верхних 16 битах адреса.
  • Указатель приводится к удвоению, а затем обратно, теряя младшие биты адреса.
  • Код, вычисляющий разницу между адресами локальных переменных из разных кадров стека как способ измерения глубины рекурсии.

Некоторые приложения могут зависеть от библиотек, которые работают некорректно, когда установлен верхний байт указателя. Мы понимаем, что быстро исправить эти основные проблемы в библиотеках может быть нетривиально. Таким образом , приложение, использующие targetSdkLevel < 30 не будет иметь указатель мечения по умолчанию включено. Мы также предоставляем аварийный люк для приложений , построенных с targetSdkLevel >= 30 , чтобы облегчить переходный период.

Аварийный люк используется, добавив следующую строку в ваш AndroidManifest.xml файл:

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

Это отключит функцию маркировки указателя для вашего приложения. Пожалуйста , обратите внимание , что это не решает основной проблемы здравоохранения код. Этот аварийный люк исчезнет в будущих версиях Android, потому что вопросы такого характера будут несовместимы с MTE .