Arm 記憶體標記擴充功能

Arm v9 導入 Arm 記憶體 Tagging Extension (MTE) 是硬體實作 標記為記憶體

大致上來說,MTE 會使用 其他中繼資料它會為記憶體位置指派標記, 與參照該記憶體位置的指標相關聯在執行階段的 CPU 檢查每個載入項目和儲存庫的指標與中繼資料標記是否相符。

在 Android 12 中,核心和使用者空間堆積記憶體配置器可以擴增 每個配置都會包含中繼資料這有助於偵測釋放後使用記憶體 緩衝區溢位錯誤是 我們的程式碼集

MTE 運作模式

MTE 提供三種運作模式:

  • 同步模式 (SYNC)
  • 非同步模式 (ASYNC)
  • 非對稱模式 (ASYMM)

同步模式 (SYNC)

相較於效能,此模式經過最佳化調整,以準確偵測錯誤。 能做為精確的錯誤偵測工具 可接受。啟用時,MTE SYNC 會做為因應安全問題的緩解措施。 如果標記不符,處理器會立即取消執行,並 透過 SIGSEGV (程式碼) 終止程序 SEGV_MTESERR),以及記憶體存取和 錯誤地址

建議您在測試期間使用此模式,做為 如果目標程序出現安全漏洞,代表 HWASan/KASAN 或正式環境 攻擊面此外,當 ASYNC 模式指出有 如果想要取得準確的錯誤報告,必須改用執行階段 API 就會進入 SYNC 模式。

在 SYNC 模式下執行時,Android 配置器會記錄所有應用程式的堆疊追蹤 配置和取消配置 以便提供更完善的錯誤報告,包括記憶體內說明 例如釋放後使用或緩衝區溢位,以及 相關的記憶體事件這類報表會提供更多背景資訊 有助於追蹤及修正錯誤

非同步模式 (ASYNC)

相較於錯誤報告的準確度,這個模式的效能較高, 可用來偵測記憶體安全錯誤
如果標記不符,處理方會繼續執行,直到最接近 核心項目 (例如系統呼叫或計時器中斷), 使用 SIGSEGV (代碼 SEGV_MTEAERR) 的程序,而不需要 記錄錯誤位址或記憶體存取作業
在經過完善測試的程式碼集,我們建議在實際工作環境中使用此模式: 已知記憶體安全錯誤密度較低,方法是使用 在測試期間使用 SYNC 模式。

非對稱模式 (ASYMM)

Arm v8.7-A 中的額外功能,非對稱 MTE 模式提供同步 包括檢查記憶體讀取、記憶體寫入的非同步檢查 效能與 ASYNC 模式類似在大多數情況下 是與 ASYNC 模式相比的改善方式,我們建議您改用該模式來取代 ASYNC (如適用)。

因此,下列描述的 API 都未提及非對稱式 模式。相反地,OS 可以設定為一律使用非對稱模式 要求非同步。如需使用 Kubernetes 的 偏好的 MTE 等級」一節。

使用者空間中的 MTE

以下各節說明如何為系統程序啟用 MTE 和應用程式互動MTE 預設為停用,但下列其中一個選項除外 特定程序中設定的元件 (請參閱下文,瞭解哪些元件 MTE 已啟用)。

使用建構系統啟用 MTE

做為整個程序的資源,MTE 是由 主執行檔下列選項可讓使用者變更此設定 個別的可執行檔,或對原始碼樹狀結構中的整個子目錄。 該設定將忽略或忽略任何非可執行檔或 測試。

1. 在 Android.bp 中啟用 MTE (範例)、 針對特定專案:

MTE 模式 設定
非同步 MTE
  sanitize: {
  memtag_heap: true,
  }
同步 MTE
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

或「Android.mk:」中

MTE 模式 設定
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

2. 使用產品在來源樹狀結構的子目錄中啟用 MTE 變數:

MTE 模式 納入清單 排除清單
非同步 PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
同步 PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

MTE 模式 設定
非同步 MTE MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
同步 MTE MEMTAG_HEAP_SYNC_INCLUDE_PATHS

或指定執行檔的排除路徑:

MTE 模式 設定
非同步 MTE PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
同步 MTE

範例 (與 PRODUCT_CFI_INCLUDE_PATHS 類似)

  PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
  PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
                                    vendor/$(vendor)/projectB

使用系統屬性啟用 MTE

只要在執行階段設定 以下系統屬性:

arm64.memtag.process.<basename> = (off|sync|async)

其中 basename 代表可執行檔的基礎名稱。

例如,設定 /system/bin/ping/data/local/tmp/ping 如要使用非同步 MTE,請使用 adb shell setprop arm64.memtag.process.ping async

使用環境變數啟用 MTE

如要覆寫建構設定,您還可以定義環境 變數:MEMTAG_OPTIONS=(off|sync|async) 如果同時定義了環境變數和系統屬性,則 變數的優先順序。

為應用程式啟用 MTE

如未指定 MTE,系統會預設為停用; 想要使用 MTE 的應用程式可藉由設定 android:memtagMode 來進行 <application> 或 標記了 <process> 標記 AndroidManifest.xml

,瞭解如何調查及移除這項存取權。 android:memtagMode=(off|default|sync|async)

設定在 <application> 標記時, 屬性會影響應用程式使用的所有程序,且可覆寫 建立個別程序 <process> 標記。

進行實驗時,相容性 可用於設定 memtagMode 屬性表示應用程式含有 未在資訊清單中指定任何值 (或 default)。
您可以在通用設定選單的 System > Advanced > Developer options > App Compatibility Changes 底下找到這些功能。設定 NATIVE_MEMTAG_ASYNCNATIVE_MEMTAG_SYNC 會啟用 MTE 在特定應用程式中
或者,您也可以使用 am 設定 指令如下:

$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name

建構 MTE 系統映像檔

強烈建議您在開發期間為所有原生二進位檔啟用 MTE 。這有助於及早偵測記憶體安全錯誤,並提供實際可行 使用者涵蓋範圍。

強烈建議您在開發期間,在所有原生二進位檔中啟用同步模式的 MTE

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

與建構系統中的任何變數一樣,SANITIZE_TARGET 可以是 做為環境變數或 make 設定 (例如,在 product.mk 檔案)。
請注意,這會啟用所有原生程序的 MTE,但不適用於 應用程式 (取自 zygote64 的分支),且 MTE 可用於 按照上述操作說明啟用。

設定 CPU 專屬的偏好 MTE 級別

在某些 CPU 上,MTE 在 ASYMM 或甚至 SYNC 模式下的效能可能會與 。這樣一來 要求較嚴格的檢查模式時,對這些 CPU 進行更嚴格的檢查; 以便取得更嚴格的檢查,在錯誤偵測方面的優勢,但不需要 不僅效能低廉
根據預設,設定為以 ASYNC 模式執行的程序會在 ASYNC 中執行 所有 CPU 都不會支援此功能如要將核心設為在開啟 SYNC 模式時執行這些程序,請按照下列步驟操作: 就必須將值同步處理作業寫入 sysfs 個項目 啟動時 /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred 讓應用程式從可以最快做出回應的位置 回應使用者要求您可以使用 init 指令碼完成這項操作。舉例來說,如要將 CPU 設為 0 至 1 在 SYNC 模式下執行 ASYNC 模式程序,並在 ASYMM 模式下使用 CPU 2-3, 可將下列指令新增至供應商 init 指令碼的 init 子句:

  write /sys/devices/system/cpu/cpu0/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu1/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu2/mte_tcf_preferred asymm
  write /sys/devices/system/cpu/cpu3/mte_tcf_preferred asymm

在 SYNC 模式中執行 ASYNC 模式的 Tombstones 時,會含有 針對記憶體錯誤位置提供精確的堆疊追蹤。不過 包括分配或交易配置堆疊追蹤這些堆疊追蹤 只有在程序設定為 SYNC 模式執行時才能使用。

,瞭解如何調查及移除這項存取權。 int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

其中 level 為 0 或 1。
停用 Malloc 中的記憶體初始化功能,避免變更記憶體標記 除非是正確的

int mallopt(M_MEMTAG_TUNING, level)

其中 level 為:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

選取代碼分配策略。

  • 預設值為 M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW - 提供確定性 指派獨特的標記,偵測線性緩衝區溢位和反向溢位錯誤 相鄰分配的數量在這個模式下, 偵測釋放後使用的錯誤,因為標記值可能只有一半 可用的機器類型請注意,MTE 無法偵測 在同一個標記區組中 (符合 16 位元組對齊的區塊) 中的溢位現象,而可能會漏掉小 因此即使在這個模式下 發生溢位現象這類溢位現象並不是 因為單一區組內的記憶體絕不會用於 分配作業。
  • M_MEMTAG_TUNING_UAF:啟用獨立隨機標記 大約 93% 能同時偵測空間 (緩衝區溢位) 和 都是暫時性 (釋放後使用) 錯誤。

除了上述 API 以外,經驗豐富的使用者可能也希望 瞭解下列事項:

  • 設定PSTATE.TCO硬體註冊作業可以暫時啟動 不檢查代碼 (範例)。 例如,複製含有未知標記內容的記憶體範圍時,或 解決熱迴圈中效能瓶頸
  • 使用 M_HEAP_TAGGING_LEVEL_SYNC 時,系統當機處理常式 提供配置和取消配置堆疊追蹤等額外資訊。 必須存取代碼位元,才能使用這項功能,方法是將 SA_EXPOSE_TAGBITS 旗標。任何會自行設定信號的程式 並委派未知的當機事件給系統 A 程式,以執行 完全一樣。

核心中的 MTE

如要為核心啟用 MTE 加速 KASAN,請使用以下指令設定核心: CONFIG_KASAN=yCONFIG_KASAN_HW_TAGS=y。這些設定 從 Android 12-5.10 開始,GKI 核心預設會啟用。
系統啟動時,可以使用以下指令列引數來控制這個位址:

  • kasan=[on|off] - 啟用或停用 KASAN (預設值: on)
  • kasan.mode=[sync|async]: 選擇同步模式或非同步模式 (預設:sync)
  • kasan.stacktrace=[on|off] - 是否要收集 堆疊追蹤 (預設值:on)
    • 也需要使用堆疊追蹤收集功能 stack_depot_disable=off
  • kasan.fault=[report|panic] - 是否只列印報表 或恐慌核心 (預設值:report)。無論如何 選項,系統就會在第一次回報錯誤後停用代碼檢查功能。
,瞭解如何調查及移除這項存取權。

強烈建議您在啟用、開發及測試上市期間使用 SYNC 模式 進行測試。您應針對使用環境變數建構系統的所有程序,全面啟用這個選項。在這個模式下,系統會在 在開發初期,程式碼集會更快穩定下來 因此能避免在實際工作環境中偵測錯誤的費用。

我們強烈建議您在正式環境中使用 ASYNC 模式。因此,這個模型 透過這項負載工具,偵測程序中是否存在記憶體安全錯誤 以及更深入的防禦機制一旦偵測到錯誤,開發人員就能 利用執行階段 API 切換至 SYNC 模式,並取得準確的堆疊追蹤

我們強烈建議您設定 CPU 專屬的偏好 MTE 等級, 我們Asymm 模式的效能特性通常與 ASYNC 相同, 而且使用起來幾乎更好按順序的小型核心通常會顯示類似的 上述三種模式的效能,並可設定成偏好 SYNC。

開發人員應檢查當機情形, /data/tombstones, logcat或監控供應商DropboxManager 產生錯誤管道如要進一步瞭解如何對 Android 原生程式碼偵錯,請參閱 請參閱這裡的資訊。

支援 MTE 的平台元件

在 Android 12 中,一些重要的安全系統元件使用 MTE ASYNC 偵測使用者當機情形 採取縱深防禦這些元件如下:

  • 網路 Daemon 和公用程式 (除了 netd)
  • 藍牙、SecureElement、NFC HAL 和系統應用程式
  • statsd Daemon
  • system_server
  • zygote64 (允許應用程式選擇使用 MTE)

系統根據下列條件選取這些指定目標:

  • 具有特殊權限的程序 (定義是指可存取某項內容的程序, 禁止 unprivileged_app SELinux 網域)
  • 處理不可靠的輸入資料 (規則 (共兩個)
  • 可接受的效能減緩情形 (速度變慢不會導致使用者可見) 延遲時間)

我們鼓勵供應商在正式環境中為更多元件啟用 MTE。 招攬生意。在開發期間,建議您先測試 這些元件使用 SYNC 模式偵測輕鬆地修正的錯誤,然後評估 ASYNC 會對效能產生影響。
日後,Android 計劃擴充系統元件 MTE 清單: 並依照即將推出的硬體設計的效能特性進行操作。