HWAddress Sanitizer

Le NDK Android est compatible avec HWAddress Sanitizer, également appelé HWASan, à partir du NDK r21 et d'Android 10 (niveau d'API 29). HWASan n'est disponible que sur les appareils Arm 64 bits.

HWASan est un outil de détection des erreurs de mémoire semblable à ASan. 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 ou 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" ou "wild free"

En outre, HWASan détecte également les utilisations suivantes :

  • Utilisation de la pile après le retour

Application exemple

Une application exemple indique comment configurer une variante de compilation pour HWASan.

Créer

Pour compiler le code natif (JNI) de votre application avec HWAddress Sanitizer, procédez comme suit :

ndk-build

Dans votre fichier Application.mk :

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake

Dans le fichier build.gradle de votre module :

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

Pour chaque cible de votre fichier CMakeLists.txt :

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

Avec le NDK 27 ou version ultérieure, vous pouvez également utiliser ce qui suit dans votre build.gradle et vous n'avez pas besoin de modifier CMakeLists.txt:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

Cela ne fonctionnera pas avec ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false.

Android 14 ou version ultérieure : ajouter wrap.sh

Si vous utilisez Android 14 ou une version ultérieure, vous pouvez utiliser un script encapsulé pour exécuter votre application débogable sur n'importe quel appareil Android. Vous pouvez ignorer cette étape si vous avez choisi de suivre les étapes des instructions de configuration.

Lisez les instructions d'empaquetage d'un script wrap.sh afin d'ajouter le script wrap.sh suivant pour arm64-v8a.

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

Exécuter

Si vous utilisez une version d'Android antérieure à la version 14 ou que vous n'avez pas ajouté de script wrap.sh, suivez les instructions de configuration avant d'exécuter votre application.

Exécutez l'application comme d'habitude. Lorsqu'une erreur de mémoire est détectée, une application plante avec SIGABRT et affiche un message détaillé dans logcat. La copie de ce message se trouve dans un fichier sous /data/tombstones et se présente comme suit:

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

Le message peut être suivi d'informations de débogage supplémentaires, telles que la liste des threads en direct dans l'application, les balises d'allocations de mémoire à proximité et les valeurs d'enregistrement du processeur.

Pour en savoir plus sur les messages d'erreur HWASan, consultez Comprendre les rapports HWASan.

Créer des exécutables de ligne de commande

Vous pouvez créer et exécuter des exécutables instrumentés avec HWASan sur Android 14 et versions ultérieures. Vous pouvez utiliser la même configuration que celle décrite dans la section Compilation pour ndk-build ou CMake pour vos exécutables. Transférez les exécutables vers un appareil équipé d'Android 14 ou version ultérieure, puis exécutez-les normalement à l'aide du shell.

Si vous utilisez libc++, assurez-vous d'utiliser la STL partagée, de la transférer sur l'appareil et de définir LD_LIBRARY_PATH sur le répertoire qui la contient lorsque vous exécutez votre binaire.

Si vous n'utilisez pas Gradle, consultez la documentation du NDK pour découvrir comment compiler à partir de la ligne de commande avec CMake et ndk-build.

Android 13 ou version antérieure : configuration

Si votre appareil est équipé d'Android 14 ou version ultérieure, vous pouvez ignorer cette étape et suivre les instructions d'utilisation de wrap.sh dans la section Compiler. Vous pouvez également suivre cette section et ignorer les instructions d'utilisation de wrapper.sh.

Pour les versions antérieures à Android 14, les applications HWASan nécessitent l'exécution d'un build HWASan Android. Vous pouvez flasher des images HWASan prédéfinies sur les appareils Pixel compatibles. Les builds sont disponibles sur ci.android.com, où vous pouvez cliquer sur le carré correspondant au build exact que vous souhaitez afin d'obtenir un lien Flash Build (Flasher un build). Pour cela, vous devez connaître le nom de code de votre téléphone.

Flasher un build sur un appareil

Il peut être plus simple d'accéder directement à flash.android.com, car ce flux commence par détecter votre appareil et vous montre uniquement les versions que vous pouvez utiliser. Les images suivantes illustrent le processus de configuration de cet outil.

Activez le mode développeur sur votre appareil et connectez-le à votre ordinateur à l'aide d'un câble USB. Cliquez sur Ajouter un appareil, sélectionnez votre appareil dans la boîte de dialogue, puis cliquez sur Connecter.

Détecter un appareil à flasher Sélectionner l'appareil auquel se connecter

Une fois votre appareil connecté, cliquez dessus pour configurer le build. Dans la zone Sélectionner un ID de build, sélectionnez la branche aosp-master-with-phones-throttled pour choisir automatiquement l'image adaptée à l'appareil que vous avez connecté.

Sélectionner l'appareil à flasher Confirmer les options flash et flasher l'appareil

Cliquez sur Installer pour flasher l'appareil.

Pour en savoir plus sur la configuration nécessaire, consultez la documentation d'Android Flash Tool. Vous pouvez également consulter la documentation AOSP pour découvrir comment créer une image HWASan à partir de la source.