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)。無論如何 選項,系統就會在第一次回報錯誤後停用代碼檢查功能。
,瞭解如何調查及移除這項存取權。

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

我們強烈建議您在正式環境中使用 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 網域 (notprivileged_app SELinux 網域)
  • 處理不可靠的輸入資料 (規則 (共兩個)
  • 可接受的效能減緩情形 (速度變慢不會導致使用者可見) 延遲時間)

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