HWAddressSanitizer

硬件輔助的 AddressSanitizer (HWASan) 是一種類似於AddressSanitizer的內存錯誤檢測工具。與 ASan 相比,HWASan 使用的 RAM 少得多,這使其適用於整個系統的清理。 HWASan 僅適用於 Android 10 及更高版本,並且僅適用於 AArch64 硬件。

雖然主要用於 C/C++ 代碼,但 HWASan 還可以幫助調試導致用於實現 Java 接口的 C/C++ 崩潰的 Java 代碼。這很有幫助,因為它會在發生內存錯誤時捕獲它們,並直接將您指向負責的代碼。

您可以從ci.android.com將預構建的 HWASan 圖像刷寫到支持的 Pixel 設備(詳細設置說明)。

與經典的 ASan 相比,HWASan 具有:

  • 類似的 CPU 開銷 (~2x)
  • 類似的代碼大小開銷 (40 – 50%)
  • 更小的 RAM 開銷 (10% – 35%)

HWASan 檢測到與 ASan 相同的錯誤集:

  • 堆棧和堆緩衝區溢出/下溢
  • 釋放後的堆使用
  • 堆棧使用範圍外
  • 雙重免費/狂野免費

此外,HWASan 在返回後檢測堆棧使用情況。

實施細節和限制

HWASan 基於內存標記方法,其中一個小的隨機標記值與指針和內存地址範圍相關聯。為了使內存訪問有效,指針和內存標籤必須匹配。 HWASan 依靠 ARMv8 功能頂部字節忽略 (TBI),也稱為虛擬地址標記,將指針標記存儲在地址的最高位中。

您可以在 Clang 文檔站點上閱讀有關HWASan 設計的更多信息。

按照設計,HWASan 沒有用於檢測溢出的 ASan 有限大小的紅色區域,也沒有用於檢測空閒後使用的 ASan 有限容量隔離區。出於這個原因,無論溢出有多大或內存被釋放多久,HWASan 都可以檢測到錯誤。這使 HWASan 比 ASan 有很大的優勢。

但是,HWASan 的可能標籤值數量有限(256),這意味著在一次程序執行期間有 0.4% 的概率丟失任何錯誤。

要求

HWASan 要求 Linux 內核接受系統調用參數中的標記指針。在以下上游補丁集中實現了對此的支持:

這些補丁在android-4.14及更高版本的通用 Android 內核中作為向後移植提供,但在 Android 10 特定的分支(例如android-4.14-q )中不可用。

Android 11開始提供對 HWASan 的用戶空間支持。

如果您使用自定義工具鏈進行構建,請確保它包含 LLVM 提交c336557f 之前的所有內容。

使用華山

使用以下命令使用 HWASan 構建整個平台:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

為方便起見,您可以將 SANITIZE_TARGET 設置添加到產品定義中,類似於aosp_coral_hwasan

與 ASan 不同,使用 HWASan 無需構建兩次。增量構建只是工作,沒有特殊的閃爍指令或擦除要求,支持靜態可執行文件,並且可以跳過除libc以外的任何庫的清理。也沒有要求如果一個庫被清理,任何鏈接到它的可執行文件也必須被清理。

要跳過模塊的清理,請使用LOCAL_NOSANITIZE := hwaddresssanitize: { hwaddress: false }

單個模塊可以使用 HWASan 進行清理,但需要注意的是libc也是 HWASan 化的。這可以通過將sanitize: { hwaddress: true }添加到相應的Android.bp模塊定義來完成。使用_hwasan後綴的構建(包括libc )時,整個 Android 平台都是使用 HWASan 構建的,因此對於 HWASan 構建,不需要手動清理libc

更好的堆棧跟踪

HWASan 使用基於幀指針的快速展開器來記錄程序中每個內存分配和釋放事件的堆棧跟踪。 Android 默認啟用 AArch64 代碼中的幀指針,因此這在實踐中非常有效。如果需要通過託管代碼展開,請在進程環境中設置HWASAN_OPTIONS=fast_unwind_on_malloc=0 。請注意,錯誤的內存訪問堆棧跟踪默認使用“慢”展開器;此設置僅影響分配和釋放跟踪。此選項可能會佔用大量 CPU,具體取決於負載。

符號化

請參閱ASan文檔中的符號化。

應用程序中的 HWASan

與 AddressSanitizer 類似,HWASan 無法查看 Java 代碼,但它可以檢測 JNI 庫中的錯誤。與 ASan 不同,支持在非 HWASan 設備上運行 HWASan 應用程序。

在 HWASan 設備上,可以使用 HWASan 檢查應用程序,方法是使用 Make 中的SANITIZE_TARGET:=hwaddress或編譯器標誌中的-fsanitize=hwaddress構建其代碼。有關更多詳細信息,請參閱應用程序開發人員文檔