核心控制流程完整性

控制流程完整性 (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 測試。請改為確保啟用或停用 CFI 時,CTS 測試都能通過,以驗證 CFI 不會影響裝置。