כשכלי HWASan מזהה באג בזיכרון, התהליך מסתיים ב-abort()
.
הדוח מודפס ב-stderr וב-Logcat. כמו כל הקריסות המקוריות ב-Android, שגיאות HWASan עלולות
נמצא תחת /data/tombstones
.
בהשוואה לקריסות נייטיב רגילות, ב-HWASan מופיע מידע נוסף בשדה 'הודעת ביטול' ליד החלק העליון של המצבה. למטה תוכלו לראות דוגמה לקריסה מבוססת-ערימה של באגים (לגבי באגים בסטאק, עיינו בהערה שבהמשך לגבי הקטעים הספציפיים למקבץ).
דוח לדוגמה
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys' Revision: 'DVT1.0' ABI: 'arm64' Timestamp: 2019-04-24 01:13:22+0000 pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<< signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … regular crash dump follows …]
הפעולה הזו דומה מאוד לדוח AddressSanitizer. בניגוד אליהם, כמעט כל הבאגים של HWASan הם "tag-mismatch", כלומר גישה לזיכרון כאשר תג מצביע לא תואם לתג הזיכרון התואם. זה יכול להיות אחד מ-
- גישה מחוץ לתחום במקבץ או בערימה
- לשימוש אחרי בחינם בערימה
- לשימוש אחרי ההחזרה על המקבץ
קטעים
בהמשך יש הסבר על כל אחד מהקטעים בדוח HWASan:
שגיאת גישה
מכיל מידע על גישה פגומה לזיכרון, כולל:
- סוג הגישה ('READ' לעומת 'WRITE')
- גודל הגישה (כמה בייטים בוצע ניסיון לגשת אליהם)
- מספר ה-thread של הגישה
- תגי מצביע וזיכרון (לניפוי באגים מתקדם)
גישה לדוח הקריסות
דוח קריסות של גישה גרועה לזיכרון. עיינו בקטע 'סמלים' כדי סימבולי.
הסיבה
הסיבה הפוטנציאלית לגישה הלא תקינה. אם יש כמה מועמדים, הן מסודרת בסדר יורד. קדימות על המידע המפורט על היא סיבה אפשרית. HWASan יכול לאבחן את הסיבות הבאות:
- שימוש אחרי שימוש בחינם
- מחסנית tag-mismatch: זו יכולה להיות מחסנית use-after-return / use after-scope, או מחוץ לתחום
- גלישת נתונים במאגר הנתונים הזמני
- גלישה ברחבי העולם
מידע על הזיכרון
תיאור המידע ש-HWASan יודע על הזיכרון שמתבצעת אליו גישה, ועשוי להיות שונה על סמך סוג הבאג.
סוג הבאג | הסיבה | פורמט דוח |
---|---|---|
חוסר התאמה בין תגים | שימוש אחרי שימוש בחינם |
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
גלישת נתונים במאגר הנתונים הזמני | שימו לב שזו יכולה להיות גם תהליך חריג.
<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
חוסר התאמה בין תגים במקבץ | בדוחות מקבץ אין הבחנה בין 'אפשרויות נוספות' / 'חסרים' ו- באגים שמשתמשים בהם אחרי החזרה. לחשבון נוסף לכך, כדי למצוא את הקצאת המחסנית שהיא מקור השגיאה, אופליין נדרש שלב סימולציית. הסבר על דוחות קריסות שבהמשך. | |
כלי חינמי לא תקף | שימוש אחרי שימוש בחינם | זהו באג כפול חינם. אם זה קורה כשמאפסים את התהליך, זה סימן לכך
הפרה של ODR.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
לא ניתן לתאר את הכתובת | בחינם (ללא זיכרון שלא הוקצה בעבר), או כפול חינם אחרי שהזיכרון שהוקצה הוצא מהמאגר החופשי של HWASan. | |
0x... הוא זיכרון הצל של HWAsan. | האפליקציה ניסתה לפנות בחינם, ללא חשש זיכרון שהוא ל-HWASan. |
דוח קריסות של מיקומים שרלוונטיים לעסק
דוח קריסות של המיקום שבו הזיכרון הוקצה. מוצג רק לשימוש לאחר שימוש ללא תשלום או באגים נטולי נתונים לא חוקיים. ראו קטע סמלים כדי לייצג סימולציה.
דוח קריסות של הקצאה
דוח קריסות של המקום שבו הוקצה הזיכרון. ראו קטע סמלים כדי לייצג סימולציה.
ניפוי באגים מתקדם מידע
דוח HWASan כולל גם כמה מידע מתקדם על תוצאות ניפוי הבאגים, כולל (לפי הסדר):
- רשימת השרשורים בתהליך
- רשימת השרשורים בתהליך
- הערך של תגי הזיכרון ליד הזיכרון שגורמת לבעיה
- תמונת ה-Dump של הרישום בנקודת הגישה לזיכרון
תמונת מצב של תג זיכרון
אפשר להשתמש בתיקיית הזיכרון של התג כדי לחפש הקצאות זיכרון בקרבת מקום עם אותו תג בתור מצביע התיוג. הגורמים האלה עלולים להוביל לגישה מחוץ לתחום עם היסט משמעותי. תג אחד תואם לערך 16 בייטים של הזיכרון; תג המצביע הוא 8 הביטים המובילים של הכתובת. תמונת מצב הזיכרון של התג לתת רמזים, עבור הדוגמה הבאה היא גלישה במאגר נתונים זמני מימין:
tags: ad/5c (ptr/mem) [...] Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: 0e 0e 0e 57 20 20 20 20 20 2e 5e 5e 5e 5e 5e b5 =>0x006f33ae2000: f6 f6 f6 f6 f6 4c ad ad ad ad ad ad [5c] 5c 5c 5c 0x006f33ae2010: 5c 04 2e 2e 2e 2e 2e 2f 66 66 66 66 66 80 6a 6a Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: ab 52 eb .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: .. .. .. .. .. .. .. .. .. .. .. .. [..] .. .. .. 0x006f33ae2010: .. 5c .. .. .. .. .. .. .. .. .. .. .. .. .. ..(שימו לב לריצה של 6 × 16 = 96 בייטים של תגי 'מודעה' בצד ימין שתואמים לתג המצביע).
אם גודל ההקצאה אינו כפולה של 16, יתרת הגודל תהיה מאוחסנים בתור תג הזיכרון והתג יישמרו כקובץ Shorts תג חלקיק. בדוגמה שלמעלה, מיד אחרי שההקצאה המודגשת תויגה אנחנו יש 5 × 16 + 4 = הקצאת 84 בייטים של תג 5c.
תג עם אפס זיכרון (לדוגמה: tags: ad/00 (ptr/mem)
) בדרך כלל מציין
באג-שימוש בסטאק אחרי החזרה.
רישום קובץ dump
תמונת המצב של רישום הנתונים בדוחות HWASan תואמת להוראה שביצעה בפועל לא תקין זיכרון גישה. אחריו מופיעה תמונת מצב אחרת של הרישום מ-handler הרגיל של Android - מתעלמים מ השני, הוא נלקח כאשר HWASan נקרא abort() והוא לא רלוונטי הבאג.
ייצוג
כדי לקבל שמות של פונקציות ומספרי שורות בדוחי קריסות (ולקבל שמות משתנים לשימוש אחרי ההיקף) באגים), נדרש שלב של סימולציית אופליין.
הגדרה בפעם הראשונה: התקנת llvm-symbolizer
כדי לסמל, המערכת צריכה להתקין את llvm-symbolizer ולוודא שאפשר לגשת אליו דרך $PATH. ב-Debian, אפשר
מתקינים אותו באמצעות sudo apt install llvm
.
קבלת קובצי סמלים
לצורך סימולזציה, אנחנו דורשים קבצים בינאריים לא מסולסלים שמכילים סמלים. המיקום שבו ניתן למצוא את המדדים האלה תלוי בסוג ה-build:
עבור גרסאות build מקומיות, ניתן למצוא את קובצי הסמלים
out/target/product/<product>/symbols/
.
עבור גרסאות build של AOSP (למשל, הבהוב מ-Flashstation), הפונקציה
גרסאות build זמינות ב-Android CI. ב-"Artifacts" עבור
build,
יהיה קובץ ${PRODUCT}-symbols-${BUILDID}.zip
.
אם אתם משתמשים בגרסאות build פנימיות מהארגון שלכם, כדאי לעיין במסמכי התיעוד של הארגון לקבלת עזרה קבלת קובצי סמלים.
סמל
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
הסבר על דוחות קריסות
לגבי באגים שמתרחשים עם משתני מקבץ, דוח HWASan יכלול פרטים כמו:
Cause: stack tag-mismatch Address 0x007d4d251e80 is located in stack of thread T64 Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000) Previously allocated frames: record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0) record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74) [...]
כדי לאפשר הבנה של באגים בסטאק, HWASan עוקב אחרי הפריימים של הסטאק שהתרחשו בעבר. נכון לעכשיו, HWASan לא הופך את התוכן הזה לתוכן מובן לאנשים בדוח על באג. נדרש שלב סמלים נוסף.
הפרות ODR
חלק מהבאגים שאינם בשימוש לאחר השימוש שמדווחים על ידי HWASan יכולים גם להעיד על הפרה של כלל הגדרה אחת (ODR). הפרה של ODR מתרחשת כשאותו משתנה מוגדר כמה פעמים באותה תוכנית. כלומר, המשתנה מושמד כמה פעמים, וזה עלול להוביל שגיאת use-after-free.
לאחר הסימולציה, הפרות ODR מובילות למצב use-after-free עם __cxa_finalize
,
גם בסטאק הגישה הלא חוקית וגם במגש 'חינם' סטאק. הערכים הקודמים "הוקצו
כאן" המקבץ מכיל __dl__ZN6soinfo17call_constructorsEv
והוא צריך
בנקודה שמגדירה את המשתנה במיקום גבוה יותר במקבץ.
אחת הסיבות להפרה של ה-ODR היא שימוש בספריות סטטיות. אם ספרייה סטטית שמגדירה כללי C++ מקושרת למספר ספריות משותפות, או קובצי הפעלה, ייתכן שהגדרות מרובות של אותו סמל יופיעו באותה כתובת דבר שיגרום לשגיאת ODR.
פתרון בעיות
HWAddressSanitizer לא יכולה לתאר את הכתובת בצורה מפורטת יותר
לפעמים יכול להיות שנגמר המקום ב-HWASan למידע על הקצאות זיכרון קודמות. במקרה כזה, הדוח הדוח יכלול רק דוח קריסות אחד לגישה מיידית לזיכרון, ואחריו הערה:
HWAddressSanitizer can not describe address in more detail.
במקרים מסוימים, אפשר לפתור את הבעיה על ידי הרצת הבדיקה מספר פעמים. אפשרות נוספת היא להגדיל את שיעור ה-HWASan.
בגודל ההיסטוריה. אפשר לעשות זאת באופן גלובלי
build/soong/cc/sanitize.go
(יש לחפש
hwasanGlobalOptions
), או בסביבת התהליך שלך (ניסיון חוזר)
adb shell echo $HWASAN_OPTIONS
כדי לראות את ההגדרות הנוכחיות).
זה יכול לקרות גם אם הזיכרון שאליו ניגשו לא ממופה או מוקצה על ידי משתמש שאינו מודע ל-HWASan
מקצה לקצה. במקרה כזה, התג mem
שמופיע בכותרת הקריסה יהיה בדרך כלל
00
. אם יש לך גישה לכל המצבה, כדאי לעיין
את תמונת המצב של מפות הזיכרון כדי לבדוק לאיזה מיפוי (אם בכלל) הכתובת שייכת.
באג בתוך אותו שרשור
המשמעות היא שהיה באג במהלך הפקת דוח הקריסה של HWASan. בדרך כלל הסיבה לכך היא באג סביבת זמן ריצה ב-HWASan, יש לדווח על באג לספק הוראות לשחזור הבעיה, אם אפשר.