沙盒化 API (SAPI) 基于成熟的 Sandbox2 项目构建。本页介绍了 SAPI 的设计架构和关键概念。
概览
SAPI 旨在为开发者提供以下工具:用于准备 C/C++ 库以进行沙盒处理的工具,以及与沙盒版 C/C++ 库通信所需的 API。
此图显示了 SAPI 沙盒 C/C++ 库的架构:
SAPI 还提供了一些原语,用于在 SAPI 库和宿主代码之间进行手动和自动(基于自定义指针属性)内存同步(数组、结构)。
最后,高级交易 API 可用于监控 SAPI 库,并在这些库发生故障时(例如由于安全违规、崩溃或资源耗尽)重新启动它们。
Sandbox2
开源项目 Sandbox2 由 Google 安全工程师开发和维护,是 SAPI 使用的核心沙盒技术。Sandbox2 包含三个主要组件:沙盒政策、执行器和Sandboxee。
沙盒政策
沙盒政策定义了沙盒化库的受限执行环境。这是通过明确哪些系统调用可以执行来实现的。SAPI 使用与 Sandbox2 相同的机制,如需详细了解如何设计和定义沙盒政策,请参阅 Sandbox Policy 部分和 Sandbox2 的“开始使用”页面。
SAPI 使用默认政策,您也可以通过在 sandbox.h 头文件中定义专用沙盒政策,并在 sapi_library 构建规则中将其作为实参传递,来使用该政策。
沙盒库
这是将在 Sandbox2 提供的受限沙盒环境中执行的沙盒化 C/C++ 库。最终,沙盒化库会公开所需的功能,供宿主代码使用。
沙盒库是使用 sapi_library build 规则构建的,您可以在其中指定自定义的沙盒政策,以定义受限的执行环境。根据库的不同,您可能需要编写封装容器或桩代码(请参阅 libcurl),但在准备 SAPI 版本时,您无需更改 C/C++ 库的源代码。
SAPI 对象和 RPC Stub
SAPI 对象是一个 C++ 对象,用于公开沙盒库的 API。它将来自宿主代码的调用转发到 RPC Stub,后者与沙盒库一起嵌入在 SAPI 库中。
这两个元素由构建系统使用 sapi_library()
构建规则自动生成。SAPI 支持两种构建系统:Google 的 Bazel 和 CMake。
主机代码
主机代码用于实现 SAPI 库提供的逻辑。否则,它会使用未沙盒化的 C/C++ 库版本。因此,宿主代码会调用 SAPI 库导出的函数,从而将数据传递给沙盒并从沙盒接收数据。
主机代码需要进行调整,才能使用 SAPI 库。最值得注意的是,由于库位于单独的沙盒进程中,因此无法调用库的函数。因此,SAPI 提供了一些工具,用于创建可将调用代理到 SAPI 库的 SAPI 对象。
概念
Bazel 构建规则
SAPI 项目提供了两个用于对 C/C++ 库进行沙盒处理的 Bazel build 规则:
sapi_library()
- 创建将 C/C++ 库沙盒化为 Sandbox2 Sandboxee 所需的所有输出。构建输出可用作cc_binary()
规则的依赖项,该规则用于构建宿主代码二进制文件。sapi_interface()
- 自动生成可包含在宿主代码二进制文件中的标头。
如需更详尽地了解 build 规则,请参阅 build 规则。
变量
SAPI 提供了一些特殊类型(称为 SAPI 类型),建议在宿主代码中使用。需要 SAPI 类型的主要原因是宿主代码与沙盒库之间的进程(以及内存)隔离。
如需更详尽地了解此主题以及一些常用 SAPI 类型的概览,请参阅变量。
交易
如上所述,对沙盒化库的任何 API 调用都会通过 RPC 层传递。为了能够处理此层中的故障,您需要实现适当的错误处理。SAPI 交易模块提供了必要的机制,以确保对沙盒库的所有调用都能顺利完成,不会出现任何 RPC 级问题,或者会返回相关错误。
如需更详尽地了解此主题,请参阅事务。
使用入门
请参阅我们的使用入门页面,设置您的第一个沙盒化 API 项目。