כלי לחיטוי של HWAddress

‫Android NDK תומך ב-HWAddress Sanitizer, שנקרא גם HWASan, החל מ-NDK r21 ומ-Android 10 (רמת API‏ 29). ‫HWASan זמין רק במכשירי Arm‏ 64 ביט.

‫HWASan הוא כלי לזיהוי שגיאות זיכרון שדומה ל-ASan. בהשוואה ל-ASan הקלאסי, ל-HWASan יש:

  • תקורה דומה של CPU ‏ (~2x)
  • תקורה דומה של גודל הקוד (40-50%)
  • תקורה קטנה בהרבה של RAM‏ (10% עד 35%)

‫HWASan מזהה את אותה קבוצה של באגים כמו ASan:

  • גלישה או חריגה ממאגר (buffer) בערימה או במחסנית
  • שימוש בערימה אחרי שחרור
  • שימוש ב-Stack מחוץ להיקף
  • חינם כפול או חינם לכל

בנוסף, HWASan מזהה גם:

  • שימוש במקבץ לאחר החזרה

אפליקציה לדוגמה

אפליקציה לדוגמה שממחישה איך להגדיר וריאציה של build עבור hwasan.

תכנות

כדי ליצור את קוד ה-Native ‏ (JNI) של האפליקציה באמצעות HWAddress Sanitizer, צריך לבצע את הפעולות הבאות:

ndk-build

בקובץ 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 (Gradle Groovy)‎

בקובץ build.gradle של המודול:

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

לכל יעד בקובץ CMakeLists.txt:

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

ב-NDK 27 ומעלה, אפשר גם להשתמש באפשרויות הבאות ב-build.gradle ולא צריך לשנות את CMakeLists.txt:

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

האפשרות הזו לא תפעל כשמשתמשים ב-ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false.

‫CMake (Gradle Kotlin)

בקובץ build.gradle של המודול:

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

לכל יעד בקובץ CMakeLists.txt:

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

ב-NDK 27 ומעלה, אפשר גם להשתמש באפשרויות הבאות ב-build.gradle ולא צריך לשנות את CMakeLists.txt:

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

האפשרות הזו לא תפעל כשמשתמשים ב-ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false.

‫Android מגרסה 14 ואילך: מוסיפים wrap.sh

אם אתם מריצים Android מגרסה 14 ואילך, אתם יכולים להשתמש בסקריפט wrap.sh כדי להריץ את האפליקציה שניתן לנפות בה באגים בכל מכשיר עם Android. אם בחרתם לפעול לפי השלבים שמפורטים בהוראות ההגדרה, אתם יכולים לדלג על השלב הזה.

פועלים לפי ההוראות כדי לארוז סקריפט wrap.sh ולהוסיף את סקריפט wrap.sh הבא בשביל arm64-v8a.

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

הרצה

אם אתם מריצים גרסת Android ישנה יותר מ-14, או שלא הוספתם סקריפט wrap.sh, עליכם לפעול לפי הוראות ההגדרה לפני הפעלת האפליקציה.

מפעילים את האפליקציה כרגיל. כשמתגלה שגיאת זיכרון, האפליקציה קורסת עם SIGABRT ומדפיסה הודעה מפורטת ב-logcat. עותק של ההודעה נמצא בקובץ בתיקייה /data/tombstones והוא נראה כך:

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)

יכול להיות שאחרי ההודעה יופיע מידע נוסף לניפוי באגים, כולל רשימת השרשורים הפעילים באפליקציה, תגים של הקצאות זיכרון סמוכות וערכי רישום של CPU.

מידע נוסף על הודעות השגיאה של HWASan זמין במאמר הסבר על דוחות HWASan.

יצירת קובצי הפעלה משורת הפקודה

אתם יכולים ליצור ולהריץ קובצי הפעלה עם HWASan ב-Android 14 ובגרסאות חדשות יותר. אתם יכולים להשתמש באותה הגדרה שמתוארת במאמר Build עבור ndk-build או CMake לקובצי ההפעלה שלכם. דוחפים את קובצי ההפעלה למכשיר עם Android 14 או גרסה חדשה יותר ומפעילים אותם כרגיל באמצעות המעטפת.

אם אתם משתמשים ב-libc++, חשוב לוודא שאתם משתמשים ב-STL המשותף, להעביר אותו למכשיר ולהגדיר את LD_LIBRARY_PATH לספרייה שמכילה אותו כשמריצים את הקובץ הבינארי.

אם אתם לא משתמשים ב-Gradle, תוכלו לעיין במסמכי התיעוד של NDK כדי ללמוד איך לבצע build משורת הפקודה באמצעות CMake ו-ndk-build.

‫Android מגרסה 13 ומטה: הגדרה

אם במכשיר שלכם מותקנת Android מגרסה 14 ואילך, אתם יכולים לדלג על השלב הזה ולפעול לפי ההוראות לשימוש ב-wrap.sh בקטע Build. אפשר גם לפעול לפי ההוראות שבקטע הזה ולדלג על ההוראות לשימוש ב-wrap.sh.

לפני Android 14, כדי להריץ אפליקציות HWASan, צריך גרסת HWASan של Android. אפשר לשדרג תמונות HWASan מוכנות מראש למכשירי Pixel נתמכים. הגרסאות זמינות בכתובת ci.android.com. שם אפשר ללחוץ על הריבוע של הגרסה המדויקת שרוצים לקבל קישור Flash Build. כדי לעשות את זה, צריך לדעת את שם הקוד של הטלפון.

העברת build של מכשיר

יכול להיות שיהיה קל יותר להיכנס ישירות לכתובת flash.android.com כי שם תהליך ההתחלה כולל זיהוי של המכשיר והצגה רק של גרסאות build שאפשר להשתמש בהן. בתמונות הבאות מוצג תהליך ההגדרה בכלי הזה.

מפעילים את מצב הפיתוח במכשיר ומחברים אותו למחשב באמצעות כבל USB. לוחצים על הוספת מכשיר חדש, בוחרים את המכשיר בתיבת הדו-שיח ולוחצים על חיבור.

זיהוי מכשיר להפעלה בוחרים את המכשיר שאליו רוצים להתחבר.

אחרי שהמכשיר מחובר, לוחצים עליו כדי להגדיר את הגרסה. בתיבה Select a build ID (בחירת מזהה build), בוחרים את הענף aosp-master-with-phones-throttled כדי לבחור באופן אוטומטי את התמונה הנכונה למכשיר שמחובר.

בחירת המכשיר שיהבהב מאשרים את אפשרויות ההפעלה של הפלאש ומפעילים את הפלאש במכשיר

לוחצים על התקנה כדי לצרוב את המכשיר.

במסמכים בנושא Android Flash Tool יש פרטים נוספים על ההגדרה הנדרשת. אפשרות אחרת היא לעיין בתיעוד של AOSP לקבלת הוראות ליצירת תמונת HWASan ממקור.