A partir de Android 11, para los procesos de 64 bits, todas las asignaciones de montón tienen una etiqueta definida por la implementación establecida en el byte superior del puntero en dispositivos con compatibilidad del kernel para la función Top Byte Ignore (TBI) de ARM. Cualquier app que modifique esta etiqueta se cerrará cuando se verifique durante la desasignación. Esto es necesario para el hardware futuro con compatibilidad con la extensión de etiquetado de memoria (MTE) de ARM.
Omisión del byte superior
La función Top-byte Ignore de ARM está disponible para el código de 64 bits en todo el hardware Armv8 AArch64. Esta función significa que el hardware ignora el byte superior de un puntero cuando accede a la memoria.
TBI requiere un kernel compatible que controle correctamente los punteros etiquetados que se pasan desde el espacio de usuario. Los kernels comunes de Android a partir de la versión 4.14 (Pixel 4) y versiones posteriores incluyen los parches de TBI necesarios.
Los dispositivos con compatibilidad con TBI en el kernel se detectan de forma dinámica en el momento del inicio del proceso y se inserta una etiqueta dependiente de la implementación en el byte superior del puntero para todas las asignaciones de montón. Después de esto, se ejecuta una verificación para garantizar que la etiqueta no se haya truncado cuando se desasignó 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 del 56 al 59 de cada asignación de memoria en la pila, el montón y las secciones 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 apps para Android que almacenen información de forma incorrecta en el byte superior del puntero fallarán en un dispositivo compatible con 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.
Asistencia para desarrolladores
Si tu app falló y se te mostró este vínculo, podría significar una de las siguientes situaciones:
- La app intentó liberar un puntero que no asignó el asignador de montón del sistema.
- Algo en tu app modificó el byte superior de un puntero. No se puede modificar el byte superior del puntero, y se debe cambiar el código para corregir este problema.
Ejemplos de uso o modificación incorrectos del puntero de byte superior
- Los punteros a un tipo en particular tienen metadatos específicos de la app almacenados en los 16 bits de dirección superiores.
- Un puntero se convierte a doble y, luego, a la inversa, lo que pierde 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 la recursividad.
Es posible que algunas apps dependan de bibliotecas que se comportan de forma incorrecta cuando se configura el byte superior del puntero. Reconocemos que podría ser
complicado solucionar estos problemas subyacentes en las bibliotecas con rapidez. Por lo tanto, las apps que usan targetSdkLevel < 30
no tendrán habilitada la etiqueta de puntero de forma predeterminada. También proporcionamos una escotilla de escape para las apps compiladas con targetSdkLevel >= 30
para facilitar el período de transición.
Para usar la salida de emergencia, agrega lo siguiente a tu archivo AndroidManifest.xml
:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
Esto inhabilita la función de etiquetado de punteros para tu app. Esto no soluciona el problema de estado del código subyacente. Esta salida de emergencia desaparecerá en versiones futuras de Android, ya que los problemas de este tipo serán incompatibles con MTE.