在沙盒中运行的 API 说明

沙盒 API (SAPI) 基于成熟的 Sandbox2 项目构建。本页介绍了 SAPI 的设计架构和关键概念。

概览

SAPI 旨在为开发者提供工具,以便准备用于沙盒化的 C/C++ 库,以及与沙盒化版本的 C/C++ 库通信所需的 API。

下图展示了 SAPI 沙盒化 C/C++ 库的架构:

SAPI 图示

SAPI 还提供了 原语用于在 SAPI 库和宿主代码之间手动和 自动(基于自定义指针属性)进行内存同步(数组、 结构)。

最后,高级事务 API 可用于 监控 SAPI 库,并在 SAPI 库失败时(例如,由于 违规、崩溃或资源耗尽)重启它们。

Sandbox2

开源项目 Sandbox2 由 Google 安全工程师开发和 维护,是 SAPI 使用的核心沙盒化技术 。Sandbox2 包含三个主要组件:沙盒 政策、 执行程序和 Sandboxee。

沙盒政策

沙盒政策定义了沙盒化库的受限执行环境。这是通过明确可以执行哪些系统调用来实现的。SAPI 使用与 Sandbox2 相同的机制,如需详细了解如何设计和定义沙盒政策,请参阅沙盒政策 部分和 Sandbox2 使用 入门页面。

默认情况下,生成的 SAPI 沙盒类使用 DefaultConfig (sapi::SandboxConfig::DefaultConfig()) 进行初始化。DefaultConfig() 使用以下内容配置沙盒:

  • 使用 sapi::Sandbox2Config::DefaultPolicyBuilder() 构建的默认 Sandbox2 政策
  • sapi::Sandbox2Config::DefaultLimits() 中的默认资源和时间限制
  • 已启用共享内存通信(与 DefaultPolicyBuilder() 中的共享内存权限配对)
  • 默认命令行标志 (sapi::SandboxConfig::DefaultFlags()) 和环境变量 (sapi::SandboxConfig::DefaultEnvironmentVariables()),用于在 sandboxee 中配置基准日志记录和运行时行为

如需自定义沙盒政策或配置,请从 sapi::SandboxConfig::DefaultConfig() 开始,修改返回的 sapi::SandboxConfig,并将其传递给生成的沙盒构造函数(或 在传递给 sapi_library build 规则的 sandbox.h 头文件中定义自定义沙盒子类)。例如,您可以从 sapi::Sandbox2Config::DefaultPolicyBuilder()开始构建政策,并链接其他规则(或 在需要更严格的配置时 直接 PolicyBuilder),并且在添加 标志或环境变量时,从 sapi::SandboxConfig::DefaultFlags()或 sapi::SandboxConfig::DefaultEnvironmentVariables() 开始,以便保留基准设置。

沙盒化库

这是将在 Sandbox2 提供的受限沙盒环境中执行的沙盒化 C/C++ 库。最终,沙盒化库 会公开可供宿主 代码使用的所需功能。

沙盒化库是使用 sapi_library build 规则构建的,您可以在其中指定自定义沙盒政策,以定义 受限执行环境。根据库的不同,您可能需要编写封装容器或桩代码(请参阅libcurl),但在准备 SAPI 版本时,您无需更改 C/C++ 库的源代码。

SAPI 对象和 RPC 桩

SAPI 对象是一个 C++ 对象,用于公开沙盒化库的 API。它将来自宿主代码的调用转发给 RPC 桩,RPC 桩与沙盒化库一起嵌入在 SAPI 库中。

这两个元素由构建系统使用 sapi_library() build 规则自动生成。SAPI 支持两个构建系统:Google 的 Bazel 和 CMake。

宿主代码

宿主代码用于实现 SAPI 库提供的逻辑。它原本会使用未沙盒化的 C/C++ 库版本。因此,宿主代码会调用 SAPI 库导出的函数,向沙盒传递数据并从沙盒接收数据。

宿主代码需要进行调整才能使用 SAPI 库。最值得注意的是,由于库位于单独的沙盒化进程中,因此无法调用库的函数。因此,SAPI 提供了用于创建 SAPI 对象的工具,该对象会将调用代理到 SAPI 库。

概念

Bazel build 规则

SAPI 项目提供了两个 Bazel build 规则,用于沙盒化 C/C++ 库:

  • sapi_library() - 创建将 C/C++ 库沙盒化为 Sandbox2 Sandboxee 所需的所有输出。build 输出可用作 cc_binary() 规则的依赖项,该规则用于构建宿主代码二进制文件。
  • sapi_interface() - 自动生成可包含在宿主代码二进制文件中的头文件。

如需详细了解 build 规则,请参阅 Build Rules。

变量

SAPI 提供了许多特殊类型(称为 SAPI 类型),我们建议您在 宿主代码中使用这些类型。需要 SAPI 类型的主要原因是宿主代码和沙盒化库之间的进程隔离(因此内存隔离)。

如需详细了解此主题并大致了解一些常用的 SAPI 类型,请参阅变量。

事务

如上所述,对沙盒化库的任何 API 调用都会通过 RPC 层传递。如需能够处理此层上的失败,您需要实现适当的错误处理。SAPI 事务 模块提供了必要的机制,以确保对 沙盒化库的所有调用都已完成,没有任何 RPC 级问题,或者 返回了相关错误。

如需详细了解此主题,请参阅 事务。

使用入门

请阅读我们的使用入门页面 ,以设置您的第一个沙盒化 API 项目。