啟用驗證啟動功能時,系統會在使用 Android 版本前,以密碼編譯方式驗證所有可執行程式碼和資料。這包括核心 (從 boot
分區載入)、裝置樹狀結構 (從 dtbo
分區載入)、system
分區、vendor
分區等等。
只讀取一次的小型分割區 (例如 boot
和 dtbo
),通常會透過將整個內容載入記憶體,然後計算其雜湊值來驗證。系統會將計算出的雜湊值與預期的雜湊值進行比較。如果值不相符,Android 就不會載入。詳情請參閱「啟動流程」。
較大的分割區無法放入記憶體 (例如檔案系統),因此可能會使用雜湊樹狀圖,在資料載入記憶體時,驗證會是持續進行的程序。在這種情況下,雜湊樹狀圖的根雜湊值會在執行期間計算,並與預期的根雜湊值進行比對。Android 包含 dm-verity 驅動程式,可驗證較大的分區。如果計算出的根雜湊不符合預期的根雜湊值,系統就不會使用該資料,Android 也會進入錯誤狀態。詳情請參閱「dm-verity 損毀」。
預期的雜湊值通常會儲存在每個已驗證分區的結尾或開頭,或儲存在專屬分區,或同時儲存在兩者中。重要的是,這些雜湊是由信任根 (直接或間接) 簽署。舉例來說,AVB 實作方式支援這兩種方法,詳情請參閱「Android 驗證開機程序」。
復原保護
即使更新程序完全安全,非持續性 Android 核心漏洞利用程式仍可能手動安裝較舊且較容易遭到攻擊的 Android 版本,重新啟動至容易遭到攻擊的版本,然後使用該 Android 版本安裝持續性漏洞利用程式。從那時起,攻擊者就永久擁有裝置,可以執行任何操作,包括停用更新。
防範這類攻擊的保護機制稱為「Rollback Protection」。回溯保護功能通常會使用防竄改儲存空間來記錄最新的 Android 版本,並在 Android 版本低於記錄版本時拒絕啟動 Android。版本通常是依分區追蹤。
如要進一步瞭解 AVB 如何處理回溯保護機制,請參閱 AVB README。
處理驗證錯誤
驗證可能會在啟動時 (例如,如果 boot
分區上計算的雜湊不符預期的雜湊) 或執行期間 (例如,如果 dm-verity 在 system
分區上遇到驗證錯誤) 失敗。如果驗證在啟動時失敗,裝置就無法啟動,使用者必須採取步驟來復原裝置。
如果驗證在執行階段失敗,流程就會變得複雜一些。如果裝置使用 dm-verity,則應在 restart
模式下進行設定。在 restart
模式中,如果遇到驗證錯誤,裝置會立即重新啟動,並設定特定標記來指出原因。啟動載入器應會注意這個標記,並將 dm-verity 切換為使用 I/O 錯誤 (eio
) 模式,並在安裝新更新之前保持這個模式。
在 eio
模式下啟動時,裝置會顯示錯誤畫面,通知使用者已偵測到資料毀損,且裝置可能無法正常運作。畫面會持續顯示,直到使用者關閉為止。在 eio
模式中,如果遇到驗證錯誤,dm-verity 驅動程式就不會重新啟動裝置,而是會傳回 EIO 錯誤,應用程式需要處理該錯誤。
意圖是讓系統更新程式執行 (以便安裝沒有損壞錯誤的新 OS),或讓使用者盡可能從裝置中取得資料。安裝新作業系統後,啟動載入程式會注意到新安裝的作業系統,並切換回 restart
模式。