標記指針

從 Android 11 開始,對於 64 位進程,所有堆分配都在具有內核支持 ARM 高字節忽略 (TBI) 的設備上的指針高字節中設置了一個實現定義的標記。在解除分配期間檢查標記時,將終止修改此標記的任何應用程序。這是必要的未來硬件ARM內存擴展標記(MTE)的支持。

忽略最高字節

ARM 的 Top-byte Ignore 功能可用於所有 Armv8 AArch64 硬件中的 64 位代碼。此功能意味著硬件在訪問內存時會忽略指針的最高字節。

TBI需要一個兼容的內核正確處理標記指針從用戶空間通過。從4.14的Android普通內核(像素4)和更高的特徵所需的TBI的補丁

在進程啟動時動態檢測內核中具有 TBI 支持的設備,並將依賴於實現的標記插入到所有堆分配的指針的頂部字節中。在此之後,將運行檢查以確保在釋放內存時標記沒有被截斷。

內存標記擴展準備就緒

ARM 的內存標記擴展 (MTE) 有助於解決內存安全問題。 MTE工作通過標記堆棧,堆,和全局每個存儲器分配的第56-第59地址位。硬件和指令集會在每次內存訪問時自動檢查是否使用了正確的標籤。

不正確地將信息存儲在所述指針的頂端字節Android應用都保證啟用MTE-設備上斷裂。在 MTE 設備可用之前,標記的指針可以更容易地檢測和拒絕指針頂部字節的錯誤使用。

開發者支持

如果您的應用程序崩潰並且系統提示您輸入此鏈接,則可能意味著以下情況之一:

  1. 應用程序試圖釋放未由系統的堆分配器分配的指針。
  2. 您的應用程序中的某些內容修改了指針的最高字節。指針的最高字節無法修改,您的代碼需要更改以解決此問題。

頂部字節指針被錯誤使用或修改的示例。

  • 指向特定類型的指針具有存儲在前 16 個地址位中的應用程序特定元數據。
  • 一個指針轉換為雙精度然後返回,丟失低地址位。
  • 代碼計算來自不同堆棧幀的局部變量地址之間的差異,作為測量遞歸深度的一種方式。

當設置指針的最高字節時,某些應用程序可能依賴於行為不正確的庫。我們認識到,快速解決庫中的這些潛在問題可能並非易事。因此,使用應用程序targetSdkLevel < 30不會有指針標記默認情況下啟用。我們還為內置的應用程序提供了一個逃生艙口targetSdkLevel >= 30 ,以緩解過渡期。

該逃生艙口被用於通過添加以下到您AndroidManifest.xml文件:

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

這將為您的應用程序禁用指針標記功能。請注意,這並沒有解決底層代碼的健康問題。這個逃生艙將在Android的未來版本中消失,因為這種性質的問題將是不兼容的MTE