邊界消毒劑

BoundsSanitizer (BoundSan) 將檢測添加到二進製文件以在數組訪問周圍插入邊界檢查。如果編譯器無法在編譯時證明訪問是安全的,並且如果在運行時知道數組的大小,則添加這些檢查,以便可以對其進行檢查。 Android 10 在藍牙和編解碼器中部署了 BoundSan。 BoundSan 由編譯器提供,並且在整個平台的各種組件中默認啟用。

執行

BoundSan 使用UBSan 的邊界消毒劑。此緩解在每個模塊級別啟用。它有助於確保 Android 的關鍵組件安全且不應被禁用。

我們強烈建議您為其他組件啟用 BoundSan。理想的候選者是特權本機代碼或解析不受信任的用戶輸入的複雜本機代碼。與啟用 BoundSan 相關的性能開銷取決於無法證明是安全的數組訪問的數量。預計平均開銷百分比很小,並測試性能是否是一個問題。

在藍圖文件中啟用 BoundSan

BoundSan 可以通過在二進制和庫模塊的misc_undefined sanitize 屬性中添加"bounds"來在藍圖文件中啟用:

sanitize: {
   misc_undefined: ["bounds"],
   diag: {
      misc_undefined: ["bounds"],
   },
   blacklist: "modulename_blacklist.txt",

診斷

diag屬性為消毒劑啟用診斷模式。僅在測試期間使用診斷模式。診斷模式不會在溢出時中止,這會抵消緩解的安全優勢並帶來更高的性能開銷,因此不建議將其用於生產構建。

黑名單

blacklist屬性允許指定一個黑名單文件,開發人員可以使用它來防止函數和源文件被清理。僅當關注性能並且目標文件/功能有很大貢獻時才使用此屬性。手動審核這些文件/函數以確保數組訪問是安全的。有關其他詳細信息,請參閱故障排除

在 makefile 中啟用 BoundSan

BoundSan 可以通過在二進制和庫模塊的LOCAL_SANITIZE變量中添加"bounds"來在 makefile 中啟用:

LOCAL_SANITIZE := bounds
# Optional features
LOCAL_SANITIZE_DIAG := bounds
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt

LOCAL_SANITIZE接受以逗號分隔的消毒劑列表。

LOCAL_SANITIZE_DIAG打開診斷模式。僅在測試期間使用診斷模式。診斷模式不會在溢出時中止,這會抵消緩解的安全優勢並帶來更高的性能開銷,因此不建議將其用於生產構建。

LOCAL_SANITIZE_BLACKLIST允許指定允許開發人員防止函數和源文件被清理的黑名單文件。僅當關注性能並且目標文件/功能有很大貢獻時才使用此屬性。手動審核這些文件/函數以確保數組訪問是安全的。有關其他詳細信息,請參閱故障排除

禁用 BoundSan

您可以在具有黑名單或函數屬性的函數和源文件中禁用 BoundSan。最好保持 BoundSan 處於啟用狀態,因此只有在函數或文件造成大量性能開銷並且已手動審查源時才禁用它。

有關使用函數屬性黑名單文件格式禁用 BoundSan 的更多信息,請參閱 Clang LLVM文檔。通過使用指定目標 sanitizer 的部分名稱將黑名單範圍限定為特定 sanitizer,以避免影響其他 sanitizer。

驗證

沒有專門針對 BoundSan 的 CTS 測試。相反,請確保在啟用或不啟用 BoundSan 的情況下通過 CTS 測試,以驗證它不會影響設備。

故障排除

啟用 BoundSan 後徹底測試組件,以確保解決任何以前未檢測到的越界訪問。

BoundSan 錯誤可以很容易地識別出來,因為它們包含以下 tombstone abort 消息:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/foobar <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: out-of-bounds'

在診斷模式下運行時,源文件、行號和索引值將打印到logcat 。默認情況下,此模式不會拋出異常消息。查看logcat以檢查是否有任何錯誤。

external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'