Microdroid 是在 pVM 中執行的迷你 Android 作業系統,您不必使用 Microdroid,可以啟動任何 OS 的 VM。不過,pVM 的主要用途並非執行獨立的 OS,而是提供獨立的執行環境,以執行部分應用程式,並提供比 Android 更強大的機密性和完整性保證。
使用傳統作業系統時,提供嚴密的機密性和完整性需要相當多的工作 (通常會重複),因為傳統作業系統不符合整體 Android 架構。舉例來說,在標準 Android 架構中,開發人員必須實作安全載入及執行部分應用程式的機制 (在 pVM 中),且酬載是根據 glibc 建構。Android 應用程式使用 Bionic,通訊需要透過 vsock 採用自訂通訊協定,且使用 adb 進行偵錯相當困難。
Microdroid 提供現成的 OS 映像檔,可將部分應用程式卸載至 pVM,開發人員不需費心調整,因此能填補這些缺口。原生程式碼是根據 Bionic 建構,通訊是透過 Binder 進行,且允許從主機 Android 匯入 APEX,並公開部分 Android API,例如用於處理硬體支援金鑰加密作業的金鑰儲存區。整體而言,開發人員應該會發現 Microdroid 是個熟悉的環境,並提供他們在完整 Android OS 中習慣使用的工具。
功能
Microdroid 是 Android 的精簡版,額外提供幾個 pVM 專用的元件。Microdroid 支援:
- NDK API 子集 (提供 Android 實作 libc 和 Bionic 的所有 API)
- 偵錯功能,例如 adb、logcat、墓碑和 gdb
- 驗證開機程序和 SELinux
- 載入及執行二進位檔,以及內嵌在 APK 中的共用程式庫
- 透過 vsock 進行 Binder RPC,並交換檔案 (含隱含完整性檢查)
- 載入 APEX
Microdroid 不支援:
android.\*
套件中的 Android Java APISystemServer 和 Zygote
圖像/使用者介面
HAL
Microdroid 架構
Microdroid 與 Cuttlefish 類似,兩者的架構都與標準 Android 相似。Microdroid 包含下列分區映像檔,這些映像檔會分組在複合磁碟映像檔中:
bootloader
- 驗證並啟動核心。boot.img
:包含核心和 init ramdisk。vendor_boot.img
- 包含 VM 專屬的核心模組,例如 virtio。super.img
- 由系統和供應商邏輯分割區組成。vbmeta.img
:內含驗證開機程序中繼資料。
分割區映像檔會隨附在虛擬化 APEX 中,並由 VirtualizationService
打包成複合磁碟映像檔。除了主要的 OS 複合磁碟映像檔外,VirtualizationService
也負責建立下列其他磁碟分割區:
payload
- 一組由 Android APEX 和 APK 支援的分割區instance
- 加密磁碟分割區,用於保存每個執行個體驗證的開機資料,例如每個執行個體的鹽、受信任的 APEX 公開金鑰和復原計數器
開機順序
Microdroid 開機順序會在裝置開機後執行。裝置啟動程序請參閱架構文件的 pVM 韌體一節。圖 1 顯示 Microdroid 開機順序期間的步驟:
以下說明各個步驟:
開機載入器會由 crosvm 載入至記憶體,而 pvmfw 則會開始執行。pvmfw 會先執行兩項工作,再跳至開機載入程式:
- 驗證開機載入程式,確認是否來自可信任的來源 (Google 或原始設備製造商)。
- 透過使用執行個體映像檔,確保同一部 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/<name>
目錄掛接 APEX。Android 和 Microdroid 掛接 APEX 的唯一差異在於,Microdroid 的 APEX 檔案來自虛擬區塊裝置 (/dev/vdc1
, …),而非一般檔案 (/system/apex/*.apex
)。zipfuse
是 Microdroid 的 FUSE 檔案系統,zipfuse
會掛接用戶端 APK,這基本上是做為檔案系統的 Zip 檔案。在底層,APK 檔案會由 pVM 透過 dm-verity 做為虛擬區塊裝置傳遞,與 APEX 相同。APK 包含設定檔,其中列出應用程式開發人員為這個 pVM 執行個體要求的所有 APEX。apexd
啟動 APEX 時會使用這份清單。開機流程會返回 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 產生的簽章。
繫結器 RPC
Android 的大多數介面都以 AIDL 表示,而 AIDL 是以 Binder Linux 核心驅動程式為基礎建構而成。為支援 pVM 之間的介面,Binder 通訊協定已重新編寫,可透過插座 (在 pVM 的情況下為 vsock) 運作。透過通訊端運作,即可在這個新環境中使用 Android 現有的 AIDL 介面。
如要設定連線,其中一個端點 (例如 pVM 酬載) 會建立 RpcServer
物件、註冊根物件,並開始監聽新連線。用戶端可以使用 RpcSession
物件連線至這個伺服器、取得 Binder
物件,並以使用核心繫結驅動程式的 Binder
物件相同方式使用。