Punteros etiquetados

A partir de Android 11, para procesos de 64 bits, todas las asignaciones de almacenamiento dinámico tienen una etiqueta definida de implementación establecida en el byte superior del puntero en dispositivos con soporte de kernel para ARM Top-byte Ignore (TBI). Cualquier aplicación que modifique esta etiqueta finaliza cuando la etiqueta se verifica durante la desasignación. Esto es necesario para el futuro hardware con compatibilidad con ARM Memory Tagging Extension (MTE).

Ignorar byte superior

La función Ignorar byte superior de ARM está disponible para código de 64 bits en todo el hardware Armv8 AArch64. Esta característica significa que el hardware ignora el byte superior de un puntero al acceder a la memoria.

TBI requiere unnúcleo compatible que maneje correctamente los punteros etiquetados pasados ​​desde el espacio de usuario. Los núcleos comunes de Android de 4.14 (Pixel 4) y versiones posteriores cuentan con los parches TBI requeridos.

Los dispositivos con soporte TBI en el kernel se detectan dinámicamente en el momento de inicio del proceso y se inserta una etiqueta dependiente de la implementación en el byte superior del puntero para todas las asignaciones de almacenamiento dinámico. Después de esto, se ejecuta una verificación para asegurarse de que la etiqueta no se haya truncado al desasignar la memoria.

Preparación de la extensión de etiquetado de memoria

La extensión de etiquetado de memoria (MTE) de ARM ayuda a abordar los problemas de seguridad de la memoria. MTE funciona etiquetando los bits de dirección 56 a 59 de cada asignación de memoria en la pila, el montón y los globales. El hardware y el conjunto de instrucciones verifican automáticamente que se use la etiqueta correcta en cada acceso a la memoria.

Se garantiza que las aplicaciones de Android que almacenan información incorrectamente en el byte superior del puntero fallarán en un dispositivo habilitado para MTE . Los punteros etiquetados facilitan la detección y el rechazo de usos incorrectos del byte superior del puntero antes de que los dispositivos MTE estén disponibles.

Soporte para desarrolladores

Si su aplicación se bloqueó y se le solicitó este enlace, podría significar uno de los siguientes:

  1. La aplicación intentó liberar un puntero que no estaba asignado por el asignador de almacenamiento dinámico del sistema.
  2. Algo en su aplicación modificó el byte superior de un puntero. El byte superior del puntero no se puede modificar y su código debe cambiarse para solucionar este problema.

Ejemplos del puntero de byte superior que se usa o modifica incorrectamente.

  • Los punteros a un tipo particular tienen metadatos específicos de la aplicación almacenados en los 16 bits de dirección superiores.
  • Un puntero convertido al doble y luego al revés, perdiendo los bits de dirección inferiores.
  • Código que calcula la diferencia entre las direcciones de las variables locales de diferentes marcos de pila como una forma de medir la profundidad de recursión.

Algunas aplicaciones pueden depender de bibliotecas que se comportan incorrectamente cuando se establece el byte superior del puntero. Reconocemos que puede no ser trivial solucionar rápidamente estos problemas subyacentes en las bibliotecas. Como tal, las aplicaciones que usan targetSdkLevel < 30 no tendrán el etiquetado de puntero habilitado de forma predeterminada. También proporcionamos una escotilla de escape para las aplicaciones creadas con targetSdkLevel >= 30 para facilitar el período de transición.

La escotilla de escape se usa agregando lo siguiente a su archivo AndroidManifest.xml :

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

Esto deshabilitará la función de etiquetado de puntero para su aplicación. Tenga en cuenta que esto no aborda el problema de salud del código subyacente. Esta escotilla de escape desaparecerá en futuras versiones de Android, porque problemas de esta naturaleza serán incompatibles con MTE .