Microdroid — это мини-ОС Android, работающая на pVM. Вам не обязательно использовать Microdroid, вы можете запустить ВМ с любой ОС. Однако основные варианты использования pVM — это не автономная ОС, а скорее предложение изолированной среды выполнения для запуска части приложения с более сильными гарантиями конфиденциальности и целостности, чем может предоставить Android.
В традиционных операционных системах обеспечение строгой конфиденциальности и целостности требует значительного объема работы (часто дублируемой), поскольку традиционные операционные системы не вписываются в общую архитектуру Android. Например, в стандартной архитектуре Android разработчикам необходимо реализовать средства безопасной загрузки и выполнения части своего приложения в pVM, а полезная нагрузка создается на основе glibc. Приложение Android использует Bionic, для связи требуется специальный протокол через vsock, а отладка с помощью adb затруднительна.
Microdroid заполняет эти пробелы, предоставляя готовый образ ОС, предназначенный для того, чтобы требовать от разработчиков наименьших усилий для выгрузки части своего приложения в PVM. Собственный код построен на базе Bionic, связь происходит через Binder, он позволяет импортировать APEX с хост-Android и предоставляет подмножество Android API, например хранилище ключей для криптографических операций с аппаратно поддерживаемыми ключами. В целом, разработчики должны найти Microdroid знакомой средой с инструментами, к которым они привыкли в полной версии ОС Android.
Функции
Microdroid — это урезанная версия Android с несколькими дополнительными компонентами, специфичными для pVM. Микродроид поддерживает:
- Подмножество API-интерфейсов NDK (предоставляются все API-интерфейсы для реализации libc и Bionic в Android)
- Функции отладки, такие как adb, logcat, tombstone и gdb.
- Проверенная загрузка и SELinux
- Загрузка и выполнение двоичного файла вместе с общими библиотеками, встроенными в APK
- Binder RPC через vsock и обмен файлами с неявной проверкой целостности
- Загрузка APEX
Микродроид не поддерживает:
API Java для Android в пакетах
android.\*
Системсервер и Зигота
Графика/пользовательский интерфейс
HAL
Микродроидная архитектура
Microdroid похож на Cuttlefish тем, что оба имеют архитектуру, аналогичную стандартной Android. Microdroid состоит из следующих образов разделов, сгруппированных в составной образ диска:
-
bootloader
— проверяет и запускает ядро. -
boot.img
— содержит ядро и инициализирующий виртуальный диск. -
vendor_boot.img
— содержит модули ядра, специфичные для виртуальной машины, такие как virtio. -
super.img
— Состоит из системных и вендорных логических разделов. -
vbmeta.img
— содержит проверенные метаданные загрузки.
Образы разделов поставляются в Virtualization APEX и упаковываются в составной образ диска службой VirtualizationService
. Помимо основного образа составного диска ОС, VirtualizationService
отвечает за создание следующих разделов:
-
payload
— набор разделов, поддерживаемых APEX и APK для Android. -
instance
— зашифрованный раздел для хранения проверенных загрузочных данных для каждого экземпляра, таких как соль для каждого экземпляра, доверенные открытые ключи APEX и счетчики отката.
Последовательность загрузки
Последовательность загрузки Microdroid происходит после загрузки устройства . Загрузка устройства обсуждается в разделе «Прошивка pVM» документа «Архитектура» . На рисунке 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 расшифровывает образ с помощью ключа, переданного на предыдущем этапе, и считывает открытые ключи и счетчики отката клиентских APK и APEX, которым доверяет эта pVM. Эта информация позже используетсяzipfuse
иapexd
, когда они монтируют клиентский APK и запрашивают APEX соответственно.Служба диспетчера Microdroid запускает
apexd
.apexd
монтирует APEX в каталогах/apex/<name>
. Единственная разница между тем, как Android и Microdroid монтируют APEX, заключается в том, что в Microdroid файлы APEX поступают из виртуальных блочных устройств (/dev/vdc1
, …), а не из обычных файлов (/system/apex/*.apex
).zipfuse
— файловая система FUSE компании Microdroid.zipfuse
монтирует клиентский APK, который по сути представляет собой Zip-файл в качестве файловой системы. Ниже файл APK передается pVM как виртуальное блочное устройство с dm-verity, так же, как и APEX. APK содержит файл конфигурации со списком APEX, которые разработчик приложения запросил для этого экземпляра pVM. Список используетсяapexd
при активации APEX.Поток загрузки возвращается в службу диспетчера Microdroid. Затем служба менеджера связывается с Android
VirtualizationService
с помощью Binder RPC, чтобы она могла сообщать о важных событиях, таких как сбой или завершение работы, и принимать запросы, такие как завершение работы pVM. Служба менеджера считывает расположение основного двоичного файла из файла конфигурации APK и выполняет его.
Обмен файлами (AuthFS)
Компоненты Android обычно используют файлы для ввода, вывода и состояния и передают их как файловые дескрипторы (тип ParcelFileDescriptor
в AIDL) с доступом, контролируемым ядром Android. AuthFS обеспечивает аналогичную функциональность для обмена файлами между взаимно не доверяющими конечными точками через границы pVM.
По сути, AuthFS — это удаленная файловая система с прозрачной проверкой целостности отдельных операций доступа, аналогичная fs-verity
. Эти проверки позволяют интерфейсу, например программе чтения файлов, работающей в pVM, обнаружить, не подделал ли ненадежный сервер, обычно Android, содержимое файла.
Для обмена файлами серверная часть ( fd\_server
) запускается с конфигурацией каждого файла, определяющей, предназначен ли он для ввода (только чтение) или вывода (чтение-запись). Для ввода внешний интерфейс обеспечивает соответствие содержимого известному хешу поверх дерева Меркла для проверки при доступе. Для вывода AuthFS внутренне поддерживает хэш-дерево содержимого, наблюдаемое при операциях записи, и может обеспечивать целостность при обратном чтении данных.
Базовый транспорт в настоящее время основан на Binder RPC, однако в будущем это может измениться для оптимизации производительности.
Управление ключами
PVM снабжены стабильным ключом запечатывания , подходящим для защиты постоянных данных, и ключом аттестации , подходящим для создания подписей, которые проверяемо создаются PVM.
Связующее РПК
Большинство интерфейсов Android выражены в AIDL , который построен на основе драйвера ядра Binder Linux. Для поддержки интерфейсов между pVM протокол Binder был переписан для работы через сокеты, vsock в случае pVM. Работа через сокеты позволяет использовать существующие интерфейсы AIDL Android в этой новой среде.
Чтобы установить соединение, одна конечная точка, например полезная нагрузка pVM, создает объект RpcServer
, регистрирует корневой объект и начинает прослушивать новые соединения. Клиенты могут подключиться к этому серверу с помощью объекта RpcSession
, получить объект Binder
и использовать его точно так же, как объект Binder
используется с драйвером Binder ядра.