Sandboxed API 使用入门
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
在此页面上,您将了解如何使用沙盒化 API (SAPI) 创建自己的沙盒化 C/C++ 库。您可以将其与头文件中的示例和代码文档一起用作指南。
构建依赖项
必须在系统上安装以下依赖项:
- 支持 UTS、IPC、用户、PID 和网络命名空间的 Linux 内核
- Linux 用户空间 API 标头
- 编译代码:GCC 6(最好是版本 7 或更高版本)或 Clang 7(或更高版本)
- 对于自动生成头文件:Clang Python 绑定
- Python 3.5 或更高版本
- Bazel 版本 2.2.0 或 CMake 版本 3.12 或更高版本。
使用 Bazel
Bazel 是推荐的构建系统,也是最容易集成的。
我们的文档使用 Clang 编译器。如果您需要特定的工具链(例如编译器、链接器等),请参阅 Bazel 文档,了解如何更改默认编译器工具链。
Debian 10 (Buster)
如需安装 build 依赖项,请执行以下操作:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
python3-pip libclang-dev
pip3 install clang
Gentoo
所需内核选项:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
如需安装 build 依赖项,请执行以下操作:
emerge dev-util/bazel dev-python/typing dev-python/clang-python
使用 CMake
CMake 是一种热门的开源元构建系统,可为 Ninja 或 Make 等构建工具生成项目文件。
Debian 10 (Buster)
如需安装 build 依赖项,请执行以下操作:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang
Gentoo
所需内核选项:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
如需安装 build 依赖项,请执行以下操作:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
开发流程
如需对 C/C++ 库进行沙盒处理,您必须为项目准备以下两项内容:
您可能熟悉 Sandbox2 示例中的 zlib,这里对整个程序 (zpipe.c) 进行了沙盒处理。在以下步骤中,您将学习如何使用 SAPI 对 zlib 库进行沙盒处理,并使用沙盒库。
1. 确定需要哪些功能
如果您查看 zlib 主机代码 (main_zlib.cc),就会发现该工具的功能是从标准输入读取数据,并使用 zlib 的 deflate()
函数压缩数据,直到读取到 EOF
标记为止。该程序总共使用了 zlib 中的三个函数:
deflateInit_()
:初始化以进行压缩
deflate()
:对数据块执行压缩操作
deflateEnd()
:结束压缩并释放动态分配的数据结构
在实际示例中,您需要查看 C/C++ 库并确定需要哪些函数。一种可能的策略是从宿主代码开始,并使用未沙盒化的库。然后,在第二步中,您可以生成沙盒化库,并调整宿主代码以使用沙盒化函数调用。
2. 编写 sapi_library build 规则
从沙盒化的 zlib 库中确定所需的三个 zlib 函数后,您可以在 BUILD 文件中定义 build 规则。如需查看 sapi_library
build 规则的相关文档,请访问build 规则页面。
以下代码段显示了 zlib SAPI 示例的 sapi_library
定义。通过使用 lib
属性,Bazel 会在 WORKSPACE 文件中查找 zlib 库。
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
结果是生成了沙盒化的 zlib 库。输出是 SAPI 对象,可以将其包含在宿主代码中,并通过 RPC 调用与沙盒库进行通信。此示例中使用的沙盒政策是默认政策。
3. 编写或更改主机代码
现在,您可以将生成的 SAPI 库纳入宿主代码中。
创建沙盒
使用 sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());
创建沙盒对象。
使用 sapi::zlib::ZlibApi api(&sandbox);
实例化 SAPI 对象,从而使沙盒函数可供使用。
使用 SAPI 类型
SAPI 类型是 SAPI 提供的特殊类型(以 C++ 类的形式),因为有时常规 C 类型无法正常运行。
在 strm
的声明中,我们可以看到 SAPI 类型的首次使用,其中使用了 SAPI 结构:sapi::v::Struct<sapi::zlib::z_stream> strm;
模板类型 (sapi::zlib::z_stream
) 是由 build 规则自动生成的代码的一个很好的示例。
如需了解详情,请参阅“变量”页面。
进行 API 调用
如需调用 defalteInit_
、deflate
或 deflateEnd
,请使用 SAPI 对象。如果您决定使用“更改”方法,则必须确保函数参数与预期值匹配。
zlib 示例中每个调用的示例:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
使用 SAPI 交易
SAPI 可将宿主代码与沙盒化库隔离开来,并让调用者能够重启或中止有问题的数据处理请求。SAPI 事务更进一步,可自动重复失败的流程。
如需了解详情,请参阅 SAPI 交易页面。
示例
在示例下,您可以找到 SAPI 团队已准备好的一些库。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-26。"],[[["\u003cp\u003eThis documentation guides you in creating sandboxed C/C++ libraries using Sandboxed API (SAPI) with Bazel or CMake build systems, including build dependencies and development process.\u003c/p\u003e\n"],["\u003cp\u003eYou'll learn how to define functions for sandboxing, create the sandbox environment, utilize SAPI types, and make API calls to interact with your sandboxed library.\u003c/p\u003e\n"],["\u003cp\u003eSAPI transactions offer the capability to automatically retry failed data processing requests, enhancing the resilience of your sandboxed code.\u003c/p\u003e\n"],["\u003cp\u003eRefer to the provided examples for practical demonstrations of sandboxing common libraries like zlib using SAPI.\u003c/p\u003e\n"]]],[],null,["On this page, you will learn how to create your own sandboxed C/C++ library with\nSandboxed API (SAPI). Use it as a guide alongside the\n[examples](/code-sandboxing/sandboxed-api/examples) and code documentation in\nthe header files.\n\nBuild Dependencies\n\nThe following dependencies must be installed on the system:\n\n- Linux kernel with support for UTS, IPC, user, PID, and network namespaces\n- Linux userspace API headers\n- To compile your code: GCC 6 (version 7 or higher preferred) or Clang 7 (or higher)\n- For auto-generating header files: Clang Python Bindings\n- Python 3.5 or later\n- [Bazel](https://bazel.build/) version 2.2.0 or [CMake](https://cmake.org/) version 3.12 or higher.\n - CMake only: [GNU Make](https://www.gnu.org/software/make/) or a version of the libcap library headers and a build tool such as [Ninja](https://ninja-build.org/) (recommended).\n\nUsing Bazel\n\nBazel is the recommended build system and is the easiest to integrate with.\n\nOur documentation uses the Clang compiler. If you need a specific toolchain\n(e.g. compiler, linker, etc.), refer to the [Bazel\ndocumentation](https://docs.bazel.build/versions/master/bazel-overview.html) for\ninformation on how to change the default compiler toolchain. \n\nDebian 10 (Buster)\n\nTo install build dependencies: \n\n echo \"deb http://storage.googleapis.com/bazel-apt stable jdk1.8\" | \\\n sudo tee /etc/apt/sources.list.d/bazel.list\n wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -\n sudo apt-get update\n sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \\\n python3-pip libclang-dev\n pip3 install clang\n\nGentoo\n\nKernel options required: \n\n General setup ---\u003e\n -*- Namespaces support\n [*] UTS namespace\n [*] IPC namespace\n [*] User namespace (EXPERIMENTAL)\n [*] PID Namespaces\n [*] Network namespace\n\nTo install build dependencies: \n\n emerge dev-util/bazel dev-python/typing dev-python/clang-python\n\nUsing CMake\n\n[CMake](https://cmake.org/) is a popular open-source meta build system that\ngenerates project files for build tools such as\n[Ninja](https://ninja-build.org/) or [Make](https://www.gnu.org/software/make/). \n\nDebian 10 (Buster)\n\nTo install build dependencies: \n\n sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \\\n python3 python3-pip libclang-dev libcap-dev\n pip3 install absl-py clang\n\nGentoo\n\nKernel options required: \n\n General setup ---\u003e\n -*- Namespaces support\n [*] UTS namespace\n [*] IPC namespace\n [*] User namespace (EXPERIMENTAL)\n [*] PID Namespaces\n [*] Network namespace\n\nTo install build dependencies: \n\n emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \\\n dev-python/clang-python\n\nDevelopment Process\n\nTo sandbox a C/C++ library, you will have to prepare two items for your project:\n\n- The [Sandboxed Library](/code-sandboxing/sandboxed-api)\n- The [Host Code](/code-sandboxing/sandboxed-api/explained#host_code) which will make use of the functionality exposed by your Sandboxed Library. SAPI will generate the [SAPI Object and RPC\n Stub](/code-sandboxing/sandboxed-api/explained#sapi_object_and_rpc_stub) automatically for you during the build process.\n\nYou may be familiar with the [zlib from the Sandbox2\nexamples](https://github.com/google/sandboxed-api/tree/main/sandboxed_api/sandbox2/examples/zlib)\nhere a whole program\n([zpipe.c](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/zlib/zpipe.c))\nwas sandboxed. In the following steps, you will learn how to use SAPI to\n[sandbox the zlib](/code-sandboxing/sandboxed-api/examples#zlib) library and\nmake use of the Sandboxed Library.\n\n1. Decide which functions are needed\n\nIf you look at the zlib host code\n([main_zlib.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/examples/zlib/main_zlib.cc)),\nyou can see that the tool's functionality is to read data from stdin and use\nzlib's `deflate()` function to compress the data until an `EOF` marker is read.\nIn total, the program uses three functions from zlib:\n\n- `deflateInit_()`: To initialize for compression\n- `deflate()`: To perform the compression operation on the data chunk\n- `deflateEnd()`: To end the compression and free dynamically allocated data structures\n\nIn a real life example you would review the C/C++ library and decide which\nfunctions are needed. A possible strategy is to start with the Host Code and use\nthe library unsandboxed. Then, in a second step, you could generate the\nSandboxed Library and adapt the Host Code to use the sandboxed function calls.\n\n2. Write the sapi_library Build Rule\n\nAfter you have identified the three zlib functions that are needed from the\nsandboxed zlib library, you can define the build rule in the\n[BUILD](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/examples/zlib/BUILD.bazel)\nfile. The documentation for the `sapi_library` build rule can be found on the\n[Build Rules](/code-sandboxing/sandboxed-api/build-rules) page.\n\nThe code snippet below shows the `sapi_library` definition for the zlib SAPI\nexample. Using the `lib` attribute, Bazel is instructed to look in the\n[WORKSPACE](https://github.com/google/sandboxed-api/blob/main/WORKSPACE) file\nfor the zlib library. \n\n sapi_library(\n name = \"zlib-sapi\",\n srcs = [],\n hdrs = [],\n functions = [\n \"deflateInit_\",\n \"deflate\",\n \"deflateEnd\",\n ],\n lib = \"@net_zlib//:zlib\",\n lib_name = \"Zlib\",\n namespace = \"sapi::zlib\",\n )\n\nThe result is that the sandboxed zlib library is generated. The output is the\nSAPI Object which can be included into the Host Code and be used to communicate\nwith the sandboxed library via RPC calls. The Sandbox Policy used in this\nexample is the default policy.\n\n3. Write or Change the Host Code\n\nIt's now time to incorporate the generated SAPI Library into the Host Code.\n\nCreate the Sandbox\n\nUse `sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());` to create a\nsandbox object.\n\nUse `sapi::zlib::ZlibApi api(&sandbox);` to instantiate the SAPI Object and thus\nmake the sandboxed functions available for use.\n\nUse SAPI Types\n\n[SAPI Types](/code-sandboxing/sandboxed-api/variables#sapi_types) are special\ntypes in the form of C++ classes that SAPI provides because sometimes regular\nC-types will not work.\n\nThe first use of a SAPI type can be observed in the declaration of `strm`, where\na SAPI Struct is used: `sapi::v::Struct\u003csapi::zlib::z_stream\u003e strm;`\n\nThe template type (`sapi::zlib::z_stream`) is a good example of code\nautomatically generated by the build rule.\n\nTake a look at the [Variables page](/code-sandboxing/sandboxed-api/variables)\nfor more details.\n\nMake API Calls\n\nTo make calls to either `defalteInit_`, `deflate`, or `deflateEnd`, use the SAPI\nObject. If you decide to use the 'change' approach, you have to make sure that\nthe function parameters match the expected values.\n\nAn example of each of the calls in the [zlib\nexample](/code-sandboxing/sandboxed-api/examples#zlib):\n\n-\n\n ```css+lasso\n api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,\n version.PtrBefore(), sizeof(sapi::zlib::z_stream));\n ```\n-\n\n ```text\n api.deflate(strm.PtrBoth(), flush);\n ```\n-\n\n ```text\n api.deflateEnd(strm.PtrBoth()).IgnoreError();\n ```\n\nUsing SAPI Transactions\n\nSAPI isolates the Host Code from the Sandboxed Library and gives the caller the\nability to restart or abort problematic data processing requests. SAPI\nTransaction goes one step further and automatically repeats failed processes.\n\nTake a look at the [SAPI Transactions\nPage](/code-sandboxing/sandboxed-api/transactions) for more details.\n\nExamples\n\nUnder [Examples](/code-sandboxing/sandboxed-api/examples) you can find a few\nlibraries, already prepared by the SAPI team."]]