在沙盒中运行的 API 说明

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

概览

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

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

SAPI 图

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

最后,高级 Transaction API 支持监控 SAPI 库,并在这些库失败时(例如,由于安全违规、崩溃或资源耗尽)重启这些库。

Sandbox2

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

沙盒政策

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

SAPI 使用默认政策,或者您也可以使用专用沙盒政策,方法是在 sandbox.h 头文件中定义该政策,然后将其作为参数传递给 sapi_library 构建规则。

沙盒化库

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

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

SAPI 对象和 RPC 存根

SAPI 对象是一个用于公开沙盒化库 API 的 C++ 对象。它将调用从主机代码转发到 RPC 存根,后者与沙盒化库一起嵌入到 SAPI 库中。

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

主机代码

主机代码用于实现 SAPI 库提供的逻辑。如果不采用,它会使用 C/C++ 库的未沙盒化版本。因此,主机代码会调用 SAPI 库导出的函数,将数据传递给沙盒并从中接收数据。

需要调整主机代码才能使用 SAPI 库。最值得注意的是,无法调用该库的函数,因为该库处于单独的沙盒进程中。因此,SAPI 提供了一些工具,用于创建 SAPI 对象来代理对 SAPI 库的调用。

概念

Bazel 构建规则

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

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

如需查看构建规则的更详尽说明,请参阅构建规则

变量

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

如需对此主题的更详尽说明以及一些常用 SAPI 类型的概览,请参阅变量

交易

如上所述,对沙盒化库的任何 API 调用都会通过 RPC 层传递。为了能够在该层上处理失败,您需要实现适当的错误处理。SAPI 事务模块提供了一种必要的机制,以确保对沙盒化库的所有调用都顺利完成,而不会出现任何 RPC 级问题,或返回并显示相关错误。

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

开始使用

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