Di halaman ini, Anda akan mempelajari cara membuat library C/C++ dengan sandbox Anda sendiri menggunakan Sandboxed API (SAPI). Gunakan sebagai panduan bersama dengan contoh dan dokumentasi kode dalam file header.
Membangun Dependensi
Dependensi berikut harus diinstal di sistem:
- Kernel Linux dengan dukungan untuk UTS, IPC, pengguna, PID, dan namespace jaringan
- Header API userspace Linux
- Untuk mengompilasi kode Anda: GCC 6 (lebih disukai versi 7 atau yang lebih tinggi) atau Clang 7 (atau yang lebih tinggi)
- Untuk membuat file header secara otomatis: Clang Python Bindings
- Python 3.5 atau yang lebih baru
- Bazel versi 2.2.0 atau CMake versi 3.12 atau yang lebih tinggi.
Menggunakan Bazel
Bazel adalah sistem build yang direkomendasikan dan paling mudah diintegrasikan.
Dokumentasi kami menggunakan compiler Clang. Jika Anda memerlukan toolchain tertentu (misalnya compiler, linker, dll.), lihat dokumentasi Bazel untuk mengetahui informasi tentang cara mengubah toolchain compiler default.
Debian 10 (Buster)
Untuk menginstal dependensi build:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.listwget -qO - https://releases.bazel.build/bazel-release.pub.gpg | sudo apt-key add -sudo apt-get updatesudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-devpip3 install clang
Gentoo
Opsi kernel yang diperlukan:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Untuk menginstal dependensi build:
emerge dev-util/bazel dev-python/typing dev-python/clang-pythonMenggunakan CMake
CMake adalah sistem meta build open source populer yang menghasilkan file project untuk alat build seperti Ninja atau Make.
Debian 10 (Buster)
Untuk menginstal dependensi build:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-devpip3 install absl-py clang
Gentoo
Opsi kernel yang diperlukan:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Untuk menginstal dependensi build:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-pythonProses Pengembangan
Untuk melakukan sandbox pada library C/C++, Anda harus menyiapkan dua item untuk project Anda:
- Library yang Di-sandbox
- Kode Host yang akan menggunakan fungsi yang diekspos oleh Library dengan Sandbox Anda. SAPI akan otomatis membuat Objek SAPI dan Stub RPC untuk Anda selama proses build.
Anda mungkin sudah memahami zlib dari contoh Sandbox2. Di sini, seluruh program (zpipe.c) di-sandbox. Pada langkah-langkah berikut, Anda akan mempelajari cara menggunakan SAPI untuk men-sandbox library zlib dan memanfaatkan Library yang Di-sandbox.
1. Menentukan fungsi yang diperlukan
Jika melihat kode host zlib
(main_zlib.cc),
Anda dapat melihat bahwa fungsi alat ini adalah membaca data dari stdin dan menggunakan
fungsi deflate() zlib untuk mengompresi data hingga penanda EOF dibaca.
Secara total, program ini menggunakan tiga fungsi dari zlib:
deflateInit_(): Untuk melakukan inisialisasi kompresideflate(): Untuk melakukan operasi kompresi pada potongan datadeflateEnd(): Untuk mengakhiri kompresi dan membebaskan struktur data yang dialokasikan secara dinamis
Dalam contoh kehidupan nyata, Anda akan meninjau library C/C++ dan memutuskan fungsi mana yang diperlukan. Strategi yang mungkin adalah memulai dengan Kode Host dan menggunakan library tanpa sandbox. Kemudian, pada langkah kedua, Anda dapat membuat Library dengan Sandbox dan menyesuaikan Kode Host untuk menggunakan panggilan fungsi dengan sandbox.
2. Menulis Aturan Build sapi_library
Setelah mengidentifikasi tiga fungsi zlib yang diperlukan dari library zlib dengan sandbox, Anda dapat menentukan aturan build dalam file BUILD. Dokumentasi untuk aturan build sapi_library dapat ditemukan di halaman
Build Rules.
Cuplikan kode di bawah menunjukkan definisi sapi_library untuk contoh zlib SAPI. Dengan menggunakan atribut lib, Bazel diinstruksikan untuk mencari library zlib di file
WORKSPACE.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
Hasilnya adalah library zlib sandbox dibuat. Outputnya adalah Objek SAPI yang dapat disertakan ke dalam Kode Host dan digunakan untuk berkomunikasi dengan library yang di-sandbox menggunakan panggilan RPC.
Contoh ini menggunakan konfigurasi sandbox default yang disediakan oleh
DefaultConfig
(sapi::SandboxConfig::DefaultConfig()).
3. Menulis atau Mengubah Kode Host
Sekarang saatnya menggabungkan Library SAPI yang dihasilkan ke dalam Kode Host.
Buat Sandbox
Gunakan sapi::zlib::ZlibSandbox sandbox; untuk membuat
objek sandbox.
Gunakan sapi::zlib::ZlibApi api(&sandbox); untuk membuat instance Objek SAPI, sehingga fungsi dengan sandbox dapat digunakan.
Untuk menyesuaikan kebijakan, flag, variabel lingkungan, atau batas sandbox, mulai dari sapi::SandboxConfig::DefaultConfig(), ubah kolom yang relevan (menggunakan sapi::Sandbox2Config::DefaultPolicyBuilder(), sapi::SandboxConfig::DefaultFlags(), atau sapi::SandboxConfig::DefaultEnvironmentVariables() agar setelan dasar dipertahankan), dan teruskan sapi::SandboxConfig ke konstruktor sandbox:
sapi::SandboxConfig config = sapi::SandboxConfig::DefaultConfig();
config.sandbox2.policy = sapi::Sandbox2Config::DefaultPolicyBuilder()
.AddFile("/path/to/file")
.BuildOrDie();
auto flags = sapi::SandboxConfig::DefaultFlags();
flags["my_flag"] = "value";
config.command_line_flags = std::move(flags);
sapi::zlib::ZlibSandbox sandbox(std::move(config));
Menggunakan Jenis SAPI
Jenis SAPI adalah jenis khusus dalam bentuk class C++ yang disediakan SAPI karena terkadang jenis C biasa tidak akan berfungsi.
Penggunaan pertama jenis SAPI dapat diamati dalam deklarasi strm, tempat
Struct SAPI digunakan: sapi::v::Struct<sapi::zlib::z_stream> strm;
Jenis template (sapi::zlib::z_stream) adalah contoh kode yang baik
yang otomatis dibuat oleh aturan build.
Lihat halaman Variabel untuk mengetahui detail selengkapnya.
Melakukan Panggilan API
Untuk melakukan panggilan ke defalteInit_, deflate, atau deflateEnd, gunakan Objek SAPI. Jika Anda memutuskan untuk menggunakan pendekatan 'perubahan', Anda harus memastikan bahwa
parameter fungsi cocok dengan nilai yang diharapkan.
Contoh setiap panggilan di zlib example:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
Menggunakan Transaksi SAPI
SAPI mengisolasi Kode Host dari Library dengan Sandbox dan memberi pemanggil kemampuan untuk memulai ulang atau membatalkan permintaan pemrosesan data yang bermasalah. Transaksi SAPI melangkah lebih jauh dan mengulangi proses yang gagal secara otomatis.
Lihat Halaman Transaksi SAPI untuk mengetahui detail selengkapnya.
Contoh
Di bagian Contoh, Anda dapat menemukan beberapa library, yang telah disiapkan oleh tim SAPI.