Pour savoir comment lire les plantages HWASan, consultez Comprendre les rapports HWASan.
Hardware-assisted AddressSanitizer (HWASan) est un outil de détection des erreurs de mémoire semblable à AddressSanitizer. HWASan utilise beaucoup moins de RAM qu'ASan, ce qui le rend adapté à la désinfection de l'ensemble du système. HWASan n'est disponible que sur Android 10 ou version ultérieure, et uniquement sur le matériel AArch64.
Bien qu'il soit principalement utile pour le code C/C++, HWASan peut également aider à déboguer le code Java qui provoque des plantages en C/C++ utilisé pour implémenter des interfaces Java. C'est utile, car cela permet de détecter les erreurs de mémoire lorsqu'elles se produisent, en vous indiquant directement le code responsable.
Comparé à la version classique d'ASan, HWASan offre les avantages suivants :
- Surcharge processeur similaire (environ 2 fois)
- Surcharge de la taille du code similaire (40–50 %)
- Surcharge RAM beaucoup plus faible (10 à 35 %)
HWASan détecte le même ensemble de bugs qu'ASan :
- Débordement positif/négatif de la pile et du tampon de tas de mémoire
- Bugs "use-after-free" au niveau des tas de mémoire
- Utilisation de la pile en dehors du champ d'application
- Bugs de type "double free"/"wild free"
En outre, HWASan détecte l'utilisation de la pile après le retour.
HWASan (comme ASan) est compatible avec UBSan. Les deux peuvent être activés simultanément sur une cible.
Détails et limites de l'implémentation
HWASan est basé sur l'approche de taggage de la mémoire, où une petite valeur de tag aléatoire est associée à la fois aux pointeurs et aux plages d'adresses mémoire. Pour qu'un accès à la mémoire soit valide, les balises de pointeur et de mémoire doivent correspondre. HWASan s'appuie sur la fonctionnalité ARMv8 "top byte ignore" (TBI), également appelée taggage d'adresse virtuelle, pour stocker le tag de pointeur dans les bits les plus élevés de l'adresse.
Pour en savoir plus sur la conception de HWASan, consultez le site de documentation Clang.
Par conception, HWASan ne dispose pas des zones rouges de taille limitée d'ASan pour détecter les dépassements de capacité ni de la quarantaine de capacité limitée d'ASan pour détecter l'utilisation après libération. C'est pourquoi HWASan peut détecter un bug, quelle que soit l'ampleur du dépassement ou l'ancienneté de la désallocation de la mémoire. Cela donne à HWASan un grand avantage sur ASan.
Toutefois, HWASan dispose d'un nombre limité de valeurs de tag possibles (256), ce qui signifie qu'il existe une probabilité de 0,4 % de manquer un bug lors d'une exécution du programme.
Conditions requises
Les versions récentes (4.14+) du noyau Android commun sont compatibles avec HWASan dès leur installation. Les branches spécifiques à Android 10 ne sont pas compatibles avec HWASan.
La prise en charge de HWASan dans l'espace utilisateur est disponible à partir d'Android 11.
Si vous utilisez un autre noyau, HWASan nécessite que le noyau Linux accepte les pointeurs tagués dans les arguments d'appel système. La prise en charge de cette fonctionnalité a été implémentée dans les ensembles de correctifs en amont suivants :
- ABI d'adresse taguée arm64
- arm64 : supprimer le tag des pointeurs utilisateur transmis au noyau
- mm : éviter de créer des alias d'adresses virtuelles dans brk()/mmap()/mremap()
- arm64 : valider les adresses taguées dans access_ok() appelées à partir des threads du noyau
Si vous effectuez la compilation avec une chaîne d'outils personnalisée, assurez-vous qu'elle inclut tout jusqu'au commit LLVM c336557f.
Utiliser HWASan
Utilisez les commandes suivantes pour compiler l'intégralité de la plate-forme à l'aide de HWASan :
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Pour plus de commodité, vous pouvez ajouter le paramètre SANITIZE_TARGET à une définition de produit, comme aosp_coral_hwasan.
Pour les utilisateurs qui connaissent AddressSanitizer, une grande partie de la complexité de compilation a disparu :
- Il n'est pas nécessaire d'exécuter make deux fois.
- Les compilations incrémentielles sont prêtes à l'emploi.
- Il n'est pas nécessaire de flasher les données utilisateur.
Certaines restrictions AddressSanitizer ont également été supprimées :
- Les exécutables statiques sont acceptés.
- Vous pouvez ignorer l'assainissement de toute cible autre que libc. Contrairement à ASan, il n'est pas nécessaire qu'un exécutable qui lie une bibliothèque soit également assaini si cette bibliothèque l'est.
Vous pouvez passer librement d'une image HWASan à une image normale (ou inversement) si le numéro de build est identique ou supérieur. Il n'est pas nécessaire d'effacer les données de l'appareil.
Pour ignorer la désinfection d'un module, utilisez LOCAL_NOSANITIZE := hwaddress
(Android.mk) ou sanitize: { hwaddress: false }
(Android.bp).
Assainir des cibles individuelles
HWASan peut être activé par cible dans une compilation régulière (non assainie), à condition que libc.so
soit également assaini. Ajoutez hwaddress: true
au bloc de désinfection dans "libc_defaults"
dans bionic/libc/Android.bp. Ensuite, procédez de la même manière dans la cible sur laquelle vous travaillez.
Notez que la désinfection de libc permet le taggage des allocations de mémoire du tas à l'échelle du système, ainsi que la vérification des tags pour les opérations de mémoire à l'intérieur de libc.so
. Cela peut permettre de détecter des bugs même dans les binaires pour lesquels HWASan n'a pas été activé si le mauvais accès à la mémoire se trouve dans libc.so
(par exemple, pthread_mutex_unlock()
sur un mutex delete()
.
Il n'est pas nécessaire de modifier les fichiers de compilation si l'ensemble de la plate-forme est compilé à l'aide de HWASan.
Traces de pile améliorées
HWASan utilise un dérouleur rapide basé sur un pointeur de frame pour enregistrer une trace de la pile pour chaque événement d'allocation et de désallocation de mémoire dans le programme. Android active les pointeurs de frame dans le code AArch64 par défaut, ce qui fonctionne très bien en pratique. Si vous devez dérouler le code géré, définissez HWASAN_OPTIONS=fast_unwind_on_malloc=0
dans l'environnement de processus. Notez que les traces de pile d'accès à une mémoire défectueuse utilisent le dérouleur "lent" par défaut. Ce paramètre n'affecte que les traces d'allocation et de désallocation. Cette option peut être très gourmande en ressources processeur, selon la charge.
Symbolisation
Consultez Symbolisation dans "Comprendre les rapports HWASan".
HWASan dans les applications
Comme AddressSanitizer, HWASan ne peut pas voir dans le code Java, mais il peut détecter les bugs dans les bibliothèques JNI. Jusqu'à Android 14, l'exécution d'applications HWASan sur un appareil non-HWASan n'était pas prise en charge.
Sur un appareil HWASan, les applications peuvent être vérifiées avec HWASan en compilant leur code avec SANITIZE_TARGET:=hwaddress
dans Make ou -fsanitize=hwaddress
dans les indicateurs du compilateur.
Sur un appareil non-HWASan (exécutant Android 14 ou version ultérieure), un paramètre de fichier wrap.sh LD_HWASAN=1
doit être ajouté.
Pour en savoir plus, consultez la documentation pour les développeurs d'applications.