Микродроид

Microdroid — это мини-версия Android OS, работающая на виртуальной машине pVM. Использовать Microdroid необязательно, можно запустить виртуальную машину с любой ОС. Однако основное назначение pVM — не запуск автономной ОС, а предоставление изолированной среды выполнения для запуска части приложения с более надежными гарантиями конфиденциальности и целостности, чем может обеспечить Android.

В традиционных операционных системах обеспечение надежной конфиденциальности и целостности требует значительных усилий (часто дублирующихся), поскольку традиционные операционные системы не соответствуют общей архитектуре Android. Например, в стандартной архитектуре Android разработчикам необходимо реализовать способ безопасной загрузки и выполнения части своего приложения в виртуальной машине pVM, а полезная нагрузка собирается с использованием glibc. Приложение Android использует Bionic, для связи требуется собственный протокол через vsock, а отладка с помощью adb представляет собой сложную задачу.

Microdroid заполняет эти пробелы, предоставляя готовый образ ОС, разработанный таким образом, чтобы разработчикам требовалось минимум усилий для переноса части своего приложения на виртуальную машину pVM. Нативный код компилируется на основе Bionic, взаимодействие происходит через Binder, и он позволяет импортировать APEX-файлы с хост-системы Android, а также предоставляет доступ к подмножеству API Android, например, к хранилищу ключей для криптографических операций с аппаратными ключами. В целом, разработчики найдут Microdroid знакомой средой с инструментами, к которым они привыкли в полной версии ОС Android.

Функции

Microdroid — это урезанная версия Android с несколькими дополнительными компонентами, специфичными для pVM. Microdroid поддерживает:

  • Подмножество API NDK (предоставляются все API для реализации libc и Bionic в Android).
  • Функции отладки, такие как adb, logcat, tombstone и gdb.
  • Проверена загрузка и SELinux.
  • Загрузка и выполнение бинарного файла вместе с разделяемыми библиотеками, встроенными в APK-файл.
  • Binder RPC через vsock и обмен файлами с неявными проверками целостности.
  • Загрузка APEX-ов

Microdroid не поддерживает:

  • API Android Java в пакетах android.\*

  • Системный сервер и зигота

  • Графика/Пользовательский интерфейс

  • HALs

Архитектура микродроида

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:

Безопасная загрузка экземпляра microdroid

Рисунок 1. Безопасная загрузка экземпляра microdroid.

Вот объяснение шагов:

  1. Загрузчик загружается в память программой CrosVM, после чего начинается выполнение pvmfw. Перед переходом к загрузчику pvmfw выполняет две задачи:

    • Проверяет загрузчик, чтобы убедиться, что он получен из надежного источника (Google или OEM-производителя).
    • Обеспечивает согласованное использование одного и того же загрузчика при многократной загрузке одной и той же виртуальной машины pVM за счет использования образа экземпляра. В частности, pVM изначально загружается с пустым образом экземпляра. pvmfw сохраняет идентификатор загрузчика в образе экземпляра и шифрует его. Таким образом, при следующей загрузке pVM с тем же образом экземпляра pvmfw расшифровывает сохраненный идентификатор из образа экземпляра и проверяет, совпадает ли он с ранее сохраненным. Если идентификаторы различаются, pvmfw отказывается загружать систему.

    Затем загрузчик запускает Microdroid.

  2. Загрузчик обращается к экземпляру диска. Подобно pvmfw, загрузчик имеет экземпляр диска, содержащий информацию об образах разделов, использованных в этом экземпляре во время предыдущих загрузок, включая открытый ключ.

  3. Загрузчик проверяет vbmeta и связанные с ним разделы, такие как boot и super , и, в случае успеха, вычисляет секреты pVM следующего этапа. Затем Microdroid передает управление ядру.

  4. Поскольку суперраздел уже проверен загрузчиком (шаг 3), ядро ​​безусловно монтирует суперраздел. Как и в полной версии Android, суперраздел состоит из нескольких логических разделов, смонтированных через dm-verity. Затем управление передается процессу init , который запускает различные собственные службы. Скрипт init.rc аналогичен скрипту полной версии Android, но адаптирован под потребности Microdroid.

  5. Процесс init запускает менеджер Microdroid, который обращается к образу экземпляра. Служба менеджера Microdroid расшифровывает образ, используя ключ, переданный на предыдущем этапе, и считывает открытые ключи и счетчики отката клиентского APK и APEX, которым доверяет этот pVM. Эта информация используется позже zipfuse и apexd при монтировании клиентского APK и запрошенных APEX соответственно.

  6. Служба Microdroid Manager запускает apexd .

  7. apexd монтирует APEX-файлы в каталоги /apex/<name> . Единственное различие между способом монтирования APEX-файлов в Android и Microdroid заключается в том, что в Microdroid APEX-файлы берутся с виртуальных блочных устройств ( /dev/vdc1 , … ), а не из обычных файлов ( /system/apex/*.apex ).

  8. zipfuse — это файловая система FUSE от Microdroid. zipfuse монтирует APK-файл клиента, который по сути является ZIP-файлом, в качестве файловой системы. В основе APK-файла лежит виртуальное блочное устройство, передаваемое pVM с помощью dm-verity, аналогично APEX. APK-файл содержит конфигурационный файл со списком APEX, запрошенных разработчиком приложения для данного экземпляра pVM. Этот список используется apexd при активации APEX.

  9. Процесс загрузки возвращается к службе управления Microdroid. Затем служба управления взаимодействует со VirtualizationService Android с помощью Binder RPC, чтобы сообщать о важных событиях, таких как сбой или завершение работы, и принимать запросы, например, на завершение работы pVM. Служба управления считывает местоположение основного исполняемого файла из конфигурационного файла APK и выполняет его.

Обмен файлами (AuthFS)

В Android-компонентах часто используются файлы для ввода, вывода и состояния, которые передаются в виде файловых дескрипторов (тип ParcelFileDescriptor в AIDL) с контролем доступа со стороны ядра Android. AuthFS обеспечивает аналогичную функциональность для обмена файлами между конечными точками, не доверяющими друг другу, через границы pVM.

По сути, AuthFS — это удалённая файловая система с прозрачными проверками целостности отдельных операций доступа, аналогичная fs-verity . Эти проверки позволяют интерфейсу, например, программе для чтения файлов, работающей в виртуальной машине pVM, обнаружить, если недоверенный бэкэнд, обычно Android, изменил содержимое файла.

Для обмена файлами запускается бэкэнд ( fd\_server ) с конфигурацией для каждого файла, указывающей, предназначен ли он для ввода (только для чтения) или вывода (чтение-запись). Для ввода фронтенд проверяет соответствие содержимого известному хешу, а также использует дерево Меркла для проверки при доступе. Для вывода AuthFS внутренне поддерживает хеш-дерево содержимого, полученного в результате операций записи, и может обеспечивать целостность при обратном считывании данных.

В настоящее время в качестве основного механизма передачи данных используется Binder RPC, однако в будущем это может измениться для оптимизации производительности.

Управление ключами

В состав pVM входят стабильный ключ для защиты постоянных данных и ключ аттестации , позволяющий создавать подписи, подлинность которых можно подтвердить с помощью pVM.

Binder RPC

Большинство интерфейсов Android реализованы на языке AIDL , который построен на основе драйвера ядра Linux Binder. Для поддержки интерфейсов между виртуальными машинами pVM протокол Binder был переписан для работы через сокеты, в случае pVM — через vsock . Работа через сокеты позволяет использовать существующие интерфейсы AIDL Android в этой новой среде.

Для установления соединения одна из конечных точек, например, полезная нагрузка pVM, создает объект RpcServer , регистрирует корневой объект и начинает прослушивать новые соединения. Клиенты могут подключаться к этому серверу, используя объект RpcSession , получать объект Binder и использовать его точно так же, как объект Binder используется с драйвером Binder ядра.