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