在這個網頁中,您將瞭解如何使用 Sandboxed API (SAPI) 建立自己的沙箱 C/C++ 程式庫。也可以做為標頭檔案中的範例和程式碼說明文件使用。
建構依附元件
下列依附元件必須安裝在系統上:
- 支援 UTS、IPC、使用者、PID 和網路命名空間的 Linux kernel
- 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)
如要安裝建構依附元件:
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
熱托
必要核心選項:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
如要安裝建構依附元件:
emerge dev-util/bazel dev-python/typing dev-python/clang-python
使用 CMake
CMake 是熱門的開放原始碼中繼建構系統,可為 Ninja 或 Make 等建構工具產生專案檔案。
Debian 10 (Buster)
如要安裝建構依附元件:
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
熱托
必要核心選項:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
如要安裝建構依附元件:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
開發程序
若要為 C/C++ 程式庫設定沙箱,您必須為專案準備兩個項目:
- 沙箱程式庫
- 主機程式碼,會使用沙箱程式庫公開的功能。SAPI 會在建構過程中自動為您產生 SAPI 物件和遠端程序呼叫 (RPC),
您可能聽過整個程式 (zpipe.c) 的Sandbox2 範例中的 zlib。在後續步驟中,您將瞭解如何使用 SAPI 沙箱 zlib 程式庫,以及使用沙箱程式庫。
1. 決定所需的函式
當您查看 zlib 主機程式碼 (main_zlib.cc) 時,您會發現這項工具的功能是從 stdin 讀取資料,並使用 zlib 的 deflate()
函式壓縮資料,直到讀取 EOF
標記為止。該程式總共使用 zlib 的三個函式:
deflateInit_()
:初始化壓縮deflate()
:對資料區塊執行壓縮作業deflateEnd()
:結束壓縮並釋出動態分配的資料結構
在實際範例中,您可以查看 C/C++ 程式庫,並判斷需要哪些函式。可行的策略是從主機程式碼開始,並使用不採用沙箱機制的程式庫。接著,在第二個步驟中,您可以產生沙箱程式庫,並將主機程式碼調整為使用沙箱函式呼叫。
2. 寫入 sapi_library 建構規則
從沙箱 zlib 程式庫中找出必要的三個 zlib 函式後,您可以在 BUILD 檔案中定義建構規則。如需 sapi_library
建構規則的說明文件,請參閱「建構規則」頁面。
下列程式碼片段顯示 zlib SAPI 範例的 sapi_library
定義。使用 lib
屬性時,Bazel 會指示查看 zlib 程式庫的 WORKSPACE 檔案。
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
) 是建構規則自動產生的良好程式碼範例。
詳情請參閱「變數」頁面。
發出 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 交易頁面。