Что такое Sandboxed API

Изолированный API (SAPI) создан на основе хорошо зарекомендовавшего себя проекта Sandbox2. На этой странице описана архитектура SAPI и ключевые концепции.

Обзор

SAPI предоставляет разработчикам инструменты для подготовки библиотек C/C++ к изолированной среде, а также API, необходимые для взаимодействия с изолированной версией библиотек C/C++.

На этой диаграмме показана архитектура изолированной библиотеки C/C++ SAPI:

Диаграмма SAPI

SAPI также предоставляет примитивы для ручной и автоматической (на основе настраиваемых атрибутов указателей) синхронизации памяти (массивов, структур) между библиотеками SAPI и кодом хоста.

Наконец, высокоуровневый Transactions API позволяет отслеживать библиотеки SAPI и перезапускать их в случае сбоя (например, из-за нарушения безопасности, сбоя или нехватки ресурсов).

Sandbox2

Проект с открытым исходным кодом Sandbox2 разработан и поддерживается инженерами по безопасности Google. Это основная технология изолированной среды, используемая SAPI. В Sandbox2 есть три основных компонента: Sandbox Policy, Executor и Sandboxee.

Правила использования изолированной среды

Правило песочницы определяет ограниченную среду выполнения для библиотеки в песочнице. Это достигается за счет уточнения того, какие системные вызовы могут быть выполнены. SAPI использует тот же механизм, что и Sandbox2. Подробную информацию о том, как разработать и определить правила песочницы, можно найти в разделе Правила песочницы и на странице Начало работы для Sandbox2.

По умолчанию сгенерированные классы изолированной среды SAPI инициализируются с помощью DefaultConfig (sapi::SandboxConfig::DefaultConfig()). DefaultConfig() настраивает изолированную среду со следующими параметрами:

  • Правило Sandbox2 по умолчанию, созданное с помощью sapi::Sandbox2Config::DefaultPolicyBuilder()
  • Ограничения на ресурсы и время по умолчанию из sapi::Sandbox2Config::DefaultLimits()
  • Включен обмен данными через общую память (в сочетании с разрешениями на использование общей памяти в DefaultPolicyBuilder()).
  • Параметры командной строки по умолчанию (sapi::SandboxConfig::DefaultFlags()) и переменные среды (sapi::SandboxConfig::DefaultEnvironmentVariables()), которые настраивают базовое ведение журнала и поведение во время выполнения в изолированной среде.

Чтобы настроить правила или конфигурацию изолированной среды, начните с sapi::SandboxConfig::DefaultConfig(), измените возвращенный sapi::SandboxConfig и передайте его в конструктор сгенерированной изолированной среды (или определите собственный подкласс изолированной среды в файле заголовка sandbox.h, переданном в правило сборки sapi_library). Например, вы можете создать правило, начиная с sapi::Sandbox2Config::DefaultPolicyBuilder(), и добавить дополнительные правила (или создать PolicyBuilder напрямую, если требуется более строгая конфигурация), а при добавлении флагов или переменных среды начать с sapi::SandboxConfig::DefaultFlags() или sapi::SandboxConfig::DefaultEnvironmentVariables(), чтобы сохранить базовые настройки.

Изолированная библиотека

Это изолированная библиотека C/C++, которая будет выполняться в ограниченной изолированной среде, предоставляемой Sandbox2. В конечном итоге изолированная библиотека предоставляет необходимую функциональность, которую может использовать код хоста.

Изолированная библиотека создается с помощью правила сборки sapi_library, в котором можно указать настраиваемое правило изолированной среды, определяющее ограниченную среду выполнения. В зависимости от библиотеки вам может потребоваться написать код-обертку или код-заглушку (см. libcurl), но вам не нужно менять исходный код библиотеки C/C++ при подготовке версии SAPI.

Объект SAPI и заглушка RPC

Объект SAPI – это объект C++, который предоставляет API изолированной библиотеки. Он перенаправляет вызовы из кода хоста в заглушку RPC, которая встроена в библиотеку SAPI вместе с библиотекой в изолированной среде.

Эти два элемента автоматически генерируются системой сборки с помощью правила сборки sapi_library(). SAPI поддерживает две системы сборки: Bazel от Google и CMake.

Код хоста

Код хоста реализует логику, предоставляемую библиотекой SAPI. Это то, что в противном случае использовало бы версию библиотеки C/C++ без изолированной среды. Таким образом, код хоста вызывает функции, экспортированные библиотекой SAPI, передавая данные в песочницу и получая данные из нее.

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

Основные понятия

Правила сборки Bazel

Проект SAPI предоставляет два правила сборки Bazel для изолирования библиотеки C/C++:

  • sapi_library() – создает все выходные данные, необходимые для изоляции библиотеки C/C++ в качестве изолированной среды Sandbox2. Результат сборки можно использовать в качестве зависимости для правила cc_binary(), которое применяется для сборки двоичного файла кода хоста.
  • sapi_interface() – автоматически генерирует заголовок, который можно включить в двоичный код хоста.

Более подробную информацию о правилах сборки можно найти в разделе Правила сборки.

Переменные

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

Более подробную информацию об этой теме и обзор некоторых часто используемых типов SAPI можно найти в разделе Переменные.

Транзакции

Как объяснялось выше, любой вызов API к изолированной библиотеке передается через уровень RPC. Чтобы справиться с ошибкой на этом уровне, необходимо реализовать надлежащую обработку ошибок. Модуль SAPI Transaction предоставляет механизм, который гарантирует, что все вызовы изолированной библиотеки будут выполнены без проблем на уровне RPC или возвращены с соответствующей ошибкой.

Более подробную информацию можно найти в статье Транзакции.

Начало работы

Чтобы создать свой первый проект Sandboxed API, прочитайте статью Начало работы.