Microdroid 是一個在 pVM 中運行的迷你 Android 作業系統。您不必使用 Microdroid,您可以使用任何作業系統啟動虛擬機器。然而,pVM 的主要用例並不是運行獨立的作業系統,而是提供一個獨立的執行環境來運行應用程式的一部分,並且具有比 Android 提供的更強的機密性和完整性保證。
對於傳統作業系統,提供強大的機密性和完整性需要大量工作(通常是重複的),因為傳統作業系統不適合整體 Android 架構。例如,使用標準 Android 架構,開發人員需要實作一種在 pVM 中安全地載入和執行部分應用程式的方法,並且有效負載是針對 glibc 建構的。 Android 應用程式使用 Bionic,通訊需要通過 vsock 的自訂協議,並且使用 adb 進行調試具有挑戰性。
Microdroid 透過提供現成的作業系統映像來填補這些空白,該映像旨在要求開發人員以最少的努力將其應用程式的一部分卸載到 pVM 中。本機程式碼是針對 Bionic 建構的,通訊透過 Binder 進行,它允許從 Android 匯入 APEX 並公開 Android API 的子集,例如使用硬體支援的金鑰進行加密操作的金鑰庫。總體而言,開發人員應該會發現 Microdroid 是一個熟悉的環境,其中包含他們在完整 Android 作業系統中已經習慣的工具。
特徵
Microdroid 是 Android 的精簡版本,帶有一些特定於 pVM 的附加元件。 Microdroid 支援:
- NDK API 的子集(提供了 Android 實作 libc 和 Bionic 的所有 API)
- 調試功能,例如 adb、logcat、tombstone 和 gdb
- 驗證啟動並啟用 SELinux
- 載入並執行嵌入 APK 中的二進位檔案以及共用庫
- 透過 vsock 進行 Binder RPC 並透過隱式完整性檢查交換文件
- APEX 的載入
Microdroid 不支援:
android.\*
套件中的 Android Java API系統伺服器和Zygote
圖形/使用者介面
哈爾
微機器人架構
Microdroid 與Cuttlefish類似,兩者都具有與標準 Android 類似的架構。 Microdroid 由下列分割區映像組成,這些映像組合在一起形成複合磁碟映像:
-
bootloader
- 驗證並啟動核心。 -
boot.img
- 包含核心和 init ramdisk。 -
vendor_boot.img
- 包含特定於 VM 的核心模組,例如 virtio。 -
super.img
- 由系統和供應商邏輯分區組成。 -
vbmeta.img
- 包含經過驗證的啟動元資料。
分割區映像在 Virtualization APEX 中提供,並由VirtualizationService
打包在複合磁碟映像中。除了主作業系統複合磁碟映像之外, VirtualizationService
還負責建立下列其他分割區:
-
payload
- 由 Android 的 APEX 和 APK 支援的一組分區 instance
- 用於持久保存每個實例驗證的啟動資料的加密分區,例如每個實例的鹽、受信任的 APEX 公鑰和回滾計數器
啟動順序
Microdroid 啟動順序發生在裝置啟動之後。設備啟動在架構文件中進行了討論。圖 1 顯示了 Microdroid 啟動順序期間發生的步驟:
以下是步驟的說明:
引導程式由 crosvm 載入到記憶體中,pvmfw 開始執行。在跳到引導程式之前,pvmfw 執行兩項任務:
- 驗證引導程式以檢查它是否來自可信任來源(Google 或 OEM)。
- 透過使用實例映像,確保在相同 pVM 的多次開機中一致地使用相同的開機載入程式。具體來說,pVM 最初使用空實例映像啟動。 pvmfw 將引導程式的識別儲存在實例映像中並對其進行加密。因此,下次使用相同的實例映像啟動 pVM 時,pvmfw 會解密實例映像中已儲存的身份,並驗證它是否與先前儲存的相同。如果身分不同,pvmfw 將拒絕啟動。
然後引導程式會引導 Microdroid。
引導程式存取實例磁碟。與 pvmfw 類似,引導程式有一個實例磁碟機,其中包含有關此實例在先前引導期間使用的分割映像的信息,包括公鑰。
引導程式驗證 vbmeta 和連結分割區,例如
boot
和super
,如果成功,則派生下一階段的 pVM 秘密。然後,Microdroid 將控制權交給核心。由於超級分割區已經被引導程式驗證(步驟3),因此核心無條件掛載超級分割區。與完整的 Android 一樣,超級分割區由透過 dm-verity 掛載的多個邏輯分割區組成。然後控制權傳遞給
init
進程,該進程啟動各種本機服務。init.rc
腳本與完整 Android 的腳本類似,但針對 Microdroid 的需求進行了客製化。init
進程啟動 Microdroid 管理器,該管理器存取實例映像。 Microdroid 管理器服務使用先前階段傳遞的金鑰解密映像,並讀取該 pVM 信任的用戶端 APK 和 APEX 的公鑰和回溯計數器。稍後zipfuse
和apexd
分別在掛載客戶端 APK 和請求的 APEX 時使用此資訊。Microdroid 管理器服務啟動
apexd
。apexd
將 APEX 掛載在/apex/<name>
目錄中。 Android 和 Microdroid 安裝 APEX 的唯一區別在於,在 Microdroid 中,APEX 檔案來自虛擬區塊裝置(/dev/vdc1
等),而不是來自常規檔案(/system/apex/*.apex
)。zipfuse
是 Microdroid 的 FUSE 檔案系統。zipfuse
掛載客戶端 APK,它本質上是一個作為檔案系統的 Zip 檔案。在下面,APK 檔案作為虛擬區塊設備由具有 dm-verity 的 pVM 傳遞,與 APEX 相同。 APK 包含一個設定文件,其中包含應用程式開發人員為此 pVM 實例請求的 APEX 清單。啟動 APEX 時apexd
使用該清單。引導流程返回 Microdroid 管理器服務。然後,管理器服務使用 Binder RPC 與 Android 的
VirtualizationService
進行通信,以便它可以報告崩潰或關閉等重要事件,並接受終止 pVM 等請求。管理器服務從 APK 的設定檔中讀取主二進位檔案的位置並執行它。
文件交換(AuthFS)
Android 元件通常使用檔案進行輸入、輸出和狀態,並將這些檔案作為檔案描述符(AIDL 中的ParcelFileDescriptor
類型)傳遞,並由 Android 核心控制存取權限。 AuthFS 促進了類似的功能,可以跨 pVM 邊界在相互不信任的端點之間交換檔案。
從根本上講,AuthFS 是一個遠端檔案系統,對各個存取操作進行透明的完整性檢查,類似於fs-verity
。這些檢查允許前端(例如在 pVM 中運行的檔案讀取程式)檢測不受信任的後端(通常是 Android)是否篡改了檔案內容。
為了交換文件,後端( fd\_server
)以每個文件的配置啟動,指定它是用於輸入(唯讀)還是輸出(讀寫)。對於輸入,前端強制內容與 Merkle 樹頂部的已知雜湊相匹配,以進行存取驗證。對於輸出,AuthFS 在內部維護從寫入作業觀察到的內容的雜湊樹,並且可以在讀回資料時強製完整性。
底層傳輸目前基於 Binder RPC,但將來可能會變更以優化效能。
密鑰管理
pVM 配備了適用於受保護的持久性資料的穩定密封金鑰,以及適用於產生由 pVM 可驗證的簽章的證明金鑰。
綁定程序遠端過程調用
Android 的大部分介面都是用AIDL表示的,它是建構在 Binder Linux 核心驅動程式之上。為了支援 pVM 之間的接口,Binder 協定已被重寫以透過套接字(對於 pVM 而言為vsock)工作。透過套接字進行操作允許在這個新環境中使用 Android 現有的 AIDL 介面。
為了建立連接,一個端點(例如 pVM 有效負載)建立一個RpcServer
對象,註冊一個根對象,並開始偵聽新連接。客戶端可以使用RpcSession
對象連接到該伺服器,取得Binder
對象,並像核心 Binder 驅動程式中使用Binder
對像一樣使用它。