Bắt đầu sử dụng Sandboxed API

Trên trang này, bạn sẽ tìm hiểu cách tạo thư viện C/C++ trong hộp cát của riêng mình bằng Sandboxed API (SAPI). Hãy dùng nó làm hướng dẫn cùng với các ví dụ và tài liệu về mã trong các tệp tiêu đề.

Xây dựng các phần phụ thuộc

Bạn phải cài đặt các phần phụ thuộc sau trên hệ thống:

  • Nhân Linux có hỗ trợ UTS, IPC, người dùng, PID và không gian tên mạng
  • Tiêu đề API không gian người dùng Linux
  • Để biên dịch mã của bạn: GCC 6 (nên dùng phiên bản 7 trở lên) hoặc Clang 7 (hoặc phiên bản cao hơn)
  • Để tự động tạo tệp tiêu đề: Clang Python Bindings
  • Python 3.5 trở lên
  • Bazel phiên bản 2.2.0 hoặc CMake phiên bản 3.12 trở lên.
    • Chỉ CMake: GNU Make hoặc một phiên bản của tiêu đề thư viện libcap và một công cụ tạo như Ninja (nên dùng).

Sử dụng Bazel

Bazel là hệ thống xây dựng được đề xuất và dễ tích hợp nhất.

Tài liệu của chúng tôi sử dụng trình biên dịch Clang. Nếu bạn cần một chuỗi công cụ cụ thể (ví dụ: trình biên dịch, trình liên kết, v.v.), hãy tham khảo tài liệu Bazel để biết thông tin về cách thay đổi chuỗi công cụ trình biên dịch mặc định.

Debian 10 (Buster)

Cách cài đặt các phần phụ thuộc của bản dựng:

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

Các lựa chọn bắt buộc của kernel:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

Cách cài đặt các phần phụ thuộc của bản dựng:

emerge dev-util/bazel dev-python/typing dev-python/clang-python

Sử dụng CMake

CMake là một hệ thống siêu bản dựng mã nguồn mở phổ biến, tạo ra các tệp dự án cho các công cụ bản dựng như Ninja hoặc Make.

Debian 10 (Buster)

Cách cài đặt các phần phụ thuộc của bản dựng:

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

Các lựa chọn bắt buộc của kernel:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

Cách cài đặt các phần phụ thuộc của bản dựng:

emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python

Quy trình phát triển

Để tạo hộp cát cho một thư viện C/C++, bạn sẽ phải chuẩn bị 2 mục cho dự án của mình:

Bạn có thể đã quen thuộc với zlib trong các ví dụ Sandbox2. Tại đây, toàn bộ chương trình (zpipe.c) đã được đưa vào hộp cát. Trong các bước sau, bạn sẽ tìm hiểu cách sử dụng SAPI để sandbox thư viện zlib và tận dụng Sandboxed Library.

1. Quyết định những hàm cần thiết

Nếu xem mã máy chủ zlib (main_zlib.cc), bạn có thể thấy rằng chức năng của công cụ này là đọc dữ liệu từ stdin và sử dụng hàm deflate() của zlib để nén dữ liệu cho đến khi đọc được một điểm đánh dấu EOF. Tổng cộng, chương trình này sử dụng 3 hàm từ zlib:

  • deflateInit_(): Để khởi tạo cho quá trình nén
  • deflate(): Để thực hiện thao tác nén trên khối dữ liệu
  • deflateEnd(): Để kết thúc quá trình nén và giải phóng các cấu trúc dữ liệu được phân bổ động

Trong ví dụ thực tế, bạn sẽ xem xét thư viện C/C++ và quyết định những hàm cần thiết. Một chiến lược có thể là bắt đầu bằng Mã máy chủ và sử dụng thư viện chưa được cách ly. Sau đó, ở bước thứ hai, bạn có thể tạo Thư viện trong hộp cát và điều chỉnh Mã máy chủ để sử dụng các lệnh gọi hàm trong hộp cát.

2. Viết quy tắc tạo sapi_library

Sau khi xác định được 3 hàm zlib cần thiết từ thư viện zlib được cách ly, bạn có thể xác định quy tắc bản dựng trong tệp BUILD. Bạn có thể xem tài liệu về quy tắc xây dựng sapi_library trên trang Quy tắc xây dựng.

Đoạn mã dưới đây cho thấy định nghĩa sapi_library cho ví dụ về SAPI zlib. Khi dùng thuộc tính lib, Bazel sẽ được hướng dẫn tìm thư viện zlib trong tệp WORKSPACE.

sapi_library(
    name = "zlib-sapi",
    srcs = [],
    hdrs = [],
    functions = [
        "deflateInit_",
        "deflate",
        "deflateEnd",
    ],
    lib = "@net_zlib//:zlib",
    lib_name = "Zlib",
    namespace = "sapi::zlib",
)

Kết quả là thư viện zlib được tạo trong hộp cát. Đầu ra là Đối tượng SAPI có thể được đưa vào Mã máy chủ và dùng để giao tiếp với thư viện trong hộp cát thông qua các lệnh gọi RPC. Chính sách hộp cát được dùng trong ví dụ này là chính sách mặc định.

3. Viết hoặc thay đổi mã chủ nhà

Giờ là lúc kết hợp Thư viện SAPI đã tạo vào Mã máy chủ.

Tạo Hộp cát

Sử dụng sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create()); để tạo một đối tượng hộp cát.

Sử dụng sapi::zlib::ZlibApi api(&sandbox); để tạo thực thể cho Đối tượng SAPI và do đó, cung cấp các hàm được cách ly để sử dụng.

Sử dụng các loại SAPI

Các loại SAPI là các loại đặc biệt dưới dạng các lớp C++ mà SAPI cung cấp vì đôi khi các loại C thông thường sẽ không hoạt động.

Lần đầu tiên sử dụng một loại SAPI có thể được quan sát trong khai báo strm, trong đó một Cấu trúc SAPI được dùng: sapi::v::Struct<sapi::zlib::z_stream> strm;

Loại mẫu (sapi::zlib::z_stream) là một ví dụ điển hình về mã do quy tắc bản dựng tự động tạo.

Hãy xem trang Biến để biết thêm thông tin chi tiết.

Tạo lệnh gọi API

Để gọi đến defalteInit_, deflate hoặc deflateEnd, hãy sử dụng Đối tượng SAPI. Nếu quyết định sử dụng phương pháp "thay đổi", bạn phải đảm bảo rằng các tham số hàm khớp với giá trị dự kiến.

Ví dụ về từng lệnh gọi trong ví dụ 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();

Sử dụng giao dịch SAPI

SAPI tách biệt Mã máy chủ khỏi Thư viện hộp cát và cho phép người gọi khởi động lại hoặc huỷ các yêu cầu xử lý dữ liệu có vấn đề. SAPI Transaction tiến thêm một bước nữa và tự động lặp lại các quy trình không thành công.

Hãy xem Trang Giao dịch SAPI để biết thêm thông tin chi tiết.

Ví dụ

Trong phần Ví dụ, bạn có thể tìm thấy một số thư viện do nhóm SAPI chuẩn bị sẵn.