במאמר הסבר על דוחות HWASan מוסבר איך לקרוא קריסות של HWASan.
AddressSanitizer (HWASan) בסיוע חומרה הוא כלי לזיהוי שגיאות בזיכרון, בדומה ל-AddressSanitizer. ב-HWASan נעשה שימוש בפחות זיכרון RAM בהשוואה ל-ASAN, ולכן הוא מתאים לניקוי של כל המערכת. HWASan זמין רק ב-Android 10 ומעלה, ורק בחומרה של AArch64.
למרות שהוא שימושי בעיקר לקוד C/C++, HWASan יכול גם לעזור בניפוי באגים בקוד Java שגורם קריסות ב-C/C++ שמשמשות להטמעת ממשקי Java. הכלי הזה שימושי כי הוא מזהה שגיאות בזיכרון בזמן שהן מתרחשות, ומפנה ישירות לקוד שאחראי להן.
אפשר להטמיע קובצי אימג' של HWASan שנוצרו מראש במכשירי Pixel נתמכים מ-ci.android.com (הוראות מפורטות להגדרה).
בהשוואה ל-ASan הקלאסי, ל-HWASan יש:
- תקורה דומה של המעבד (CPU) (כ-2x)
- יתרת קוד דומה (40% עד 50%)
- תקורה קטנה בהרבה של RAM (10%-35%)
HWASan מזהה את אותה קבוצת באגים כמו ASan:
- זליגה/חוסר מקום במאגרים של סטאק ושל אשכול
- שימוש בערימה (heap) אחרי 'free'
- שימוש ב-Stack מחוץ להיקף
- Double free/wild free
בנוסף, HWASan מזהה שימוש בסטאק אחרי החזרה.
HWAsan (זהה ל-ASan) תואם ל-UBSan, ואפשר להפעיל את שניהם ביעד בו-זמנית.
פרטים על ההטמעה ומגבלות
HWASan מבוסס על זיכרון גישת תיוג, שבה משויך ערך קטן של תג אקראי גם באמצעות מצביעים וגם טווחים של כתובות זיכרון. לזיכרון ושהגישה חוקית, תג הסמן ותגי הזיכרון חייבים להיות תואמים. HWASan מסתמך על התעלמות מבייט עליונה של התכונה ARMv8 (TBI), שנקרא גם תיוג כתובת וירטואלי, לאחסון תג המצביע הביטים הגבוהים ביותר של הכתובת.
אפשר לקרוא עוד על העיצוב של HWASan באתר התיעוד של Clang.
מעצם הגדרתו, ל-HWAsan אין אזורי סכנה בגודל מוגבל כמו ב-ASan לזיהוי זליגות, או מקום מוגבל בבידוד כמו ב-ASan לזיהוי שימוש לאחר סיום תקופת הניסיון. לכן, מערכת HWASan יכולה לזהות באג לא משנה כמה גדול החריגה או לפני כמה זמן הזיכרון היה : transactionlocation ל-HWASan יש יתרון גדול על פני ASan.
עם זאת, ל-HWASan יש מספר מוגבל של ערכי תגים אפשריים (256), כלומר יש סבירות של 0.4% לכך שיפספס באג כלשהו במהלך הרצה אחת של התוכנית.
הדרישות
הגרסאות האחרונות (4.14 ואילך) של ליבת Android הנפוצה תומכות ב-HWASan מראש. להסתעפויות הספציפיות של Android 10 אין תמיכה ב-HWASan.
תמיכה במרחב המשתמש ל-HWASan זמינה החל מ-Android 11.
אם אתם עובדים עם ליבה אחרת, HWASan מחייב את ליבה של Linux לקבל מצביעים מתויגים בארגומנטים של קריאות מערכת. התמיכה בכך הופעלה בחבילות התיקונים הבאות ב-upstream:
- arm64 tagged address ABI
- arm64: הסרת תגים מכתובות משתמש שהועברו לליבה
- mm: נמנעים מיצירה של כתובות וירטואליות חלופיות ב-brk()/mmap()/mremap()
- arm64: אימות כתובות מתויגות ב-access_ok() שנקרא משרתי הליבה
אם אתם מבצעים פיתוח באמצעות ערכת כלים מותאמת אישית, חשוב לוודא שהיא כוללת את כל השינויים עד ל-commit של LLVM c336557f.
שימוש ב-HWASan
כדי ליצור את כל הפלטפורמה באמצעות HWASan, משתמשים בפקודות הבאות:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
מטעמי נוחות, אפשר להוסיף את ההגדרה SANITIZE_TARGET להגדרת מוצר, דומה ל- aosp_coral_hwasan.
משתמשים שמכירים את AddressSanitizer לא צריכים להתמודד עם הרבה מהמורכבות של ה-build:
- אין צורך להריץ את make פעמיים.
- גרסאות build מצטברות פועלות באופן מובנה.
- אין צורך לבצע איפוס נתוני המשתמש.
גם חלק מההגבלות של AddressSanitizer הוסרו:
- יש תמיכה בקובצי הפעלה סטטיים.
- מותר לוותר על חיטוי עבור כל יעד מלבד libc. בניגוד ל-ASAN, אין דרישה שאם ספרייה מסוימת עוברת תהליך ניטרול, כל קובץ הפעלה שמקושר אליה צריך לעבור אותו גם כן.
ניתן לעבור בין HWASan לתמונות רגילות באותו מספר build (או גבוה יותר) נעשה בחופשיות. אין צורך לאפס את נתוני המכשיר.
כדי לדלג על ניטרול של מודול, משתמשים ב-LOCAL_NOSANITIZE := hwaddress
(Android.mk) או ב-sanitize: { hwaddress: false }
(Android.bp).
טיהור יעדים ספציפיים
אפשר להפעיל את HWASan לכל יעד ב-build רגיל (ללא סניטיזציה), כל עוד גם libc.so
עובר סניטיזציה. מוסיפים את hwaddress: true
לבלוק הטיהור ב-"libc_defaults"
ב-bionic/libc/Android.bp. לאחר מכן חוזרים על הפעולה ביעד שעליו אתם עובדים.
חשוב לשים לב שחיטוי libc מאפשר תיוג של הקצאות זיכרון של הזיכרון ברמת המערכת, וגם
בדיקה של התגים לפעולות זיכרון בתוך libc.so
. כך אפשר לזהות באגים גם בקובצי בינארי שלא הופעל בהם HWASan, אם הגישה השגויה לזיכרון נמצאת ב-libc.so
(למשל: pthread_mutex_unlock()
ב-mutex עם delete()
).
אין צורך לשנות קובצי build אם כל הפלטפורמה נבנתה באמצעות HWASan.
תחנת הבזק
למטרות פיתוח, ניתן לשדרג למכשיר Pixel גרסת build של AOSP שתומך ב-HWASan עם תוכנת אתחול לא נעולה באמצעות Flashstation. בוחרים את היעד _hwasan, למשל: aosp_flame_hwasan-userdebug. לצפייה מסמכי תיעוד של NDK עבור HWASan למפתחים של אפליקציות, לקבלת פרטים נוספים.
מעקבי ערימה משופרים
HWASan משתמש ב-unwinder מהיר שמבוסס על מצביע מסגרת כדי לתעד מעקב סטאק לכל אירוע הקצאה וביטול הקצאה של זיכרון בתוכנית. Android מפעילה את נקודות הסימון של המסגרת בקוד AArch64 כברירת מחדל, כך שהשיטה הזו פועלת מצוין בפועל. אם אתם צריכים לבצע ביטול של קוד מנוהל, צריך להגדיר את HWASAN_OPTIONS=fast_unwind_on_malloc=0
בסביבת התהליך. שימו לב שמקבץ גישה לא טוב לזיכרון
עקבות משתמשים באופרטור "איטי" לבטל הרצה כברירת מחדל; ההגדרה הזו משפיעה רק על
מעקבי הקצאה ו-Deallocation. האפשרות הזאת יכולה להיות
עתיר מעבד (CPU), בהתאם לעומס.
ייצוג
מידע נוסף זמין בקטע סמליזציה במאמר 'הסבר על דוחות HWASan'.
HWASan באפליקציות
בדומה ל-AddressSanitizer, גם HWASan לא יכול לראות בקוד Java, אבל הוא יכול לזהות באגים בספריות ה-JNI. עד גרסת Android 14, ב-HWASan פועל HWASan במכשיר שאינו HWASan לא הייתה תמיכה באפליקציות.
במכשיר HWASan, אפשר לבדוק אפליקציות באמצעות HWASan על ידי פיתוח של
קוד עם SANITIZE_TARGET:=hwaddress
אינץ'
יצרן או -fsanitize=hwaddress
בדגלי מהדר.
במכשיר שאינו HWASan (עם Android מגרסה 14 ואילך), צריך להוסיף את ההגדרה LD_HWASAN=1
לקובץ wrap.sh.
לצפייה
תיעוד למפתחי אפליקציות
אפשר לקבל פרטים נוספים.