מיקומים מתויגים

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

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

התכונה Top-byte Ignore של ARM זמינה לקוד של 64 ביט בכל החומרה של Armv8 AArch64. המשמעות של התכונה הזו היא שהחומרה מתעלמת מהבייט העליון של מצביע כשהיא ניגשת לזיכרון.

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

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

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

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

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

תמיכת מפתחים

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

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

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

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

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

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

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

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