サンドボックス化された API の説明

Sandboxed API(SAPI)は、確立された Sandbox2 プロジェクトをベースに構築されています。このページでは、SAPI の設計アーキテクチャと主なコンセプトについて説明します。

概要

SAPI は、C/C++ ライブラリをサンドボックス化するためのツールと、サンドボックス化されたバージョンの C/C++ ライブラリとの通信に必要な API をデベロッパーに提供するように設計されています。

この図は、SAPI サンドボックス化された C/C++ ライブラリのアーキテクチャを示しています。

SAPI の図

SAPI は、SAPI ライブラリとホストコード間の手動および自動(カスタム ポインタ属性に基づく)メモリ同期(配列、構造体)用のプリミティブも提供します。

最後に、高レベルの Transactions API により、SAPI ライブラリをモニタリングし、障害(セキュリティ違反、クラッシュ、リソースの枯渇など)が発生した場合は再起動できます。

Sandbox2

オープンソース プロジェクト Sandbox2 は、Google のセキュリティ エンジニアによって開発、保守されており、SAPI で使用されるコア サンドボックス テクノロジーです。Sandbox2 は、サンドボックス ポリシー、エグゼキュータ、サンドボックスの 3 つの主要コンポーネントで構成されています。

サンドボックス ポリシー

サンドボックス ポリシーは、サンドボックス化されたライブラリの制限付き実行環境を定義します。これは、実行可能なシステムコールを明確にすることで実現されます。SAPI は Sandbox2 と同じメカニズムを使用します。サンドボックス ポリシーの設計と定義の方法について詳しくは、サンドボックス ポリシーのセクションと Sandbox2 のスタートガイドのページをご覧ください。

デフォルトでは、生成された SAPI サンドボックス クラスは DefaultConfig(sapi::SandboxConfig::DefaultConfig())を使用して初期化されます。DefaultConfig() は、次の構成でサンドボックスを構成します。

  • sapi::Sandbox2Config::DefaultPolicyBuilder() でビルドされたデフォルトの Sandbox2 ポリシー
  • sapi::Sandbox2Config::DefaultLimits() のデフォルトのリソースと時間制限
  • 共有メモリ通信が有効(DefaultPolicyBuilder() の共有メモリ権限とペア設定)
  • デフォルトのコマンドライン フラグ(sapi::SandboxConfig::DefaultFlags())と環境変数(sapi::SandboxConfig::DefaultEnvironmentVariables())。サンドボックス内のベースライン ロギングとランタイム動作を構成します。

サンドボックス ポリシーまたは構成をカスタマイズするには、sapi::SandboxConfig::DefaultConfig() から開始し、返された sapi::SandboxConfig を変更して、生成されたサンドボックス コンストラクタに渡します(または、sapi_library ビルドルールに渡された sandbox.h ヘッダー ファイルでカスタム サンドボックス サブクラスを定義します)。たとえば、sapi::Sandbox2Config::DefaultPolicyBuilder() からポリシーの構築を開始し、追加のルールをチェーンできます(より制限の厳しい構成が必要な場合は、PolicyBuilder を直接構築します)。フラグや環境変数を追加する場合は、sapi::SandboxConfig::DefaultFlags() または sapi::SandboxConfig::DefaultEnvironmentVariables() から開始して、ベースライン設定が保持されるようにします。

サンドボックス化されたライブラリ

これは、Sandbox2 によって提供される制限付きサンドボックス環境で実行されるサンドボックス化された C/C++ ライブラリです。最終的に、サンドボックス化されたライブラリは、ホストコードで使用できる必要な機能を公開します。

サンドボックス ライブラリは sapi_library ビルドルールでビルドされます。このルールでは、制限付き実行環境を定義するカスタマイズされたサンドボックス ポリシーを指定できます。ライブラリによっては、ラッパーまたはスタブコードを記述する必要がある場合があります(libcurl を参照)。ただし、SAPI バージョンを準備する際に、C/C++ ライブラリのソースコードを変更する必要はありません。

SAPI オブジェクトと RPC スタブ

SAPI オブジェクトは、サンドボックス化されたライブラリの API を公開する C++ オブジェクトです。ホストコードからの呼び出しを RPC スタブに転送します。RPC スタブは、サンドボックス ライブラリとともに SAPI ライブラリに埋め込まれています。

これら 2 つの要素は、sapi_library() ビルドルールを使用してビルドシステムによって自動的に生成されます。SAPI は、Google の Bazel と CMake の 2 つのビルドシステムをサポートしています。

ホストコード

ホストコードは、SAPI ライブラリが提供するロジックを実装するものです。これは、サンドボックス化されていないバージョンの C/C++ ライブラリを使用するものです。そのため、ホストコードは SAPI ライブラリによってエクスポートされた関数を呼び出し、サンドボックスとの間でデータを送受信します。

ホストコードは、SAPI ライブラリを使用するように調整する必要があります。特に、ライブラリは別のサンドボックス プロセスに存在するため、ライブラリの関数を呼び出すことはできません。そのため、SAPI には、SAPI ライブラリへの呼び出しをプロキシする SAPI オブジェクトを作成するツールが用意されています。

コンセプト

Bazel ビルドルール

SAPI プロジェクトには、C/C++ ライブラリをサンドボックス化するための 2 つの Bazel ビルドルールが用意されています。

  • sapi_library() - C/C++ ライブラリを Sandbox2 Sandboxee としてサンドボックス化するために必要なすべての出力を作成します。ビルド出力は、ホストコード バイナリのビルドに使用される cc_binary() ルールの依存関係として使用できます。
  • sapi_interface() - ホストコード バイナリに含めることができるヘッダーを自動生成します。

ビルドルールの詳細については、ビルドルールをご覧ください。

変数

SAPI には、SAPI タイプと呼ばれる特別なタイプがいくつか用意されています。これらは、ホストコードで使用することをおすすめします。SAPI タイプが必要な主な理由は、ホストコードとサンドボックス化されたライブラリ間のプロセス(つまりメモリ)の分離です。

このトピックの詳細な説明と、一般的に使用される SAPI タイプの一部の概要については、変数をご覧ください。

トランザクション

前述のように、サンドボックス化されたライブラリへの API 呼び出しは、RPC レイヤを介して渡されます。このレイヤで障害を処理できるようにするには、適切なエラー処理を実装する必要があります。SAPI トランザクション モジュールは、サンドボックス化されたライブラリへのすべての呼び出しが RPC レベルの問題なしに完了するか、関連するエラーを返すようにするために必要なメカニズムを提供します。

このトピックの詳細については、トランザクションをご覧ください。

スタートガイド

スタートガイドのページを読んで、最初の Sandboxed API プロジェクトを設定します。