內核控制流程完整性

控制流程完整性(CFI) 是一種安全機制,不允許更改已編譯二進位檔案的原始控制流程圖,使執行此類攻擊變得更加困難。

在 Android 9 中,我們在更多元件和核心中啟用了 LLVM 對 CFI 的實作。系統CFI預設開啟,但需啟用核心CFI。

LLVM 的 CFI 需要使用連結時間最佳化 (LTO)進行編譯。 LTO 保留目標檔案的 LLVM 位元碼表示直到連結時,這使得編譯器能夠更好地推斷可以執行哪些最佳化。啟用 LTO 可減少最終二進位檔案的大小並提高效能,但會增加編譯時間。在 Android 上的測試中,LTO 和 CFI 的組合對程式碼大小和效能的影響可以忽略不計;在少數情況下,兩者都有所改善。

有關 CFI 以及如何處理其他前向控制檢查的更多技術細節,請參閱LLVM 設計文件

執行

kCFI 補丁存在於所有受支援的 Android 核心版本中。 CONFIG_CFI_CLANG選項啟用 kCFI,並在 GKI 中預設設定。

故障排除

啟用後,解決其驅動程式可能存在的任何類型不匹配錯誤。透過不相容的函數指標進行的間接函數呼叫會導致 CFI 跳閘。當偵測到 CFI 故障時,核心會列印警告,其中包括被呼叫的函數和導致故障的堆疊追蹤。透過確保函數指標始終與所呼叫的函數具有相同的類型來修正此問題。

為了幫助調試 CFI 故障,請啟用CONFIG_CFI_PERMISSIVE ,它會列印出警告而不是導致核心恐慌。不得在生產上使用寬容模式。

驗證

目前,還沒有專門針對CFI的CTS測試。相反,請確保 CTS 測試在啟用或未啟用 CFI 的情況下通過,以驗證 CFI 不會影響裝置。