מצביעים תויגו

החל מ-Android 11, בתהליכים של 64 ביט, כל הקצאות הערימה (heap) תג מוגדר בהטמעה שמוגדר בבייט העליון של הסמן במכשירים עם תמיכה בליבה (kernel) של ARM Top-byte התעלמות (TBI). כל אפליקציה שמשנה את זה התג נסגר כשהתג נבדק במהלך בחירת המיקום (Deallocation). זה הכרחי לחומרה עתידית עם תמיכה בתוסף תיוג זיכרון ב-ARM (MTE).

התעלמות מבייט עליון

התכונה 'התעלמות מתצוגה עליונה' של ARM זמינה בקוד של 64 ביט בכל החומרה מסוג Armv8 AArch64. תכונה זו פירושה שהחומרה מתעלמת מהבייט העליון של מצביע כאשר גישה לזיכרון.

TBI דורש קובץ תואם ליבה (kernel) שמטפלת בצורה תקינה במצביעים מתויגים שמועברים ממרחב המשתמשים. Android Common Kernels מ-4.14 (Pixel 4) ואילך כוללות את ה-TBI הנדרש תיקונים.

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

מוּכנוּת התוסף לתיוג זיכרון

תוסף תיוג הזיכרון (MTE) של ARM עוזר לטפל בבעיות של אבטחת זיכרון. MTE פועל על ידי תיוג ביטים של כתובות 56-59 בכל זיכרון. ב-Stack, בערימה וב-globals. החומרה וההוראות בודקת באופן אוטומטי שנעשה שימוש בתג הנכון בכל גישה לזיכרון.

אפליקציות ל-Android שמאחסנות מידע באופן שגוי בבייט העליון שהסמן בטוח להתקלקל במכשיר עם תמיכה ב-MTE. בעזרת תגים מתויגים קל יותר לזהות ולדחות שימושים שגויים בחלק העליון של המסך בייט של הסמן לפני שמכשירי MTE זמינים.

תמיכת מפתחים

אם האפליקציה קרסה והמוצגת לכם את הקישור הזה, יכול להיות אחד מהפרטים הבאים:

  1. האפליקציה ניסתה לשחרר מצביע שלא הוקצה על ידי מקצה הערימה של המערכת.
  2. משהו באפליקציה שלך שינה את הבייט העליון של מצביע. הבייט העליון של אי אפשר לשנות את הסמן וצריך לשנות את הקוד כדי לפתור את הבעיה בעיה.

דוגמאות לשימוש שגוי בסמן של הבייט העליון או שינוי שלו.

  • להפניות לסוג מסוים מאוחסנים מטא-נתונים ספציפיים לאפליקציה ב-16 הביטים המובילים של הכתובת.
  • העברת הסמן למצב כפול ואז חזרה, מאבד את ביטים של כתובות נמוכות יותר.
  • חישוב קוד ההפרש בין הכתובות של משתנים מקומיים ממסגרות סטאק שונות כדרך למדוד את עומק רקורסיה.

אפליקציות מסוימות עשויות להסתמך על ספריות שמתנהגות באופן שגוי הבייט העליון של הסמן מוגדר. אנחנו מבינים שיכול להיות לתקן את הבעיות הבסיסיות האלה בספריות במהירות. לכן, אפליקציות שנעשה בהן שימוש ב-targetSdkLevel < 30 תיוג הסמן לא יופעל כברירת מחדל. אנחנו גם מספקים תווי בריחה (escape) מפתח לאפליקציות שפותחו באמצעות targetSdkLevel >= 30 כדי להקל את תקופת המעבר.

כדי להשתמש בפתח המילוט, מוסיפים את הפרטים הבאים אל קובץ AndroidManifest.xml:

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

הפעולה הזו תשבית את התכונה 'תיוג מצביע' עבור אפליקציה. הבעיה לא מתייחסת את הבעיה הבסיסית בתקינות הקוד. פתח המילוט הזה ייעלם בעתיד של Android, בגלל שבעיות מהסוג הזה לא יתאימו ל MTE.