Microdroid

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

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

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

Функции

Microdroid – это урезанная версия Android с несколькими дополнительными компонентами, предназначенными для защищенных виртуальных машин. Microdroid поддерживает:

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

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

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

  • SystemServer и Zygote;

  • Графика и интерфейс

  • HAL

Архитектура Microdroid

Microdroid похож на Cuttlefish тем, что оба имеют архитектуру, аналогичную стандартной архитектуре Android. Microdroid состоит из следующих образов разделов, сгруппированных в составной образ диска:

  • bootloader – проверяет и запускает ядро.
  • boot.img – содержит ядро и initramfs.
  • vendor_boot.img – содержит модули ядра, относящиеся к виртуальной машине, например virtio.
  • super.img – состоит из логических разделов системы и поставщика.
  • vbmeta.img – содержит метаданные проверки при запуске.

Образы разделов поставляются в APEX виртуализации и упаковываются в составной образ диска с помощью VirtualizationService. Помимо основного составного образа диска ОС, VirtualizationService отвечает за создание следующих разделов:

  • payload – набор разделов, поддерживаемых APEX и APK Android.
  • instance – зашифрованный раздел для хранения данных проверки при запуске, относящихся к экземпляру, например соли, доверенных открытых ключей APEX и счетчиков отката.

Порядок загрузки

Загрузка Microdroid происходит после загрузки устройства. Загрузка устройства описана в разделе "Встроенное ПО pVM" документа Архитектура. На рисунке 1 показаны этапы загрузки Microdroid.

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

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

Ниже описаны шаги, которые необходимо выполнить.

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

    • Проверяет загрузчик, чтобы убедиться, что он получен из доверенного источника (Google или производителя оригинального оборудования).
    • Обеспечивает использование одного и того же загрузчика при нескольких загрузках одной и той же виртуальной машины с помощью образа экземпляра. В частности, pVM изначально загружается с пустым образом экземпляра. pvmfw сохраняет идентификатор загрузчика в образе экземпляра и шифрует его. Поэтому при следующем запуске виртуальной машины с тем же образом экземпляра 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>. Единственное различие между тем, как Android и Microdroid монтируют APEX, заключается в том, что в 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 Manager. Затем сервис менеджера связывается с VirtualizationService Android, используя Binder RPC, чтобы сообщать о важных событиях, таких как сбой или завершение работы, и принимать запросы, например на завершение работы pVM. Сервис менеджера считывает местоположение основного исполняемого файла из файла конфигурации APK и выполняет его.

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

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

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

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

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

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

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

Binder RPC

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

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