À partir d'Android 11, pour les processus 64 bits, toutes les allocations de tas ont une balise définie par l'implémentation dans le premier octet du pointeur sur les appareils compatibles avec le kernel pour l'ignorement du premier octet (TBI, Top-byte Ignore) ARM. Toute application qui modifie cette balise est arrêtée lorsque la balise est vérifiée lors de la désallocation. Cela est nécessaire pour les futurs appareils compatibles avec l'extension d'ajout de balises de mémoire ARM (MTE).
Ignorer le premier octet
La fonctionnalité d'ignorement du premier octet d'ARM est disponible pour le code 64 bits sur tous les matériels Armv8 AArch64. Cette fonctionnalité signifie que le matériel ignore l'octet supérieur d'un pointeur lors de l'accès à la mémoire.
La TBI nécessite un kernel compatible qui gère correctement les pointeurs tagués transmis depuis l'espace utilisateur. Les noyaux communs Android à partir de la version 4.14 (Pixel 4) et les versions ultérieures incluent les correctifs TBI requis.
Les appareils compatibles avec le TBI dans le kernel sont détectés de manière dynamique au début du processus, et une balise dépendante de l'implémentation est insérée dans le premier octet du pointeur pour toutes les allocations de tas. Une vérification est ensuite effectuée pour s'assurer que la balise n'a pas été tronquée lors de la désallocation de la mémoire.
Disponibilité de l'extension Memory Tagging
La Memory Tagging Extension (MTE) d'ARM permet de résoudre les problèmes de sécurité de la mémoire. MTE fonctionne en étiquetant les 56e à 59e bits d'adresse de chaque allocation de mémoire sur la pile, le tas de mémoire et les variables globales. Le matériel et l'ensemble d'instructions vérifient automatiquement que la balise appropriée est utilisée à chaque accès à la mémoire.
Les applications Android qui stockent des informations de manière incorrecte dans l'octet supérieur du pointeur sont garanties pour planter sur un appareil compatible avec MTE. Les pointeurs tagués permettent de détecter et de rejeter plus facilement les utilisations incorrectes du premier octet du pointeur avant que les appareils MTE ne soient disponibles.
Assistance pour les développeurs
Si votre application a planté et que vous avez reçu ce lien, cela peut signifier l'une des choses suivantes:
- L'application a essayé de libérer un pointeur qui n'a pas été alloué par l'outil d'allocation de tas du système.
- Un élément de votre application a modifié l'octet supérieur d'un pointeur. L'octet supérieur du pointeur ne peut pas être modifié. Votre code doit être modifié pour résoudre ce problème.
Exemples d'utilisation ou de modification incorrecte du pointeur d'octet supérieur.
- Les pointeurs vers un type particulier comportent des métadonnées spécifiques à l'application stockées dans les 16 premiers bits d'adresse.
- Un pointeur converti en double, puis en arrière, ce qui perd les bits d'adresse inférieurs.
- Code calculant la différence entre les adresses des variables locales de différents frames de pile afin de mesurer la profondeur de récursion.
Certaines applications peuvent dépendre de bibliothèques qui se comportent de manière incorrecte lorsque l'octet supérieur du pointeur est défini. Nous sommes conscients qu'il peut être difficile de résoudre rapidement ces problèmes sous-jacents dans les bibliothèques. Par conséquent, le taggage du pointeur n'est pas activé par défaut pour les applications qui utilisent targetSdkLevel < 30
. Nous fournissons également une issue de secours pour les applications créées avec targetSdkLevel >= 30
afin de faciliter la période de transition.
Pour utiliser la sortie d'urgence, ajoutez ce qui suit à votre fichier AndroidManifest.xml
:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
Cette opération désactive la fonctionnalité de taggage du pointeur pour votre application. Cela ne résout pas le problème sous-jacent lié à l'état du code. Cette échappatoire disparaîtra dans les futures versions d'Android, car les problèmes de cette nature seront incompatibles avec MTE.