AddressSanitizer assisté par le matériel

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 et versions ultérieures, 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. Il est utile, car il détecte les erreurs de mémoire lorsqu'elles se produisent, ce qui vous permet d'identifier 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 mise en œuvre

HWASan est basé sur l' approche de memory tagging, 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 mémoire soit valide, les tags de pointeur et de mémoire doivent correspondre. HWASan s'appuie sur la fonctionnalité ARMv8 Top Byte Ignore (TBI), également appelée virtual address tagging, 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ébordements ni de la quarantaine de capacité limitée d'ASan pour détecter l'utilisation après libération. Pour cette raison, HWASan peut détecter un bug quelle que soit l'ampleur du débordement ou l'ancienneté de la désallocation de la mémoire. Cela donne à HWASan un avantage considérable 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. Les branches spécifiques d'Android 10 ne sont pas compatibles avec HWASan.

La compatibilité avec l'espace utilisateur pour HWASan 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 compatibilité a été implémentée dans les patchsets en amont suivants :

Si vous effectuez une compilation avec une chaîne d'outils personnalisée, assurez-vous qu'elle inclut tous les éléments jusqu'au commit LLVM c336557f.

Utiliser HWASan

Utilisez les commandes suivantes pour compiler l'ensemble 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 la compilation a disparu :

  • Il n'est pas nécessaire d'exécuter la commande make deux fois.
  • Les compilations incrémentales fonctionnent immédiatement.
  • Il n'est pas nécessaire de flasher les données utilisateur.

Certaines restrictions d'AddressSanitizer ont également disparu :

  • Les exécutables statiques sont compatibles.
  • Il est possible d'ignorer la désinfection de toute cible autre que libc. Contrairement à ASan, il n'est pas obligatoire que si une bibliothèque est désinfectée, tout exécutable qui la lie le soit également.

Vous pouvez passer librement d'images HWASan à des images standards avec le même numéro de version (ou un numéro supérieur). Il n'est pas nécessaire d'effacer l'appareil.

Pour ignorer la désinfection d'un module, utilisez LOCAL_NOSANITIZE := hwaddress (Android.mk) ou sanitize: { hwaddress: false } (Android.bp).

Désinfecter des cibles individuelles

HWASan peut être activé par cible dans une compilation standard (non désinfectée), à condition que libc.so soit également désinfecté. Ajoutez hwaddress: true au bloc de désinfection dans "libc_defaults" dans bionic/libc/Android.bp. Procédez ensuite de la même manière dans la cible sur laquelle vous travaillez.

Notez que la désinfection de libc permet de taguer les allocations de mémoire de tas à l'échelle du système, ainsi que le contrôle des tags pour les opérations de mémoire dans libc.so. Cela peut détecter des bugs même dans les binaires sur lesquels HWASan n'a pas été activé si l'accès mémoire incorrect se trouve dans libc.so (par exemple, pthread_mutex_unlock() sur un mutex delete()ed).

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.

Meilleures traces de pile

HWASan utilise un dérouleur rapide basé sur un pointeur de frame pour enregistrer une trace de 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 du 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 mémoire incorrect traces 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, en fonction de la charge.

Symbolisation

Consultez la section Symbolisation dans "Comprendre les rapports HWASan".

HWASan dans les applications

Comme AddressSanitizer, HWASan ne peut pas voir 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 compatible.

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), vous devez ajouter un fichier wrap.sh définissant LD_HWASAN=1 Pour en savoir plus, consultez la documentation pour les développeurs d'applications.