Ab Android 11 haben alle Heap-Zuweisungen für 64‑Bit-Prozesse auf Geräten mit Kernelunterstützung für ARM Top-Byte Ignore (TBI) ein vom Implementierungscode definiertes Tag im obersten Byte des Zeigers. Alle Apps, die dieses Tag ändern, werden beendet, wenn das Tag bei der Deaktivierung geprüft wird. Dies ist für zukünftige Hardware mit ARM Memory Tagging Extension (MTE) erforderlich.
Ignorieren des ersten Bytes
Die ARM-Funktion „Top-Byte Ignore“ ist für 64‑Bit-Code auf allen Armv8-AArch64-Hardwareplattformen verfügbar. Bei dieser Funktion ignoriert die Hardware das oberste Byte eines Zeigers beim Zugriff auf den Arbeitsspeicher.
Für TBI ist ein kompatibler Kernel erforderlich, der getaggte Zeiger verarbeitet, die aus dem Userspace übergeben werden. Android Common Kernels ab Version 4.14 (Google Pixel 4) enthalten die erforderlichen TBI-Patches.
Geräte mit TBI-Unterstützung im Kernel werden beim Starten des Prozesses dynamisch erkannt und ein implementierungsabhängiges Tag wird in das oberste Byte des Zeigers für alle Heap-Zuweisungen eingefügt. Anschließend wird geprüft, ob das Tag bei der Dealokation des Speichers nicht abgeschnitten wurde.
Bereitschaft für Memory Tagging Extension
Die Memory Tagging Extension (MTE) von ARM hilft, Probleme mit der Speichersicherheit zu beheben. MTE funktioniert, indem die 56. bis 59. Adressbits jeder Speicherzuweisung im Stack, Heap und in den globalen Variablen getaggt werden. Die Hardware und der Befehlssatz prüfen bei jedem Speicherzugriff automatisch, ob das richtige Tag verwendet wird.
Android-Apps, die Informationen fälschlicherweise im obersten Byte des Zeigers speichern, funktionieren auf einem MTE-kompatiblen Gerät garantiert nicht. Mit getaggten Pointern lässt sich die falsche Verwendung des obersten Bytes des Pointers leichter erkennen und ablehnen, bevor MTE-Geräte verfügbar sind.
Entwicklersupport
Wenn Ihre App abgestürzt ist und Sie auf diesen Link verwiesen wurden, kann das folgende Ursachen haben:
- Die App hat versucht, einen Verweis freizugeben, der nicht vom Heap-Allocator des Systems zugewiesen wurde.
- Irgendetwas in Ihrer App hat das oberste Byte eines Zeigers geändert. Das oberste Byte des Zeigers kann nicht geändert werden. Ihr Code muss geändert werden, um dieses Problem zu beheben.
Beispiele für eine falsche Verwendung oder Änderung des Top-Byte-Pointers
- In den oberen 16 Adressbits von Pointern zu einem bestimmten Typ sind appspezifische Metadaten gespeichert.
- Ein Pointer wird in „double“ und dann wieder zurück gewandelt, wobei die niedrigeren Adressbits verloren gehen.
- Code, der die Differenz zwischen den Adressen lokaler Variablen aus verschiedenen Stackframes berechnet, um die Rekursionstiefe zu messen.
Einige Apps sind möglicherweise von Bibliotheken abhängig, die sich falsch verhalten, wenn das oberste Byte des Zeigers festgelegt ist. Uns ist bewusst, dass es nicht einfach sein kann, diese zugrunde liegenden Probleme in Bibliotheken schnell zu beheben. Daher ist das Zeiger-Tagging in Apps, die targetSdkLevel < 30
verwenden, standardmäßig deaktiviert. Für Apps, die mit targetSdkLevel >= 30
erstellt wurden, bieten wir außerdem eine Notausstiegsluke, um die Übergangsphase zu erleichtern.
Fügen Sie der Datei AndroidManifest.xml
Folgendes hinzu, um den Notausstieg zu verwenden:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
Dadurch wird die Funktion „Pointer-Tagging“ für Ihre App deaktiviert. Das zugrunde liegende Problem mit der Codequalität wird dadurch nicht behoben. Dieser Ausweg wird in zukünftigen Android-Versionen nicht mehr verfügbar sein, da Probleme dieser Art mit MTE nicht kompatibel sind.