A partir de Android 11, para procesos de 64 bits, todas las asignaciones de montón 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 se verifica la etiqueta durante la desasignación. Esto es necesario para el hardware futuro con soporte ARM Memory Tagging Extension (MTE).
Ignorar byte superior
La función Top-byte Ignore 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 un kernel compatible que maneje correctamente los punteros etiquetados pasados desde el espacio de usuario. Los núcleos comunes de Android a partir de la versión 4.14 (Pixel 4) y superiores incluyen los parches TBI necesarios.
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 del montón. Después de esto, se ejecuta una verificación para garantizar 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 utilice 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 se romperá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 falló y se le mostró este enlace, podría significar uno de los siguientes:
- La aplicación intentó liberar un puntero que no fue asignado por el asignador de montón del sistema.
- Algo en su aplicación modificó el byte superior de un puntero. El byte superior del puntero no se puede modificar y es necesario cambiar el código para solucionar este problema.
Ejemplos de uso o modificación incorrecta del puntero del byte superior.
- 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 se convierte en doble y luego retrocede, perdiendo los bits de dirección inferiores.
- Código que calcula la diferencia entre las direcciones de variables locales de diferentes marcos de pila como una forma de medir la profundidad de la recursividad.
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 utilizan targetSdkLevel < 30
no tendrán el etiquetado de puntero habilitado de forma predeterminada. También proporcionamos una trampilla de escape para aplicaciones creadas con targetSdkLevel >= 30
para facilitar el período de transición.
La trampilla de escape se utiliza 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 soluciona el problema de salud del código subyacente. Esta trampilla de escape desaparecerá en futuras versiones de Android, porque problemas de esta naturaleza serán incompatibles con MTE .